-
Notifications
You must be signed in to change notification settings - Fork 1.1k
fix: L3 cherry-pick lane of the 260827 bug-PR merge round (#2639 #2647) #2721
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
fefeb05
e1e6ec0
6877f64
7d49790
45c3d31
8af9ff2
ad8ab4f
b64de51
da1e8af
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| # The status/created_at split is narrower than it first looked | ||
|
|
||
| The L3 pick for #2639 rests on a distinction: `status` is safe to backfill, | ||
| `created_at` is not, because `created_at` breaks the byte-exact combo passthrough | ||
| assertion. The reviewer auditing the cherry-pick asked the obvious follow-up — does | ||
| `status` violate the same contract? — and the honest answer is **yes, it can**. | ||
|
|
||
| ## Evidence | ||
|
|
||
| `tests/server-combo-failover-e2e.test.ts` builds its backup body with | ||
| `responsesSuccess()` (line 216), which already sets `status: "completed"` on both the | ||
| response and the message item. So the byte-exact assertion never exercises the | ||
| `status` backfill — it passes because the field is already present. | ||
|
|
||
| Remove that one field from the fixture and the same assertion fails on this branch: | ||
|
|
||
| ``` | ||
| $ cd /tmp/ocx-statusprobe # fixture with the item's status: "completed" deleted | ||
| $ bun test ./tests/server-combo-failover-e2e.test.ts -t 'exact backup response' | ||
| (fail) ... returns the exact backup response | ||
| + "status": "completed", # injected into a body relayed verbatim | ||
| ``` | ||
|
|
||
| And it passes with dev's version of the backfill file restored: | ||
|
|
||
| ``` | ||
| $ git checkout 2feffbdc3 -- src/server/responses/responses-field-backfill.ts | ||
| $ bun test ./tests/server-combo-failover-e2e.test.ts -t 'exact backup response' | ||
| 1 pass, 0 fail | ||
| ``` | ||
|
|
||
| So the difference between the two halves is NOT that one mutates passthrough bodies | ||
| and the other does not. Both do. `src/server/responses/core.ts:4145` runs | ||
| `backfillResponsesFieldsJson` on the bounded-JSON answer, and line 3937 installs the | ||
| SSE rewrite, on the passthrough path as well as the translated one. | ||
|
|
||
| ## What the difference actually is | ||
|
|
||
| `created_at` fires on EVERY response body that lacks the field, and a relay that omits | ||
| `created_at` is common. `status` fires only on a `message` item that lacks `status`, | ||
| which is rarer and is a genuine spec violation upstream — `OutputMessage.status` is | ||
| required, while a missing `created_at` is a Response-level omission the same decoders | ||
| complain about. The blast radius differs by roughly an order of magnitude, and the | ||
| existing test suite happens to sit on the safe side of the `status` case and the | ||
| unsafe side of the `created_at` case. | ||
|
|
||
| That is a defensible reason to take one and hold the other, but it is a difference of | ||
| DEGREE, not of kind, and 002 overstated it as a clean line. Corrected here. | ||
|
|
||
| ## Consequence | ||
|
|
||
| The open question in 002 — whether the backfill should be scoped to the translated | ||
| path so a verbatim relay stays verbatim — now applies to `status` too, not only to | ||
| `created_at`. Whoever resolves it should resolve both together. That is a follow-up | ||
| for its own PABCD cycle, not something to bolt onto this cherry-pick: it changes | ||
| behavior for every Responses provider, and the right answer probably involves the | ||
| passthrough path opting out of field backfill entirely. | ||
|
|
||
| Recorded rather than fixed here because this lane's contract is "take the correct | ||
| part of a partially-right PR", and the `status` backfill IS what #2639 got right. | ||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,53 @@ | ||||
| # L3 audit — reviewer findings and dispositions | ||||
|
|
||||
| The independent reviewer audited `codex/l3-cherry-picks-260827` (PR #2721) and | ||||
| returned VERDICT: FAIL. Nine findings; four required code changes. All are fixed. | ||||
|
|
||||
| | # | Finding | Disposition | | ||||
| |---|---|---| | ||||
| | 1 | `status` backfill correctly scoped to `type === "message"`, uses `"status" in item` so a falsy value is never overwritten | confirmed, no change | | ||||
| | 2 | `created_at` exclusion verified causally (73/74 before, 74/74 after) | confirmed | | ||||
| | 3 | The status/created_at split survives on FIXTURE CONTENTS, not on a principled difference | recorded in 021 | | ||||
| | 4 | **`response.queued` produced `completed`** — an unstarted message marked finished | fixed `6877f646f` | | ||||
| | 5 | **The regenerated fixture resurrected `stealth/ox-alpha`**, removed in `328931265` | fixed `45c3d31eb` | | ||||
| | 6 | **The self-correction justification is false** | fixed `ad8ab4f70` | | ||||
| | 7 | Dropping the PR's test file was right (it reintroduced both ox-alpha ids) | confirmed | | ||||
| | 8 | Split is clean; one stray ` *` comment line | fixed `8af9ff2bf` | | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Remove spaces from the inline code span. MD038 reports spaces inside the inline code span on Line 15. Remove the inner spaces so the span contains only the intended 🧰 Tools🪛 markdownlint-cli2 (0.23.2)[warning] 15-15: Spaces inside code span elements (MD038, no-space-in-code) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||
| | 9 | No status coverage lost by deleting the created_at tests; 148/148 at head | confirmed | | ||||
|
|
||||
| ## Finding 6 is the one worth remembering | ||||
|
|
||||
| I wrote a provenance comment saying it was acceptable to record the reporter's | ||||
| unverified ladders BECAUSE `refreshCommandCodeReasoningEfforts()` would re-read the | ||||
| public profile and replace a wrong row after the first upstream rejection. I had read | ||||
| that function and it does exactly what I described — in the code. | ||||
|
|
||||
| The reviewer ran it against the live site instead: | ||||
|
|
||||
| ``` | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Add a language to the fenced block. MD040 reports that the fence on Line 27 has no language tag. Mark this output block as Proposed fix-```
+```text📝 Committable suggestion
Suggested change
🧰 Tools🪛 markdownlint-cli2 (0.23.2)[warning] 27-27: Fenced code blocks should have a language specified (MD040, fenced-code-language) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||
| gpt-5.6-luna -> UNDEFINED | ||||
| google/gemini-3.7-flash -> UNDEFINED | ||||
| deepseek/deepseek-v4-flash-vision-exp -> UNDEFINED | ||||
| ``` | ||||
|
|
||||
| Confirmed independently: all three URLs return 200, and | ||||
| `grep -c -i 'reasoning efforts'` on the fetched HTML is 0. The pages ship the ladder | ||||
| inside a serialized React payload whose `reasoningEfforts` array is EMPTY in the | ||||
| delivered bytes. `parsedProfileEfforts` needs prose of the form | ||||
| "Reasoning efforts ... are supported;", finds none, returns undefined — so the row is | ||||
| never replaced. The same measurement returns 0 for `deepseek-v4-pro`, `GLM-5.3` and | ||||
| `muse-spark-1.2`, so the mechanism is dead for EVERY row in the table, not just the | ||||
| three added here. | ||||
|
|
||||
| The lesson is narrow and worth stating: a safety net that exists in the code is not a | ||||
| safety net that functions. I cited a mechanism as the reason to accept unverified | ||||
| data without testing that the mechanism fires. The reviewer tested it. | ||||
|
|
||||
| ## Carried forward | ||||
|
|
||||
| The dead parser is a real pre-existing defect: `parsedProfileEfforts` should read the | ||||
| embedded `reasoningEfforts` payload rather than prose. It is NOT fixed here — it | ||||
| affects every row, it is not what #2647 reported, and bolting it onto a cherry-pick | ||||
| lane would be exactly the scope creep this round is structured to avoid. It belongs | ||||
| in its own cycle, and the source comment now says so plainly so the next person does | ||||
| not re-derive the false justification. | ||||
|
Comment on lines
+48
to
+53
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Clarify the proposed parser fix. Lines 35-37 state that the delivered This matters because 🧰 Tools🪛 LanguageTool[style] ~51-~51: Consider an alternative for the overused word “exactly”. (EXACTLY_PRECISELY) 🤖 Prompt for AI Agents |
||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -91,6 +91,29 @@ function nextSyntheticItemSlot(): ItemIdSlot { | |||||||||||||
| return { kind: "fallback", ordinal: syntheticItemOrdinal }; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Backfill `status` on a message output item if missing. | ||||||||||||||
| * | ||||||||||||||
| * The Responses API spec defines `status` as a required field on | ||||||||||||||
| * `OutputMessage`. Some upstream relays omit it, which causes strict | ||||||||||||||
| * deserializers (e.g. grok-build's serde types) to fail with | ||||||||||||||
| * `missing field 'status'`. Only message items carry this field in the | ||||||||||||||
| * Responses schema; reasoning, function_call, and other item types do not. | ||||||||||||||
| * | ||||||||||||||
| * The value is inferred from the event context: `output_item.added` and | ||||||||||||||
| * `response.created` / `response.in_progress` mean the message is still | ||||||||||||||
| * being generated (`in_progress`); `output_item.done` and | ||||||||||||||
| * `response.completed` / `response.incomplete` mean the message is | ||||||||||||||
| * finalized (`completed` / `incomplete` respectively). | ||||||||||||||
| * | ||||||||||||||
| * Returns the same object reference if no change is needed. | ||||||||||||||
| */ | ||||||||||||||
| function backfillItemStatus(item: Record<string, unknown>, inferredStatus: string): Record<string, unknown> { | ||||||||||||||
| if (item.type !== "message") return item; | ||||||||||||||
| if ("status" in item) return item; | ||||||||||||||
| return { ...item, status: inferredStatus }; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Backfill annotations: [] on an output_text content part if missing. | ||||||||||||||
| * Returns the same object reference if no change is needed. | ||||||||||||||
|
|
@@ -122,10 +145,10 @@ function backfillContentArray(content: unknown): unknown { | |||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Walk an output item and backfill output_text parts in its content. | ||||||||||||||
| * Also backfills a missing required id on the item itself. | ||||||||||||||
| * Also backfills a missing required id and status on the item itself. | ||||||||||||||
| * Returns the same object reference if nothing changed. | ||||||||||||||
| */ | ||||||||||||||
| function backfillOutputItem(item: unknown, slot: ItemIdSlot): unknown { | ||||||||||||||
| function backfillOutputItem(item: unknown, slot: ItemIdSlot, inferredStatus: string): unknown { | ||||||||||||||
| if (!isPlainObject(item)) return item; | ||||||||||||||
| // The compact wire family is the `/v1/responses/compact` format, not a Responses output item. | ||||||||||||||
| // Those items have no `id` in that contract, so synthesizing one changes a response body the | ||||||||||||||
|
|
@@ -136,34 +159,92 @@ function backfillOutputItem(item: unknown, slot: ItemIdSlot): unknown { | |||||||||||||
| const content = item.content; | ||||||||||||||
| const repaired = backfillContentArray(content); | ||||||||||||||
| const withId = backfillItemId(item, slot); | ||||||||||||||
| if (repaired === content && withId === item) return item; | ||||||||||||||
| return { ...withId, ...(repaired === content ? {} : { content: repaired }) }; | ||||||||||||||
| const withStatus = backfillItemStatus(withId, inferredStatus); | ||||||||||||||
| if (repaired === content && withStatus === item) return item; | ||||||||||||||
| return { ...withStatus, ...(repaired === content ? {} : { content: repaired }) }; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Walk a response object's output[] and backfill output_text parts. | ||||||||||||||
| * | ||||||||||||||
| * `inferredItemStatus` is the status to backfill on message items that lack | ||||||||||||||
| * one — derived from the event type so `output_item.added` / `response.created` | ||||||||||||||
| * gets `in_progress` while `output_item.done` / `response.completed` gets | ||||||||||||||
| * `completed`. | ||||||||||||||
| * | ||||||||||||||
| * Deliberately does NOT backfill `created_at`. #2639 proposed it for the same | ||||||||||||||
| * strict-decoder reason as `status`, but the proxy also relays some upstream | ||||||||||||||
| * responses verbatim, and `tests/server-combo-failover-e2e.test.ts` asserts a | ||||||||||||||
| * combo backup response is returned byte-exact. Injecting a field the upstream | ||||||||||||||
| * never sent breaks that contract. Both cannot hold for the same body, so the | ||||||||||||||
| * `created_at` half needs its own decision about which contract yields; it is | ||||||||||||||
| * not a detail to slip in beside `status`. | ||||||||||||||
| * | ||||||||||||||
| * Returns the same object reference if nothing changed. | ||||||||||||||
| */ | ||||||||||||||
| function backfillResponseOutput(response: unknown): unknown { | ||||||||||||||
| function backfillResponseOutput(response: unknown, inferredItemStatus: string): unknown { | ||||||||||||||
| if (!isPlainObject(response)) return response; | ||||||||||||||
| const output = response.output; | ||||||||||||||
| if (!Array.isArray(output)) return response; | ||||||||||||||
| let changed = false; | ||||||||||||||
| const repaired = output.map((item, idx) => { | ||||||||||||||
| if (!isPlainObject(item)) return item; | ||||||||||||||
| const next = backfillOutputItem(item, { kind: "index", index: idx }); | ||||||||||||||
| const next = backfillOutputItem(item, { kind: "index", index: idx }, inferredItemStatus); | ||||||||||||||
| if (next !== item) changed = true; | ||||||||||||||
| return next; | ||||||||||||||
| }); | ||||||||||||||
| return changed ? { ...response, output: repaired } : response; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Infer the status to backfill on a message item from the event type. | ||||||||||||||
| * | ||||||||||||||
| * `output_item.added` means the item is still being generated (`in_progress`); | ||||||||||||||
| * `output_item.done` means it is finalized (`completed`). Response-level events | ||||||||||||||
| * infer from the response's own status field — which is authoritative when present. | ||||||||||||||
| * If the response status is also absent, the event type itself determines the phase: | ||||||||||||||
| * `response.created` / `response.in_progress` → `in_progress`, | ||||||||||||||
| * `response.completed` → `completed`, `response.incomplete` → `incomplete`. | ||||||||||||||
| */ | ||||||||||||||
| function inferredStatusForEventType(eventType: string): string { | ||||||||||||||
| if (eventType === "response.output_item.added") return "in_progress"; | ||||||||||||||
| if (eventType === "response.output_item.done") return "completed"; | ||||||||||||||
| if (eventType === "response.created" || eventType === "response.in_progress") return "in_progress"; | ||||||||||||||
| // `queued` is a real Responses lifecycle status: the response exists but has not | ||||||||||||||
| // started generating. Without this row it falls through to the `completed` | ||||||||||||||
| // default below, which would mark an unstarted message as finished. | ||||||||||||||
| if (eventType === "response.queued") return "in_progress"; | ||||||||||||||
| if (eventType === "response.incomplete" || eventType === "response.failed") return "incomplete"; | ||||||||||||||
| return "completed"; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Map a response-level lifecycle status to a valid OutputMessage status. | ||||||||||||||
| * | ||||||||||||||
| * `OutputMessage.status` accepts only `in_progress`, `completed`, or | ||||||||||||||
| * `incomplete`. Response-level statuses like `failed` or `cancelled` have no | ||||||||||||||
| * direct message-level equivalent, but `incomplete` is the correct semantic | ||||||||||||||
| * mapping: the message did not finish generating. Writing `completed` would | ||||||||||||||
| * assert something the upstream never claimed — a client branching on | ||||||||||||||
| * `status === "completed"` would treat a truncated message as whole. | ||||||||||||||
| */ | ||||||||||||||
| function messageStatusFromResponseStatus(status: string): string | null { | ||||||||||||||
| if (status === "in_progress" || status === "completed" || status === "incomplete") return status; | ||||||||||||||
| // A queued response has not begun generating, so its message items are | ||||||||||||||
| // in_progress — never completed. Returning null here would fall back to the | ||||||||||||||
| // event-type inference, whose default is `completed`. | ||||||||||||||
| if (status === "queued") return "in_progress"; | ||||||||||||||
| if (status === "failed" || status === "cancelled") return "incomplete"; | ||||||||||||||
| return null; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Statelessly rewrite one SSE event: backfill annotations | ||||||||||||||
| * on any output_text content part found in the event payload. | ||||||||||||||
| */ | ||||||||||||||
| function rewriteEvent(event: Record<string, unknown>): Record<string, unknown> { | ||||||||||||||
| const type = typeof event.type === "string" ? event.type : ""; | ||||||||||||||
| const inferredItemStatus = inferredStatusForEventType(type); | ||||||||||||||
| let next = event; | ||||||||||||||
| let changed = false; | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -177,8 +258,8 @@ function rewriteEvent(event: Record<string, unknown>): Record<string, unknown> { | |||||||||||||
| // is not recoverable in that case, but a unique id is what strict decoders require, and a | ||||||||||||||
| // well-formed stream still gets the stable index-derived id. | ||||||||||||||
| const item = typeof rawIndex === "number" && Number.isInteger(rawIndex) && rawIndex >= 0 | ||||||||||||||
| ? backfillOutputItem(event.item, { kind: "index", index: rawIndex }) | ||||||||||||||
| : backfillOutputItem(event.item, nextSyntheticItemSlot()); | ||||||||||||||
| ? backfillOutputItem(event.item, { kind: "index", index: rawIndex }, inferredItemStatus) | ||||||||||||||
| : backfillOutputItem(event.item, nextSyntheticItemSlot(), inferredItemStatus); | ||||||||||||||
| if (item !== event.item) { | ||||||||||||||
| next = { ...next, item }; | ||||||||||||||
| changed = true; | ||||||||||||||
|
|
@@ -198,7 +279,13 @@ function rewriteEvent(event: Record<string, unknown>): Record<string, unknown> { | |||||||||||||
| // response.created / in_progress / completed / incomplete / failed: | ||||||||||||||
| // response.output[].content[] -> output_text parts | ||||||||||||||
| if (isPlainObject(event.response)) { | ||||||||||||||
| const response = backfillResponseOutput(event.response); | ||||||||||||||
| // For response-level events, prefer the response's own status when it is a valid | ||||||||||||||
| // OutputMessage status. Response lifecycle statuses like "failed" or "cancelled" | ||||||||||||||
| // have no message-level equivalent — fall back to the event-type inference instead. | ||||||||||||||
| const responseStatus = typeof event.response.status === "string" | ||||||||||||||
| ? messageStatusFromResponseStatus(event.response.status) ?? inferredItemStatus | ||||||||||||||
| : inferredItemStatus; | ||||||||||||||
| const response = backfillResponseOutput(event.response, responseStatus); | ||||||||||||||
| if (response !== event.response) { | ||||||||||||||
| next = { ...next, response }; | ||||||||||||||
| changed = true; | ||||||||||||||
|
|
@@ -210,9 +297,9 @@ function rewriteEvent(event: Record<string, unknown>): Record<string, unknown> { | |||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Create a stateless SSE block rewrite that backfills annotations and | ||||||||||||||
| * on output_text content parts. Unconditional: the field is a required | ||||||||||||||
| * canonical Responses field, so adding it when absent is safe for all | ||||||||||||||
| * clients. | ||||||||||||||
| * message status on output_text content parts and message items. | ||||||||||||||
| * Unconditional: both are required canonical Responses fields, so adding | ||||||||||||||
| * them when absent is safe for all clients. | ||||||||||||||
|
Comment on lines
+300
to
+302
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Correct the documented field contract.
Proposed wording- * message status on output_text content parts and message items.
+ * `annotations` on output_text content parts and `status` on message items.📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- applicable repository conventions and learnings ---'
find /tmp/coderabbit-repo-knowledge/lidge-jun-opencodex-7afea732 -maxdepth 2 -type f -name '*.md' -print \
-exec sh -c 'echo "--- $1"; head -80 "$1"' sh {} \;
printf '%s\n' '--- target file outline and relevant source ---'
ast-grep outline src/server/responses/responses-field-backfill.ts
rg -n -C 8 'createResponsesFieldBackfillBlockRewrite|rewriteEvent|inferredStatusForEventType|combo|failover|verbatim|passthrough|response\.status|message\.status' \
src/server/responses src tests 2>/dev/null || true
printf '%s\n' '--- target file ---'
cat -n src/server/responses/responses-field-backfill.ts | sed -n '1,380p'
printf '%s\n' '--- directly relevant tests ---'
fd -i 'responses-field-backfill|combo|failover' tests src | head -80Repository: lidge-jun/opencodex Length of output: 50376 🏁 Script executed: #!/bin/bash
set -e
log=/tmp/coderabbit-shell-logs/shell-output-l5hLnO
printf '%s\n' '--- backfill definitions and callers from captured output ---'
rg -n -C 12 'createResponsesFieldBackfillBlockRewrite|rewriteEvent|inferredStatusForEventType|responses-field-backfill' "$log" | head -240
printf '%s\n' '--- source references ---'
rg -n -C 8 'createResponsesFieldBackfillBlockRewrite|responsesFieldBackfill|backfill' src/server src | head -320
printf '%s\n' '--- combo response relay and body handling ---'
rg -n -C 10 'combo|failover|rawBody|body|Response\.json|new Response|response\.text|response\.arrayBuffer|verbatim|passthrough' \
src/server src/combos src/lib 2>/dev/null | head -500
printf '%s\n' '--- target implementation ---'
cat -n src/server/responses/responses-field-backfill.ts | sed -n '1,360p'Repository: lidge-jun/opencodex Length of output: 50376 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- backfill implementation ---'
cat -n src/server/responses/responses-field-backfill.ts | sed -n '130,345p'
printf '%s\n' '--- response stream setup and JSON response path ---'
cat -n src/server/responses/core.ts | sed -n '3820,3975p'
cat -n src/server/responses/core.ts | sed -n '4070,4170p'
printf '%s\n' '--- exact byte-preservation contracts and fixtures ---'
rg -n -C 14 'byte.?exact|byte.?for.?byte|verbatim|raw.*body|body.*raw|passthrough.*body|backup response' \
src tests/server-combo-failover-e2e.test.ts tests/responses-field-backfill.test.ts | head -500
printf '%s\n' '--- combo dispatch definitions ---'
rg -n -C 12 'handleResponses|runTurn|comboFailureDecision|failover|child|adopt|selected' \
src/server/policy-fallback.ts src/server/responses/core.ts src/combos | head -600Repository: lidge-jun/opencodex Length of output: 50376 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- exact combo byte-preservation fixture and helpers ---'
cat -n tests/server-combo-failover-e2e.test.ts | sed -n '170,245p'
cat -n tests/server-combo-failover-e2e.test.ts | sed -n '1280,1345p'
rg -n -C 10 'function responsesSuccess|const responsesSuccess|responsesSuccess|comboAttempt|onConsumedComboFailure|handleResponsesCore|comboFailureDecision' \
tests/server-combo-failover-e2e.test.ts src/server/responses/core.ts src/server/responses/policy-fallback.ts src/combos
printf '%s\n' '--- combo fallback call chain ---'
cat -n src/server/responses/policy-fallback.ts | sed -n '1,180p'
rg -n -C 14 'comboAttempt|onConsumedComboFailure|handleResponsesCore|policyFallback|comboFailure' src/server/responses/core.ts src/server/responses/policy-fallback.ts | head -500
printf '%s\n' '--- JSON response return after backfill ---'
cat -n src/server/responses/core.ts | sed -n '4110,4235p'Repository: lidge-jun/opencodex Length of output: 50376 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- combo child construction and delegation ---'
cat -n src/server/responses/core.ts | sed -n '1810,2025p'
printf '%s\n' '--- bounded JSON response construction ---'
cat -n src/server/responses/core.ts | sed -n '4150,4275p'
printf '%s\n' '--- route/adapter response handoff before passthrough handling ---'
cat -n src/server/responses/core.ts | sed -n '3680,3865p'
printf '%s\n' '--- exact fixture status omission probe in source ---'
rg -n -C 8 'status: undefined|delete .*status|missing.*status|without.*status|output:.*message|type: "message"' \
tests/server-combo-failover-e2e.test.ts tests/responses-field-backfill.test.ts | head -300Repository: lidge-jun/opencodex Length of output: 50375 Preserve byte-exact combo backup bodies before applying field backfills.
The existing fixture at 🤖 Prompt for AI Agents |
||||||||||||||
| */ | ||||||||||||||
| export function createResponsesFieldBackfillBlockRewrite(): SseBlockRewrite { | ||||||||||||||
| const rewrite: SseBlockRewrite = (block: string): readonly string[] => { | ||||||||||||||
|
|
@@ -245,7 +332,12 @@ export function backfillResponsesFieldsJson(payload: string): string { | |||||||||||||
| return payload; | ||||||||||||||
| } | ||||||||||||||
| if (!isPlainObject(response)) return payload; | ||||||||||||||
| const repaired = backfillResponseOutput(response); | ||||||||||||||
| // For a non-streaming response, derive the item status from the response's own | ||||||||||||||
| // status field when it is a valid OutputMessage status; fall back to "completed". | ||||||||||||||
| const inferredItemStatus = typeof response.status === "string" | ||||||||||||||
| ? messageStatusFromResponseStatus(response.status) ?? "completed" | ||||||||||||||
| : "completed"; | ||||||||||||||
| const repaired = backfillResponseOutput(response, inferredItemStatus); | ||||||||||||||
| if (repaired === response) return payload; | ||||||||||||||
| return JSON.stringify(repaired); | ||||||||||||||
| } | ||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Add language tags to the fenced shell transcripts.
markdownlint-cli2reports MD040 for both fences. Change each opening fence to```shellor```text.Also applies to: 26-26
🧰 Tools
🪛 markdownlint-cli2 (0.23.2)
[warning] 17-17: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Source: Linters/SAST tools