Skip to content

[Bug]: ACP registry gives every model the last session's config options, so one Copilot auto session removes reasoning_effort from all Copilot models #21567

Closed as not planned

Description

@armedi

Before submitting

Area

apps/server (packages/provider-acp-registry)

Summary

For an ACP registry provider, T3 builds one set of option descriptors from whichever session most recently reported configOptions and gives that set to every model of the provider. ACP agents report options for the session's current model, so the options of one model leak onto all the others.

With GitHub Copilot this flips reasoning_effort on and off for all Copilot models: when any Copilot session is on the auto model (which has no reasoning_effort option), T3 then rejects reasoning_effort for gpt-6.1-sol, claude-opus-5.5, and the rest. This lasts until some other Copilot session reports its options again. Agents that call delegate_task see the rejection, decide Copilot "doesn't support reasoning effort", and dispatch without it, so children silently run at the default effort.

Root cause

packages/provider-acp-registry/src/server/adapter.ts, around lines 222-226 at 1451e7c: every session's config update is published as the provider's live configuration:

onSessionConfigurationUpdate: (configOptions, modeState) =>
  runtimeCoordinator.publishLiveConfiguration(
    options.instanceId,
    normalizeAcpRegistryLiveConfiguration(configOptions, modeState),
  ),

packages/provider-acp-registry/src/server/driver.ts, modelsFromDiscovery (around lines 90-120): one capabilities object, built from that single session's configOptions, is assigned to every discovered model:

const capabilities = ... createModelCapabilities({ optionDescriptors: discovery.configOptions });
...
discovered.map((model) => ({ slug: model.id, ..., capabilities }))

invalidOptionSelections in apps/server/src/mcp/OrchestratorMcpService.ts then checks every model's selections against these shared descriptors.

What Copilot actually reports per model

I queried Copilot CLI 1.0.96 directly over ACP (copilot --acp, session/new, then session/set_config_option with configId: "model") and read the returned configOptions:

Current model reasoning_effort values
auto option absent (only mode, model, allow_all)
claude-sonnet-5.5, claude-opus-5.5, claude-haiku-5.5, gpt-6-astra low, medium, high, xhigh, max
gpt-6.1-sol, gpt-6-luna none, low, medium, high, xhigh, max
grok-4.7 low, medium, high, xhigh
gemini-4-argon, gemini-3.8-flash, mai-code-1.1-flash low, medium, high

So both the presence of reasoning_effort and its allowed values depend on the model, but T3 shows one model's list for all of them.

Steps to reproduce

Deterministic, using the orchestrator MCP tools from any thread (Copilot provider enabled through the ACP registry, signed in):

  1. Start a Copilot child on auto:
    delegate_task { task: "Reply with exactly OK.", target: { providerInstanceId: "acpRegistry_copilot", model: "auto", options: { allow_all: "on" } }, mode: "wait" } → completes.
  2. Start a Copilot child on gpt-6.1-sol with effort:
    delegate_task { task: "Reply with exactly OK.", target: { providerInstanceId: "acpRegistry_copilot", model: "gpt-6.1-sol", options: { reasoning_effort: "high", allow_all: "on" } }, mode: "wait" }
    → rejected: Model gpt-6.1-sol on provider acpRegistry_copilot rejected options: Unknown option reasoning_effort; supported options: mode, allow_all.
  3. Start any Copilot child on a model that has the option, without passing it:
    delegate_task { ..., model: "claude-haiku-5.5", options: { allow_all: "on" } } → completes.
  4. Repeat step 2 → accepted now; the child thread's configuration shows reasoning_effort: high.

The same mechanism also affects allowed values. After a gpt-6.1-sol session, a bad value was rejected with must be one of: none, low, medium, high, xhigh, max (gpt's list), while orchestrator_capabilities earlier listed low…max for every Copilot model (sonnet's list). I expect that after a grok-4.7 session, max would be rejected for claude-opus-5.5 too; I haven't tested that case.

Expected behavior

Each model's option descriptors reflect what the agent reports for that model: reasoning_effort stays available for gpt-6.1-sol regardless of what another session is running, with gpt-6.1-sol's own levels. A session on auto (or any other model) changes only auto's options.

Actual behavior

Every model of the provider gets the option set of whichever session last reported configOptions. After any auto session, reasoning_effort disappears from every Copilot model in orchestrator_capabilities, and delegate_task rejects it. Allowed levels flip between models' lists the same way. The isDefault model also follows the last session's current model.

In my logs this rejection appeared 26 times across 11 threads over about a week. Each time, the calling agent dropped the option and ran the child at the default effort.

Impact

Major degradation or frequent failure. Intermittent and silent: effort selection for Copilot works or fails depending on unrelated sessions.

Version or commit

T3 Code (Nightly) 0.1.1-nightly.20261018.3335; source references at main @ 1451e7c.

Environment

macOS (Darwin 25.6), desktop app. Provider: GitHub Copilot CLI 1.0.96 through the ACP registry (acpRegistry_copilot).

Logs

Model gpt-6.1-sol on provider acpRegistry_copilot rejected options: Unknown option reasoning_effort; supported options: mode, allow_all.
Model claude-sonnet-5.5 on provider acpRegistry_copilot rejected options: Unknown option reasoning_effort; supported options: mode, allow_all.
Model claude-haiku-5.5 on provider acpRegistry_copilot rejected options: Unknown option reasoning_effort; supported options: mode, allow_all.

Workaround

Before dispatching with reasoning_effort, start a throwaway Copilot session on a model that has the option, and pass no effort. Its config update republishes a descriptor set that includes reasoning_effort.

Possible fix

Keep the live configuration per model (keyed by the session's current model id), or capture each model's configOptions (e.g. by setting model on the probe session per model). Then build capabilities per model in modelsFromDiscovery instead of sharing one object. Until a model's options are known, falling back to "no descriptors" (skip validation, as invalidOptionSelections already does when descriptors is undefined) would be safer than rejecting with another model's list.

Activity

  1. juliusmarminge commented on Oct 19, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Closing as a duplicate of #15177. It is the same ACP registry bug: one session's configOptions are published as the provider's live configuration and assigned to every model via modelsFromDiscovery, so another model's option set (here Copilot auto dropping reasoning_effort) leaks onto the rest.

    #15177 tracks the Devin/thought_level case with the same root cause; open fix PRs include #19575 and #19754. Please continue there (your Copilot/reasoning_effort repro and per-model table are useful additional evidence).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    duplicateThis issue or pull request already exists

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions