Repository navigation
Subagent models are ignored when using GitHub Copilot provider — All Premium Requests billed to orchestrator model (Claude Opus 4.6) #20859
Description
Description
Summary
When using the GitHub Copilot provider, models configured for subagents (mode: "subagent") are not being respected. Even though OpenCode internally shows usage of the correct models for subagents, all Premium Requests in GitHub Copilot billing are attributed exclusively to the primary/orchestrator model (Claude Opus 4.6).
GitHub Copilot Billing Summary (March 2026)
Total Premium Requests: 300
Claude Opus 4.6: 228 (Mar 26) + 72 (Mar 27) = 300 requests
Claude Sonnet 4.6: 0 requests
GPT-5.4: 0 requests
Gemini 3.1 Pro: 0 requests
All 300 Premium Requests were billed exclusively to Claude Opus 4.6, despite explicitly configuring multiple subagents with cheaper models (Sonnet, Gemini, GPT-5.4).
Notable observation:
In the CSV export from GitHub, models that were supposedly used (Claude Sonnet 4.6, GPT-5.4, Gemini 3.1 Pro) appear in the report but with 0 requests. Other models that were never used during the period do not appear at all. This suggests that GitHub is aware of the configured models, but is still routing and billing all activity through the orchestrator’s model (Opus).
→ Total: 300 Premium Requests, all charged to Claude Opus 4.6. Other models show 0.
Evidence from OpenCode
Output from opencode stats --models (github-copilot models only):
github-copilot/claude-sonnet-4.6
Messages: 845
Input Tokens: 2.7M
Output Tokens: 487.4K
github-copilot/claude-opus-4.6
Messages: 491
Input Tokens: 4.3M
Output Tokens: 301.6K
github-copilot/gemini-3.1-pro-preview
Messages: 33
...
github-copilot/gpt-5.4
Messages: 19
...
Configuration (opencode.json)
Relevant agents configuration:
"gentleman"→mode: "primary",model: "github-copilot/claude-opus-4.6""sdd-orchestrator"→mode: "primary",model: "github-copilot/claude-opus-4.6""sdd-apply"→mode: "subagent",model: "github-copilot/claude-sonnet-4.6""sdd-archive"→mode: "subagent",model: "github-copilot/claude-sonnet-4.6""sdd-design"→mode: "subagent",model: "github-copilot/claude-opus-4.6""sdd-explore"→mode: "subagent",model: "github-copilot/claude-sonnet-4.6""sdd-init"→mode: "subagent",model: "github-copilot/claude-sonnet-4.6""sdd-propose"→mode: "subagent",model: "github-copilot/gemini-3.1-pro-preview""sdd-spec"→mode: "subagent",model: "github-copilot/gemini-3.1-pro-preview""sdd-tasks"→mode: "subagent",model: "github-copilot/gpt-5.4""sdd-verify"→mode: "subagent",model: "github-copilot/gpt-5.4"
Additional observation
When I inspected subagents inside OpenCode, it appeared that the correct model was being selected for each subagent. However, in the final GitHub Copilot billing, everything was still charged under the orchestrator model (Claude Opus 4.6).
Expected behavior
Subagents should execute using their explicitly configured model, and Premium Requests should be billed according to the actual model used in each call (or at least not force everything to the primary agent’s model).
This issue causes significant over-consumption of the most expensive model (Opus) even when cheaper models are explicitly assigned to subagents.
OpenCode version: 1.3.13
Plugins
opencode-copilot-auth (the official bridge between OpenCode and GitHub Copilot)
OpenCode version
1.3.13
Steps to reproduce
- Configure multiple subagents with different
github-copilot/*models. - Run complex workflows using the orchestrator that heavily delegate to subagents.
- Compare
opencode stats --modelswith the downloaded GitHub Copilot usage CSV.
Screenshot and/or share link
No response
Operating System
Ubuntu 24.04.1
Terminal
wsl in windows terminal
Activity
github-actions commentedon Apr 3, 2026
This issue might be a duplicate of existing issues. Please check:
If your issue is distinct from the above (e.g., the billing attribution specifically rather than model selection), please clarify the difference.
berrujaime commentedon Apr 3, 2026
This issue is not a duplicate of the two mentioned.
#18615 is about the model parameter being ignored when launching a subagent by agent name (it falls back to the agent's built-in chain). In my case, the subagents are correctly using the models I configured. I can confirm this with opencode stats --models, where I see messages and tokens being consumed on Claude Sonnet 4.6, GPT-5.4, Gemini 3.1 Pro, etc.
#16937 is about the Desktop App consuming separate premium requests per subagent (higher total usage). My issue is different: it's about billing attribution.
Actual problem:
Even though OpenCode internally executes the subagents with their configured cheaper models, all Premium Requests (300 in my case) are being billed by GitHub Copilot exclusively to the orchestrator's model (Claude Opus 4.6). In the GitHub Copilot usage CSV, the other models show 0 requests.
In short:
Model selection works correctly at runtime.
Billing attribution fails with the GitHub Copilot provider: everything is charged to the expensive main agent model.
Can this be reviewed by the team? It appears there is an issue with how the model is passed to the GitHub Copilot API when using subagents in "subagent" mode.
gndk commentedon Apr 4, 2026
Subagents should not consume any additional requests at all since they are not user requests. Which is also the behaviour I see when using the same model for subagents. Maybe your mismatch actually is caused by the model switch in subagent config?
berrujaime commentedon Apr 4, 2026
No, it's not caused by a model switch.
When I configure subagents with different/cheaper models (Claude Sonnet 4.6, GPT-5.4, Gemini, etc.), they internally use those models correctly. I can clearly see this in opencode stats --models, with thousands of input/output tokens consumed on the cheaper models.
However, in the GitHub Copilot usage CSV, all premium requests (hundreds) are still attributed only to the orchestrator model (github-copilot/claude-opus-4.6). The other models show 0 requests.
When all subagents use the same model as the orchestrator, billing works fine (only 1 premium request). The problem only appears when using different models in subagents.
This looks like a billing attribution issue with the GitHub Copilot provider when model switching is used in subagent mode.
kendotpm commentedon Apr 13, 2026
That's exactly how github copilot bills.
If you try the reverse (free orchestrating to premium), you won't see any premium usage increases. For how long I don't know, its been patched out of VS and CLI when you go this reverse direction.
If you were to parallelize your sub-agents as full-blown agents and have your orchestrator shipping messages to them as new sessions (not via the task tool, just straight up non-interactive bash calls), you'd see all that usage pile up in Github billing.
@gndk's first sentence is accurate. Emphasis mine:
Orchestrators don't save you requests, they save you context so your smart orchestrator can keep everything together while your cheaper coders / reviewers don't clog up the orchestrator's context (particularly important on copilot's miniscule context sizes).
Here's Opus explaining how the copilot plugin is instrumented in opencode.
Two-Layer System
The plugin lives at
packages/opencode/src/plugin/copilot.tsin the OpenCode monorepo.Layer 1 — Fetch wrapper (runs on every API call)
Parses the request body to determine
x-initiator:isAgent = last.role !== "user"— if the last message is a tool result (role "tool") or assistant, it's agent-initiatedisAgent = !(last.role === "user" && hasNonToolCalls)— special handling for mixed content (tool_result + text in same message)"user"(conservative — may overcount)Layer 2 —
chat.headersplugin hook (runs before fetch, can override)Three cases:
x-initiator: "agent"(free)x-initiator: "agent"(free)Plugin output spreads AFTER fetch-level, so the plugin hook wins when it sets a value.
The Agent → Subagent Chain for 0x orchestrator → 3x subagent.
The parentID check is the mechanism that makes subagent calls unconditionally free. It doesn't matter what model the subagent uses or what the message roles look like — if parentID is set, the plugin forces
"agent"and billing never sees it.Edit: formatting
gauravlochan commentedon Jun 2, 2026
@kendotpm That is so strange. So the fix would have to come from GitHub?
github-actions commentedon Aug 2, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.