fix(wrap): route OpenCode custom OpenAI-compatible upstreams - #3110
fix(wrap): route OpenCode custom OpenAI-compatible upstreams#3110Parideboy wants to merge 1 commit into
Conversation
…mlabs-ai#3107) `headroom wrap opencode` always forwarded OpenAI-shaped traffic to api.openai.com with no way to point it at a third-party provider like DeepSeek, so a DeepSeek-configured OpenCode session got its requests silently sent to OpenAI and rejected with an HTTP 401 error. Add --openai-api-url to opencode() (mirroring the plumbing already used by proxy/vibe/grok) and reject combining it with --copilot-subscription, since the two pick different upstream-selection strategies. Also update the OpenCode docs, which told DeepSeek users not to use `headroom wrap` at all, to document the new flag as the supported path. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
PR governanceThis PR follows the template and is marked ready for human review. |
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
JerrettDavis
left a comment
There was a problem hiding this comment.
This implementation looks internally coherent, but it substantially overlaps #3125 and the two changes should not both merge independently. #3125 also adds the canonical OPENAI_TARGET_API_URL environment variable and broader user guidance; this PR usefully updates the canonical docs/opencode.mdx page. I recommend consolidating that documentation addition into the selected implementation (likely #3125) and closing the duplicate, rather than landing both.
|
Agreed with @JerrettDavis — #3125 fixes the same bug (#3107) and is more complete: it also adds the Closing this one in favor of #3125. One thing worth carrying over: this PR also updated |
Description
headroom wrap opencodealways forwards OpenAI-shaped traffic tohttps://api.openai.com/v1, with no flag or env var to point it at a third-party OpenAI-compatible provider. A user who configures OpenCode for DeepSeek and then runsheadroom wrap opencodegets their requests silently forwarded to OpenAI instead, which rejects the DeepSeek key with an HTTP 401 error. Making this worse,docs/content/docs/opencode-deepseek.mdxexplicitly told users not to useheadroom wrapat all for this case, leaving no documented path for DeepSeek users throughwrap opencode.The proxy-side plumbing to support a custom upstream already exists and is already used by other
wrapsubcommands (vibe,grokhardcode their own upstream URLs through the same_ensure_proxy(openai_api_url=...)path). This PR exposes it as a user-settable--openai-api-urloption onopencode(), following the same pattern as the open sibling PR #3018 (fix(wrap): route Cline custom upstreams), and updates the docs so DeepSeek users have a workingwrap opencodepath.Closes #3107
Type of Change
Changes Made
headroom/cli/wrap.py: add--openai-api-urloption toopencode(), thread it into the_ensure_proxy(...)call, and reject combining it with--copilot-subscription(the two pick different, incompatible upstream-selection strategies), matching the file's existing incompatible-flag validation pattern.tests/test_cli/test_wrap_opencode.py: four new tests covering the flag being forwarded, theNonedefault when omitted, its presence in--help(and absence fromwrap codex --help), and the conflict with--copilot-subscriptionfailing fast before any proxy work.docs/content/docs/opencode.mdx: document the new flag in the Options block, with a cross-link to the DeepSeek guide.docs/content/docs/opencode-deepseek.mdx: rewrite the "Models appear but requests fail" troubleshooting section and the "What's NOT in this guide" bullet, which previously told readers not to useheadroom wrapat all, to instead document--openai-api-urlas the supported fix/shortcut.Testing
pytest)ruff check .)mypy headroom)Test Output
Real Behavior Proof
.venv(mypy 1.19.1, pytest 9.0.3, ruff 0.15.17), local editable install ofheadroom.venv/Scripts/headroom.exe wrap opencode --helpto confirm the flag is listed;.venv/Scripts/headroom.exe wrap opencode --openai-api-url https://api.deepseek.com/v1 --copilot-subscriptionto confirm the conflict check fires before any proxy/config work--helpoutput lists--openai-api-url URLwith the full help text; the conflicting-flags command exits 1 with the newClickExceptionmessage and does not start a proxy or touch OpenCode's configapi.deepseek.com(would require a real DeepSeek API key and a running OpenCode install); this PR only adds the CLI plumbing, the underlying_ensure_proxy/proxy-side forwarding ofopenai_api_urlis pre-existing and already covered by otherwrapsubcommands' testsRuntime Rollout Safety
--openai-api-urlpreserves the exact prior behavior (upstream defaults to OpenAI, or to the Copilot subscription URL when--copilot-subscriptionis set)--openai-api-urlreverts to prior behaviorReview Readiness
Checklist
CHANGELOG.md— it is generated by release-please from my Conventional Commit PR title (a CI guard enforces this)Additional Notes
Coordination: this touches a different section of
headroom/cli/wrap.py(OpenCode, ~line 7203) than the open sibling PR #3018 (Cline, ~line 6564), which fixes the identical class of bug forwrap cline. No textual conflict expected between the two, but line numbers may shift if #3018 merges first.