Server API ignores agent's configured model when only agent parameter is passed #4313

Open
opened 2026-02-16 17:43:24 -05:00 by yindo · 6 comments
Owner

Originally created by @cyhhao on GitHub (Jan 6, 2026).

Originally assigned to: @rekram1-node on GitHub.

Description

When using the OpenCode Server HTTP API to send a message with only the agent parameter (without explicitly passing model), the server does not use the agent's configured default model from opencode.json. Instead, it falls back to the global default model.

Configuration in ~/.config/opencode/opencode.json:

{
  "model": "anthropic/claude-opus-4-5",
  "agent": {
    "build": {
      "model": "anthropic/claude-opus-4-5"
    },
    "plan": {
      "model": "openai/gpt-5.2",
      "reasoningEffort": "xhigh"
    }
  }
}

API Request:

curl -X POST "http://localhost:4096/session/{session_id}/message" \
  -H "x-opencode-directory: /path/to/project" \
  -H "Content-Type: application/json" \
  -d '{"agent": "plan", "parts": [{"type": "text", "text": "Hello"}]}'

Expected behavior:
The server should use openai/gpt-5.2 (the model configured for the plan agent).

Actual behavior:
The server uses google/gemini-3-pro-preview (or another fallback model), ignoring the agent's configured model.

Evidence from API response:

{
  "info": {
    "modelID": "gemini-3-pro-preview",
    "providerID": "google",
    "agent": "plan"
  }
}

Additional context:

  • The /agent API endpoint returns native agents (build, plan) without their configured model field, even though the model is specified in opencode.json
  • The /config API only returns custom agents (like code-reviewer) with their model configuration, not native agents
  • According to the documentation, agent-specific models should override the global default

This issue affects users who want to use different models for different agents via the Server API, which is a common use case for building integrations and plugins.

Plugins

opencode-antigravity-auth@1.2.7

OpenCode version

1.1.3

Steps to reproduce

  1. Configure agent-specific models in ~/.config/opencode/opencode.json:

    {
      "agent": {
        "plan": {
          "model": "openai/gpt-5.2"
        }
      }
    }
    
  2. Start the OpenCode server: opencode serve

  3. Create a session via API:

    curl -X POST "http://localhost:4096/session" \
      -H "x-opencode-directory: /path/to/project" \
      -H "Content-Type: application/json" \
      -d '{}'
    
  4. Send a message with only the agent parameter:

    curl -X POST "http://localhost:4096/session/{session_id}/message" \
      -H "x-opencode-directory: /path/to/project" \
      -H "Content-Type: application/json" \
      -d '{"agent": "plan", "parts": [{"type": "text", "text": "What model are you?"}]}'
    
  5. Observe that the response uses a different model than configured for the plan agent

Screenshot and/or share link

No response

Operating System

macOS 15.5

Terminal

No response

Originally created by @cyhhao on GitHub (Jan 6, 2026). Originally assigned to: @rekram1-node on GitHub. ### Description When using the OpenCode Server HTTP API to send a message with only the `agent` parameter (without explicitly passing `model`), the server does not use the agent's configured default model from `opencode.json`. Instead, it falls back to the global default model. **Configuration in `~/.config/opencode/opencode.json`:** ```json { "model": "anthropic/claude-opus-4-5", "agent": { "build": { "model": "anthropic/claude-opus-4-5" }, "plan": { "model": "openai/gpt-5.2", "reasoningEffort": "xhigh" } } } ``` **API Request:** ```bash curl -X POST "http://localhost:4096/session/{session_id}/message" \ -H "x-opencode-directory: /path/to/project" \ -H "Content-Type: application/json" \ -d '{"agent": "plan", "parts": [{"type": "text", "text": "Hello"}]}' ``` **Expected behavior:** The server should use `openai/gpt-5.2` (the model configured for the `plan` agent). **Actual behavior:** The server uses `google/gemini-3-pro-preview` (or another fallback model), ignoring the agent's configured model. **Evidence from API response:** ```json { "info": { "modelID": "gemini-3-pro-preview", "providerID": "google", "agent": "plan" } } ``` **Additional context:** - The `/agent` API endpoint returns native agents (`build`, `plan`) without their configured `model` field, even though the model is specified in `opencode.json` - The `/config` API only returns custom agents (like `code-reviewer`) with their model configuration, not native agents - According to the [documentation](https://opencode.ai/docs/agents#model), agent-specific models should override the global default This issue affects users who want to use different models for different agents via the Server API, which is a common use case for building integrations and plugins. ### Plugins opencode-antigravity-auth@1.2.7 ### OpenCode version 1.1.3 ### Steps to reproduce 1. Configure agent-specific models in `~/.config/opencode/opencode.json`: ```json { "agent": { "plan": { "model": "openai/gpt-5.2" } } } ``` 2. Start the OpenCode server: `opencode serve` 3. Create a session via API: ```bash curl -X POST "http://localhost:4096/session" \ -H "x-opencode-directory: /path/to/project" \ -H "Content-Type: application/json" \ -d '{}' ``` 4. Send a message with only the `agent` parameter: ```bash curl -X POST "http://localhost:4096/session/{session_id}/message" \ -H "x-opencode-directory: /path/to/project" \ -H "Content-Type: application/json" \ -d '{"agent": "plan", "parts": [{"type": "text", "text": "What model are you?"}]}' ``` 5. Observe that the response uses a different model than configured for the `plan` agent ### Screenshot and/or share link _No response_ ### Operating System macOS 15.5 ### Terminal _No response_
Author
Owner

@github-actions[bot] commented on GitHub (Jan 6, 2026):

This issue might be a duplicate of existing issues. Please check:

  • #4901: SDK Messages cause switch back to default model - Similar issue where API/SDK interactions ignore the user's manually selected model and revert to the agent's default model
  • #4475: Plugins using noReply seem to cause model to switch to agent default - Plugins/API calls causing model configuration to be ignored and revert to agent defaults
  • #5623: Custom subagents with explicit model config throw ProviderModelNotFoundError - Issues with custom agents not respecting configured models
  • #6636: Subagent with specific model results in model change in build and plan mode - Model configuration not being respected for subagents
  • #6928: Subtask commands do not inherit model - Commands not inheriting the agent's configured or selected model

All of these appear to be related to the same underlying issue: the Server API and other interfaces not properly respecting agent-specific model configurations from opencode.json when only the agent parameter is passed without an explicit model.

Feel free to ignore if your specific case differs from these.

@github-actions[bot] commented on GitHub (Jan 6, 2026): This issue might be a duplicate of existing issues. Please check: - #4901: SDK Messages cause switch back to default model - Similar issue where API/SDK interactions ignore the user's manually selected model and revert to the agent's default model - #4475: Plugins using noReply seem to cause model to switch to agent default - Plugins/API calls causing model configuration to be ignored and revert to agent defaults - #5623: Custom subagents with explicit model config throw ProviderModelNotFoundError - Issues with custom agents not respecting configured models - #6636: Subagent with specific model results in model change in build and plan mode - Model configuration not being respected for subagents - #6928: Subtask commands do not inherit model - Commands not inheriting the agent's configured or selected model All of these appear to be related to the same underlying issue: the Server API and other interfaces not properly respecting agent-specific model configurations from opencode.json when only the agent parameter is passed without an explicit model. Feel free to ignore if your specific case differs from these.
Author
Owner

@rekram1-node commented on GitHub (Jan 6, 2026):

/oc if this is a bug, find it and fix it

@rekram1-node commented on GitHub (Jan 6, 2026): /oc if this is a bug, find it and fix it
Author
Owner

@opencode-agent[bot] commented on GitHub (Jan 6, 2026):

Summary of Analysis:

After extensive code analysis, I investigated the reported issue where the Server API allegedly ignores an agent's configured model when only the agent parameter is passed.

Key files examined:

  • packages/opencode/src/session/prompt.ts - Model resolution logic at line 806
  • packages/opencode/src/agent/agent.ts - Agent state initialization and model configuration at line 184
  • packages/opencode/src/config/config.ts - Configuration loading and merging
  • packages/opencode/src/server/server.ts - API endpoint handlers
  • packages/opencode/test/agent/agent.test.ts - Existing tests that confirm functionality

Findings:

  1. The model resolution logic at prompt.ts:806 is correct: model: input.model ?? agent.model ?? (await lastModel(input.sessionID))
  2. The agent configuration loading at agent.ts:184 correctly applies models: if (value.model) item.model = Provider.parseModel(value.model)
  3. Tests at test/agent/agent.test.ts confirm that agent model configuration works correctly (see test "custom agent config overrides native agent properties" at line 136)
  4. The configuration loading from global (~/.config/opencode/) and project directories works correctly

Possible explanations for the reported issue:

  1. Config file location - The config might not be at the expected path (~/.config/opencode/opencode.json)
  2. State caching - If the server was started before the config was created/modified, the cached state wouldn't include the updated config (restart required)
  3. Environment-specific issue - XDG paths might differ on certain systems

Conclusion:
I could not identify a specific bug in the codebase that would cause this behavior. The code logic appears correct and tests pass. The issue is likely environmental or related to state caching behavior. If this is a recurring issue for users, it might be worth adding better diagnostics or documentation about config loading and caching.

New%20session%20-%202026-01-06T19%3A10%3A22.999Z
opencode session  |  github run

@opencode-agent[bot] commented on GitHub (Jan 6, 2026): **Summary of Analysis:** After extensive code analysis, I investigated the reported issue where the Server API allegedly ignores an agent's configured model when only the `agent` parameter is passed. **Key files examined:** - `packages/opencode/src/session/prompt.ts` - Model resolution logic at line 806 - `packages/opencode/src/agent/agent.ts` - Agent state initialization and model configuration at line 184 - `packages/opencode/src/config/config.ts` - Configuration loading and merging - `packages/opencode/src/server/server.ts` - API endpoint handlers - `packages/opencode/test/agent/agent.test.ts` - Existing tests that confirm functionality **Findings:** 1. The model resolution logic at `prompt.ts:806` is correct: `model: input.model ?? agent.model ?? (await lastModel(input.sessionID))` 2. The agent configuration loading at `agent.ts:184` correctly applies models: `if (value.model) item.model = Provider.parseModel(value.model)` 3. Tests at `test/agent/agent.test.ts` confirm that agent model configuration works correctly (see test "custom agent config overrides native agent properties" at line 136) 4. The configuration loading from global (`~/.config/opencode/`) and project directories works correctly **Possible explanations for the reported issue:** 1. **Config file location** - The config might not be at the expected path (`~/.config/opencode/opencode.json`) 2. **State caching** - If the server was started before the config was created/modified, the cached state wouldn't include the updated config (restart required) 3. **Environment-specific issue** - XDG paths might differ on certain systems **Conclusion:** I could not identify a specific bug in the codebase that would cause this behavior. The code logic appears correct and tests pass. The issue is likely environmental or related to state caching behavior. If this is a recurring issue for users, it might be worth adding better diagnostics or documentation about config loading and caching. <a href="https://opencode.ai/s/VSn02he0"><img width="200" alt="New%20session%20-%202026-01-06T19%3A10%3A22.999Z" src="https://social-cards.sst.dev/opencode-share/TmV3IHNlc3Npb24gLSAyMDI2LTAxLTA2VDE5OjEwOjIyLjk5OVo=.png?model=opencode/claude-opus-4-5&version=1.1.3&id=VSn02he0" /></a> [opencode session](https://opencode.ai/s/VSn02he0)&nbsp;&nbsp;|&nbsp;&nbsp;[github run](/anomalyco/opencode/actions/runs/20759142618)
Author
Owner

@rekram1-node commented on GitHub (Jan 6, 2026):

This seems to be a bug w/ ur plugin, works fine without it

@rekram1-node commented on GitHub (Jan 6, 2026): This seems to be a bug w/ ur plugin, works fine without it
Author
Owner

@cyhhao commented on GitHub (Jan 6, 2026):

Additional Finding: Anthropic Model Routing Bug

I discovered a separate but related issue. When explicitly passing model parameters to the API, the API reports using the requested model, but the actual model responding is different.

Test Results

Requested Model API reports modelID Model self-identifies as
claude-opus-4-5 claude-opus-4-5 claude-sonnet-4-20250514
claude-sonnet-4-5 claude-sonnet-4-5 claude-sonnet-4-20250514
claude-haiku-4-5 claude-haiku-4-5 claude-sonnet-4-20250514
gpt-4o (OpenAI) gpt-4o Works correctly

Reproduction

# Request claude-opus-4-5
curl -s -X POST 'http://127.0.0.1:4096/session/{session_id}/message' \
  -H 'Content-Type: application/json' \
  -H 'x-opencode-directory: /tmp/test' \
  -d '{"parts": [{"type": "text", "text": "Respond with ONLY your model name/version, nothing else."}], "model": {"providerID": "anthropic", "modelID": "claude-opus-4-5"}}'

# Response shows modelID: claude-opus-4-5
# But the text response is: "claude-sonnet-4-20250514"

Hypothesis

The opencode-antigravity-auth@1.2.7 plugin may be routing all Anthropic requests to claude-sonnet-4 regardless of which model is requested. This could be:

  1. An OAuth tier/permission limitation
  2. A bug in the plugin's model routing logic

This is a different issue from the agent-config-model problem described in the original issue. Should I open a separate issue for this?

@cyhhao commented on GitHub (Jan 6, 2026): ## Additional Finding: Anthropic Model Routing Bug I discovered a separate but related issue. When explicitly passing model parameters to the API, the **API reports using the requested model**, but the **actual model responding is different**. ### Test Results | Requested Model | API reports `modelID` | Model self-identifies as | |-----------------|-------------------------|--------------------------| | `claude-opus-4-5` | `claude-opus-4-5` | `claude-sonnet-4-20250514` | | `claude-sonnet-4-5` | `claude-sonnet-4-5` | `claude-sonnet-4-20250514` | | `claude-haiku-4-5` | `claude-haiku-4-5` | `claude-sonnet-4-20250514` | | `gpt-4o` (OpenAI) | `gpt-4o` | ✅ Works correctly | ### Reproduction ```bash # Request claude-opus-4-5 curl -s -X POST 'http://127.0.0.1:4096/session/{session_id}/message' \ -H 'Content-Type: application/json' \ -H 'x-opencode-directory: /tmp/test' \ -d '{"parts": [{"type": "text", "text": "Respond with ONLY your model name/version, nothing else."}], "model": {"providerID": "anthropic", "modelID": "claude-opus-4-5"}}' # Response shows modelID: claude-opus-4-5 # But the text response is: "claude-sonnet-4-20250514" ``` ### Hypothesis The `opencode-antigravity-auth@1.2.7` plugin may be routing all Anthropic requests to `claude-sonnet-4` regardless of which model is requested. This could be: 1. An OAuth tier/permission limitation 2. A bug in the plugin's model routing logic This is a different issue from the agent-config-model problem described in the original issue. Should I open a separate issue for this?
Author
Owner

@Steffen025 commented on GitHub (Feb 3, 2026):

Confirming this issue WITHOUT any plugins

I'm experiencing the exact same behavior in a fresh setup without the antigravity plugin.

My Setup

  • OpenCode 1.1.40
  • Custom agents in .opencode/agents/ with explicit model config
  • No plugins installed

Agent Definition (.opencode/agents/PerplexityResearcher.md)

---
name: PerplexityResearcher
model: perplexity/sonar
---

Reproduction

Task({
  subagent_type: "PerplexityResearcher",
  prompt: "Research X"
})

Expected

Agent uses perplexity/sonar as configured.

Actual

Agent runs on session default (Claude), ignoring the agent's model field entirely.

Evidence

The code at task.ts:102-105 should respect agent.model:

const model = agent.model ?? fallback

But the agent lookup by subagent_type string doesn't seem to load the custom agent definition from .opencode/agents/.

This is a real bug affecting custom multi-provider agent setups, not just plugin-related.

@Steffen025 commented on GitHub (Feb 3, 2026): ## Confirming this issue WITHOUT any plugins I'm experiencing the exact same behavior in a fresh setup **without** the antigravity plugin. ### My Setup - OpenCode 1.1.40 - Custom agents in `.opencode/agents/` with explicit model config - No plugins installed ### Agent Definition (`.opencode/agents/PerplexityResearcher.md`) ```yaml --- name: PerplexityResearcher model: perplexity/sonar --- ``` ### Reproduction ```typescript Task({ subagent_type: "PerplexityResearcher", prompt: "Research X" }) ``` ### Expected Agent uses `perplexity/sonar` as configured. ### Actual Agent runs on session default (Claude), ignoring the agent's `model` field entirely. ### Evidence The code at `task.ts:102-105` should respect `agent.model`: ```typescript const model = agent.model ?? fallback ``` But the agent lookup by `subagent_type` string doesn't seem to load the custom agent definition from `.opencode/agents/`. This is a **real bug** affecting custom multi-provider agent setups, not just plugin-related.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#4313