fix(backends): send the CLI/API contracts these backends actually have - #243
Merged
Yifan Yang (Yif-Yang) merged 1 commit intoAug 21, 2026
Merged
Conversation
Two backends were emitting parameters that their target does not accept, so
both silently did nothing (or aborted) instead of what the code intended.
Copilot (skillopt_sleep/backend.py)
-----------------------------------
`--allowed-tools` is not a GitHub Copilot CLI option; the CLI exits with
`error: unknown option '--allowed-tools'` before doing any work, so both
Copilot call paths were dead. Two independent axes were also conflated:
* `--allow-all-tools` waives the interactive approval prompt and the CLI's
own help calls it "required for non-interactive mode" -- removing it breaks
headless runs, so it is not the flag to scope on.
* `--available-tools` is the visibility axis: "Only these tools will be
available to the model". That is where scoping belongs.
Keep the former, scope with the latter. The selector is also case-sensitive:
verified against Copilot CLI 1.0.80 that `--available-tools=bash` lets the
tool run while `--available-tools=Bash` blocks it, so the default is
lowercase `bash` (override: COPILOT_AVAILABLE_TOOLS).
MiniMax (skillopt/model/minimax_backend.py)
-------------------------------------------
`chat_template_kwargs.enable_thinking` is a Qwen/HuggingFace-serving
convention that appears nowhere in MiniMax's OpenAI-compatible reference, so
the endpoint ignored it and thinking stayed at the server default regardless
of the configured flag. Send the documented top-level field instead:
`{"thinking": {"type": "adaptive" | "disabled"}}`.
M2.x accepts `{"type": "disabled"}` but keeps thinking on anyway, so it is
sent `adaptive` rather than a value that misrepresents what the model does.
Unknown deployments default to `adaptive`, matching the documented API
default of thinking-on-when-omitted.
Tests assert the exact wire payload / argv, and each new test fails when its
fix is reverted.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #170 and #190. Both PRs moved in the right direction, and their test scaffolding is kept — but each shipped a parameter its target does not accept, so as merged neither backend does what it says. This corrects both against the real contracts.
Copilot —
skillopt_sleep/backend.py--allowed-toolsis not a GitHub Copilot CLI option:Both Copilot call paths (
_calland the task-replay path) sent it, so both aborted before doing any work.Two independent axes were also conflated:
--allow-all-toolswaives the interactive approval prompt. The CLI's own help says it is "required for non-interactive mode" — dropping it breaks headless runs. This is a permission flag, not a scoping flag.--available-toolsis the visibility axis: "Only these tools will be available to the model." This is where scoping belongs.So: keep
--allow-all-tools, scope with--available-tools(defaultbash, override viaCOPILOT_AVAILABLE_TOOLS).The selector is case-sensitive, which is easy to get wrong. Verified live against Copilot CLI 1.0.80:
--available-tools bash"toolName":"bash"— tool runs--available-tools Bash--available-tools writeThat last row is the control: the flag really does narrow the surface, rather than being accepted and ignored.
MiniMax —
skillopt/model/minimax_backend.pychat_template_kwargs.enable_thinkingis a Qwen/HuggingFace-serving convention. It appears nowhere in MiniMax's OpenAI-compatible reference, so the endpoint ignores it and thinking stays at the server default no matter what the flag says.This predates #190 — the field was already on
main; #190 built model-aware logic on top of it, so the routing worked but the value never reached the model.The documented control is the top-level
thinkingobject:{"thinking": {"type": "adaptive"}} {"thinking": {"type": "disabled"}}Also per the docs, the M2.x family accepts
{"type": "disabled"}but keeps thinking on regardless. Sendingdisabledthere would record a request that misrepresents what the model actually did, so M2.x is sentadaptive. This preserves #190's intent (M2.7 keeps always-on thinking) without a value that lies. Unknown deployments default toadaptive, matching the documented API default of thinking-on-when-omitted.Reference: https://platform.minimax.io/docs/api-reference/text-openai-api
Tests
Both suites now assert the exact wire payload / argv rather than the shape the code happens to produce, plus explicit regression guards (
test_nonexistent_allowed_tools_flag_is_never_sent,test_unsupported_chat_template_kwargs_is_never_sent).