Description
When sub-agents (explore, librarian, oracle, hephaestus, etc.) are spawned via the oh-my-openagent plugin, they fail to resolve OpenRouter model IDs (e.g. anthropic/claude-sonnet-4.6, google/gemini-3-flash) because createAgentProvider() performs a hardcoded lookup in models.SupportedModels using the agent's configured model ID. Sub-session agents are created with config.AgentTask (see agent-tool.go:57), which reads from config.Agents[AgentTask].Model — a static global config key, not the model/provider specified by the parent session or plugin.
The oh-my-openagent plugin calls promptAsync with model: { providerID: "openrouter", modelID: "anthropic/claude-sonnet-4.6" } in the request body. However, OpenCode's server-side agent creation completely ignores this field and instead uses the hardcoded AgentTask model from global config. This means:
- OpenRouter model IDs (e.g.
anthropic/claude-sonnet-4.6) do not exist in models.SupportedModels — OpenCode uses its own prefixed IDs (e.g. openrouter.claude-3.5-sonnet, openrouter.gpt-4o)
- Even if the ID existed,
createAgentProvider() at agent.go:712 does models.SupportedModels[agentConfig.Model] with no fallback or override mechanism
- The error manifests as "Provider returned error" (when model resolution partially succeeds but provider lookup fails) or "Missing Authentication header" (when the model can't be resolved at all and falls back to a broken provider)
Plugins
oh-my-openagent v3.17.4
OpenCode version
1.3.5 (may affect later versions too — root cause is in the model resolution code path)
Steps to reproduce
- Configure
openrouter provider with a valid API key in opencode.json
- Set an agent's model to an OpenRouter model ID like
anthropic/claude-sonnet-4.6 or google/gemini-3-flash
- Have the main agent (Sisyphus) spawn a sub-agent via oh-my-openagent's
call_omo_agent tool
- Observe the sub-agent fails with "Provider returned error" or "Missing Authentication header"
Root Cause Analysis
File: internal/llm/agent/agent.go:706-757 — createAgentProvider()
func createAgentProvider(agentName config.AgentName) (provider.Provider, error) {
cfg := config.Get()
agentConfig, ok := cfg.Agents[agentName]
if !ok {
return nil, fmt.Errorf("agent %s not found", agentName)
}
model, ok := models.SupportedModels[agentConfig.Model] // ← LINE 712: HARD LOOKUP
if !ok {
return nil, fmt.Errorf("model %s not supported", agentConfig.Model)
}
providerCfg, ok := cfg.Providers[model.Provider]
if !ok {
return nil, fmt.Errorf("provider %s not supported", model.Provider)
}
// ...
}
File: internal/llm/agent/agent-tool.go:57 — Sub-session creation
agent, err := NewAgent(config.AgentTask, b.sessions, b.messages, TaskAgentTools(b.lspClients))
// ↑ Uses AgentTask's hardcoded model from global config
// Does NOT accept or use any model/provider override from the caller
File: internal/llm/models/models.go:50-98 — SupportedModels
func init() {
maps.Copy(SupportedModels, AnthropicModels)
maps.Copy(SupportedModels, OpenAIModels)
maps.Copy(SupportedModels, GeminiModels)
maps.Copy(SupportedModels, OpenRouterModels) // Uses prefixed IDs like "openrouter.gpt-4o"
// ...
}
The OpenRouter models use prefixed IDs (e.g. "openrouter.gpt-4.1", "openrouter.claude-3.5-sonnet"), while oh-my-openagent sends raw OpenRouter IDs (e.g. "anthropic/claude-sonnet-4.6"). These don't match, so the lookup fails.
Key finding: No per-request model/provider override mechanism exists.
UpdateAgentModel() exists but is a one-time config mutation, not per-request
Agent struct has only Model, MaxTokens, ReasoningEffort — no override fields
- The prompt body's
model field is silently ignored by the server-side agent creation
Suggested Fix
Two possible approaches:
A) Add model/provider override to agent creation:
// In agent-tool.go, pass model override from the session context
agent, err := NewAgent(config.AgentTask, b.sessions, b.messages,
TaskAgentTools(b.lspClients),
TaskAgentModelOverride(overrideModelID)) // NEW: optional override
B) Add a model ID alias/translation layer:
- When a model ID is not found in
SupportedModels, attempt to match it against OpenRouter model definitions by comparing APIModel fields
- E.g.
"anthropic/claude-sonnet-4.6" → find OpenRouter model with matching APIModel
Operating System
Windows 11 24H2
Terminal
Windows Terminal
Description
When sub-agents (explore, librarian, oracle, hephaestus, etc.) are spawned via the oh-my-openagent plugin, they fail to resolve OpenRouter model IDs (e.g.
anthropic/claude-sonnet-4.6,google/gemini-3-flash) becausecreateAgentProvider()performs a hardcoded lookup inmodels.SupportedModelsusing the agent's configured model ID. Sub-session agents are created withconfig.AgentTask(seeagent-tool.go:57), which reads fromconfig.Agents[AgentTask].Model— a static global config key, not the model/provider specified by the parent session or plugin.The oh-my-openagent plugin calls
promptAsyncwithmodel: { providerID: "openrouter", modelID: "anthropic/claude-sonnet-4.6" }in the request body. However, OpenCode's server-side agent creation completely ignores this field and instead uses the hardcodedAgentTaskmodel from global config. This means:anthropic/claude-sonnet-4.6) do not exist inmodels.SupportedModels— OpenCode uses its own prefixed IDs (e.g.openrouter.claude-3.5-sonnet,openrouter.gpt-4o)createAgentProvider()atagent.go:712doesmodels.SupportedModels[agentConfig.Model]with no fallback or override mechanismPlugins
oh-my-openagent v3.17.4
OpenCode version
1.3.5 (may affect later versions too — root cause is in the model resolution code path)
Steps to reproduce
openrouterprovider with a valid API key inopencode.jsonanthropic/claude-sonnet-4.6orgoogle/gemini-3-flashcall_omo_agenttoolRoot Cause Analysis
File:
internal/llm/agent/agent.go:706-757—createAgentProvider()File:
internal/llm/agent/agent-tool.go:57— Sub-session creationFile:
internal/llm/models/models.go:50-98—SupportedModelsThe OpenRouter models use prefixed IDs (e.g.
"openrouter.gpt-4.1","openrouter.claude-3.5-sonnet"), while oh-my-openagent sends raw OpenRouter IDs (e.g."anthropic/claude-sonnet-4.6"). These don't match, so the lookup fails.Key finding: No per-request model/provider override mechanism exists.
UpdateAgentModel()exists but is a one-time config mutation, not per-requestAgentstruct has onlyModel,MaxTokens,ReasoningEffort— no override fieldsmodelfield is silently ignored by the server-side agent creationSuggested Fix
Two possible approaches:
A) Add model/provider override to agent creation:
B) Add a model ID alias/translation layer:
SupportedModels, attempt to match it against OpenRouter model definitions by comparingAPIModelfields"anthropic/claude-sonnet-4.6"→ find OpenRouter model with matchingAPIModelOperating System
Windows 11 24H2
Terminal
Windows Terminal