Skip to content

fix(muse-proxy): gate tools-carrying requests from the warm/exec CLI fallback (#6117) - #6256

Merged
dezren39 merged 1 commit into
mainfrom
fix/muse-proxy-tools-fallback
Nov 5, 2026
Merged

dezren39 merged 1 commit into
mainfrom
fix/muse-proxy-tools-fallback

Conversation

@dezren39

@dezren39 dezren39 commented Nov 5, 2026 •

Copy link
Copy Markdown
Member

Track 3 of the tool-call-audit "fix all" program (opencode#1708, code#6117): muse-direct's warm/exec fallback doctrine defect.

Where the code actually lives

The audit (§6 of code-inventory.md) locates muse-direct's implementation in this repo: OpenCode's muse-direct block speaks OpenAI Responses to bin/muse-proxy.mjs on :18747. There is no muse-direct provider under packages/ai/src/providers/ in the opencode fork (that route lands on the generic fork openai provider -> this proxy), so the fix lands here and is cross-recorded on opencode#1708.

Fallback map (measured from code)

  • POST /v1/responses (the actual muse-direct route): direct-only already — no credential = loud 404, exchange/transport failure = loud 502. No vendor fallback exists on this route.
  • POST /v1/chat/completions: direct first; on no-upstream-response (no credential, MUSE_PROXY_DIRECT=0, exchange/fetch transport failure, unexpected direct error) it fell to warm (muse serve), and on any warm failure before commit, to exec (muse exec); a 403 client_attestation_denied on the direct path also returned "fall back" explicitly.
  • Warm/exec behavior with tools: the client's tools array was never passed (warm receives only messages; exec receives only a --prompt-file). formatPrompt flattened assistant tool_calls to [Tool Call: name(args)] prose and tool results to Tool Result (id): ... transcript lines. The Muse CLI then acted with its OWN tools (--approval-mode never) and only final text returned with finish_reason: "stop" — a session could flip between real tool calls (direct) and simulated CLI agency (fallback) turn by turn, silently.

Decision: gate, don't conform (and why)

Conforming warm/exec to emit real client tool calls is impossible: the muse serve/muse exec surfaces return only final text — there is no wire tool-call emission for arbitrary client tools to translate. Their conforming end state is the facade migration (opencode#1155). So, per code#6117's muse-proxy ask, the vendor fallback is REMOVED for the class it can harm:

  • A request that carries tools (non-empty tools, a forced tool_choice, or a history containing tool_calls / role: "tool" messages) is direct-or-error. If direct cannot serve it, the proxy returns a loud 502 with error.code: "tools_fallback_ineligible" naming the limitation, and warm/exec are never attempted.
  • Text-only requests keep the warm/exec reliability fallback (no tool calls exist to degrade there), and every chat response now records the serving path in the X-Muse-Proxy-Path header (direct / warm / exec).
  • The muse provider stays disabled and nothing here dispatches on muse/* models; the Meta pool was not touched (walled until 2026-11-09).

Tests

node --test bin/muse-proxy.test.mjs — 44/44 pass (run twice), 7 new "tools gate" tests:

  • tools-carrying + no credential -> 502, stub log proves neither muse exec (--prompt-file) nor muse serve (START) was invoked, warm deliberately enabled
  • tools-carrying + MUSE_PROXY_DIRECT=0 -> 502, no exec
  • tools-carrying + attestation denial -> 502, CLI door never took over (pins the behavior change; the text-only attestation-fallback test still passes unchanged)
  • history-only tool loop (no tools array) -> 502
  • direct path still clean: tools-carrying request -> 200, real tool_calls with byte-exact arguments, finish_reason: "tool_calls", X-Muse-Proxy-Path: direct
  • text-only fallback retained: 200 via exec, X-Muse-Proxy-Path: exec
  • /v1/responses with tools + no credential -> loud 404, CLI never touched

Retest

Ready for the opencode#1708 retest queue: live muse-direct round-trip after the Meta pool wall resets 2026-11-09T00:00:00Z. Not deployed by this PR — the coordinator sequences the shared build/deploy.

Refs developing-today-forks/opencode#1708, closes the muse-proxy item of #6117 (claude-code/commandcode items are separate tracks).


Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.

@dezren39
dezren39 requested a review from a team as a code owner November 5, 2026 15:14
@coderabbitai

coderabbitai Bot commented Nov 5, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 44 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: e4de0b22-50ad-4113-9a79-40e6bf30d47c
Commits

Reviewing files that changed from the base of the PR and between 49df2c0 and f280827.

Files selected for processing: 2

  • bin/muse-proxy.mjs
  • bin/muse-proxy.test.mjs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@dezren39
dezren39 merged commit 2a67620 into main Nov 5, 2026
1 check passed
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-05T15:16:07.256036Z f280827 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

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.

1 participant