Several downstream clients send non-cache compatibility fields across Chat, Responses, Anthropic Messages, and Responses WebSocket surfaces. The proxy now normalizes legacy functions/function_call, maps web_search tools across protocols, rejects unsupported HTTP Responses continuation shapes before upstream dispatch, and applies configurable service_tier policy consistently before requests leave the server.
Constraint: Publication flow keeps day-to-day commits on dev and opens main PRs from a release branch.
Constraint: No new dependencies; web_search-only simulation reuses the existing local search route.
Rejected: Forward external HTTP previous_response_id to strict upstreams | it produces ambiguous continuation failures and stale retry behavior outside WebSocket state.
Rejected: Add a dedicated search dependency | existing /v1/search route is sufficient for synthetic server-tool responses.
Confidence: high
Scope-risk: moderate
Directive: Keep Responses HTTP continuation checks aligned with WebSocket continuation support before relaxing these guards.
Tested: npm run typecheck:server
Tested: npx vitest run --root . src/server/proxy-core/responsesPreflight.test.ts src/server/proxy-core/serviceTierPolicy.test.ts src/server/test-fixtures/protocol/non-cache-field-matrix.test.ts src/server/transformers/openai/responses/conversion.test.ts src/server/transformers/anthropic/messages/conversion.test.ts src/server/routes/proxy/chat.stream.test.ts src/server/routes/proxy/responses.codex-oauth.test.ts
Tested: npx vitest run --root . src/server/routes/proxy/responses.websocket.test.ts
Tested: npm run repo:drift-check
Not-tested: Full application build and full Vitest suite
Co-authored-by: OmX <omx@oh-my-codex.dev>
The last CI failure after the review cleanup was only a stale test expectation:
function_call fallback items now correctly use fc_* item ids while preserving the
call_* id in call_id. Updating the test keeps the suite aligned with the
Responses payload shape we intentionally adopted in the bridge.
Constraint: Keep the fix to the assertion only; the production behavior already matches the reviewed contract
Rejected: Revert the fc_* item id change | that would reopen the review thread we intentionally fixed
Confidence: high
Scope-risk: narrow
Directive: When bridge output semantics change intentionally, update sibling facade tests in the same PR so CI reflects the new contract immediately
Tested: Focused vitest for openai responses outbound/response bridge, Gemini request bridge, Settings payload rules; typecheck; git diff --check
Not-tested: Full npm test
The remaining review threads were down to route alias hygiene, proxy-safe header
ordering, and a Gemini canonical tool-result mismatch. This commit makes the
alias/websocket behavior explicit, preserves contributor helper safety, and
teaches the canonical Gemini path to recover tool names and wrap function
results the same way the OpenAI-shaped path already does.
Constraint: Keep the last review fixes limited to the current branch so the release PR stays easy to reason about
Rejected: Defer the Gemini canonical fix to a later refactor | the review found a real functional mismatch and the fix stayed localized to the request bridge
Confidence: high
Scope-risk: narrow
Directive: Keep canonical-to-provider bridges internally consistent; if one path resolves tool names or wraps results, the sibling path should not diverge silently
Tested: Focused vitest for Gemini request bridge, route aliases, upstream request builder, responses response bridge, contributor updater; typecheck; git diff --check
Not-tested: Full npm test; any broader end-to-end Gemini live-provider behavior outside the covered bridge tests
The latest review pass found a few more concrete edge-cases that were still
cheap to close: invalid /responses aliases could still rewrite typos, websocket
session headers should prefer proxy-safe dashed forms, contributor rendering
needed an input guard, and several upstream request/response helpers still had
small contract mismatches around Accept/beta handling and synthesized tool ids.
These fixes keep the release branch behavior explicit while the PR remains open.
Constraint: Keep changes surgical and well-covered so the review cleanup does not destabilize the already-green release branch
Rejected: Leave these for post-merge cleanup | they were still active review threads with straightforward fixes
Confidence: high
Scope-risk: narrow
Directive: When alias routes exist only for ergonomics, reject unknown subpaths loudly instead of silently rewriting them
Tested: Focused vitest for contributor updater, route aliases, upstream request builder, openai responses response bridge; typecheck; git diff --check
Not-tested: Full npm test; the remaining Gemini review thread that likely needs a broader canonical-tool-result contract decision
A few review threads still pointed at real behavior mismatches: Anthropic tool
JSON deltas were still trimming whitespace, Responses conversion still raised
low token caps to the floor, and the bare /responses GET alias returned upgrade
messaging that did not match the actual websocket entrypoint. This commit makes
those behaviors explicit and locks them with focused tests.
Constraint: Keep the release branch green while fixing only the review findings that have a clear, testable contract
Rejected: Leave these for a follow-up cleanup PR | they were low-diff and directly blocked comment resolution on the current release PR
Confidence: high
Scope-risk: narrow
Directive: Preserve raw stream delta text unless a downstream protocol explicitly requires normalization; whitespace can be semantic in incremental payloads
Tested: Focused vitest for anthropic stream bridge, responses conversion, route aliases; typecheck; git diff --check
Not-tested: Full npm test; the remaining review threads that still need broader product decisions
The PR still had a few targeted review threads around contributor pagination,
route-layer passthroughs, dead header fallbacks, and synthetic response ids.
These are small enough to settle directly on the release branch without
broadening the merge scope, and they tighten the repo back toward the
service-owned boundaries this refactor is aiming for.
Constraint: Keep the changes narrow and regression-covered so the release PR stays green while review threads are closed out
Rejected: Leave the minor threads for follow-up after merge | they were isolated enough to fix now and would keep noise on the PR
Confidence: high
Scope-risk: narrow
Directive: When a route shim stops serving any route-local behavior, point callers at the owning service instead of keeping a passthrough around
Tested: Focused vitest for contributor updater, openai responses response bridge, upstream request builder, stats proxy logs, architecture boundaries; typecheck; repo drift check; git diff --check
Not-tested: Full npm test; unresolved review threads that still require larger product decisions
The release branch still had unresolved review comments around payload-rule
atomicity, brand blocking, compact fallback controls, and response
compatibility edge-cases. This patch pulls those behaviors back in line with
the intended contracts and adds focused regression coverage for the fragile
bridges.
Constraint: The fixes must stay narrow to the PR branch so review/merge can continue without reopening the larger dev snapshot conflict set
Rejected: Leave outdated-looking threads unresolved until after merge | reviewers still see concrete unfixed regressions in the current release branch
Rejected: Re-run another broad merge from dev/main | too risky while the PR branch is already green and mergeable
Confidence: medium
Scope-risk: moderate
Directive: If these release-branch fixes need to persist for future release cuts, backport them onto dev instead of re-fighting the same review threads next time
Tested: Focused vitest for settings events, brand matcher, compact responses, codex compatibility, anthropic stream bridge, openai chat response bridge; typecheck; repo drift check; git diff --check
Not-tested: Full npm test; live PR thread resolution state after push
The transferred dev snapshot was not publication-ready yet: full tests still
failed because worktree-local docs resolution assumed a repo-root node_modules
tree, some protocol expectations no longer matched the refactored request
bridges, oauth/account-token route tests reused stale modules after resetting
DATA_DIR, and model discovery still fired unawaited default-token writes.
This follow-up makes the moved dev branch self-consistent and green again by
stabilizing module/test isolation, awaiting token mirroring writes, and
aligning narrow tests with the current transformer and request-builder
contracts.
Constraint: The fix set had to stay narrow and unblock the new dev branch without reworking the broader transferred refactor
Rejected: Revert the transferred snapshot | would lose the user's requested dev-branch continuation point
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: If more DATA_DIR-scoped API test files start flaking under shared workers, reset modules before importing singleton db/config modules instead of relying on process env mutation alone
Tested: git diff --check; npm run typecheck; npm run repo:drift-check; npm test
Not-tested: Live OAuth/provider flows outside the mocked test harness
The root checkout already contained a large in-progress proxy, transformer,
and settings refactor. This commit captures that exact work on a dedicated
local dev branch without disturbing the original dirty worktree, so the
changes can be continued or split from dev instead of living only as
uncommitted state.
Constraint: The source checkout was already dirty on another branch, so the move had to preserve that worktree while excluding local .idea and .omx residue from the commit
Rejected: Switch the dirty root checkout directly to dev | risked disrupting the original branch and in-progress state
Confidence: medium
Scope-risk: broad
Reversibility: clean
Directive: Treat this as a transfer snapshot; fix the failing oauth/accountTokens/normalized/docs test regressions before merge or publication
Tested: git diff --check; npm run typecheck; npm run repo:drift-check
Not-tested: Clean test pass; npm test currently fails in oauth routes, accountTokens sync, shared normalized helpers, gemini route expectations, architecture-boundaries, and docs vitepress config
Fixes#130
The inbound normalizer forwarded all unknown top-level fields to Gemini
API. Client-specific fields like requestId caused upstream 400 errors.
Changed from blocklist (only 3 entries) to allowlist of known Gemini API
fields: contents, systemInstruction, cachedContent, safetySettings,
generationConfig, tools, toolConfig, labels, model.
- Added support for preserving native response.compaction payloads when compact serialization is requested in `serializeResponsesFinalPayload`.
- Implemented serialization of compact mode as `response.compaction` instead of an ordinary response object.
- Introduced a new type `ResponsesFinalSerializationMode` to manage serialization modes.
- Refactored `serializeResponsesFinalPayload` to handle different serialization modes and usage payloads.
- Added tests to ensure correct behavior for compact serialization and preservation of upstream payloads.
- Updated favicon assets and documentation configuration for VitePress.
- Added `routeCompatibility.ts` to handle response compatibility for different endpoints.
- Introduced `chatEndpointStrategy.ts` to manage chat endpoint recovery and downgrading logic.
- Created tests for chat formats and input file handling in `chatFormatsCore.test.ts` and `inputFile.test.ts`.
- Developed `endpointCompatibility.ts` to define compatibility checks and header building for various endpoints.
- Implemented protocol lifecycle management in `protocolLifecycle.ts` and corresponding tests in `protocolModel.test.ts`.
- Enhanced tooltip functionality with a new `TooltipLayer` component and associated tests.
- Refactored existing components to improve tooltip handling and ensure proper rendering in the application.
- Updated modelTesterSession tests to serialize assistant history as output_text and removed mime_type from input_file.
- Introduced new tests for stats proxy logs routes, covering paginated log retrieval and detailed log views with parsed billing details.
- Added server-driven tests for ProxyLogs component to validate API interactions and UI rendering based on server data.
- Updated chat stream tests to clarify reasoning behavior and ensure correct handling of include lists.
- Enhanced responses proxy route to normalize include lists and apply default reasoning includes based on request context.
- Improved transformer metadata handling, ensuring proper serialization and deserialization of metadata records.
- Added tests for preserving reasoning signatures and managing citations in OpenAI-compatible responses.
- Refined the logic for injecting default includes in responses and ensured compatibility with codex surface defaults.