-
Notifications
You must be signed in to change notification settings - Fork 2.3k
feat: add model_candidates and /switch-model command for runtime model switching #1773
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
- Added model_candidates: z.array(z.string()).optional() to AgentOverrideConfigSchema - Updated JSON schema generation (build-schema.ts uses correct Zod 4 method) - Maintains backward compatibility (field is optional) - JSON schema now includes model_candidates field Preparation for Task 3: Runtime state management module
…l override - createSisyphusAgent: add agentName?: string parameter - createHephaestusAgent: add agentName?: string parameter - createAtlasAgent: add agentName to OrchestratorContext - Each create function uses getActiveModel(agentName) for override - Builtin-agents pass agentName when creating agents This enables runtime model switching for Sisyphus, Hephaestus, and Atlas through getActiveModel() integration with the model-switcher state module.
- Add switch-model command template with model switching instructions - Update BuiltinCommandName type to include 'switch-model' - Update BuiltinCommandNameSchema enum to include 'switch-model' - Add switch-model to BUILTIN_COMMAND_DEFINITIONS with argumentHint The command provides: - Current model assignments display for all agents - Model candidates listing for specific agents - Model switching instructions - Validation for model candidates - Clear error messages for invalid models Template includes detailed instructions for parsing arguments, getting current model info, validating inputs, and performing model switches using model-switcher APIs.
- Test loadCandidates() parsing with/without/empty model_candidates - Test setActiveModel() and getActiveModel() override functionality - Test getCandidates() and getCurrentModelInfo() state queries - Test backward compatibility (config without model_candidates) - Test invalid agent name handling - 12 test cases all passing Tests use unique agent names to avoid singleton state interference between test cases.
|
Thank you for your contribution! Before we can merge this PR, we need you to sign our Contributor License Agreement (CLA). To sign the CLA, please comment on this PR with: This is a one-time requirement. Once signed, all your future contributions will be automatically accepted. I have read the CLA Document and I hereby sign the CLA You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot. |
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.
3 issues found across 25 files
Confidence score: 3/5
- Test pollution risk in
src/features/model-switcher/model-switcher.test.tscould cause flaky or misleading test results due to shared state between blocks. - Runtime model switching may not take effect until restart because
src/agents/hephaestus.tscaches model configuration after initialization, which is a concrete user-facing behavior risk. - Given the medium severity issues (6–7/10) impacting runtime behavior and test reliability, this is a moderate-risk merge.
- Pay close attention to
src/agents/hephaestus.ts,src/features/model-switcher/model-switcher.test.ts,test-zod4.ts- stale model config, shared-state tests, and accidental experimental file inclusion.
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="src/features/model-switcher/model-switcher.test.ts">
<violation number="1" location="src/features/model-switcher/model-switcher.test.ts:78">
P1: Test pollution due to shared state dependency between test blocks</violation>
</file>
<file name="src/agents/hephaestus.ts">
<violation number="1" location="src/agents/hephaestus.ts:607">
P2: Model configuration becomes stale after agent initialization - runtime model switching may not take effect until agent restart</violation>
</file>
<file name="test-zod4.ts">
<violation number="1" location="test-zod4.ts:1">
P2: Accidental inclusion of temporary experimental file `test-zod4.ts`</violation>
</file>
Since this is your first cubic review, here's how it works:
- cubic automatically reviews your code and comments on bugs and improvements
- Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
- Add one-off context when rerunning by tagging
@cubic-dev-aiwith guidance or docs links (includingllms.txt) - Ask questions if you need clarification on any suggestion
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| }) | ||
| }) | ||
|
|
||
| describe("Candidate retrieval", () => { |
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.
P1: Test pollution due to shared state dependency between test blocks
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/features/model-switcher/model-switcher.test.ts, line 78:
<comment>Test pollution due to shared state dependency between test blocks</comment>
<file context>
@@ -0,0 +1,169 @@
+ })
+ })
+
+ describe("Candidate retrieval", () => {
+ test("should return candidates array for agent with candidates", () => {
+ const candidates = getCandidates("test_agent_3")
</file context>
| useTaskSystem = false, | ||
| agentName?: string | ||
| ): AgentConfig { | ||
| const effectiveModel = agentName ? getActiveModel(agentName) ?? model : model |
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.
P2: Model configuration becomes stale after agent initialization - runtime model switching may not take effect until agent restart
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/agents/hephaestus.ts, line 607:
<comment>Model configuration becomes stale after agent initialization - runtime model switching may not take effect until agent restart</comment>
<file context>
@@ -600,8 +601,10 @@ export function createHephaestusAgent(
+ useTaskSystem = false,
+ agentName?: string
): AgentConfig {
+ const effectiveModel = agentName ? getActiveModel(agentName) ?? model : model
const tools = availableToolNames ? categorizeTools(availableToolNames) : []
const skills = availableSkills ?? []
</file context>
| @@ -0,0 +1,15 @@ | |||
| import { z } from "zod" | |||
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.
P2: Accidental inclusion of temporary experimental file test-zod4.ts
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At test-zod4.ts, line 1:
<comment>Accidental inclusion of temporary experimental file `test-zod4.ts`</comment>
<file context>
@@ -0,0 +1,15 @@
+import { z } from "zod"
+
+const testSchema = z.object({
</file context>
|
Closing this PR. Will create a new PR for auth-connected model filtering feature. |
Problem
Currently, changing an agent's LLM model requires:
This workflow is inefficient and disrupts the development flow, especially when experimenting with different models during a session.
Solution
Added a new configuration field
model_candidatesto agent overrides and a builtin slash command/switch-modelthat enables runtime model switching within an active session.New Configuration: model_candidates
Each agent can now define a list of alternative models:
{ "agents": { "sisyphus": { "model": "zai-coding-plan/glm-4.7", "model_candidates": [ "zai-coding-plan/glm-4.7", "google/antigravity-claude-opus-4-6-thinking", "cursor-acp/gpt-5.2" ] }, "oracle": { "model_candidates": ["claude-3-5-opus", "claude-3-7-sonnet"] } } }New Command: /switch-model
The
/switch-modelcommand provides:/switch-model- Show current model assignments for all agents/switch-model <agent-name>- Show available model candidates for a specific agent/switch-model <agent-name> <model-id>- Immediately switch the agent to the specified modelExample usage:
Implementation Details
Schema Changes
model_candidates: z.array(z.string()).optional()toAgentOverrideConfigSchemaBuiltinCommandNameSchemaenumCore Architecture
src/features/model-switcher/state.tswith singleton pattern for runtime state managementloadCandidates(),setActiveModel(),getActiveModel(),getCandidates(),getCurrentModelInfo()buildAgent()to apply model overrides during agent creationAgent Integration
createSisyphusAgent(),createHephaestusAgent(),createAtlasAgent()to acceptagentNameparametergetActiveModel(agentName)for model selectionCommand Implementation
/switch-modelbuiltin command with detailed usage instructionsBreaking Changes
None. The
model_candidatesfield is optional, so existing configurations without it continue to work as before.Testing
Usage
model_candidatesto your agent configuration in oh-my-opencode.json/switch-model <agent-name> <model-id>to change the active modelSummary by cubic
Add runtime model switching for agents via an optional model_candidates config and a new /switch-model command. This lets you change an agent’s LLM during a session without editing config or restarting.
New Features
Migration
Written for commit 530a571. Summary will update on new commits.