diff --git a/cli/src/codex/loop.ts b/cli/src/codex/loop.ts index d0d170c4..51a5c7aa 100644 --- a/cli/src/codex/loop.ts +++ b/cli/src/codex/loop.ts @@ -7,12 +7,14 @@ import { codexRemoteLauncher } from './codexRemoteLauncher'; import { ApiClient, ApiSessionClient } from '@/lib'; import type { CodexCliOverrides } from './utils/codexCliOverrides'; import type { CodexPermissionMode } from '@hapi/protocol/types'; +import type { CollaborationMode } from './appServerTypes'; export type PermissionMode = CodexPermissionMode; export interface EnhancedMode { permissionMode: PermissionMode; model?: string; + collaborationMode?: CollaborationMode['mode']; } interface LoopOptions { diff --git a/cli/src/codex/runCodex.ts b/cli/src/codex/runCodex.ts index 16768d55..91657eca 100644 --- a/cli/src/codex/runCodex.ts +++ b/cli/src/codex/runCodex.ts @@ -42,7 +42,8 @@ export async function runCodex(opts: { const messageQueue = new MessageQueue2((mode) => hashObject({ permissionMode: mode.permissionMode, - model: mode.model + model: mode.model, + collaborationMode: mode.collaborationMode })); const codexCliOverrides = parseCodexCliOverrides(opts.codexArgs); @@ -50,6 +51,7 @@ export async function runCodex(opts: { let currentPermissionMode: PermissionMode = opts.permissionMode ?? 'default'; const currentModel = opts.model; + let currentCollaborationMode: EnhancedMode['collaborationMode']; const lifecycle = createRunnerLifecycle({ session, @@ -75,7 +77,8 @@ export async function runCodex(opts: { const enhancedMode: EnhancedMode = { permissionMode: messagePermissionMode ?? 'default', - model: currentModel + model: currentModel, + collaborationMode: currentCollaborationMode }; const formattedText = formatMessageWithAttachments(message.content.text, message.content.attachments); messageQueue.push(formattedText, enhancedMode); @@ -97,18 +100,36 @@ export async function runCodex(opts: { return parsed.data as PermissionMode; }; + const resolveCollaborationMode = (value: unknown): EnhancedMode['collaborationMode'] => { + if (value === null) { + return undefined; + } + if (typeof value !== 'string') { + throw new Error('Invalid collaboration mode'); + } + const trimmed = value.trim(); + if (!trimmed) { + throw new Error('Invalid collaboration mode'); + } + return trimmed as EnhancedMode['collaborationMode']; + }; + session.rpcHandlerManager.registerHandler('set-session-config', async (payload: unknown) => { if (!payload || typeof payload !== 'object') { throw new Error('Invalid session config payload'); } - const config = payload as { permissionMode?: unknown }; + const config = payload as { permissionMode?: unknown; collaborationMode?: unknown }; if (config.permissionMode !== undefined) { currentPermissionMode = resolvePermissionMode(config.permissionMode); } + if (config.collaborationMode !== undefined) { + currentCollaborationMode = resolveCollaborationMode(config.collaborationMode); + } + syncSessionMode(); - return { applied: { permissionMode: currentPermissionMode } }; + return { applied: { permissionMode: currentPermissionMode, collaborationMode: currentCollaborationMode } }; }); try { diff --git a/cli/src/codex/utils/appServerConfig.test.ts b/cli/src/codex/utils/appServerConfig.test.ts index 2cc03759..1155b7bd 100644 --- a/cli/src/codex/utils/appServerConfig.test.ts +++ b/cli/src/codex/utils/appServerConfig.test.ts @@ -48,6 +48,17 @@ describe('appServerConfig', () => { expect(params.model).toBe('o3'); }); + it('puts collaboration mode in turn params with model settings', () => { + const params = buildTurnStartParams({ + threadId: 'thread-1', + message: 'hello', + mode: { permissionMode: 'default', model: 'o3', collaborationMode: 'plan' } + }); + + expect(params.collaborationMode).toEqual({ mode: 'plan', settings: { model: 'o3' } }); + expect(params.model).toBeUndefined(); + }); + it('applies CLI overrides for turns when permission mode is default', () => { const params = buildTurnStartParams({ threadId: 'thread-1', diff --git a/cli/src/codex/utils/appServerConfig.ts b/cli/src/codex/utils/appServerConfig.ts index f9abb67f..5a2aa102 100644 --- a/cli/src/codex/utils/appServerConfig.ts +++ b/cli/src/codex/utils/appServerConfig.ts @@ -136,8 +136,14 @@ export function buildTurnStartParams(args: { params.sandboxPolicy = sandboxPolicy; } + const collaborationMode = args.mode?.collaborationMode; const model = args.overrides?.model ?? args.mode?.model; - if (model) { + if (collaborationMode) { + const settings = model ? { model } : undefined; + params.collaborationMode = settings + ? { mode: collaborationMode, settings } + : { mode: collaborationMode }; + } else if (model) { params.model = model; }