Skip to content

feat: Add model switching inside an active session#3

Merged
pertrai1 merged 6 commits into
mainfrom
feature/model-switching
Apr 2, 2026
Merged

feat: Add model switching inside an active session#3
pertrai1 merged 6 commits into
mainfrom
feature/model-switching

Conversation

@pertrai1

@pertrai1 pertrai1 commented Apr 2, 2026

Copy link
Copy Markdown
Owner

Summary

Adds the ability to switch AI models during an active REPL session without restarting.

What's included

  • /model command — Lists available models and lets users switch between them interactively
  • /status update — Now displays the current active model alongside other session info
  • Updated subagent support — Subagents inherit the active model from the parent session
  • Structured logging — Logging updated to structured format; test assertions updated accordingly
  • Lint fixes — File renames, module extraction, and lint violation resolution

Commits

  • 3e35f27 fix: resolve lint violations - rename files, extract modules, structured logging
  • f8e23fc fix: update test assertions to match structured logging format
  • e49a550 feat: add model switching inside an active session
  • 21275aa docs: mark model switching task complete in ROADMAP
  • 0adc3e8 docs: add Socratic Journal entry for model switching

Summary by cubic

Add in-session model switching to the REPL via a new /model command. /status now shows the active model, and subagents inherit model changes automatically.

  • New Features

    • /model command to view or switch the active model without restarting.
    • /status includes the current model.
    • Subagents use getModel() so they always run with the session’s active model.
  • Refactors

    • Extracted SSE parsing to src/api/sse-parser.ts; anthropic.ts re-exports parseSSEStream.
    • Structured warning logs with updated tests.
    • Consistent filenames: compressConversation.ts, runCli.ts, and tool files (editFileTool.ts, readFileTool.ts, writeFileTool.ts).
    • Centralized error handling in file tools and grep for clearer messages.
    • Added lint config and scripts with eslint, typescript-eslint, and eslint-plugin-llm-core.

Written for commit e8a3a77. Summary will update on new commits.

Summary by CodeRabbit

  • New Features

    • Model switching now available within active REPL sessions via the new /model command
    • /status command now displays the current model
  • Bug Fixes

    • More specific, structured warnings for configuration and file read/write errors
  • Refactoring

    • SSE parsing moved to a dedicated module
    • Centralized and standardized file operation error handling
    • Updated internal module import paths/naming
  • Tests

    • Added comprehensive model-switching test coverage
  • Chores

    • Added ESLint configuration and npm lint scripts

pertrai1 added 5 commits April 2, 2026 07:49
- 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
@coderabbitai

coderabbitai Bot commented Apr 2, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 53bd89e6-d146-4393-a6a8-0ff5e8c6fb49

📥 Commits

Reviewing files that changed from the base of the PR and between 0adc3e8 and e8a3a77.

📒 Files selected for processing (1)
  • README.md

📝 Walkthrough

Walkthrough

This 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

Cohort / File(s) Summary
Roadmap & Documentation
ROADMAP.md, docs/SOCRATIC_JOURNAL.md
Marked model-switching as completed; documented late-binding getModel() approach and REPL /model command wiring.
ESLint Configuration
eslint.config.mjs, package.json
Added ESLint config merging TypeScript and llm-core presets; added lint/lint:fix scripts and dev dependencies.
Model Switching Feature
src/repl.ts, src/repl/commands.ts, src/subagent/tool.ts
Made REPL model mutable, added getModel/setModel callbacks, implemented /model command, and changed subagent tool to call getModel() at execution time.
SSE Parser Extraction
src/api/sse-parser.ts, src/api/anthropic.ts, src/context/compressConversation.ts
Extracted SSE parsing into sse-parser.ts; anthropic re-exports parser/type; imports updated in compressConversation.
Tool Modules & Error Handling
src/tools/index.ts, src/tools/editFileTool.ts, src/tools/readFileTool.ts, src/tools/writeFileTool.ts, src/tools/grep.ts
Renamed tool files to camelCase; centralized read/write/edit error classification helpers; grep refactored with recursive directory search and clearer error responses.
Config & Context Updates
src/config/index.ts, src/config/context.ts, src/config/loadConfigFile.ts
Swapped loader import/re-export to loadConfigFile.js; changed warnings to structured console.warn calls with error objects.
CLI & Agent Imports
src/cli.ts, src/agent.ts
Updated import paths to renamed CLI and context modules (runCli.js, compressConversation.js).
Tests — Imports & Mocks
src/__tests__/* (various)
Updated many test import paths to match renamed modules; added getModel/setModel mocks in CLI/REPL-related tests and tightened console.warn assertions.
New Tests
src/__tests__/model-switching.test.ts
Added comprehensive tests for /model and /status behaviors, covering getter/setter calls, output text, case handling, and status inclusion of model.
Docs — README
README.md
Updated built-in commands to include /model and model reporting in /status.

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 A squeak and a hop, the model can roam,
Late-bound and lively, it finds a new home,
Parsers unburdened, tools tidy and neat,
Tests keep the rhythm — the switch is complete! 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.76% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and specifically describes the main feature added: enabling model switching during an active REPL session.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/model-switching

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment thread src/repl/commands.ts
Comment on lines +53 to +54
if (trimmed.toLowerCase().startsWith("/model")) {
const arg = trimmed.slice("/model".length).trim();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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 👍 / 👎.

@pertrai1
pertrai1 merged commit 85e33b2 into main Apr 2, 2026
3 checks passed
@pertrai1
pertrai1 deleted the feature/model-switching branch April 2, 2026 15:00

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.

Comment thread package.json
"eslint-plugin-llm-core": "^0.3.2",
"tsx": "^4.21.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.0.0",

@cubic-dev-ai cubic-dev-ai Bot Apr 2, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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>
Suggested change
"typescript-eslint": "^8.0.0",
"typescript-eslint": "^8.58.0",
Fix with Cubic

Comment thread src/repl/commands.ts
return true;
}

if (trimmed.toLowerCase().startsWith("/model")) {

@cubic-dev-ai cubic-dev-ai Bot Apr 2, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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>
Suggested change
if (trimmed.toLowerCase().startsWith("/model")) {
if (trimmed.toLowerCase() === "/model" || trimmed.toLowerCase().startsWith("/model ")) {
Fix with Cubic

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.

1 participant