Skip to content

fix(ai): recover Codex SSE tool-choice rejections - #3699

Open
sj0618 wants to merge 1 commit into
Yeachan-Heo:devfrom
sj0618:codex/fix-codex-sse-tool-choice-fallback
Open

fix(ai): recover Codex SSE tool-choice rejections#3699
sj0618 wants to merge 1 commit into
Yeachan-Heo:devfrom
sj0618:codex/fix-codex-sse-tool-choice-fallback

Conversation

@sj0618

@sj0618 sj0618 commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

What

  • Recognize the statusless Codex SSE representation of invalid_request_error when its message is the existing exact named-tool-not-in-tools rejection.
  • Retry once without forced tool_choice before any output is emitted.
  • Keep explicit non-400 statuses and unrelated provider error codes ineligible for this fallback.

Why

Fixes #3669.

The HTTP 400 form already uses the forced-tool-choice capability fallback, but the equivalent HTTP 200 SSE error carries a semantic provider code and no HTTP status. This remains a single contributor-authored commit rebased onto current dev.

Testing

  • bun test packages/ai/test/openai-codex-responses-tool-choice.test.ts packages/ai/test/tool-choice-capability.test.ts — 47 passed, 269 assertions
  • bunx biome check packages/ai/src/providers/openai-codex-responses.ts packages/ai/src/utils/tool-choice-capability.ts packages/ai/test/openai-codex-responses-tool-choice.test.ts packages/ai/test/tool-choice-capability.test.ts packages/ai/CHANGELOG.md — passed
  • bun --cwd=packages/ai run check:types — passed
  • git diff --check upstream/dev...HEAD — passed

GJC verdict

gajae.pr-review-verdict.v1 merge-approved sha256:988fa047450b0978a5bbd6bc4bdaa918f245ea2e reviewer:architect evidence:local-diff-review

  • Target branch is dev
  • Focused tests and package type check pass
  • Tested locally
  • CHANGELOG updated under ## [Unreleased]
  • Verdict above matches the exact PR head

@sj0618
sj0618 force-pushed the codex/fix-codex-sse-tool-choice-fallback branch from 8245006 to 1c81b55 Compare August 1, 2026 08:06
@Yeachan-Heo

Copy link
Copy Markdown
Owner

Signed: Yeachan-Heo / gajae-code AI-provider red-team

VERDICT: DEFERRED — exact-head review not admitted.

The exact PR head is still current at 1c81b55f26f8ec2a99f5c4065f5d55e6a4334cbe, and its checks are terminal-green (21 total: 15 success, 6 skipped, 0 failures, 0 non-terminal). It is not compatible with the current dev base: the PR targets b40bc271502a0802e212e5538c5d0e8436643029, current dev is 2c99a7f226635e812bc8fe8669787242029ce662, and GitHub reports mergeable=false, mergeable_state=dirty.

Per batch policy, no hostile implementation review or approval is attached while the exact head is stale/incompatible with current dev. Rebase onto current dev, rerun exact-head CI, and resubmit for independent review. No merge performed.

[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo Yeachan-Heo left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

REQUEST_CHANGES

Reviewed exact head 1c81b55f26f8ec2a99f5c4065f5d55e6a4334cbe against current origin/dev c1bf3be50e2cf0dfdf51b57eb43f7a99521c94b8.

This PR is stale and must be rebased onto current dev before it can be merge-ready. The PR base is b40bc271502a0802e212e5538c5d0e8436643029, not the requested current baseline. I inspected packages/ai/src/utils/tool-choice-capability.ts:23-31 and the Codex SSE error conversion. The new match is constrained to a forced tool choice plus invalid_request_error and the existing tool-choice message predicate, while nonmatching codes and HTTP 500 remain excluded; no additional credential, fallback-loop, or output-leak blocker was found in this exact diff.

Focused verification at the exact head passed: bun test packages/ai/test/openai-codex-responses-tool-choice.test.ts packages/ai/test/tool-choice-capability.test.ts (44 pass). Rebase onto c1bf3be50e2cf0dfdf51b57eb43f7a99521c94b8, rerun the clean one-shot fallback and cancellation coverage, and do not merge this stale head.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@probepark

Copy link
Copy Markdown
Contributor

Exact-head maintainer follow-up completed against current dev@54b14cb6e.

I rebased and corrected the statusless SSE fallback so it is Codex-only and accepts only an exact named-function rejection when the rejected name matches the forced name and that name exists in the final serialized tools list. The shared HTTP-400 classifier remains unchanged. Added negative coverage for managed mode, abort/output, required mode, mismatched/missing names, and second rejection/no third request.

Evidence at reviewed commit 01c472023:

  • bun test packages/ai/test/tool-choice-capability.test.ts packages/ai/test/openai-codex-responses-tool-choice.test.ts — 47 pass, 269 assertions
  • bun --cwd=packages/ai run check — passed
  • independent Architect — CLEAR / APPROVE

I cannot push to the contributor fork (Permission to sj0618/gajae-code.git denied). The reviewed commit is published at probepark/gajae-code:fix/issue-3669-pr3699-review:
probepark@01c472023

Please update this PR head from that commit/branch (or explicitly authorize maintainer takeover and disposition of this PR). No duplicate PR has been opened.

@Yeachan-Heo

Copy link
Copy Markdown
Owner

Census reassignment receipt: Codex SSE tool-choice transport batch reviewed for routing-contract overlap.

Exact head: 1c81b55f26f8ec2a99f5c4065f5d55e6a4334cbe. Current dev: bf37cb30d0442926ad3fb2b2c6fc26a6d3edeffc.

The changed files do not overlap MiniMax policy files, but this PR is not merge-ready: review changes are requested by Yeachan-Heo and its recorded base is stale relative to current dev. No mutation or merge was performed.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@probepark

Copy link
Copy Markdown
Contributor

Current-dev refresh of the previously reviewed corrected candidate (contributor ownership preserved; no duplicate PR opened):

  • Base: 971ff98fc5c33e34de0962c3e59c18f51a65c395
  • Candidate head: 3873f35b1a6499e64aec2d162c26b1329a1b756a
  • Published branch: probepark/review/issue-3669-current-dev
  • Focused tests: 47 passed, 269 assertions
  • Changed-file Biome check: passed
  • packages/ai type check: passed after isolated-worktree dependency install
  • git diff --check upstream/dev...HEAD: passed

The dev advance since the earlier review overlaps only packages/ai/CHANGELOG.md, not the candidate source/test files. Adoption still requires the contributor to update this PR or an explicit maintainer takeover decision.

@sj0618
sj0618 force-pushed the codex/fix-codex-sse-tool-choice-fallback branch 2 times, most recently from d63f5e4 to 17cba5e Compare August 3, 2026 14:13
Codex can reject a named tool choice through a statusless SSE error even when the final request contained that tool. Keep the fallback Codex-specific and retry only the clean exact-name failure once.

Lore-id: 3669-sse-tool-choice

Constraint: forced tool name must exist in final serialized tools

Constraint: retry only before output and outside managed fallback

Rejected: shared statusless classifier | broadens behavior across providers

Confidence: high

Scope-risk: narrow

Reversibility: easy

Tested: 47 focused tests, 269 assertions; packages/ai check
@sj0618
sj0618 force-pushed the codex/fix-codex-sse-tool-choice-fallback branch from 17cba5e to 988fa04 Compare August 3, 2026 14:17
@probepark

Copy link
Copy Markdown
Contributor

Exact current-dev corrected candidate refresh (contributor ownership preserved; no duplicate PR opened):

  • Base: 971ff98fc5c33e34de0962c3e59c18f51a65c395
  • Candidate head: c63c447b2ae2c608e5d8d27c541b1112b0371dcc
  • Published branch: probepark/review/issue-3669-current-dev
  • Focused tests: 50 passed, 287 assertions
  • packages/ai check: passed
  • git diff --check: passed
  • Independent exact-head audit 137-G003G004ExactAudit: CLEAR / APPROVE, no findings

This candidate fixes the remaining pre-runtime hole: an initial HTTP named-tool rejection now transfers explicit downgrade state into the SSE runtime, so later same-turn provider retries cannot reintroduce tool_choice. The statusless classifier remains exact and the provider/tool fallback budgets remain independent.

Adoption still requires the contributor to update this PR from the published candidate or an explicit maintainer takeover decision.

@probepark

Copy link
Copy Markdown
Contributor

Exact current-dev update after the contributor rebased PR #3699:

  • Current upstream/dev: aebb0f6d119acf178a9c710f460f83e9735bb8e6
  • Contributor head observed: 988fa047450b0978a5bbd6bc4bdaa918f245ea2e (OPEN/CLEAN, still CHANGES_REQUESTED)
  • Corrected candidate: bb9bce6eca92dd7c51288bb459fe653cffed3d5b
  • Published branch: probepark/review/issue-3669-current-dev
  • Focused tests: 50 passed, 287 assertions
  • packages/ai check and exact-range diff check: passed
  • Independent exact-current-dev audit 138-RebasedCandidateAudit: CLEAR / APPROVE, no findings

The contributor rebase incorporates the earlier narrow classifier work but still lacks the 110-line final delta that separates provider/tool retry budgets and keeps both initial-HTTP and SSE downgrades sticky across later same-turn reopens. The published candidate contains those repairs and their three-request regressions.

No duplicate PR was opened and contributor ownership remains intact. Adoption requires updating this PR from the published candidate or an explicit maintainer takeover decision.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants