Model Overrides
Relevant source files
The following files were used as context for generating this wiki page:
Model Overrides allow users to bypass the default Large Language Model (LLM) associated with a specific AI engine in Morty. This feature provides flexibility to use specific model versions (such as Claude 3.5 Sonnet instead of the default) or to utilize custom models supported by specific providers like OpenCode or Qwen.
The mechanism is implemented across the core shell script (morty.sh) and the TypeScript CLI, ensuring that the preferred model string is propagated from command-line arguments through the execution logic to the final API or CLI call of the underlying AI engine.
Sources: morty.sh:31, cli/src/cli/args.ts:74-76, README.md:120-125
Architecture and Data Flow
The model override value flows through the system starting from the user's CLI input. It is stored in the runtime configuration and eventually passed to the engine execution methods.
Data Flow Diagram
The following diagram illustrates how a model override value moves from the command line to the actual execution of an AI task.
The flow ensures that any component responsible for calling an AI tool is aware of the desired model variant.
Sources: morty.sh:658-692, cli/src/execution/parallel.ts:114-118, cli/src/engines/codex.ts:18-21
User Interface and Shortcuts
Morty provides two primary ways to override a model: the generic --model flag and specific shortcuts like --sonnet.
| Flag | Description | Engine Impact |
|---|---|---|
--model <name> | Explicitly sets the model string for the active engine. | All Engines |
--sonnet | Shortcut that sets engine to claude and model to sonnet. | Claude |
In the TypeScript implementation, the --sonnet flag is treated as a high-priority override that simultaneously selects the Claude engine and defines the model.
Sources: morty.sh:424-428, cli/src/cli/args.ts:71-76, README.md:123-125
Implementation Details
State Management
In morty.sh, the override is stored in the MODEL_OVERRIDE global variable. In the TypeScript CLI, it is defined within the RuntimeOptions interface as an optional string.
export interface RuntimeOptions {
aiEngine: string;
// ... other options
modelOverride?: string;
}
Sources: morty.sh:31, cli/src/config/types.ts:85
Engine Integration
When an engine executes a task, it checks for the presence of the modelOverride. For example, the CodexEngine appends the --model argument to its CLI call if an override is provided.
const args = ["exec", "--full-auto", "--json", "--output-last-message", lastMessageFile];
if (options?.modelOverride) {
args.push("--model", options.modelOverride);
}
args.push(prompt);
Sources: cli/src/engines/codex.ts:17-21
Similarly, the shell script version handles this through conditional variable expansion when invoking various AI CLIs.
Sources: morty.sh:662, morty.sh:668, morty.sh:686
Parallel Execution and Conflict Resolution
Model overrides are persistent even during complex workflows like parallel execution and AI-assisted merge conflict resolution.
- Parallel Agents: When spawning multiple agents in isolated worktrees, the
modelOverrideis passed to therunAgentInWorktreefunction to ensure every agent uses the specified model. - Conflict Resolution: If merge conflicts occur after parallel tasks, the
resolveConflictsWithAIfunction receives themodelOverrideto ensure the resolution task is performed by the preferred model.
Sources: cli/src/execution/parallel.ts:46, cli/src/execution/parallel.ts:285-291, cli/src/execution/conflict-resolution.ts:39
Conflict Resolution Sequence
This diagram shows how the model override is utilized during the automated conflict resolution phase.
Conclusion
Model Overrides serve as a critical configuration layer in Morty, allowing developers to optimize for cost, speed, or intelligence by selecting specific LLMs. By propagating this setting through standard runtime options, Morty ensures consistent behavior across single-task execution, parallel agent workflows, and automated maintenance tasks like conflict resolution.