Skip to content

subagent model variants are parsed but not applied at runtime in v1.4.0 #21632

Closed as not planned

Description

@haitaoxw

Description

After upgrading from v1.3.17 to v1.4.0, subagents no longer appear to honor agent-level variant settings at runtime.

The config is parsed correctly, but the effective request behavior does not reflect the configured model variant. Downgrading back to v1.3.17 restores the expected behavior.

Expected behavior:

If a subagent is configured like this:

"gsd-code-reviewer": {
  "model": "codex/gpt-5.3-codex",
  "variant": "high"
}

and the model defines:

"gpt-5.3-codex": {
  "variants": {
    "high": {
      "reasoningEffort": "high"
    }
  }
}

then the spawned subagent should use the high variant's effective options at runtime.

Actual behavior in v1.4.0:

  • opencode debug config shows the subagent has the expected variant
  • opencode debug agent gsd-code-reviewer also shows the resolved variant-derived options
  • but when the subagent is invoked through the task/subagent path, the actual runtime behavior does not reflect the configured reasoning level

This was previously working in v1.3.17.

What I verified:

  1. Config parsing is correct
    • opencode debug config shows the subagent config correctly
    • opencode debug agent gsd-code-reviewer shows the resolved values including the variant-derived options
  2. This is not a config merge issue
    • I verified both global config and project config resolution
    • The final resolved config is correct
  3. This seems specific to subagent runtime
    • Running a subagent directly with opencode run --agent gsd-code-reviewer ... falls back to the default primary agent
    • so the only meaningful path is through task/subagent execution, and that is where the configured variant appears to be lost or ignored

Regression:

  • Works as expected: v1.3.17
  • Broken / no longer effective: v1.4.0

I also tested adding reasoningEffort directly on the subagent config. The config/debug layer still reflects it, but runtime behavior still appears incorrect for subagents in v1.4.0.

This suggests the issue is likely in the subagent execution path rather than config parsing.

This may be related to agent.variant handling issues such as #13790, but this report is specifically about subagents: the variant is visible in debug output yet appears not to affect runtime behavior when invoked through the task/subagent path.

Plugins

No response

OpenCode version

v1.4.0

Steps to reproduce

  1. Install opencode v1.4.0
  2. Configure a model with a variant that changes reasoning settings, for example:
"model": {
  "gpt-5.3-codex": {
    "provider": "codex",
    "options": {
      "reasoningEffort": "medium"
    },
    "variants": {
      "high": {
        "reasoningEffort": "high"
      }
    }
  }
}
  1. Configure a subagent to use that model variant, for example:
"agent": {
  "gsd-code-reviewer": {
    "model": "codex/gpt-5.3-codex",
    "variant": "high",
    "mode": "subagent"
  }
}
  1. Verify config resolution:
    • run opencode debug config
    • run opencode debug agent gsd-code-reviewer
    • confirm both show the expected variant / variant-derived options
  2. Invoke the subagent through the task/subagent execution path in a normal session
  3. Compare behavior with v1.3.17

Observed result:
In v1.4.0, the subagent does not appear to use the configured variant at runtime, even though debug output shows it resolved correctly.

Expected result:
The spawned subagent should inherit and use the configured model variant at runtime.

Screenshot and/or share link

No response

Operating System

Linux 6.17.0-19-generic x86_64 GNU/Linux

Terminal

xterm-256color

Activity

  1. added
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on Apr 9, 2026
  2. github-actions commented on Apr 9, 2026

    @github-actions
    Contributor

    This issue doesn't fully meet our contributing guidelines.

    What needs to be fixed:

    • OpenCode version is empty (_No response_) — please specify the exact version (e.g., v1.4.0)
    • Steps to reproduce is empty (_No response_) — please provide a minimal, reproducible sequence of steps so maintainers can verify the regression
    • Operating System and Terminal are also empty — environment info helps narrow down platform-specific issues

    Please edit this issue to address the above within 2 hours, or it will be automatically closed.


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

    If you believe this was flagged incorrectly, please let a maintainer know.

  3. added
    needs:complianceThis means the issue will auto-close after 2 hours.
    and removed
    needs:complianceThis means the issue will auto-close after 2 hours.
    on Apr 9, 2026
  4. github-actions commented on Apr 9, 2026

    @github-actions
    Contributor

    Thanks for updating the issue! It now follows the contributing guidelines and includes all the required information. We appreciate the detailed reproduction steps and version context.

  5. nilltadios commented on Apr 17, 2026

    @nilltadios

    The bug reported here (a subagent's configured variant not applied at runtime) has a second, closely-related manifestation on the same code path: when a subagent has no configured model and inherits the parent's model, it also does not inherit the parent's active variant. The subagent ends up with variant = undefined and falls back to the provider default.

    Concrete symptom: a parent running gpt-5.4 at variant xhigh spawns a subagent that silently runs at reasoningEffort: "medium" (the default injected in provider/transform.ts around line 871–883 for gpt-5.4 when no variant is present). The subagent "thinks" visibly less than the parent, which is what first tipped me off.

    Root cause trace (on current dev, 54078c4):

    1. packages/opencode/src/tool/task.ts:102-105 reads only modelID / providerID from the parent assistant message:

      const model = next.model ?? {
        modelID: msg.info.modelID,
        providerID: msg.info.providerID,
      }

      msg.info.variant exists on the assistant message schema (session/message-v2.ts:448) but is never read.

    2. task.ts:131-145 then calls ops.prompt({ ..., model: { modelID, providerID }, ... }) with no variant field.

    3. packages/opencode/src/session/prompt.ts:935-941 resolves variant as:

      const same = ag.model && model.providerID === ag.model.providerID && model.modelID === ag.model.modelID
      const full = !input.variant && ag.variant && same ? ... : undefined
      const variant = input.variant ?? (ag.variant && full?.variants?.[ag.variant] ? ag.variant : undefined)

      For an inherited-model subagent, ag.model is undefined → same is false → the ag.variant branch is gated off → variant is undefined.

    So there are two distinct failure modes routing through the same spot:

    • The one originally reported here: subagent has its own model + variant, but something in the v1.4.0 runtime path still drops it. (Guard on line 941 requiring full?.variants?.[ag.variant] is a likely suspect — if full fails to resolve for any reason, the variant is silently dropped.)
    • This extension: subagent inherits the parent's model and gets no variant at all, because the parent's variant is never forwarded through task.ts.

    Minimal fix for the second case: carry msg.info.variant through task.ts and pass it as input.variant to ops.prompt, so variant inheritance follows model inheritance. That alone should address the parent-inheritance symptom; the configured-variant-ignored path on line 941 likely needs a separate look.

  6. 0serna commented on Apr 24, 2026

    @0serna

    same issue

  7. 21pounder commented on Apr 29, 2026

    @21pounder
    Contributor

    I've investigated this bug and can confirm the root cause with debug logs.

    Root cause

    In packages/opencode/src/session/prompt.ts:902:

    const same = ag.model && model.providerID === ag.model.providerID && model.modelID === ag.model.modelID

    When a subagent has no explicit model configured (inheriting the parent's), ag.model is undefined → same is false → ag.variant is silently dropped.

    I added a temporary debug log to confirm:

    log.info("variant debug", { agVariant: ag.variant, inputVariant: input.variant, same, variant, agModel: ag.model })

    Subagent running (configured with variant: "high", no model):

    Image

    Bug confirmed — agVariant=high is present but variant is missing (undefined):

    Image

    Fix

    const same = !ag.model || (model.providerID === ag.model.providerID && model.modelID === ag.model.modelID)

    I'll open a PR with this one-line change.

  8. removed
    bugSomething isn't working
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on May 3, 2026
  9. jsheremeta-alt commented on Jun 4, 2026

    @jsheremeta-alt

    Still reproducing on v1.15.13. Here is additional evidence from the runtime binary and local session database.

    Binary analysis

    The Task tool execute function resolves the model like this:

    let b = $.model ?? {modelID: I.info.modelID, providerID: I.info.providerID}

    Then passes only modelID and providerID to the prompt call:

    G.prompt({
      model: {modelID: b.modelID, providerID: b.providerID},
      agent: $.name,
      ...
    })

    No variant, no options, no reasoningEffort, no enable_thinking, no temperature. The prompt function does accept variant as a top-level parameter (the TUI path uses it this way), but the Task tool never passes it. This is the same root cause that @nilltadios and @21pounder traced above.

    Session database evidence

    I queried the OpenCode SQLite database (~/.local/share/opencode/opencode.db) to check what sub-agent sessions actually record at runtime:

    SELECT id, parent_id, agent, model, tokens_reasoning 
    FROM session 
    WHERE parent_id IS NOT NULL 
    ORDER BY time_updated DESC

    Every single sub-agent session has variant: "default" in the model field, regardless of what is configured in agent frontmatter. My build-steward sub-agent has enable_thinking: true, reasoningEffort: high in its frontmatter but recorded 0 reasoning tokens in its actual run. Other sub-agents show similarly mismatched token counts.

    Primary agents do apply variants correctly. Those sessions show the correct variant value.

    About the closed PRs

    PR #20742 by @dbpolito addressed this but was closed by automated PR cleanup on May 15 due to insufficient reactions. PR #12567 by @mugnimaestra has been open since February with a working fix and video demonstration but remains unmerged.

    Could #20742 be reopened? It had tests and was from an SST team member.

  10. github-actions commented on Aug 4, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions