Skip to content

feat(models): add live session model switching and /init skill#199

Merged
lavaman131 merged 2 commits intomainfrom
lavaman131/hotfix/models
Feb 15, 2026
Merged

feat(models): add live session model switching and /init skill#199
lavaman131 merged 2 commits intomainfrom
lavaman131/hotfix/models

Conversation

@lavaman131
Copy link
Collaborator

@lavaman131 lavaman131 commented Feb 15, 2026

Summary

This PR introduces two major improvements:

  1. Live session model switching: Enable runtime model changes for Claude and Copilot agents without requiring a new session
  2. Dynamic /init skill: Replace static template files with an intelligent codebase exploration skill that generates tailored project documentation

Key Changes

Model Switching

  • Add setActiveSessionModel to CodingAgentClient interface (src/sdk/types.ts:623)
  • Claude implementation: Persist model changes on session config for subsequent turns (src/sdk/claude-client.ts:1121)
  • Copilot implementation: Rebind active session with updated model and reasoning effort (src/sdk/copilot-client.ts:881)
  • Update UnifiedModelOperations to prefer SDK-level model switching over pendingModel fallback
  • Normalize Claude model preferences to canonical aliases (opus, sonnet, haiku) by stripping provider prefixes
  • Fix model preference persistence to use effective model from modelOps instead of raw config

/init Skill Refactor

  • Remove static template files: CLAUDE.md, AGENTS.md, MODULE_DOCUMENTATION.md, and .atomic/settings.json
  • Add /init builtin skill that dynamically explores the codebase using sub-agents (src/ui/commands/skill-commands.ts:1106)
  • Generated documentation is tailored to actual project structure, tech stack, and conventions
  • Clean up additional_files and preserve_files references from agent configs

Other Improvements

  • Reformat skill-commands.ts to consistent 4-space indentation
  • Add comprehensive test coverage for setActiveSessionModel behavior
  • Update model operations tests to verify normalized preference handling

Breaking Changes

None. The changes are backwards compatible.

Test Plan

  • Verify model switching works mid-session for both Claude and Copilot agents
  • Confirm model preferences persist correctly with canonical aliases
  • Run /init skill on a fresh project and verify generated CLAUDE.md/AGENTS.md are populated
  • Run existing test suite (bun test) to check for regressions

Developer added 2 commits February 15, 2026 06:19
…it skill

Replace the static CLAUDE.md/AGENTS.md template files that were copied
during `atomic init` with a new `/init` builtin skill that dynamically
explores the codebase and generates populated project documentation.

- Remove CLAUDE.md, AGENTS.md, MODULE_DOCUMENTATION.md, and
  .atomic/settings.json template files
- Remove additional_files/preserve_files references from agent configs
- Add `/init` builtin skill that uses sub-agents to discover project
  metadata and generate tailored CLAUDE.md/AGENTS.md
- Reformat skill-commands.ts to consistent 4-space indentation

Assistant-model: Claude Code
Enable runtime model switching without requiring a new session for
Claude and Copilot agents by adding setActiveSessionModel to the SDK
client interface.

- Add setActiveSessionModel to CodingAgentClient interface
- Implement for ClaudeAgentClient (persists on session config for
  future turns) and CopilotClient (rebinds session with updated model)
- Update UnifiedModelOperations to prefer SDK model setter over
  pendingModel/requiresNewSession fallback
- Pass reasoning effort to Copilot during model switch
- Fix model preference persistence to use effective model from
  modelOps rather than raw selected ID
- Normalize Claude model preferences to canonical aliases (opus,
  sonnet, haiku) stripping provider prefixes

Assistant-model: Claude Code
@lavaman131 lavaman131 merged commit d5c8a4e into main Feb 15, 2026
3 checks passed
@lavaman131 lavaman131 deleted the lavaman131/hotfix/models branch February 15, 2026 06:22
@claude claude bot changed the title fix(models): live session model switching and init skill refactor feat(models): add live session model switching and /init skill Feb 15, 2026
@claude
Copy link

claude bot commented Feb 15, 2026

PR Review: fix(models): live session model switching and init skill refactor

Summary

This PR makes two significant changes:

  1. Live session model switching - Adds setActiveSessionModel to enable runtime model changes without requiring a new session for Claude and Copilot agents
  2. Replace static init templates with /init skill - Removes hardcoded CLAUDE.md, AGENTS.md, and MODULE_DOCUMENTATION.md template files, replacing them with a dynamic /init builtin skill that explores the codebase

Code Quality & Best Practices

Strengths

  • Good test coverage for new functionality: Tests added for setActiveSessionModel in claude-client.test.ts, model operations test expansion, settings normalization tests, and builtin commands tests
  • Clean interface extension: The CodingAgentClient interface properly extends with an optional setActiveSessionModel method
  • Proper fallback handling: The UnifiedModelOperations.setModel() prefers SDK model setter when available, with sensible fallback for SDKs that don't support live switching

Issues

  1. Inconsistent indentation change in skill-commands.ts (lines 2586-3727): The entire file was reformatted from 2-space to 4-space indentation. This creates unnecessary diff noise and deviates from what appears to be the project's 2-space convention. Consider:

    • Reverting the indentation changes
    • If 4-space is intentional, this should be a separate formatting PR
  2. Missing type annotation in src/ui/index.ts:289-295:

    const sdkSetModel = agentType === "opencode" && "setActivePromptModel" in client
      ? async (selectedModel: string) => { ... }
      : agentType && "setActiveSessionModel" in client
        ? async (selectedModel: string, options?: { reasoningEffort?: string }) => { ... }
        : undefined;

    The nested ternary with different function signatures could benefit from explicit typing or a helper function for clarity.


Potential Bugs & Issues

  1. Race condition potential in CopilotClient.setActiveSessionModel (copilot-client.ts:403-452):

    • The method gets the last active session, unsubscribes from events, calls resumeSession, then re-subscribes
    • If events fire between unsubscribe and re-subscribe, they could be lost
    • Consider keeping the old subscription active until the new one is confirmed
  2. No validation for empty model arrays in ClaudeAgentClient.setActiveSessionModel:

    const activeSessions = Array.from(this.sessions.values()).filter((state) => !state.isClosed);
    const activeSession = activeSessions[activeSessions.length - 1];
    if (!activeSession) { return; }

    This silently does nothing if no active session exists. Consider logging a warning or returning an error state.

  3. Model preference persistence timing in chat.tsx:3046-3057:

    if (modelOps && 'setPendingReasoningEffort' in modelOps) {
      (modelOps as {...}).setPendingReasoningEffort(reasoningEffort);
    }
    const result = await modelOps?.setModel(selectedModel.id);

    Setting pending reasoning effort before setModel is correct for Copilot (which uses it), but ensure this ordering is intentional for all agent types.


Performance Considerations

  1. normalizeClaudeModelPreference string operations (settings.ts:37-51):

    const canonical = CLAUDE_CANONICAL_MODELS.find((name) =>
      normalized === name || normalized.includes(name)
    );

    Using includes could match unintended substrings (e.g., "haikuv2" would match "haiku"). Consider using a more precise match:

    normalized === name || normalized.startsWith(`${name}-`) || normalized.endsWith(`-${name}`)
  2. Session rebind in Copilot (copilot-client.ts:437):

    • resumeSession appears to rebind the entire session with all tools and config. For frequent model switches, this could be expensive. Consider if there's a lighter-weight API.

Security Concerns

  1. No input sanitization on model ID in ClaudeAgentClient.setActiveSessionModel:
    const targetModel = stripProviderPrefix(model).trim();
    if (!targetModel) { throw new Error("Model ID cannot be empty."); }
    While basic validation exists, consider validating against a whitelist of known model identifiers to prevent potential injection issues if the model string is used in API calls.

Test Coverage

Good:

  • Unit tests for setActiveSessionModel behavior
  • Tests for model preference normalization including canonical alias stripping
  • Test for effective model usage in state updates

Missing:

  • Integration test for end-to-end model switching during an active session
  • Test for the new /init skill execution
  • Test for CopilotClient.setActiveSessionModel (only Claude client is tested)
  • Error handling tests for failed resumeSession calls

Suggestions

  1. Split this PR - The /init skill refactor and model switching are independent features. Separating them would make review and potential rollbacks easier.

  2. Add JSDoc comments to setActiveSessionModel interface method explaining:

    • When it's safe to call
    • What happens to conversation history
    • Expected behavior per agent type
  3. Consider deprecation path - The removal of CLAUDE.md/AGENTS.md templates is a breaking change for users who relied on atomic init generating these files. Consider:

    • Adding a migration note
    • Keeping a minimal template as fallback if /init skill fails
  4. Revert indentation changes in skill-commands.ts or make it a separate formatting commit


Overall Assessment

The core model-switching functionality is well-implemented with proper abstraction through the CodingAgentClient interface. The test coverage for the new functionality is reasonable. However, the /init skill and template removal changes deserve separate consideration due to the breaking nature of removing static templates.

Recommendation: Consider splitting this into two PRs:

  1. Live session model switching (ready to merge with minor fixes)
  2. /init skill refactor (needs more testing and migration planning)

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