Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/api/apiMachine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,14 @@ export class ApiMachineClient {
}: MachineRpcHandlers) {
// Register spawn session handler
this.rpcHandlerManager.registerHandler('spawn-happy-session', async (params: any) => {
const { directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token, environmentVariables } = params || {};
const { directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token, model, environmentVariables } = params || {};
logger.debug(`[API MACHINE] Spawning session with params: ${JSON.stringify(params)}`);

if (!directory) {
throw new Error('Directory is required');
}

const result = await spawnSession({ directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token, environmentVariables });
const result = await spawnSession({ directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token, model, environmentVariables });

switch (result.type) {
case 'success':
Expand Down
19 changes: 17 additions & 2 deletions src/daemon/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ export async function startDaemon(): Promise<void> {
const spawnSession = async (options: SpawnSessionOptions): Promise<SpawnSessionResult> => {
logger.debugLargeJson('[DAEMON RUN] Spawning session', options);

const { directory, sessionId, machineId, approvedNewDirectoryCreation = true } = options;
const { directory, sessionId, machineId, approvedNewDirectoryCreation = true, model } = options;
let directoryCreated = false;

try {
Expand Down Expand Up @@ -325,6 +325,13 @@ export async function startDaemon(): Promise<void> {

// Final merge: Profile vars first, then auth (auth takes precedence to protect authentication)
let extraEnv = { ...profileEnv, ...authEnv };

// If model is provided via spawn options, set ANTHROPIC_MODEL (takes precedence over profile)
if (model) {
extraEnv.ANTHROPIC_MODEL = model;
logger.debug(`[DAEMON RUN] Model set from spawn options: ${model}`);
}

logger.debug(`[DAEMON RUN] Final environment variable keys (before expansion) (${Object.keys(extraEnv).length}): ${Object.keys(extraEnv).join(', ')}`);

// Expand ${VAR} references from daemon's process.env
Expand Down Expand Up @@ -388,7 +395,9 @@ export async function startDaemon(): Promise<void> {
const cliPath = join(projectPath(), 'dist', 'index.mjs');
// Determine agent command - support claude, codex, and gemini
const agent = options.agent === 'gemini' ? 'gemini' : (options.agent === 'codex' ? 'codex' : 'claude');
const fullCommand = `node --no-warnings --no-deprecation ${cliPath} ${agent} --happy-starting-mode remote --started-by daemon`;
// Add --model flag if specified (for Claude agent)
const modelArg = model && (options.agent === 'claude' || options.agent === undefined) ? ` --model ${model}` : '';
const fullCommand = `node --no-warnings --no-deprecation ${cliPath} ${agent} --happy-starting-mode remote --started-by daemon${modelArg}`;

// Spawn in tmux with environment variables
// IMPORTANT: Pass complete environment (process.env + extraEnv) because:
Expand Down Expand Up @@ -495,6 +504,12 @@ export async function startDaemon(): Promise<void> {
'--started-by', 'daemon'
];

// Add --model flag if model was specified (for Claude agent)
if (model && (options.agent === 'claude' || options.agent === undefined)) {
args.push('--model', model);
logger.debug(`[DAEMON RUN] Added --model ${model} to CLI args`);
}

// TODO: In future, sessionId could be used with --resume to continue existing sessions
// For now, we ignore it - each spawn creates a new session
const happyProcess = spawnHappyCLI(args, {
Expand Down
2 changes: 2 additions & 0 deletions src/modules/common/registerCommonHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ export interface SpawnSessionOptions {
approvedNewDirectoryCreation?: boolean;
agent?: 'claude' | 'codex' | 'gemini';
token?: string;
/** Model alias (e.g., 'sonnet', 'opus') or full name. Takes precedence over environmentVariables.ANTHROPIC_MODEL */
model?: string;
environmentVariables?: {
// Anthropic Claude API configuration
ANTHROPIC_BASE_URL?: string; // Custom API endpoint (overrides default)
Expand Down