Skip to content

fix(responses): preserve Meta Muse tool-choice semantics - #5969

Closed
shawn-kim-ai wants to merge 2 commits into
lidge-jun:devfrom
shawn-kim-ai:codex/muse-tool-choice
Closed

shawn-kim-ai wants to merge 2 commits into
lidge-jun:devfrom
shawn-kim-ai:codex/muse-tool-choice

Conversation

@shawn-kim-ai

@shawn-kim-ai shawn-kim-ai commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Meta Muse rejects non-auto tool choices, so Grok Build requests can fail upstream with HTTP 400. Preserve none by removing tool declarations and omitting the selector; reject forced, named, and allowed-tools selectors locally instead of silently relaxing their meaning. Validate the original selector before tool filtering can erase that intent. Other provider destinations retain their existing behavior.

Verification

  • Pinned Bun 1.4.0: bun run typecheck, bun run structure:check, bun run privacy:scan, and bun run --cwd docs-site build passed. Focused run: bun scripts/test.ts tests/responses/responses-muse-tool-choice.test.ts tests/responses/responses-muse-tool-name-alias.test.ts tests/providers/muse-tool-name-alias.test.ts tests/test-layout.test.ts tests/test-layout-tooling.test.ts (52 passed).
  • Clean baseline: the new regression file failed 6 cases before the fix. Live patched-handler probes completed none without tools and rejected constrained selectors with zero upstream sends.
  • bun run test: parallel segment 31,644 passed / 38 skipped / 1 timeout in the existing Claude model-discovery test; the serial native-codex-toggle test also failed (absent instead of current); other serial segments passed. The native-toggle failure reproduced identically on the pre-fix baseline (12 passed / 1 failed), so it is not introduced by this patch. Full-run totals: 32,276 passed / 61 skipped / 2 failed. The timed-out file then passed alone (13/13), including that case in 71 ms. The full invocation remains recorded as failed. The native-toggle baseline failure is a local launchd ownership refusal: a job is loaded but its plist is absent in the isolated test home. The guard correctly refuses the write, leaving state: absent; it was not bypassed. Both baseline and patched runs produce the same failure. Focused coverage and typecheck pass; clean-host full-suite confirmation remains for CI before merge.
  • Scoped Thermos, deslop, unslop, APOSD and nose reviews found no outstanding defects or new duplication families.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • Required local validation passed; commands, results, and any full-suite exception are documented.

  • I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Summary by CodeRabbit

  • New Features
    • Meta Muse Responses requests now support omitted or automatic tool selection. Explicitly disabling tools sends an empty tool list and removes additional tools from the input.
    • Unsupported forced, named, and allowed-tool selections now return HTTP 400 before the request is sent to Meta. Other Responses destinations retain their existing behavior.
  • Documentation
    • Updated platform support and tool-selection documentation to describe Meta Muse’s supported options and compatibility limits.

@coderabbitai

coderabbitai Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: lidge-jun/opencodex/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: b50c558b-efae-45f9-8f85-8aa8ae15c4ae

📥 Commits

Reviewing files that changed from the base of the PR and between af38c95 and a1d6e43.

📒 Files selected for processing (13)
  • design-debt.md
  • docs-site/src/content/docs/ko/reference/platform-support.md
  • docs-site/src/content/docs/reference/platform-support.md
  • scripts/test-layout/layout.json
  • src/adapters/openai-responses/muse-tool-choice.ts
  • src/adapters/openai-responses/passthrough.ts
  • src/server/responses/passthrough-dispatch.ts
  • structure/providers-and-adapters.md
  • structure/transports/responses.md
  • tests/fixtures/test-layout-expected.json
  • tests/providers/muse-tool-name-alias.test.ts
  • tests/responses/responses-muse-tool-choice.test.ts
  • tests/responses/responses-muse-tool-name-alias.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

Meta Responses requests now normalize tool selection at the final request boundary. Unsupported choices return HTTP 400 before an upstream request. Tests and documentation cover this behavior; other Responses destinations retain their existing behavior.

Changes

Meta Responses tool-choice handling

Layer / File(s) Summary
Request normalization and error handling
src/adapters/openai-responses/muse-tool-choice.ts, src/adapters/openai-responses/passthrough.ts, src/server/responses/passthrough-dispatch.ts
For Meta destinations, the adapter accepts omitted or auto choices and applies none by clearing tools, removing tool_choice and parallel_tool_calls, and filtering additional_tools from array-valued input. Unsupported choices raise a compatibility error that the dispatch path returns as a redacted HTTP 400 error.
Tool-choice behavior tests
tests/responses/responses-muse-tool-choice.test.ts, tests/responses/responses-muse-tool-name-alias.test.ts, tests/providers/muse-tool-name-alias.test.ts, scripts/test-layout/layout.json, tests/fixtures/test-layout-expected.json
Tests cover supported and unsupported choices, pre-upstream errors, and unchanged xAI behavior. Alias tests now check that automatic tool choice remains unchanged. Test-layout mappings include the new test.
Compatibility contract documentation
structure/providers-and-adapters.md, structure/transports/responses.md, docs-site/src/content/docs/reference/platform-support.md, docs-site/src/content/docs/ko/reference/platform-support.md, design-debt.md
The documentation describes Meta’s supported and rejected tool choices and distinguishes behavior for other destinations. The audit note records its scope and results.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant ResponsesClient
  participant preparePassthroughExchange
  participant passthroughAdapter
  participant normalizeMuseToolChoice
  participant MetaResponses
  ResponsesClient->>preparePassthroughExchange: Submit Responses request
  preparePassthroughExchange->>passthroughAdapter: Build finalized request
  passthroughAdapter->>normalizeMuseToolChoice: Normalize Meta tool choice
  normalizeMuseToolChoice-->>passthroughAdapter: Return normalized body or compatibility error
  passthroughAdapter->>MetaResponses: Send request when normalization succeeds
  preparePassthroughExchange-->>ResponsesClient: Return redacted HTTP 400 for compatibility error
Loading

Merge Risk: ⚪ Minimal · up to a1d6e

The audit date needs no correction, and the inspected request paths preserve the intended Meta tool-choice behavior. No identified issue blocks merging after normal checks.

Security Architecture Review

Security architecture risk: 🔵 Low · up to a1d6e

Unsupported tool choices are now rejected before forwarding to Meta, while supported choices and other destinations retain their intended behavior. The change is narrowly scoped, though not every dispatch path has been verified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The observed new selector handling is bounded to requests routed to the Meta hostname; the inspected non-Meta request retains its selector.

Trust Boundaries and Controls

  • observed — A client-supplied unsupported selector raises a compatibility error before the outbound request is returned; the inspected HTTP handler responds with a redacted 400, and integration tests record no upstream send.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 6 files. (7 skipped: 7… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: preserving Meta Muse tool-choice semantics for Responses requests.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 6 files. (7 skipped: 7 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Sep 26, 2026
@github-actions

github-actions Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

✅ READY

  • all PR quality gates passed; the review readiness checklist is complete.

Review readiness checklist

  • ✅ Required local validation passed; commands, results, and any full-suite exception are documented.
  • ✅ I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).
  • ✅ I resolved all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

✅ 4/4 boxes ticked.

This pull request is already Ready for Review.
The review-ready label marks this PR as ready; review automation runs independently.
Maintainers: @lidge-jun @Ingwannu

@github-actions
github-actions Bot marked this pull request as ready for review September 26, 2026 15:47
@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 16 / 80

Meta Muse는 tool_choice로 auto만 받습니다. none이나 함수 이름을 그대로 넘기면 Meta가 400을 돌려줍니다. 이 PR은 Meta 주소(api.meta.ai)로 나가는 Responses 요청만 고칩니다.

선택을 빼거나 auto로 두면 요청은 그대로 나갑니다. none이면 도구 목록을 빈 배열로 바꿉니다. tool_choice와 parallel_tool_calls는 빼고, input 안의 additional_tools 항목도 지웁니다. 예전 대화의 함수 호출 기록은 남습니다. required, 함수 이름, allowed_tools, null은 Meta로 보내기 전에 여기서 400을 냅니다. 도구를 빼는 필터가 나가는 본문의 선택을 none으로 고쳐도, 호출자가 처음 보낸 값이 강제 선택이면 그 400이 먼저입니다. xAI 같은 다른 주소는 예전과 같습니다. 이름 별칭 테스트는 Meta에서 더 이상 못 보내는 강제 선택을 auto로 바꿨고, 고르지 않은 도구를 거절하는 검사는 xAI로 옮겼습니다.

바탕 브랜치는 dev입니다. types.ts와 config.ts를 나누는 변경은 아닙니다. 같은 주제를 다루는 열린 PR은 없습니다.

라인 - design-debt.md. 저장소 루트에 새로 넣은 감사 메모입니다. dev 루트에는 이런 파일이 없고, 표 안에도 발견이 없습니다. 제품 동작과 관계없는 기록이라 머지 대상이 아닙니다.

메인테이너의 판단이 필요한 지점

압축 요청은 도구와 tool_choice를 빼는 것이 원래 동작입니다. 이 PR은 그 뒤에 호출자가 처음 보낸 선택을 다시 봅니다. auto나 none이 아니면 요약을 만들지 않고 400을 냅니다. tests/responses/responses-muse-tool-choice.test.ts의 compaction 테스트가 그 거절을 고정합니다. 강제 선택을 조용히 요약으로 바꾸지 않으려는 것이면 맞습니다. 도구를 지정해 둔 대화를 Meta로 요약해야 하면, 압축 경로는 이 검사에서 빼야 합니다.

판별은 모델 이름이 아니라 api.meta.ai 호스트입니다. 그 호스트의 요청은 전부 같은 규칙을 탑니다. 64자 이름 별칭과 같은 범위입니다.

너의 추천

none을 빈 도구로 보내고, 강제 선택은 올리기 전에 400으로 막는 방향은 테스트와 맞습니다. design-debt.md는 빼는 쪽이 좋습니다. 압축까지 막을지가 의도라면 그 파일만 빼고 머지해도 됩니다. types.ts/config.ts 분할 때문에 닫을 이유는 없습니다.

이 댓글은 grok-bot이 작성했습니다

lidge-jun added a commit that referenced this pull request Sep 26, 2026
)

Six focused fixes from the assigned bug batch remain as separate attributed commits.

| PR | Change | Author |
| --- | --- | --- |
| #5969 | Preserve Meta Muse tool-choice semantics and reject unsupported selectors before dispatch. | shawnkim |
| #5944 | Remove unsupported hosted web-search declarations for Xiaomi MiMo destinations. | codingbo |
| #5938 | Restart the Windows service child after unexpected exits, including exit 0, while reserving the intentional stay-out code. | codingbo |
| #5935 | Reject Claude message-thread state on translated routes so the client resends full history. | kaladinhonor |
| #5939 | Rewrite standalone `\\0` escapes in Meta tool-schema patterns to equivalent `\\x00`. | boblob6969 |
| #5951 | Preserve Kiro-reported credits across stream attempts and in the usage ledger. | codingbo |

A separate integration commit keeps upstream-controlled Kiro event-type text out of opt-in debug logs. The Kiro stream retains the previously landed bounded HTTP-error text when combined with credit metering.

Left out: #5977. Independent security review found that its local read capability authenticates the request but not the HTTP response. A substituted listener could return a shape-valid forged `protected` verdict. A correct server proof bound to the nonce, endpoint, and body is outside this batch. Both its source commit and status-validation follow-up were reverted in new commits; its test and layout entries are gone. The source PR remains open.

Co-authored-by: shawnkim <shawnkim@markncompany.co.kr>
Co-authored-by: codingbo <cnsdbo@163.com>
Co-authored-by: kaladinhonor <266145786+kaladinhonor@users.noreply.github.com>
Co-authored-by: boblob6969 <boblob6969@icloud.com>
@lidge-jun

Copy link
Copy Markdown
Owner

Thanks! This landed on dev through bug-PR merge train batch 9B, #5985 (merge bf04176). Your change is one commit on dev with you as the author and a Co-authored-by trailer. Closing since the content is now on dev.

@lidge-jun lidge-jun closed this Sep 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working review-ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants