-
Notifications
You must be signed in to change notification settings - Fork 1.1k
feat(config): add model variant support #677
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this 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.
68e1c4d to
a3592fa
Compare
There was a problem hiding this 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.
a3592fa to
f804efc
Compare
|
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 |
f804efc to
33aed90
Compare
|
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:
Applied some fixes: in this draft PR if you were interested: jkoelker#1 |
|
Lol just noticed you probably fixed it 4 mins ago. will test again, feel free to ignore me if so. |
|
@imarshallwidjaja the categories vs agents config is very brittle at the moment, i would reccomend setting the model + varient explicitly everywhere. |
33aed90 to
ac9bf51
Compare
c889467 to
1d42434
Compare
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
1d42434 to
2b8853c
Compare
imarshallwidjaja
left a comment
There was a problem hiding this 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).
There was a problem hiding this 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
variantfield toAgentOverrideConfigandCategoryConfigschemas 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.
| 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); |
Copilot
AI
Jan 13, 2026
There was a problem hiding this comment.
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:
- Lines 322-331 apply the agent/category variant to the message (unconditionally on first message, conditionally on subsequent messages)
- 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:
- Checking for ultrawork before applying agent variants, or
- Having keyword detector override variants from agent config but not variants from other sources
| 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) | |
| } |
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).
Written for commit 2b8853c. Summary will update on new commits.