Summary
Async-mode chat (dynamic-thinking / fire-and-forget submission) with save_to_session=true completes the execution successfully but never creates a chat session — the conversation is silently lost instead of being persisted.
Context
Caught by two consecutive full-suite runs (2026-07-03, 2026-07-04):
tests/test_dynamic_thinking_status.py::TestAsyncModeSessionPersistence::test_async_mode_with_save_to_session (tests/test_dynamic_thinking_status.py:455) — 0 sessions found before AND after the async turn
::test_async_mode_session_contains_messages (tests/test_dynamic_thinking_status.py:514) — same
Environment cascade is ruled out: in the 2026-07-04 run the sibling async tests in the same module passed (test_async_mode_returns_accepted, test_async_mode_execution_id_is_pollable, test_async_mode_completes_eventually, test_sse_stream_available_during_execution) — so the async execution path itself worked while session persistence did not.
Acceptance Criteria
Technical Notes
save_to_session is handled in src/backend/routers/chat.py (model in src/backend/models.py)
- Suspect the async completion path finalizes the execution without running the session-persistence step the sync path runs — check where the sync path writes
chat_sessions/chat_messages vs what the async terminal applier does
Summary
Async-mode chat (dynamic-thinking / fire-and-forget submission) with
save_to_session=truecompletes the execution successfully but never creates a chat session — the conversation is silently lost instead of being persisted.Context
Caught by two consecutive full-suite runs (2026-07-03, 2026-07-04):
tests/test_dynamic_thinking_status.py::TestAsyncModeSessionPersistence::test_async_mode_with_save_to_session(tests/test_dynamic_thinking_status.py:455) — 0 sessions found before AND after the async turn::test_async_mode_session_contains_messages(tests/test_dynamic_thinking_status.py:514) — sameEnvironment cascade is ruled out: in the 2026-07-04 run the sibling async tests in the same module passed (
test_async_mode_returns_accepted,test_async_mode_execution_id_is_pollable,test_async_mode_completes_eventually,test_sse_stream_available_during_execution) — so the async execution path itself worked while session persistence did not.Acceptance Criteria
save_to_session=truecreates achat_sessionsrow and persists both user and assistant messages once the execution completesTestAsyncModeSessionPersistencetests pass in the integration suiteTechnical Notes
save_to_sessionis handled insrc/backend/routers/chat.py(model insrc/backend/models.py)chat_sessions/chat_messagesvs what the async terminal applier does