Fix interrupted run replay state

This commit is contained in:
武阳
2026-05-07 17:07:57 +08:00
parent 47d3678a18
commit 5b4f7c2c8d
3 changed files with 409 additions and 12 deletions
+103
View File
@@ -257,6 +257,109 @@ class GuiServerTests(unittest.TestCase):
self.assertEqual(payload['status'], 'running')
self.assertEqual(payload['current_stage'], 'first stage')
def test_cancel_run_marks_streaming_session_tail_cancelled(self) -> None:
with tempfile.TemporaryDirectory() as d:
root = Path(d)
client, state = _build_client(root)
session_root = root / 'accounts' / 'alice' / 'sessions'
save_agent_session(
StoredAgentSession(
session_id='thread-1',
model_config={'model': 'test-model'},
runtime_config={'cwd': str(root)},
system_prompt_parts=('system prompt',),
user_context={},
system_context={},
messages=(
{'role': 'user', 'content': 'hello'},
{
'role': 'assistant',
'content': '我先看看文件',
'tool_calls': [
{
'id': 'call-1',
'function': {'name': 'list_dir', 'arguments': '{}'},
}
],
},
{
'role': 'tool',
'content': '',
'tool_call_id': 'call-1',
'state': 'streaming',
'metadata': {'phase': 'starting'},
},
),
turns=1,
tool_calls=1,
usage={},
total_cost_usd=0.0,
file_history=(),
budget_state={'status': 'running'},
plugin_state={},
),
directory=session_root,
)
state.run_manager.start('alice', 'thread-1')
response = client.post(
'/api/runs/cancel',
json={'account_id': 'alice', 'session_id': 'thread-1'},
)
self.assertEqual(response.status_code, 200)
self.assertTrue(response.json()['cancelled'])
stored = load_agent_session('thread-1', directory=session_root)
self.assertEqual(stored.messages[-1]['role'], 'assistant')
self.assertEqual(stored.messages[-1]['stop_reason'], 'cancelled')
self.assertEqual(
stored.messages[-1]['metadata']['status'],
'cancelled',
)
self.assertNotEqual(stored.messages[-1].get('state'), 'streaming')
def test_latest_run_reports_interrupted_for_orphaned_streaming_session(self) -> None:
with tempfile.TemporaryDirectory() as d:
root = Path(d)
client, _ = _build_client(root)
session_root = root / 'accounts' / 'alice' / 'sessions'
save_agent_session(
StoredAgentSession(
session_id='thread-1',
model_config={'model': 'test-model'},
runtime_config={'cwd': str(root)},
system_prompt_parts=('system prompt',),
user_context={},
system_context={},
messages=(
{'role': 'user', 'content': 'hello'},
{
'role': 'tool',
'content': '',
'tool_call_id': 'call-1',
'state': 'streaming',
'metadata': {'phase': 'starting'},
},
),
turns=1,
tool_calls=1,
usage={},
total_cost_usd=0.0,
file_history=(),
budget_state={'status': 'running'},
plugin_state={},
),
directory=session_root,
)
response = client.get(
'/api/runs/latest',
params={'account_id': 'alice', 'session_id': 'thread-1'},
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json()['status'], 'interrupted')
def test_chat_uses_account_scoped_model_config(self) -> None:
with tempfile.TemporaryDirectory() as d:
client, _ = _build_client(Path(d))