mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-11-12 22:20:33 +00:00
* feat(hitl): add human-in-the-loop approval for high-risk tool calls * fix(hitl): address approval review findings * docs(hitl): keep agent guidance under size limit * fix(hitl): guard approval pause recovery * docs(hitl): shrink inherited guidance * fix(hitl): harden approval admission and recovery * fix(approvals): address review safety and reconciliation gaps * ci: retry approval checks after runner timeout --------- Co-authored-by: wangzeren <1004695029@qq.com>
35 lines
1.8 KiB
Python
35 lines
1.8 KiB
Python
"""Exercise upgrade, retry and downgrade through the actual migration chain."""
|
|
|
|
import asyncio
|
|
|
|
import pytest
|
|
import sqlalchemy as sa
|
|
from alembic import command
|
|
from sqlalchemy.ext.asyncio import create_async_engine
|
|
|
|
from deerflow.persistence import bootstrap
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_approval_migration_retry_and_downgrade(tmp_path):
|
|
engine = create_async_engine(f"sqlite+aiosqlite:///{tmp_path / 'migration.db'}")
|
|
cfg = bootstrap._get_alembic_config(engine)
|
|
try:
|
|
await asyncio.to_thread(command.upgrade, cfg, "0052_batch_continuation")
|
|
await asyncio.to_thread(command.upgrade, cfg, "0053_tool_approvals")
|
|
async with engine.begin() as conn:
|
|
await conn.execute(sa.text("INSERT INTO tool_approvals (request_id,user_id,thread_id,incarnation,run_id,fingerprint,kind,status,payload,created_at) VALUES ('r','u','t','i','run','fingerprint','audit','consumed','{}',1)"))
|
|
await asyncio.to_thread(command.stamp, cfg, "0052_batch_continuation")
|
|
async with engine.begin() as conn:
|
|
await conn.execute(sa.text("DROP INDEX ix_tool_approvals_scope"))
|
|
await asyncio.to_thread(command.upgrade, cfg, "0053_tool_approvals")
|
|
async with engine.connect() as conn:
|
|
assert (await conn.execute(sa.text("SELECT request_id FROM tool_approvals"))).scalar_one() == "r"
|
|
indexes = await conn.run_sync(lambda c: sa.inspect(c).get_indexes("tool_approvals"))
|
|
assert {index["name"] for index in indexes} == {"ix_tool_approvals_run", "ix_tool_approvals_scope"}
|
|
await asyncio.to_thread(command.downgrade, cfg, "0052_batch_continuation")
|
|
async with engine.connect() as conn:
|
|
assert not await conn.run_sync(lambda c: sa.inspect(c).has_table("tool_approvals"))
|
|
finally:
|
|
await engine.dispose()
|