You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Orchestrator V2: look up one model in orchestrator_capabilities, and list valid models when delegate_task rejects one
#21201
PR #19756 trims the default orchestrator_capabilities result to favorite models with slim options, and adds a providerInstanceId filter. That covers browsing. The most common call in my threads is narrower: the user named a model, and the agent wants that one entry. Two small additions would cover it:
A model filter on orchestrator_capabilities, so the agent reads one entry instead of a catalog.
delegate_task errors that list the valid models and providers, the way option errors already list valid values. Then an agent can delegate directly and recover from a typo without a catalog call at all.
Problem to solve
Most of my delegations name the model: "use a gpt-6.1-sol subagent on extra high". Over one week, Claude agents in 68 of my threads called orchestrator_capabilities 48 times, each time to confirm a model the user had already named. On main one call returns 28,391 characters (about 7K tokens), and the result stays in context for the rest of the session:
Part
Size
Models
cursor
18,252 chars
47
claudeAgent
6,360 chars
13
codex
4,538 chars
7
5 other providers
~1,800 chars
0–1 each
features and thread fields
~400 chars
The entry the agent needs, codex / gpt-6.1-sol with its options, is 633 characters. About 2% of the response.
#19756 fixes most of this when the named model is a favorite. When it isn't, the agent sees omittedModels and calls again with models: "all", which #19756 measured at 18,822 characters. Narrowing by providerInstanceId still returns every Codex model when the agent wants one.
Codex agents work around it by filtering the result inside their JS exec tool before printing. Claude Code can't filter a tool result, so it reads the whole thing.
delegate_task can't stand in for the lookup either. Its option errors already list valid values (OrchestratorMcpService.ts:334):
Model gpt-6.1-sol on provider codex rejected options: Option reasoningEffort must be one of: low, medium, high, xhigh, max, ultra.
Its model and provider errors don't (L1280, L1239):
Model gpt-6.1-sool is not advertised by provider codex.
Provider instance codx is not registered.
After either one the agent has to fetch the catalog. And the injected instructions tell it to fetch the catalog first anyway (orchestrationInstructions.ts:9).
Model gpt-6.1-sool is not advertised by provider codex. Advertised models: gpt-6.1-sol, gpt-6-astra, gpt-6-sol, gpt-6-luna, gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna.
Provider instance codx is not registered. Instances that can run child tasks: claudeAgent, codex, cursor.
3. One line in the tool description and the injected instructions
For example: "When the user names a model, call delegate_task directly; a rejected target lists the valid values. Pass model to orchestrator_capabilities to look up one model's options."
With all three, a named-model delegation costs about 150 tokens (filtered lookup) or nothing (direct delegate_task), down from about 7K.
Acceptance criteria
orchestrator_capabilities({ providerInstanceId: "codex", model: "gpt-6.1-sol" }) returns one provider with one model and its options.
orchestrator_capabilities({ model: "sol" }) returns every model whose ID contains sol, across providers, including models that aren't favorites.
A model filter with no match returns providers: [], not an error.
Calls without model behave as before.
delegate_task with a model the provider doesn't advertise returns model_unavailable with the provider's advertised models in the message.
delegate_task with an unregistered providerInstanceId returns provider_unavailable with the instances that can run child tasks.
The orchestrator_capabilities tool description mentions model.
A static model list in my agent instructions. It competes with T3's instruction to call the tool, goes stale when models change, and option IDs differ per model (Codex models take reasoningEffort: xhigh/max/ultra, Claude models take effort).
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Summary
PR #19756 trims the default
orchestrator_capabilitiesresult to favorite models with slim options, and adds aproviderInstanceIdfilter. That covers browsing. The most common call in my threads is narrower: the user named a model, and the agent wants that one entry. Two small additions would cover it:modelfilter onorchestrator_capabilities, so the agent reads one entry instead of a catalog.delegate_taskerrors that list the valid models and providers, the way option errors already list valid values. Then an agent can delegate directly and recover from a typo without a catalog call at all.Problem to solve
Most of my delegations name the model: "use a gpt-6.1-sol subagent on extra high". Over one week, Claude agents in 68 of my threads called
orchestrator_capabilities48 times, each time to confirm a model the user had already named. Onmainone call returns 28,391 characters (about 7K tokens), and the result stays in context for the rest of the session:cursorclaudeAgentcodexfeaturesand thread fieldsThe entry the agent needs,
codex / gpt-6.1-solwith its options, is 633 characters. About 2% of the response.#19756 fixes most of this when the named model is a favorite. When it isn't, the agent sees
omittedModelsand calls again withmodels: "all", which #19756 measured at 18,822 characters. Narrowing byproviderInstanceIdstill returns every Codex model when the agent wants one.Codex agents work around it by filtering the result inside their JS
exectool before printing. Claude Code can't filter a tool result, so it reads the whole thing.delegate_taskcan't stand in for the lookup either. Its option errors already list valid values (OrchestratorMcpService.ts:334):Its model and provider errors don't (L1280, L1239):
After either one the agent has to fetch the catalog. And the injected instructions tell it to fetch the catalog first anyway (
orchestrationInstructions.ts:9).Proposed behavior
1.
modelfilter onorchestrator_capabilities{ "providerInstanceId": "codex", "model": "gpt-6.1-sol" }modeltakes an exact model ID or a case-insensitive substring ("sol").models: "all".providerInstanceId. Providers with no matching model are left out.model, behavior is whatever fix(server): orchestrator_capabilities defaults to favorite models with slim options #19756 defines.Result for the call above, in #19756's slim option shape:
{ "inheritedProviderInstanceId": "claudeAgent", "inheritedModel": "claude-opus-5-5", "providers": [ { "providerInstanceId": "codex", "canRunChildTask": true, "canRunCrossProviderChildTask": true, "models": [ { "id": "gpt-6.1-sol", "label": "GPT-6.1-Sol", "options": [ { "id": "reasoningEffort", "type": "select", "values": ["low", "medium", "high", "xhigh", "max", "ultra"], "default": "low", "currentValue": "low" }, { "id": "serviceTier", "type": "select", "values": ["default", "priority"], "default": "default" } ] } ] } ] }About 600 characters.
2. Valid values in
delegate_tasktarget errorsMatch what option errors already do:
3. One line in the tool description and the injected instructions
For example: "When the user names a model, call
delegate_taskdirectly; a rejected target lists the valid values. Passmodeltoorchestrator_capabilitiesto look up one model's options."With all three, a named-model delegation costs about 150 tokens (filtered lookup) or nothing (direct
delegate_task), down from about 7K.Acceptance criteria
orchestrator_capabilities({ providerInstanceId: "codex", model: "gpt-6.1-sol" })returns one provider with one model and its options.orchestrator_capabilities({ model: "sol" })returns every model whose ID containssol, across providers, including models that aren't favorites.modelfilter with no match returnsproviders: [], not an error.modelbehave as before.delegate_taskwith a model the provider doesn't advertise returnsmodel_unavailablewith the provider's advertised models in the message.delegate_taskwith an unregisteredproviderInstanceIdreturnsprovider_unavailablewith the instances that can run child tasks.orchestrator_capabilitiestool description mentionsmodel.Affected area
apps/server/src/mcp/OrchestratorMcpService.ts: capabilities filtering (where fix(server): orchestrator_capabilities defaults to favorite models with slim options #19756 adds favorites), and the target errors inresolveTargetat L1239 and L1280.packages/contracts/src/orchestratorMcp.ts: the capabilities input that fix(server): orchestrator_capabilities defaults to favorite models with slim options #19756 introduces.apps/server/src/mcp/toolkits/orchestrator/tools.ts: theorchestrator_capabilitiesdescription at L53.packages/provider-core/src/server/orchestrationInstructions.ts: the line at L9.Non-goals
modelfilter should follow whatever they settle on.Alternatives considered
reasoningEffort: xhigh/max/ultra, Claude models takeeffort).exec. Claude Code has no way to.Decisions needed
modelsearch the full catalog, as proposed, or only the default scope?modelfilter into fix(server): orchestrator_capabilities defaults to favorite models with slim options #19756, or ship it after?Related
providerInstanceIdfilter.orchestrator_capabilitiesanddelegate_taskignore hidden models.delegate_taskandtask_status.orchestrator_capabilitiesaddition (usage limits).orchestrator_capabilitiescame out of.Written with Claude Opus 5.5 in Claude Code (via T3 Code).
All reactions