Repository navigation
Description
Area
apps/server
Summary
ACP registry providers show the option list of one model on every model. When the current ACP model has fewer thought_level choices, all models lose the missing choices.
With Devin, a thread on glm-5-3-flash-max (which offers low/high/max) makes Claude Opus 5.5 show only Low / High / Max. Opus 5.5 itself offers low/medium/high/xhigh/max.
Steps to reproduce
- Add Devin through the ACP registry (
acpRegistry, agentdevin). - Start a Devin thread on
glm-5-3-flash-maxand send a message. - Start a new Devin thread and select Claude Opus 5.5 (
claude-opus-5-5-medium). - Open the mode / thinking menu.
Expected behavior
Each model shows its own options. Opus 5.5 shows Low, Medium, High, Extra High, Max.
Actual behavior
Opus 5.5 (and all 108 Devin models) shows only Low, High, Max: the list of the GLM model.
The provider cache confirms it. ~/.t3/caches/acpRegistry_devin.json gives every model the same thought_level options:
- Host A, live/probed model
claude-opus-5-5-medium: 108 models ×low/medium/high/xhigh/max - Host B, live/probed model
glm-5-3-flash-max: 108 models ×low/high/max
Both hosts use the same Devin CLI version, account, and T3 provider settings. Refreshing the provider does not help, because the live configuration from the last session overrides the probe.
Cause
modelsFromDiscovery builds one capabilities object from discovery.configOptions and assigns it to every model. ACP configOptions describe the current session, so their values are valid only for the current model. applyAcpRegistryLiveConfiguration does the same with the last live session's configuration, which stays in memory until the provider instance is recreated.
A possible fix: attach session option descriptors only to currentModelId, and keep the descriptors last seen for each model (from the probe and from live sessions) instead of copying one set to all models.
Impact
Minor bug or occasional failure
Version or commit
T3 Code nightly 0.0.46-nightly.20261003.2610 (server). Code references are at 31a9da1. Devin CLI 3000.11.3.
Environment
Ubuntu 26.04 server, Windows desktop client over Tailscale. Also seen with a WSL2 server.
Workaround
Send one message in a Devin thread on a model with the full option list (for example Opus 5.5). The live configuration then gives the full list to all models, until another model becomes current.
Activity
juliusmarminge commentedon Oct 3, 2026
Note
Grok responding on behalf of Julius.
Triage
Thanks @snnbotchway. The repro, the two-host cache comparison, and the code pointers all line up. I confirmed this on current
main(31a9da179). It's a real catalog bug in the ACP registry snapshot, and Devin makes it visible because itsthought_levelchoices change with the current model.What the menu is reading
The composer looks up the selected model's
capabilities(getProviderModelCapabilities).modelsFromDiscoverybuilds one capabilities object from the sessionconfigOptionsand assigns that same object, includingcurrentValue, to every model. The comment there says those options ride on every model so the composer can drive them per thread.applyAcpRegistryLiveConfigurationrebuilds the catalog the same way from the latest live session.ACP
configOptionsdescribe the current session. The disposable discovery probe (probeAcpRegistryConfiguration→acpRegistryProbeResult) never switches models, so the list it stores is whatever model that test session happened to be on, and a laterconfig_option_updatereplaces it. Live configuration is one entry per provider instance (liveConfigurationByInstance), so the newest Devin session wins for every model and every thread on that instance. That entry stays until the driver instance is recreated or disposed, or until logout or auth loss.A provider refresh probes again, and then
withLiveRuntimeStatepaints the stored live configuration back on top, which is why a refresh keeps the short list. A server restart drops the in-memory overlay, but the next probe stamps a single session's list onto the catalog again. The cache file is that published snapshot, so identicalthought_levelarrays on all 108 models come from the same write.The in-repo ACP mock already varies
thought_levelwithcurrentModelId(apps/server/scripts/acp-mock-agent.ts), but the registry snapshot doesn't keep those lists apart.What still works at send time
On session open,
AcpAdapterV2skips a stored select value the live session doesn't offer and logs an agent rejection instead of failing the turn. That only runs once a session exists, though. It doesn't restore Medium or Extra High on the Opus menu, and it doesn't stop the GLM list from showing for Opus beforehand. Your workaround of sending on a model with the wider list just changes which single list every model shares.Likely fix area
Your suggestion fits this failure: keep the last
thought_levellist seen for each model (from probes and live sessions) and attach session options only to the current model, instead of copying one set to all models. A maintainer will decide on the fix direction.jonandeva commentedon Nov 11, 2026
Another agent affected: Mistral Vibe (ACP registry, Vibe 3.1.0). Here it sticks across restarts too.
What happened
~/.t3/caches/acpRegistry_mistral_vibe.json) showedthinking: [off, high]on all seven Vibe models.off.thinking: [off]. That includes DeepSeek V4.1 Flash, GLM 5.3 and Medium 3.5.delegate_taskthen rejectedthinking: highfor any of them: "Option thinking must be one of: off."Why it persists for Vibe
Vibe writes the session's model to
active_modelin~/.vibe/config.toml. The discovery probe's session therefore opens on whichever model was used last, even after a T3 restart. One run on a model with no thinking levels collapses the menu for every Vibe model untilactive_modelis changed back by hand.Workaround
Set
active_model = "mistral-medium-3.5"in~/.vibe/config.toml, then start any Vibe session. The catalog went back to[off, high]for all models.Side effect worth noting
The wider list is just as wrong in the other direction. Custom
[[models]]entries with nothinking_levelsshowhighbecause Medium 3.5's list is copied onto them. The user can't tell from the menu whetherhighwill be honoured or silently skipped at session open. +1 to keeping options per model.