feat: support codex collaboration_modes

This commit is contained in:
weishu
2026-01-26 22:48:02 +08:00
parent 3a1379dc01
commit 83f07c199d
4 changed files with 45 additions and 5 deletions
+2
View File
@@ -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 {
+25 -4
View File
@@ -42,7 +42,8 @@ export async function runCodex(opts: {
const messageQueue = new MessageQueue2<EnhancedMode>((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 {
@@ -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',
+7 -1
View File
@@ -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;
}