mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-30 04:30:48 +00:00
fix(acp): add session/set_config_option method for mode and model configuration
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
407a66c959
commit
33d65af79b
4 changed files with 279 additions and 50 deletions
|
|
@ -81,6 +81,14 @@ export class AgentSideConnection implements Client {
|
|||
const validatedParams = schema.setModelRequestSchema.parse(params);
|
||||
return agent.setModel(validatedParams);
|
||||
}
|
||||
case schema.AGENT_METHODS.session_set_config_option: {
|
||||
if (!agent.setConfigOption) {
|
||||
throw RequestError.methodNotFound();
|
||||
}
|
||||
const validatedParams =
|
||||
schema.setConfigOptionRequestSchema.parse(params);
|
||||
return agent.setConfigOption(validatedParams);
|
||||
}
|
||||
default:
|
||||
throw RequestError.methodNotFound(method);
|
||||
}
|
||||
|
|
@ -489,4 +497,7 @@ export interface Agent {
|
|||
cancel(params: schema.CancelNotification): Promise<void>;
|
||||
setMode?(params: schema.SetModeRequest): Promise<schema.SetModeResponse>;
|
||||
setModel?(params: schema.SetModelRequest): Promise<schema.SetModelResponse>;
|
||||
setConfigOption?(
|
||||
params: schema.SetConfigOptionRequest,
|
||||
): Promise<schema.SetConfigOptionResponse>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import {
|
|||
type ConversationRecord,
|
||||
type DeviceAuthorizationData,
|
||||
} from '@qwen-code/qwen-code-core';
|
||||
import type { ApprovalModeValue } from './schema.js';
|
||||
import type { ApprovalModeValue, ConfigOption } from './schema.js';
|
||||
import * as acp from './acp.js';
|
||||
import { buildAuthMethods } from './authMethods.js';
|
||||
import { AcpFileSystemService } from './service/filesystem.js';
|
||||
|
|
@ -295,6 +295,104 @@ class GeminiAgent {
|
|||
return await session.setModel(params);
|
||||
}
|
||||
|
||||
async setConfigOption(
|
||||
params: acp.SetConfigOptionRequest,
|
||||
): Promise<acp.SetConfigOptionResponse> {
|
||||
const { sessionId, configId, value } = params;
|
||||
|
||||
// Get the session's config
|
||||
const session = this.sessions.get(sessionId);
|
||||
if (!session) {
|
||||
throw acp.RequestError.invalidParams(
|
||||
`Session not found for id: ${sessionId}`,
|
||||
);
|
||||
}
|
||||
|
||||
switch (configId) {
|
||||
case 'mode': {
|
||||
await this.setMode({
|
||||
sessionId,
|
||||
modeId: value as ApprovalModeValue,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'model': {
|
||||
await this.setModel({
|
||||
sessionId,
|
||||
modelId: value as string,
|
||||
});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw acp.RequestError.invalidParams(
|
||||
`Unsupported configId: ${configId}`,
|
||||
);
|
||||
}
|
||||
|
||||
// Return all config options with current values
|
||||
return {
|
||||
configOptions: this.buildConfigOptions(session.getConfig()),
|
||||
};
|
||||
}
|
||||
|
||||
private buildConfigOptions(config: Config): ConfigOption[] {
|
||||
const currentApprovalMode = config.getApprovalMode();
|
||||
const allConfiguredModels = config.getAllConfiguredModels();
|
||||
const rawCurrentModelId = (config.getModel() || '').trim();
|
||||
const currentAuthType = config.getAuthType?.();
|
||||
|
||||
// Check if current model is a runtime model
|
||||
const activeRuntimeSnapshot = config.getActiveRuntimeModelSnapshot?.();
|
||||
const currentModelId = activeRuntimeSnapshot
|
||||
? formatAcpModelId(
|
||||
activeRuntimeSnapshot.id,
|
||||
activeRuntimeSnapshot.authType,
|
||||
)
|
||||
: this.formatCurrentModelId(rawCurrentModelId, currentAuthType);
|
||||
|
||||
// Build mode config option
|
||||
const modeOptions = APPROVAL_MODES.map((mode) => ({
|
||||
value: mode,
|
||||
name: APPROVAL_MODE_INFO[mode].name,
|
||||
description: APPROVAL_MODE_INFO[mode].description,
|
||||
}));
|
||||
|
||||
const modeConfigOption: ConfigOption = {
|
||||
id: 'mode',
|
||||
name: 'Mode',
|
||||
description: 'Session permission mode',
|
||||
category: 'mode',
|
||||
type: 'select',
|
||||
currentValue: currentApprovalMode,
|
||||
options: modeOptions,
|
||||
};
|
||||
|
||||
// Build model config option
|
||||
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 ?? '',
|
||||
};
|
||||
});
|
||||
|
||||
const modelConfigOption: ConfigOption = {
|
||||
id: 'model',
|
||||
name: 'Model',
|
||||
description: 'AI model to use',
|
||||
category: 'model',
|
||||
type: 'select',
|
||||
currentValue: currentModelId,
|
||||
options: modelOptions,
|
||||
};
|
||||
|
||||
return [modeConfigOption, modelConfigOption];
|
||||
}
|
||||
|
||||
private async ensureAuthenticated(config: Config): Promise<void> {
|
||||
const selectedType = config.getModelsConfig().getCurrentAuthType();
|
||||
if (!selectedType) {
|
||||
|
|
@ -478,55 +576,6 @@ class GeminiAgent {
|
|||
};
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ export const AGENT_METHODS = {
|
|||
session_list: 'session/list',
|
||||
session_set_mode: 'session/set_mode',
|
||||
session_set_model: 'session/set_model',
|
||||
session_set_config_option: 'session/set_config_option',
|
||||
};
|
||||
|
||||
export const CLIENT_METHODS = {
|
||||
|
|
@ -475,6 +476,23 @@ export const configOptionSchema = z.object({
|
|||
|
||||
export type ConfigOption = z.infer<typeof configOptionSchema>;
|
||||
|
||||
export const setConfigOptionRequestSchema = z.object({
|
||||
sessionId: z.string(),
|
||||
configId: z.string(),
|
||||
value: z.unknown(),
|
||||
});
|
||||
|
||||
export const setConfigOptionResponseSchema = z.object({
|
||||
configOptions: z.array(configOptionSchema),
|
||||
});
|
||||
|
||||
export type SetConfigOptionRequest = z.infer<
|
||||
typeof setConfigOptionRequestSchema
|
||||
>;
|
||||
export type SetConfigOptionResponse = z.infer<
|
||||
typeof setConfigOptionResponseSchema
|
||||
>;
|
||||
|
||||
// newSessionResponseSchema includes modes and configOptions for ACP/Zed integration
|
||||
export const newSessionResponseSchema = z.object({
|
||||
sessionId: z.string(),
|
||||
|
|
@ -684,6 +702,7 @@ export const agentRequestSchema = z.union([
|
|||
listSessionsRequestSchema,
|
||||
setModeRequestSchema,
|
||||
setModelRequestSchema,
|
||||
setConfigOptionRequestSchema,
|
||||
]);
|
||||
|
||||
export const agentNotificationSchema = sessionNotificationSchema;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue