Skip to content

Conversation

@jkoelker
Copy link
Contributor

@jkoelker jkoelker commented Jan 11, 2026

Allow optional model variant config for agents and categories. Propagate category variants into task model payloads so category-driven runs inherit provider-specific variants.

Closes: #647


Summary by cubic

Adds optional model variant support to agents and categories. Variants inherit from categories and flow into task model payloads and chat messages, enabling provider-specific tiers (Linear 647).

  • New Features
    • Config/schema: add optional variant to AgentOverrideConfig and CategoryConfig; JSON schema updated.
    • Agent build: agents with a category inherit its variant; createBuiltinAgents accepts user categories.
    • Background tasks: model payload now includes variant; Sisyphus task passes category variant when used.
    • Chat pipeline: first-message variant gate applies agent/category variant on session start; applyAgentVariant sets variant if message has none; keyword detector won’t overwrite an existing variant.
    • Tests added for schema, agent building, keyword hook, and Sisyphus task.

Written for commit 2b8853c. Summary will update on new commits.

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@jkoelker jkoelker force-pushed the fix/add-variant-support branch from 68e1c4d to a3592fa Compare January 11, 2026 00:04
Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 16 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

@jkoelker jkoelker force-pushed the fix/add-variant-support branch from a3592fa to f804efc Compare January 11, 2026 00:54
@jkoelker
Copy link
Contributor Author

Fixed variant not being set to config value when cached in the model state. This only takes effect on new sessions, so if you change the variant with ctrl+t and then resume the session, it stays whatever was set.

@jkoelker jkoelker force-pushed the fix/add-variant-support branch from f804efc to 33aed90 Compare January 11, 2026 03:21
@imarshallwidjaja
Copy link
Contributor

I've been testing this and i'm finding it to not be working properly. Do you have a sample oh-my-opencode.json config i can use to test? I've been using:

{
  "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json",
  "auto_update": false,
  "google_auth": false,
  "categories": {
    "visual-engineering": {
      "model": "google/antigravity-gemini-3-pro",
      "variant": "high",
      "temperature": 0.7
    },
    "ultrabrain": {
      "model": "openai/gpt-5.2",
      "variant": "xhigh",
      "temperature": 0.1
    },
    "artistry": {
      "model": "google/antigravity-gemini-3-pro",
      "variant": "high",
      "temperature": 0.9
    },
    "quick": {
      "model": "google/antigravity-gemini-3-flash",
      "variant": "low",
      "temperature": 0.3
    },
    "most-capable": {
      "model": "openai/gpt-5.2",
      "variant": "high",
      "temperature": 0.3
    },
    "writing": {
      "model": "google/antigravity-gemini-3-flash",
      "variant": "high",
      "temperature": 0.5
    },
    "general": {
      "model": "google/antigravity-claude-opus-4-5-thinking",
      "variant": "medium",
      "temperature": 0.3
    }
  },
  "agents": {
    "Sisyphus": {
      "category": "general"
    },
    "Sisyphus-Junior": {
      "category": "general"
    },
    "oracle": {
      "category": "most-capable"
    },
    "librarian": {
      "category": "writing"
    },
    "explore": {
      "category": "quick"
    },
    "frontend-ui-ux-engineer": {
      "category": "visual-engineering"
    },
    "document-writer": {
      "category": "writing"
    },
    "multimodal-looker": {
      "category": "visual-engineering"
    },
    "orchestrator-sisyphus": {
      "category": "general"
    },
    "Prometheus (Planner)": {
      "category": "most-capable"
    },
    "Metis (Plan Consultant)": {
      "category": "most-capable"
    },
    "Momus (Plan Reviewer)": {
      "category": "ultrabrain"
    }
  }
}

And finding some issues:

  • Category inheritance wasn’t applied when the category came from agent overrides. Builtin agents only inherited category defaults when the agent definition itself had category, not when the user set agents.{name}.category.
    • Fix validated: treat agents.{name}.category as the source of truth and apply category defaults (model/temperature/variant/etc) unless explicitly overridden per-agent.
  • Special-case agents bypassed category logic entirely e.g. Prometheus (Planner), Sisyphus-Junior
    • Fix validated: resolve these agents’ model/settings from agents.{name}.category → categories.{cat} first, then fall back.

Applied some fixes: in this draft PR if you were interested: jkoelker#1

@imarshallwidjaja
Copy link
Contributor

Lol just noticed you probably fixed it 4 mins ago. will test again, feel free to ignore me if so.

@jkoelker
Copy link
Contributor Author

@imarshallwidjaja the categories vs agents config is very brittle at the moment, i would reccomend setting the model + varient explicitly everywhere.

@jkoelker jkoelker force-pushed the fix/add-variant-support branch from 33aed90 to ac9bf51 Compare January 11, 2026 16:05
@jkoelker jkoelker force-pushed the fix/add-variant-support branch 2 times, most recently from c889467 to 1d42434 Compare January 12, 2026 19:46
Allow optional model variant config for agents and categories.
Propagate category variants into task model payloads so
category-driven runs inherit provider-specific variants.

Closes: code-yeongyu#647
@jkoelker jkoelker force-pushed the fix/add-variant-support branch from 1d42434 to 2b8853c Compare January 13, 2026 04:38
Copy link
Contributor

@imarshallwidjaja imarshallwidjaja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry all just actually confirming that this does 100% work as expected when you properly set the variants in all of the configured agents & categories. Have been using it on a local build merged on top of dev to test (tracking thinking budgets requested using Antigravity Manager).

@KNN-07 KNN-07 requested a review from Copilot January 13, 2026 05:48
@KNN-07 KNN-07 merged commit d2a5f47 into code-yeongyu:dev Jan 13, 2026
6 checks passed
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds optional model variant support to agents and categories, enabling provider-specific tier configuration (e.g., "low", "high", "max") that propagates through the system from configuration to task execution and chat messages.

Changes:

  • Added optional variant field to AgentOverrideConfig and CategoryConfig schemas with comprehensive validation tests
  • Implemented variant inheritance: agents inherit variants from their configured categories, with explicit agent variants taking precedence
  • Created variant application utilities (resolveAgentVariant, applyAgentVariant) and first-message tracking mechanism to apply variants on session start
  • Updated background task system and Sisyphus task tool to propagate category variants into model payloads
  • Modified chat message hooks to apply agent/category variants while respecting pre-existing variants (e.g., from ultrawork keyword)

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/config/schema.ts Added optional variant string field to AgentOverrideConfigSchema and CategoryConfigSchema
src/config/schema.test.ts Added validation tests for variant field in both agent and category schemas
assets/oh-my-opencode.schema.json Updated JSON schema to include variant field in all agent configurations and category definitions
src/agents/types.ts Added variant field to AgentOverrideConfig type definition
src/agents/utils.ts Updated buildAgent and createBuiltinAgents to accept categories config and inherit variant from category if agent doesn't have explicit variant
src/agents/utils.test.ts Added test verifying agents inherit variant from their category configuration
src/shared/agent-variant.ts New utility functions to resolve agent variants from config (with category fallback) and conditionally apply to messages
src/shared/agent-variant.test.ts Comprehensive tests for variant resolution and application logic
src/shared/first-message-variant.ts New gate mechanism to track new sessions and control first-message variant application
src/shared/first-message-variant.test.ts Tests for session tracking and variant gate behavior
src/shared/index.ts Added export for new agent-variant module
src/features/background-agent/types.ts Extended model type in BackgroundTask and LaunchInput to include optional variant field
src/tools/sisyphus-task/tools.ts Updated category model resolution to include variant from category config when launching background tasks
src/tools/sisyphus-task/tools.test.ts Added test verifying variant propagation to background task model payload
src/hooks/keyword-detector/index.ts Modified ultrawork keyword handler to only set variant if not already defined, preserving configured variants
src/hooks/keyword-detector/index.test.ts Added test confirming ultrawork respects pre-existing variants
src/index.ts Integrated variant application in chat.message hook with first-message gate and subsequent-message conditional application, plus session lifecycle tracking
src/plugin-handlers/config-handler.ts Passed user categories config to createBuiltinAgents for variant inheritance

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +323 to 333
if (firstMessageVariantGate.shouldOverride(input.sessionID)) {
const variant = resolveAgentVariant(pluginConfig, input.agent)
if (variant !== undefined) {
message.variant = variant
}
firstMessageVariantGate.markApplied(input.sessionID)
} else {
applyAgentVariant(pluginConfig, input.agent, message)
}

await keywordDetector?.["chat.message"]?.(input, output);
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variant application logic may prevent ultrawork keyword from working when agents have configured variants. The order of operations is:

  1. Lines 322-331 apply the agent/category variant to the message (unconditionally on first message, conditionally on subsequent messages)
  2. Line 333 runs keyword detector, which only sets variant to "max" if message.variant === undefined

This means if an agent has a configured variant, the keyword detector will always see it as already set and never apply the "max" variant for ultrawork. While this behavior is tested in keyword-detector/index.test.ts (line 214), consider whether ultrawork should be able to override configured agent variants, as users explicitly typing "ultrawork" might expect it to boost capability regardless of agent configuration.

If ultrawork should be able to override agent variants, consider either:

  1. Checking for ultrawork before applying agent variants, or
  2. Having keyword detector override variants from agent config but not variants from other sources
Suggested change
if (firstMessageVariantGate.shouldOverride(input.sessionID)) {
const variant = resolveAgentVariant(pluginConfig, input.agent)
if (variant !== undefined) {
message.variant = variant
}
firstMessageVariantGate.markApplied(input.sessionID)
} else {
applyAgentVariant(pluginConfig, input.agent, message)
}
await keywordDetector?.["chat.message"]?.(input, output);
// Run keyword detector first so that ultrawork (or other keywords)
// can set message.variant (e.g., to "max") before agent variants
// are applied.
await keywordDetector?.["chat.message"]?.(input, output);
if (firstMessageVariantGate.shouldOverride(input.sessionID)) {
const variant = resolveAgentVariant(pluginConfig, input.agent)
if (variant !== undefined && message.variant === undefined) {
message.variant = variant
}
firstMessageVariantGate.markApplied(input.sessionID)
} else if (message.variant === undefined) {
applyAgentVariant(pluginConfig, input.agent, message)
}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Configure default variants from new opencode config

3 participants