feat(acp): add set models interface (#20991)

This commit is contained in:
Shreya Keshive
2026-03-03 17:29:42 -05:00
committed by GitHub
parent c70c95ead3
commit 34f0c1538b
3 changed files with 221 additions and 2 deletions
@@ -37,6 +37,16 @@ import {
ApprovalMode,
getVersion,
convertSessionToClientHistory,
DEFAULT_GEMINI_MODEL,
DEFAULT_GEMINI_FLASH_MODEL,
DEFAULT_GEMINI_FLASH_LITE_MODEL,
PREVIEW_GEMINI_MODEL,
PREVIEW_GEMINI_3_1_MODEL,
PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL,
PREVIEW_GEMINI_FLASH_MODEL,
DEFAULT_GEMINI_MODEL_AUTO,
PREVIEW_GEMINI_MODEL_AUTO,
getDisplayString,
} from '@google/gemini-cli-core';
import * as acp from '@agentclientprotocol/sdk';
import { AcpFileSystemService } from './fileSystemService.js';
@@ -255,13 +265,23 @@ export class GeminiAgent {
session.sendAvailableCommands();
}, 0);
return {
const { availableModels, currentModelId } = buildAvailableModels(
config,
loadedSettings,
);
const response = {
sessionId,
modes: {
availableModes: buildAvailableModes(config.isPlanEnabled()),
currentModeId: config.getApprovalMode(),
},
models: {
availableModels,
currentModelId,
},
};
return response;
}
async loadSession({
@@ -316,12 +336,22 @@ export class GeminiAgent {
session.sendAvailableCommands();
}, 0);
return {
const { availableModels, currentModelId } = buildAvailableModels(
config,
this.settings,
);
const response = {
modes: {
availableModes: buildAvailableModes(config.isPlanEnabled()),
currentModeId: config.getApprovalMode(),
},
models: {
availableModels,
currentModelId,
},
};
return response;
}
private async initializeSessionConfig(
@@ -432,6 +462,16 @@ export class GeminiAgent {
}
return session.setMode(params.modeId);
}
async unstable_setSessionModel(
params: acp.SetSessionModelRequest,
): Promise<acp.SetSessionModelResponse> {
const session = this.sessions.get(params.sessionId);
if (!session) {
throw new Error(`Session not found: ${params.sessionId}`);
}
return session.setModel(params.modelId);
}
}
export class Session {
@@ -482,6 +522,11 @@ export class Session {
});
}
setModel(modelId: acp.ModelId): acp.SetSessionModelResponse {
this.config.setModel(modelId);
return {};
}
async streamHistory(messages: ConversationRecord['messages']): Promise<void> {
for (const msg of messages) {
const contentString = partListUnionToString(msg.content);
@@ -1467,3 +1512,94 @@ function buildAvailableModes(isPlanEnabled: boolean): acp.SessionMode[] {
return modes;
}
function buildAvailableModels(
config: Config,
settings: LoadedSettings,
): {
availableModels: Array<{
modelId: string;
name: string;
description?: string;
}>;
currentModelId: string;
} {
const preferredModel = config.getModel() || DEFAULT_GEMINI_MODEL_AUTO;
const shouldShowPreviewModels = config.getHasAccessToPreviewModel();
const useGemini31 = config.getGemini31LaunchedSync?.() ?? false;
const selectedAuthType = settings.merged.security.auth.selectedType;
const useCustomToolModel =
useGemini31 && selectedAuthType === AuthType.USE_GEMINI;
const mainOptions = [
{
value: DEFAULT_GEMINI_MODEL_AUTO,
title: getDisplayString(DEFAULT_GEMINI_MODEL_AUTO),
description:
'Let Gemini CLI decide the best model for the task: gemini-2.5-pro, gemini-2.5-flash',
},
];
if (shouldShowPreviewModels) {
mainOptions.unshift({
value: PREVIEW_GEMINI_MODEL_AUTO,
title: getDisplayString(PREVIEW_GEMINI_MODEL_AUTO),
description: useGemini31
? 'Let Gemini CLI decide the best model for the task: gemini-3.1-pro, gemini-3-flash'
: 'Let Gemini CLI decide the best model for the task: gemini-3-pro, gemini-3-flash',
});
}
const manualOptions = [
{
value: DEFAULT_GEMINI_MODEL,
title: getDisplayString(DEFAULT_GEMINI_MODEL),
},
{
value: DEFAULT_GEMINI_FLASH_MODEL,
title: getDisplayString(DEFAULT_GEMINI_FLASH_MODEL),
},
{
value: DEFAULT_GEMINI_FLASH_LITE_MODEL,
title: getDisplayString(DEFAULT_GEMINI_FLASH_LITE_MODEL),
},
];
if (shouldShowPreviewModels) {
const previewProModel = useGemini31
? PREVIEW_GEMINI_3_1_MODEL
: PREVIEW_GEMINI_MODEL;
const previewProValue = useCustomToolModel
? PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL
: previewProModel;
manualOptions.unshift(
{
value: previewProValue,
title: getDisplayString(previewProModel),
},
{
value: PREVIEW_GEMINI_FLASH_MODEL,
title: getDisplayString(PREVIEW_GEMINI_FLASH_MODEL),
},
);
}
const scaleOptions = (
options: Array<{ value: string; title: string; description?: string }>,
) =>
options.map((o) => ({
modelId: o.value,
name: o.title,
description: o.description,
}));
return {
availableModels: [
...scaleOptions(mainOptions),
...scaleOptions(manualOptions),
],
currentModelId: preferredModel,
};
}