fix(acp): add modes and configOptions to session/new response

Add missing 'modes' and 'configOptions' fields to NewSessionResponse
to enable mode switching (plan/yolo/auto-edit) in Zed ACP client.

- Update schema.ts: add configOptionSchema and extend newSessionResponseSchema
- Update acpAgent.ts: add buildModesData() and buildConfigOptions() helpers

Fixes ACP mode control issue where Zed couldn't switch approval modes.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
mingholy.lmh 2026-02-28 17:09:04 +08:00
parent 1f46ed28d9
commit e5bdd5b635
2 changed files with 98 additions and 5 deletions

View file

@ -153,10 +153,14 @@ class GeminiAgent {
const session = await this.createAndStoreSession(config);
const availableModels = this.buildAvailableModels(config);
const modesData = this.buildModesData(config);
const configOptions = this.buildConfigOptions(config);
return {
sessionId: session.getId(),
models: availableModels,
modes: modesData,
configOptions,
};
}
@ -449,6 +453,70 @@ class GeminiAgent {
};
}
private buildModesData(config: Config): acp.ModesData {
const currentApprovalMode = config.getApprovalMode();
const availableModes = APPROVAL_MODES.map((mode) => ({
id: mode as ApprovalModeValue,
name: APPROVAL_MODE_INFO[mode].name,
description: APPROVAL_MODE_INFO[mode].description,
}));
return {
currentModeId: currentApprovalMode as ApprovalModeValue,
availableModes,
};
}
private buildConfigOptions(config: Config): acp.ConfigOption[] {
const currentApprovalMode = config.getApprovalMode();
const currentModelId = this.formatCurrentModelId(
config.getModel() || this.config.getModel() || '',
config.getAuthType(),
);
const modeOptions = APPROVAL_MODES.map((mode) => ({
value: mode,
name: APPROVAL_MODE_INFO[mode].name,
description: APPROVAL_MODE_INFO[mode].description,
}));
const allConfiguredModels = config.getAllConfiguredModels();
const modelOptions = allConfiguredModels.map((model) => {
const effectiveModelId =
model.isRuntimeModel && model.runtimeSnapshotId
? model.runtimeSnapshotId
: model.id;
return {
value: formatAcpModelId(effectiveModelId, model.authType),
name: model.label,
description: model.description ?? '',
};
});
return [
{
id: 'mode',
name: 'Mode',
description: 'Session permission mode',
category: 'mode',
type: 'select',
currentValue: currentApprovalMode,
options: modeOptions,
},
{
id: 'model',
name: 'Model',
description: 'AI model to use',
category: 'model',
type: 'select',
currentValue: currentModelId,
options: modelOptions,
},
];
}
private formatCurrentModelId(
baseModelId: string,
authType?: AuthType,

View file

@ -59,7 +59,7 @@ export type CancelNotification = z.infer<typeof cancelNotificationSchema>;
export type AuthenticateRequest = z.infer<typeof authenticateRequestSchema>;
export type NewSessionResponse = z.infer<typeof newSessionResponseSchema>;
// Note: NewSessionResponse type is defined later after newSessionResponseSchema
export type LoadSessionResponse = z.infer<typeof loadSessionResponseSchema>;
@ -285,10 +285,7 @@ export const sessionModelStateSchema = z.object({
currentModelId: modelIdSchema,
});
export const newSessionResponseSchema = z.object({
sessionId: z.string(),
models: sessionModelStateSchema,
});
// Note: newSessionResponseSchema is defined later in the file after modesDataSchema
export const loadSessionResponseSchema = z.null();
@ -451,6 +448,34 @@ export const modesDataSchema = z.object({
availableModes: z.array(modeInfoSchema),
});
export const configOptionSchema = z.object({
id: z.string(),
name: z.string(),
description: z.string(),
category: z.string(),
type: z.string(),
currentValue: z.string(),
options: z.array(
z.object({
value: z.string(),
name: z.string(),
description: z.string(),
}),
),
});
export type ConfigOption = z.infer<typeof configOptionSchema>;
// newSessionResponseSchema includes modes and configOptions for ACP/Zed integration
export const newSessionResponseSchema = z.object({
sessionId: z.string(),
models: sessionModelStateSchema,
modes: modesDataSchema,
configOptions: z.array(configOptionSchema),
});
export type NewSessionResponse = z.infer<typeof newSessionResponseSchema>;
export const agentInfoSchema = z.object({
name: z.string(),
title: z.string(),