fix(anthropic): preserve response model metadata - #1122
Conversation
📝 WalkthroughWalkthroughThe change separates physical routed model identity from the client-facing response identifier. It adds hidden Anthropic compatibility aliases, stores ChangesRouted model identity
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant CodexClient
participant ResponsesCore
participant RoutedProvider
participant ResponseBridge
participant RequestLog
CodexClient->>ResponsesCore: Send routed model selector
ResponsesCore->>RoutedProvider: Send physical model identifier
RoutedProvider-->>ResponsesCore: Return response payload
ResponsesCore->>ResponseBridge: Provide _responseModelId
ResponseBridge-->>CodexClient: Emit canonical response model
ResponsesCore->>RequestLog: Preserve physical resolvedModel
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
⏳ DRAFT
What to do
Review readiness checklist
1/4 boxes ticked. This PR stays in draft until every box above is ticked. |
|
✅ Deterministic PR hygiene checks passed. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/response-model-identity.test.ts`:
- Around line 54-68: Add focused Bun regression tests near the existing
response-model identity tests that activate both the image-loop and
web-search-loop sidecar bridge paths. For each path, assert the upstream request
uses the bare model ID and every client-facing Responses event reports the
provider-qualified selector, covering streaming behavior rather than only the
non-streaming openai-chat adapter path.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 7ac23ed6-d419-4926-bf19-2e3f8b261210
📒 Files selected for processing (10)
src/codex/catalog/sync.tssrc/images/loop.tssrc/server/request-log.tssrc/server/responses/core.tssrc/types.tssrc/web-search/loop.tstests/codex-catalog-restore.test.tstests/codex-catalog.test.tstests/request-log.test.tstests/response-model-identity.test.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7217bba887
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
This is a valuable implementation and the request-log preservation is an improvement over the first maintainer draft. I would prefer to keep the contributor PR if the remaining contract gaps are closed. Before marking it ready, please address these points:
Please keep the PR in draft until those are covered and all CI/review findings are resolved. I am leaving #1121 open only as a comparison/reference while this contributor PR is updated; I will not merge either duplicate in the current state. |
7217bba to
edec576
Compare
|
All requested contract gaps are addressed on
Verification on the rebased head: 370 focused tests, 0 failures, 1,666 assertions; typecheck and privacy scan pass. The full local suite produced 9,431 passes / 8 skips with one unrelated intermittent @codex review |
|
✅ Action performedReview finished.
|
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/codex/catalog/provider-fetch.ts`:
- Line 568: Resolve the effective per-model adapter before populating catalog
metadata, rather than copying the provider adapter. In
src/codex/catalog/provider-fetch.ts lines 568 and 1297-1302, update the
CatalogModel adapter assignments to use the existing resolver with provider
metadata and the relevant model.id or cm.modelId, preserving provider adapters
as the fallback when no model override exists.
In `@src/codex/catalog/sync.ts`:
- Around line 386-396: Update the compatibility-alias generation around the
existing routed-slug deduplication in the sync flow to track emitted hidden
aliases separately by bare Anthropic physical ID. When multiple providers share
the same m.id, deterministically retain one compatibility row and its routed
target instead of emitting duplicate slug values; preserve the existing
resolveSlugAliasCollisions behavior for routed-public slugs and satisfy the
two-provider coverage in tests/codex-catalog.test.ts.
In `@src/codex/convergence.ts`:
- Around line 181-185: Update the empty-discovery fallback in the convergence
logic around nativeSlugs to retain compatibility aliases whose
opencodex_routed_slug targets a preserved routed row, while keeping direct alias
exclusion from nativeSlugs. Ensure retained aliases preserve their context and
compaction metadata, and add a regression test covering convergence with an
empty provider discovery result.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 3f1fb371-df4c-4fc4-b177-2f42de34b131
📒 Files selected for processing (24)
src/codex/catalog/effort.tssrc/codex/catalog/parsing.tssrc/codex/catalog/provider-fetch.tssrc/codex/catalog/sync.tssrc/codex/convergence.tssrc/images/loop.tssrc/server/index.tssrc/server/request-log.tssrc/server/responses-model-rewrite.tssrc/server/responses/core.tssrc/types.tssrc/web-search/loop.tsstructure/03_catalog-and-subagents.mdstructure/04_transports-and-sidecars.mdtests/codex-catalog-restore.test.tstests/codex-catalog.test.tstests/codex-convergence-contract.test.tstests/images/loop.test.tstests/openai-api-virtual-models.test.tstests/openai-provider-option-e2e.test.tstests/passthrough-abort.test.tstests/request-log.test.tstests/response-model-identity.test.tstests/web-search.test.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: edec576496
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Follow-up review fixes are on @codex review |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Current revision and recent commits ==='
git rev-parse --short HEAD
git show --no-patch --oneline HEAD
git show --no-patch --oneline 538b0285 2>/dev/null || true
git show --no-patch --oneline be85b99b 2>/dev/null || true
echo '=== Files changed from PR base (merge-base with origin default branch if available) ==='
base_ref=""
for ref in origin/main origin/master main master; do
if git rev-parse --verify -q "$ref" >/dev/null; then
base_ref="$ref"
break
fi
done
if [ -n "$base_ref" ]; then
merge_base="$(git merge-base "$base_ref" HEAD)"
git diff --name-status "$merge_base"...HEAD
else
git show --stat --oneline HEAD
fi
echo '=== Follow-up commit diffs ==='
for commit in 538b0285 be85b99b; do
if git rev-parse --verify -q "$commit" >/dev/null; then
echo "--- $commit ---"
git diff --unified=50 "${commit}^" "$commit" -- \
src/codex src/server src/types.ts tests structure || true
fi
done
echo '=== Relevant symbol map ==='
for file in \
src/codex/catalog/parsing.ts \
src/codex/catalog/provider-fetch.ts \
src/codex/catalog/sync.ts \
src/codex/convergence.ts \
src/server/request-log.ts \
src/server/responses/core.ts \
src/server/responses-model-rewrite.ts \
tests/response-model-identity.test.ts \
tests/codex-catalog.test.ts \
tests/codex-convergence-contract.test.ts \
tests/request-log.test.ts; do
if [ -f "$file" ]; then
echo "--- $file ---"
ast-grep outline "$file" --items all 2>/dev/null || true
fi
doneLength of output: 138021 🏁 Script executed: #!/bin/bash
set -euo pipefail
show() {
local file="$1" start="$2" end="$3"
echo "=== ${file}:${start}-${end} ==="
nl -ba "$file" | sed -n "${start},${end}p"
}
show src/codex/catalog/parsing.ts 88 140
show src/codex/catalog/sync.ts 314 424
show src/codex/catalog/sync.ts 460 675
show src/codex/catalog/sync.ts 980 1110
show src/codex/convergence.ts 162 226
show src/codex/catalog/provider-fetch.ts 519 615
show src/server/adapter-resolve.ts 1 220
show src/providers/slug-codec.ts 1 260
show src/router.ts 1 260
show src/server/responses/core.ts 850 975
show src/providers/openai-virtual-models.ts 1 240
show src/server/request-log.ts 500 635
show src/server/request-log.ts 750 860
echo '=== All preservation/alias/adapter override references ==='
rg -n -C 4 \
'preserveResolvedModelFromRoute|routedContextCompatTarget|isRoutedContextCompatEntry|ROUTED_CONTEXT_COMPAT_CATALOG_KIND|modelAdapters|resolveWireProtocolOverride' \
src tests \
-g '*.ts'
echo '=== Response identity test remainder ==='
nl -ba tests/response-model-identity.test.ts | sed -n '90,280p'
echo '=== Catalog alias and convergence test context ==='
nl -ba tests/codex-catalog.test.ts | sed -n '740,900p'
nl -ba tests/codex-convergence-contract.test.ts | sed -n '130,240p'Length of output: 1645 🏁 Script executed: #!/bin/bash
set -euo pipefail
show() {
local file="$1" start="$2" end="$3"
echo "=== ${file}:${start}-${end} ==="
sed -n "${start},${end}p" "$file" | awk -v n="$start" '{printf "%6d\t%s\n", n++, $0}'
}
show src/codex/catalog/parsing.ts 88 140
show src/codex/catalog/sync.ts 314 424
show src/codex/catalog/sync.ts 460 675
show src/codex/catalog/sync.ts 980 1110
show src/codex/convergence.ts 162 226
show src/codex/catalog/provider-fetch.ts 519 615
show src/server/adapter-resolve.ts 1 220
show src/providers/slug-codec.ts 1 260
show src/router.ts 1 260
show src/server/responses/core.ts 850 975
show src/providers/openai-virtual-models.ts 1 240
show src/server/request-log.ts 500 635
show src/server/request-log.ts 750 860
echo '=== All preservation/alias/adapter override references ==='
rg -n -C 4 \
'preserveResolvedModelFromRoute|routedContextCompatTarget|isRoutedContextCompatEntry|ROUTED_CONTEXT_COMPAT_CATALOG_KIND|modelAdapters|resolveWireProtocolOverride' \
src tests \
-g '*.ts'
echo '=== Response identity test remainder ==='
show tests/response-model-identity.test.ts 90 280
echo '=== Catalog alias and convergence test context ==='
show tests/codex-catalog.test.ts 740 900
show tests/codex-convergence-contract.test.ts 130 240Length of output: 175307
If the active catalog contains:
then both targets survive at Lines 585-592. The sync result contains two entries with This conflicts with the invariant in Please deduplicate retained aliases by You are interacting with an AI system. |
|
Addressed the remaining empty-discovery sync case in @codex review |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Follow-up commit ==='
git show --no-patch --oneline f121d324
git diff --unified=35 'f121d324^' f121d324 -- \
src/codex/catalog/sync.ts tests/codex-catalog.test.ts
echo '=== Relevant symbols ==='
ast-grep outline src/codex/catalog/sync.ts --items all --match 'buildCatalogEntries|sync|Catalog' || true
ast-grep outline tests/codex-catalog.test.ts --items all --match 'compat|sync|alias' || true
echo '=== Compatibility alias references with context ==='
rg -n -C 10 \
'routedContextCompatTarget|isRoutedContextCompatEntry|retainedCompat|compatCandidates|ROUTED_CONTEXT_COMPAT_CATALOG_KIND' \
src/codex/catalog/sync.ts tests/codex-catalog.test.ts
echo '=== Documentation invariant ==='
rg -n -C 5 'one hidden|compatibility alias|routed-context-compat' \
structure/03_catalog-and-subagents.mdLength of output: 29770
This behavior matches the invariant in If you found this review helpful, would you consider giving us a shout-out on X? Thank you for using CodeRabbit! ✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/codex/convergence.ts`:
- Around line 205-211: Update the preservedCompat filter in the convergence
logic to deduplicate retained aliases by both routed target and slug, tracking
each accepted target alongside preservedAliasSlugs. Add a regression case
covering two distinct alias slugs referencing the same surviving
opencodex_routed_slug, ensuring convergence retains only one alias row.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 40558b1b-c37c-4f35-92b2-8eada959a0a5
📒 Files selected for processing (9)
src/codex/catalog/provider-fetch.tssrc/codex/catalog/sync.tssrc/codex/convergence.tssrc/server/responses/core.tsstructure/03_catalog-and-subagents.mdstructure/04_transports-and-sidecars.mdtests/codex-catalog.test.tstests/codex-convergence-contract.test.tstests/response-model-identity.test.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f121d324fc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
23225b7 to
471356f
Compare
|
@codex review Rebased on current |
|
@coderabbitai review Please re-review rebased head |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Revision ==='
git rev-parse --short HEAD
git show --no-patch --format='%H%n%s%n%P' HEAD
git show --no-patch --oneline 471356f9 2>/dev/null || true
echo '=== Merge base and changed files ==='
base_ref=''
for ref in origin/dev dev origin/main main origin/master master; do
if git rev-parse --verify -q "$ref" >/dev/null; then
base_ref="$ref"
break
fi
done
if [ -n "$base_ref" ]; then
merge_base="$(git merge-base "$base_ref" HEAD)"
echo "base_ref=$base_ref"
echo "merge_base=$merge_base"
git diff --name-status "$merge_base"...HEAD
echo '=== Diff stat ==='
git diff --stat "$merge_base"...HEAD
else
echo 'No base ref found; showing current commit stat.'
git show --stat --oneline HEAD
fi
echo '=== Relevant symbol outlines ==='
for file in \
src/codex/catalog/sync.ts \
src/codex/catalog/parsing.ts \
src/codex/convergence.ts \
src/codex/catalog/provider-fetch.ts \
src/server/responses/core.ts \
src/server/responses-model-rewrite.ts \
src/server/request-log.ts \
src/images/loop.ts \
src/web-search/loop.ts \
src/types.ts \
tests/response-model-identity.test.ts \
tests/codex-catalog.test.ts \
tests/codex-convergence-contract.test.ts \
tests/request-log.test.ts \
tests/images/loop.test.ts \
tests/web-search.test.ts; do
if [ -f "$file" ]; then
echo "--- $file ---"
ast-grep outline "$file" --items all 2>/dev/null || true
fi
done
echo '=== Identity and compatibility-alias references ==='
rg -n -C 5 \
'_responseModelId|preserveResolvedModelFromRoute|rewriteResponsesModelJson|createResponsesModelPayloadRewrite|isRoutedContextCompatEntry|routedContextCompatTarget|ROUTED_CONTEXT_COMPAT_CATALOG_KIND|opencodex_routed_slug' \
src tests structure \
-g '*.ts' -g '*.md'Length of output: 128484 🏁 Script executed: #!/bin/bash
set -euo pipefail
show() {
local file="$1" start="$2" end="$3"
echo "=== ${file}:${start}-${end} ==="
nl -ba "$file" | sed -n "${start},${end}p"
}
echo '=== Rebased head commit diff ==='
git diff --unified=60 HEAD^ HEAD -- \
src/codex/catalog/sync.ts \
src/codex/catalog/parsing.ts \
src/codex/convergence.ts \
src/codex/catalog/provider-fetch.ts \
src/server/responses/core.ts \
src/server/responses-model-rewrite.ts \
src/server/request-log.ts \
src/images/loop.ts \
src/web-search/loop.ts \
src/types.ts \
tests/response-model-identity.test.ts \
tests/codex-catalog.test.ts \
tests/codex-convergence-contract.test.ts \
tests/request-log.test.ts \
tests/images/loop.test.ts \
tests/web-search.test.ts \
structure/03_catalog-and-subagents.md \
structure/04_transports-and-sidecars.md
echo '=== Final route normalization ==='
show src/server/responses/core.ts 850 950
echo '=== Responses model rewriter ==='
show src/server/responses-model-rewrite.ts 1 80
echo '=== Passthrough SSE and JSON paths ==='
show src/server/responses/core.ts 2020 2145
show src/server/responses/core.ts 2240 2320
echo '=== Bridge JSON and SSE paths ==='
show src/server/responses/core.ts 2550 2675
show src/server/responses/core.ts 3240 3375
echo '=== Catalog generation and empty-discovery retention ==='
show src/codex/catalog/sync.ts 319 425
show src/codex/catalog/sync.ts 570 625
show src/codex/convergence.ts 162 235
echo '=== Response identity test ==='
show tests/response-model-identity.test.ts 1 330
echo '=== Alias regressions ==='
show tests/codex-catalog.test.ts 780 945
show tests/codex-convergence-contract.test.ts 145 235
echo '=== Normalization call sites and direct upstream response returns ==='
rg -n -C 4 'applyFinalRouteRequestNormalization\s*\(|return upstreamResponse|new Response\(upstreamResponse\.body|rewriteResponsesModelJson|createResponsesModelPayloadRewrite' \
src/server/responses/core.tsLength of output: 120640 🏁 Script executed: #!/bin/bash
set -euo pipefail
show() {
local file="$1" start="$2" end="$3"
echo "=== ${file}:${start}-${end} ==="
sed -n "${start},${end}p" "$file" | awk -v line="$start" '{printf "%6d %s\n", line++, $0}'
}
echo '=== Final route normalization ==='
show src/server/responses/core.ts 850 965
echo '=== Responses model rewriter ==='
show src/server/responses-model-rewrite.ts 1 80
echo '=== Passthrough SSE and JSON paths ==='
show src/server/responses/core.ts 2020 2160
show src/server/responses/core.ts 2240 2325
echo '=== Bridge JSON and SSE paths ==='
show src/server/responses/core.ts 2550 2675
show src/server/responses/core.ts 3240 3375
echo '=== Combo metadata producer and lifecycle consumers ==='
rg -n -C 8 'COMBO_CATALOG_KIND|opencodex_catalog_kind|isComboLifecycleEntry|deriveComboCatalogModel' \
src/codex tests/codex-catalog.test.ts \
-g '*.ts'
echo '=== Catalog generation and empty-discovery retention ==='
show src/codex/catalog/sync.ts 319 425
show src/codex/catalog/sync.ts 570 625
show src/codex/convergence.ts 162 235
echo '=== Full response-identity regression file ==='
show tests/response-model-identity.test.ts 1 340
echo '=== Image and web-search identity regression sections ==='
show tests/images/loop.test.ts 115 175
show tests/web-search.test.ts 390 470
echo '=== All normalization call sites and direct upstream returns ==='
rg -n -C 5 'applyFinalRouteRequestNormalization\s*\(|return upstreamResponse|new Response\(upstreamResponse\.body|rewriteResponsesModelJson|createResponsesModelPayloadRewrite' \
src/server/responses/core.tsLength of output: 121423 🏁 Script executed: #!/bin/bash
set -euo pipefail
show() {
local file="$1" start="$2" end="$3"
echo "=== ${file}:${start}-${end} ==="
sed -n "${start},${end}p" "$file" | awk -v line="$start" '{printf "%6d %s\n", line++, $0}'
}
echo '=== Remaining convergence catalog assembly ==='
show src/codex/convergence.ts 175 260
echo '=== Combo marker and legacy-combo references in convergence ==='
rg -n -C 6 'combo-v1|COMBO_CATALOG_KIND|isComboCatalogEntry|Routed via opencodex → combo|isComboLifecycleEntry|exactComboSlugs' \
src/codex/convergence.ts tests/codex-convergence-contract.test.ts \
-g '*.ts'
echo '=== Convergence test setup and all catalog assertions ==='
show tests/codex-convergence-contract.test.ts 1 260
echo '=== Sync versus convergence native-row eligibility ==='
sed -n '496,508p' src/codex/catalog/sync.ts | awk -v line=496 '{printf "%6d %s\n", line++, $0}'
sed -n '181,188p' src/codex/convergence.ts | awk -v line=181 '{printf "%6d %s\n", line++, $0}'
echo '=== Build catalog behavior for supplied native slugs ==='
rg -n -C 4 'for \(const slug of gptSlugs\)|deriveEntry\(template, slug' src/codex/catalog/sync.tsLength of output: 23046
{
"slug": "claude-sonnet-5",
"opencodex_catalog_kind": "combo-v1"
}then Lines 182-187 add The later filter at This differs from Import a shared combo lifecycle predicate into Add a convergence regression that starts with a stale bare combo alias, performs convergence after the combo is removed, and asserts that the alias is absent rather than recreated as a native row. You are interacting with an AI system. |
471356f to
31ce122
Compare
|
Final rebased head |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 31ce122644
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (!current || slug.localeCompare(catalogModelSlug(current)) < 0) { | ||
| routedContextCompatWinnerByBareId.set(model.id, model); |
There was a problem hiding this comment.
Match compatibility aliases to bare routing precedence
When multiple enabled Anthropic providers expose the same bare model ID, this lexicographic winner can differ from the provider that actually handles that bare selector. For example, if anthropic-z precedes anthropic-a in config, routeByKnownModelPattern selects anthropic-z via Object.entries(...).find, but this code points the hidden alias at anthropic-a; persisted bare threads then receive context and compaction metadata for the wrong provider. Fresh evidence on the rebased head is that src/router.ts still resolves bare Claude IDs in config order while this comparison uses localeCompare. Select the alias using the router's precedence or suppress it when the bare selector is ambiguous.
Useful? React with 👍 / 👎.
| return parsed._responseModelId !== route.modelId | ||
| ? rewriteResponsesModelJson(repaired, parsed._responseModelId!) | ||
| : repaired; |
There was a problem hiding this comment.
Rewrite successful JSON when Content-Type is absent
When an openai-responses passthrough gateway returns a successful non-streaming Responses JSON body without a Content-Type header, this new model rewrite is never reached because the enclosing branch requires application/json; execution instead falls through to the raw relay at line 2353. The client therefore still receives the bare physical model rather than the provider-qualified catalog selector. Treat a headerless successful non-streaming passthrough as bounded JSON, analogous to the existing headerless-SSE fallback, before applying this rewrite.
Useful? React with 👍 / 👎.
|
Thank you for both the report and the implementation — this is landing as #1138, credited to you via Your mechanism is what I adopted, essentially as designed: What I narrowed, and why. In #1122 What I did not carry over: the catalog work ( That took the change from 25 files to 10. Verified: 132 pass / 0 fail on the identity, image-loop, web-search and request-log suites; red-then-green confirmed (the four qualified Anthropic JSON/SSE cases failed before the fix while the non-Anthropic guard already passed); typecheck and privacy scan clean. Leaving this PR open for you. |
Summary
owned_by, and mark compatibility/combo lifecycle ownership with explicitopencodex_catalog_kindvalues. Duplicate bare IDs select one deterministic alias owner; combo aliases suppress shadowed compatibility rows; fresh builds and transient sync/convergence fallback deduplicate legacy rows consistently; restore removes generated rows deterministically.Closes #1117
Verification
bun run typecheckbun run privacy:scan31ce1226: 409 focused tests passed, 0 failed, 1,818 assertions across response identity, image/web-search bridges, passthrough, catalog sync/restore/convergence, immutable gather authority, DeepSeek wire selection, request logs, combo failover, and virtual-model transports.action_required, zero jobs started).Checklist
All CI tests are green on my local testing.
I pushed my PR to the latest dev commit.
I resolved all correct Codex and CodeRabbit findings.
My PR is ready for review.
Summary by CodeRabbit
Bug Fixes
Documentation