Repository navigation
Keep DeepSeek reasoning through tool calls and conversation replay - #1241
Conversation
Signed-off-by: dada-yan <BinjunYann@gmail.com>
WaylandYang
left a comment
There was a problem hiding this comment.
Thank you, this is the right fix and it goes through every place the field could get lost: parsing, rig, the final-answer call, the RAG fallback, storage and trimming. With tools in the request DeepSeek needs every previous turn's reasoning_content back, so replaying it for finished answers and not only tool turns is needed. Keeping it in tool_exchange and filtering it out of the replayed exchange avoids a migration, and counting it in the history budget keeps trimming honest.
One thing for later, not for this PR: other OpenAI-compatible endpoints that emit reasoning_content will now get it back too and spend history budget on it. If one of them turns out to reject it, the place to switch it off is push_message / to_message. Thanks again.
Why
In DeepSeek thinking mode, a reply can contain both
reasoning_contentand a tool call. The client discarded the reasoning, so the request carrying the tool result failed with HTTP 400. Conversation replay also discarded it, including the reasoning attached to completed answers, which DeepSeek requires on later requests carrying tools: provider protocol.What changes
LlmClientresponses, rig messages and subsequent tool requests. Preserve empty strings and omit absent fields.The code and tests exceed 500 added lines because parsing, rig translation, persistence and replay form one protocol path: all must retain the field for both tool continuation and the next user question to work. The tests cover those loss boundaries and an actual three-turn database round trip in this one fix.
Previously stored conversation rows remain readable; reasoning already discarded by older code cannot be reconstructed.
How it was checked
macOS arm64, Rust 1.98.1, commit
830b7a4based ondevat70bf7a7f:cargo +1.98.1 fmt --all --checkcargo +1.98.1 clippy --locked --offline --workspace --all-targets -- -D warningsUTOPIA_DATABASE_URL=<isolated PostgreSQL 16 + pgvector> UTOPIA_TEST_REQUIRE_DB=1 cargo +1.98.1 test --locked --offline --workspace: 1,540 reported passed, 0 failed, 6 ignored. Database-backed tests ran against a freshly migrated, dedicated local cluster; external-service smoke tests retain their usual skips when endpoints are unset.Before review
git commit -s).UTOPIA_DATABASE_URLset andUTOPIA_TEST_REQUIRE_DB=1.