feat: Add model switching inside an active session#3
Conversation
- Add /model slash command to show current model or switch to a new one - Show current model in /status output - Make model mutable in REPL session state - Update subagent tool to use model getter for dynamic resolution - Add tests for /model command and status model display
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThis PR adds live model switching in the REPL, moves SSE parsing to a dedicated module, refactors tool error handling into classifiers, renames several tool modules to camelCase, updates imports/tests accordingly, and adds ESLint configuration and scripts. Tests and command handlers are updated to use getModel/setModel callbacks. Changes
Sequence Diagram(s)sequenceDiagram
participant User as User (REPL)
participant Commands as Slash Commands
participant State as Mutable Model State
participant Subagent as Subagent Tool
participant Agent as Agent Loop
User->>Commands: /model claude-sonnet
Commands->>State: setModel("claude-sonnet")
State-->>Commands: (model updated)
Commands->>User: Model switched: old → new
User->>Agent: trigger runAgentLoop
Agent->>Subagent: request tool execution
Subagent->>State: getModel()
State-->>Subagent: "claude-sonnet"
Subagent->>Agent: execute using current model
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0adc3e8dcd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (trimmed.toLowerCase().startsWith("/model")) { | ||
| const arg = trimmed.slice("/model".length).trim(); |
There was a problem hiding this comment.
Match /model command on full token
The /model handler uses startsWith("/model"), so any unknown slash command that begins with that prefix (for example /models) is treated as a model switch and sets the active model to the trailing suffix (e.g., s). After this typo, subsequent requests will fail against the API until the user manually corrects the model, which makes normal command mistakes break the session state unexpectedly.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
2 issues found across 32 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="package.json">
<violation number="1" location="package.json:40">
P2: Version range for `typescript-eslint` (`^8.0.0`) is misaligned with `@typescript-eslint/utils` (`^8.58.0`). These are from the same monorepo and should share the same minimum version to avoid mismatched transitive dependencies.</violation>
</file>
<file name="src/repl/commands.ts">
<violation number="1" location="src/repl/commands.ts:53">
P2: Use an exact token match for `/model` instead of `startsWith("/model")`. A typo like `/models` currently matches, slices the suffix `"s"` as the argument, and silently sets the active model to an invalid value — breaking all subsequent API calls until manually corrected.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
| "eslint-plugin-llm-core": "^0.3.2", | ||
| "tsx": "^4.21.0", | ||
| "typescript": "^5.9.3", | ||
| "typescript-eslint": "^8.0.0", |
There was a problem hiding this comment.
P2: Version range for typescript-eslint (^8.0.0) is misaligned with @typescript-eslint/utils (^8.58.0). These are from the same monorepo and should share the same minimum version to avoid mismatched transitive dependencies.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At package.json, line 40:
<comment>Version range for `typescript-eslint` (`^8.0.0`) is misaligned with `@typescript-eslint/utils` (`^8.58.0`). These are from the same monorepo and should share the same minimum version to avoid mismatched transitive dependencies.</comment>
<file context>
@@ -30,8 +32,12 @@
+ "eslint-plugin-llm-core": "^0.3.2",
"tsx": "^4.21.0",
"typescript": "^5.9.3",
+ "typescript-eslint": "^8.0.0",
"vitest": "^4.1.0"
}
</file context>
| "typescript-eslint": "^8.0.0", | |
| "typescript-eslint": "^8.58.0", |
| return true; | ||
| } | ||
|
|
||
| if (trimmed.toLowerCase().startsWith("/model")) { |
There was a problem hiding this comment.
P2: Use an exact token match for /model instead of startsWith("/model"). A typo like /models currently matches, slices the suffix "s" as the argument, and silently sets the active model to an invalid value — breaking all subsequent API calls until manually corrected.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/repl/commands.ts, line 53:
<comment>Use an exact token match for `/model` instead of `startsWith("/model")`. A typo like `/models` currently matches, slices the suffix `"s"` as the argument, and silently sets the active model to an invalid value — breaking all subsequent API calls until manually corrected.</comment>
<file context>
@@ -40,10 +43,22 @@ export async function handleSlashCommand(
+ return true;
+ }
+
+ if (trimmed.toLowerCase().startsWith("/model")) {
+ const arg = trimmed.slice("/model".length).trim();
+ if (arg.length === 0) {
</file context>
| if (trimmed.toLowerCase().startsWith("/model")) { | |
| if (trimmed.toLowerCase() === "/model" || trimmed.toLowerCase().startsWith("/model ")) { |
Summary
Adds the ability to switch AI models during an active REPL session without restarting.
What's included
/modelcommand — Lists available models and lets users switch between them interactively/statusupdate — Now displays the current active model alongside other session infoCommits
3e35f27fix: resolve lint violations - rename files, extract modules, structured loggingf8e23fcfix: update test assertions to match structured logging formate49a550feat: add model switching inside an active session21275aadocs: mark model switching task complete in ROADMAP0adc3e8docs: add Socratic Journal entry for model switchingSummary by cubic
Add in-session model switching to the REPL via a new
/modelcommand./statusnow shows the active model, and subagents inherit model changes automatically.New Features
/modelcommand to view or switch the active model without restarting./statusincludes the current model.getModel()so they always run with the session’s active model.Refactors
src/api/sse-parser.ts;anthropic.tsre-exportsparseSSEStream.compressConversation.ts,runCli.ts, and tool files (editFileTool.ts,readFileTool.ts,writeFileTool.ts).grepfor clearer messages.eslint,typescript-eslint, andeslint-plugin-llm-core.Written for commit e8a3a77. Summary will update on new commits.
Summary by CodeRabbit
New Features
/modelcommand/statuscommand now displays the current modelBug Fixes
Refactoring
Tests
Chores