feat: add reasoning_content support for OpenRouter chat completions#88
Conversation
commit: |
jpr5
left a comment
There was a problem hiding this comment.
PR Review Summary
Reviewed by 7 specialized agents (code-reviewer, silent-failure-hunter, test-analyzer, comment-analyzer, type-design-analyzer, test-file-reviewer, CI/packaging) across all 6 changed files.
Zero actionable findings — clean PR.
The implementation is straightforward and well-executed. reasoning_content is correctly threaded through the full pipeline:
- Types (
SSEDelta,ChatCompletionMessage): optional, not nullable — matches OpenRouter's wire format - Helpers (
buildTextChunks,buildTextCompletion): reasoning chunks emitted before content (streaming), conditional spread for non-streaming — both correct - Server (
handleCompletions): passesresponse.reasoningthrough to both builders — clean plumbing - Stream collapse (
collapseOpenAISSE): extractsreasoning_contentfrom deltas using the same defensive pattern as existing content extraction
Tests are solid — 8 new tests covering streaming ordering, content/reasoning reconstruction, absence cases, and stream-collapse extraction. Assertions are specific (exact string equality, index comparison for ordering), not weak.
One note
The branch is ~21 commits behind main (branched before v1.8.0). A rebase before merge would confirm no conflicts with the reasoning work that landed in PR #81.
🤖 Reviewed with Claude Code
OpenRouter returns reasoning via reasoning_content in the chat completions message/delta format. This adds support for emitting and collapsing reasoning_content in both streaming and non-streaming responses.
fc6a74c to
66e61be
Compare
|
Thank you! 🙏 |
## Summary - **Per-test sequence isolation** via `X-Test-Id` header — each test gets its own fixture match counters across all 12 HTTP + 3 WebSocket handlers (#93) - **Combined content + toolCalls** in fixture responses — new `ContentWithToolCallsResponse` type across OpenAI Chat, Responses, Anthropic Messages, and Gemini with stream collapse support (#92) - **OpenRouter reasoning_content** support (#88) - **Clean URLs** for docs site — all pages restructured as directories, .html extensions removed from links - Fix `web_search_call` items to use `action.query` matching real OpenAI API (#89) - Bump aimock-pytest to 0.3.0 ## Version bumps - `package.json`: 1.8.0 → 1.9.0 - `pyproject.toml`: 0.2.0 → 0.3.0 - `Chart.yaml` appVersion: 1.8.0 → 1.9.0 - `plugin.json` / `marketplace.json`: 1.8.0 → 1.9.0 ## Test plan - [x] All 2206 tests pass (including 80 new clean-URL validation tests) - [x] Build passes - [x] Prettier clean - [ ] npm publish triggers automatically on merge via OIDC workflow - [ ] Verify v1.9.0 appears on npm after merge 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Summary
reasoning_contentfield to chat completions streaming (delta.reasoning_content) and non-streaming (message.reasoning_content) responsescollapseOpenAISSEto extractreasoning_contentfrom chat completions delta chunks for record-and-replayWhat's included
This PR covers the aimock mock server side — emitting
reasoning_contentin/v1/chat/completionsresponses when a fixture hasreasoningset. It does NOT cover any additional OpenRouter-specific behavior (e.g.reasoning_details, model routing, provider preferences). Those may need separate work.Files changed
src/types.ts— addedreasoning_contenttoSSEDeltaandChatCompletionMessagesrc/helpers.ts—buildTextChunksandbuildTextCompletionnow accept and emit reasoningsrc/server.ts— passesresponse.reasoningthrough to chat completions builderssrc/stream-collapse.ts— extractsreasoning_contentfrom chat completions deltasTest plan
🤖 Generated with Claude Code