Skip to content

fix(copilot): forward role-specific model config to launch and restore#2975

Open
anmol0b wants to merge 3 commits into
AgentWrapper:mainfrom
anmol0b:fix/copilot-forward-model-config
Open

fix(copilot): forward role-specific model config to launch and restore#2975
anmol0b wants to merge 3 commits into
AgentWrapper:mainfrom
anmol0b:fix/copilot-forward-model-config

Conversation

@anmol0b

@anmol0b anmol0b commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

What

Adds appendModelFlag to the GitHub Copilot adapter, called from both GetLaunchCommand and GetRestoreCommand, so a configured agentConfig.model is forwarded as --model to the copilot CLI. Also adds a GetConfigSpec override advertising the model field, matching claude-code, codex (#2869), and kiro (#2932).

Why

Fixes #2895. A worker/orchestrator configured with a specific model silently fell back to Copilot's global default because the adapter never read cfg.Config.Model — same root-cause pattern as #2769 (Codex) and #2897 (Vibe) in this audit series.

How

  • Mirrors fix: pass Codex model config to launch commands #2869's appendModelFlag pattern exactly: appends --model only when non-blank, so an unconfigured launch is byte-for-byte unchanged.
  • Unlike Vibe, Copilot's CLI takes the model directly as a launch flag (no TOML/config-file indirection), so this fix is scoped entirely to copilot.go — no port-interface changes needed.
  • Replaced the now-outdated TestGetConfigSpecHasNoCustomFieldsYet (asserted zero fields) with TestGetConfigSpecReportsModelField, since that assumption no longer holds once model is declared.

Testing

All existing tests pass, plus:

  • TestGetConfigSpecReportsModelField
  • TestGetConfigSpecRespectsCanceledContext
  • TestGetLaunchCommandAppendsModelFlag
  • TestGetLaunchCommandOmitsBlankModel
  • TestGetRestoreCommandAppendsModelFlag
Screenshot 2026-07-22 at 7 25 45 PM

Checklist

  • Branched from main (or continuing an existing PR branch)
  • One focused change; links the related issue when applicable
  • Follows AGENTS.md conventions and PR hygiene
  • Tests added/updated for user-visible behavior where it makes sense
  • Relevant CI checks pass for the area touched (go, frontend, etc.)

@somewherelostt

Copy link
Copy Markdown
Collaborator

Thanks for contributing to Agent Orchestrator.

This PR is being picked up by the current external contributor on-call pair:

If someone is already working on this, please continue as usual.
The on-call pair is added for visibility, tracking, and support, not to take over the work.
If you need help with review, direction, reproduction, or next steps, please tag @illegalcall and @Pulkit7070 here.

For faster context or live questions, you can also join the AO Discord.

Join the session here:
https://discord.gg/H6ZDcUXmq

Come by if you want to see what is being built, ask questions, or just hang around with the community.

@codebanditssss codebanditssss left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code is correct and go test ./internal/adapters/agent/copilot/... is green locally, all 9 checks green. The blank/whitespace guard and the byte-for-byte-unchanged-when-unconfigured property both hold.

One thing surfaced by reading this next to #2985, which I looked at just before this. The two PRs take opposite positions on the restore path, and I don't think either is wrong — but the series would be easier to follow if it said why. Detail inline.

For what it's worth, both positions have precedent in the tree: codex wires restore (codex.go:151), claudecode doesn't. So this isn't a case of one of them being a mistake.

Comment thread backend/internal/adapters/agent/copilot/copilot.go Outdated
Comment thread backend/internal/adapters/agent/copilot/copilot_test.go
@codebanditssss

Copy link
Copy Markdown
Collaborator

Following up on my earlier question about whether copilot --model X --resume Y was verified — there's now a relevant precedent.

@Hardik180704 checked the equivalent composition against a real CLI in #2989:

Verified against the real Pi CLI. I resumed an existing session using pi --model openai/gpt-4o --session <id>. Pi found the correct session and attempted to use the explicitly provided OpenAI model, confirming that --model and --session are accepted together and forwarded correctly.

That doesn't settle this PR — Copilot uses --resume, not --session, and it's a different CLI — so the question I raised is still technically open. But it does two useful things: it shows the check is cheap (resume one session against a real install), and it means the series is no longer in a state where nobody has verified anything.

Given you wired restore here and deferred it in #2985 for exactly this reason, one run of copilot --model <model> --resume <id> would close the loop and let the two PRs stop disagreeing. If it works, #2985's deferral can be dropped; if it doesn't, this one should follow #2985's lead.

Still not blocking from my side — codex sets precedent for wiring restore, so this isn't wrong as it stands.

@illegalcall

Copy link
Copy Markdown
Collaborator

Thanks for this — the code is clean (gofmt/vet clean, tests pass locally) and the launch path is well-grounded: --model is a documented Copilot CLI flag, so copilot --model <value> on launch will take effect.

One thing I'd like evidence on before merging: the restore path. This PR also appends --model to the --resume invocation (copilot --resume <id> --model <value>), but the current tests only assert argv shape — they don't prove the resumed session actually adopts the new model.

The Copilot CLI docs describe --resume as loading the full saved conversation context, and the flags reference doesn't document --resume accepting/honoring --model. So my concern is that on resume the flag may be silently ignored (session keeps its original model) rather than applied. It won't error — both are valid top-level flags — so a passing argv test wouldn't catch a no-op.

Could you add a bit of evidence that --model is actually honored on resume against a real copilot install? A screenshot or terminal capture showing a resumed session running on the overridden model (vs. its original) would settle it.

If it turns out resume doesn't honor --model, the cleaner move would be to mirror the Kimi PR (#2985): forward on launch only, and lock the restore decision in with a test until it's verified. Launch forwarding on its own is a solid, mergeable fix.

@Pulkit7070 Pulkit7070 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed against the model-config adapter family pattern. go test ./internal/adapters/agent/copilot -count=1 passes, go vet clean, go build ./... clean, gofmt -l clean.

Matches the established pattern:

  • appendModelFlag trims and no-ops on blank/whitespace.
  • Launch and restore both append --model after approval flags and before --agent/--interactive <prompt>, so it is ahead of the positional prompt.
  • GetConfigSpec advertises the model field with a good description including an example.
  • Tests cover launch + restore + blank + configspec, plus a canceled-context check. Nice.

Non-blocking note inline about the helper signature.

Comment thread backend/internal/adapters/agent/copilot/copilot.go Outdated
@codebanditssss
codebanditssss self-requested a review July 23, 2026 23:41

@codebanditssss codebanditssss left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

anmol0b added 2 commits July 24, 2026 23:25
…ly consistency string directly. Functionally identical output.
@codebanditssss

Copy link
Copy Markdown
Collaborator

heads up, the build-test and lint failures here aren't flaky, so a re-run won't clear them. both are the same root cause: gofmt/goimports on 6 files.

build-test (gofmt -l .) and lint (goimports: 6) both flag:

  • internal/adapters/agent/authprobe/authprobe.go
  • internal/adapters/agent/claudecode/claudecode.go
  • internal/adapters/agent/codex/codex.go
  • internal/adapters/agent/copilot/auth.go
  • internal/adapters/agent/kilocode/auth.go
  • internal/adapters/agent/opencode/opencode.go

quick fix from backend/:

gofmt -w internal/adapters/agent/{authprobe,claudecode,codex,copilot,kilocode,opencode}
goimports -w internal/adapters/agent/{authprobe,claudecode,codex,copilot,kilocode,opencode}

or just gofmt -w . && goimports -w . and push. everything else is green.

@Pulkit7070

Copy link
Copy Markdown
Collaborator

Re-checked after 637505e and the CI retrigger. The note from my first pass is addressed: appendModelFlag now takes ports.AgentConfig (copilot.go line 347), matching the rest of the model-config family rather than passing a bare string.

On the lint/build-test failure flagged earlier: it is resolved on the current head (6327609). I pulled both changed files at head and ran gofmt -l with no output, so they are properly formatted, and the format, lint, and build-test checks are all green now (along with the native matrix on ubuntu/macos/windows). For what it is worth, the "6 files" in the earlier heads-up does not match this PR, which changes only copilot.go and copilot_test.go, so that comment looks like it referred to the broader family or a prior state.

Nothing outstanding from me. The change is the standard, behavior-preserving model-flag forwarding, now consistent with the family, gofmt clean, and green across CI.

@Pulkit7070 Pulkit7070 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes to hold the merge until the restore-path behavior is settled. To be clear, this is not a code-quality problem: I stress-ran the package (go test -race -count=3), plus go vet and go build, all clean, gofmt is clean, and the appendModelFlag refactor to take ports.AgentConfig is good. The launch path is solid: copilot --model is a documented launch flag.

The open item is the restore path, and I am corroborating the concern already raised on this PR. GetRestoreCommand emits copilot [approval] --model <value> --resume <id>. Copilot's --resume loads the full saved conversation context, and the CLI flag reference does not document --resume honoring --model, so on resume the flag may be silently ignored (the session keeps its original model) rather than applied. Both are valid top-level flags, so it will not error, which means the current argv-shape tests would pass even if resume forwarding is a no-op. I could not verify this locally because it needs a real authenticated copilot install.

Two ways to clear this:

  1. Provide evidence that --model is honored on resume against a real copilot install (a terminal capture of a resumed session running on the overridden model versus its original).
  2. Or forward on launch only and drop --model from GetRestoreCommand, mirroring the Kimi PR #2985, and lock that decision in with a test asserting restore does not carry --model until it is verified.

Launch-only forwarding is a solid, mergeable fix on its own. Holding the merge until one of the above lands.

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.

GitHub Copilot ignores role-specific model config on launch

5 participants