fix(cli): resolve environment loading and auth validation issues in ACP mode (#18025)

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
Bryan Morgan
2026-02-03 00:54:10 -05:00
committed by GitHub
parent 1b274b081d
commit e7bfd2bf83
12 changed files with 477 additions and 40 deletions

View File

@@ -40,7 +40,7 @@ import { AcpFileSystemService } from './fileSystemService.js';
import { Readable, Writable } from 'node:stream';
import type { Content, Part, FunctionCall } from '@google/genai';
import type { LoadedSettings } from '../config/settings.js';
import { SettingScope } from '../config/settings.js';
import { SettingScope, loadSettings } from '../config/settings.js';
import * as fs from 'node:fs/promises';
import * as path from 'node:path';
import { z } from 'zod';
@@ -139,7 +139,11 @@ export class GeminiAgent {
// Refresh auth with the requested method
// This will reuse existing credentials if they're valid,
// or perform new authentication if needed
await this.config.refreshAuth(method);
try {
await this.config.refreshAuth(method);
} catch (e) {
throw new acp.RequestError(getErrorStatus(e) || 401, getErrorMessage(e));
}
this.settings.setValue(
SettingScope.User,
'security.auth.selectedType',
@@ -152,12 +156,47 @@ export class GeminiAgent {
mcpServers,
}: acp.NewSessionRequest): Promise<acp.NewSessionResponse> {
const sessionId = randomUUID();
const config = await this.initializeSessionConfig(
const loadedSettings = loadSettings(cwd);
const config = await this.newSessionConfig(
sessionId,
cwd,
mcpServers,
loadedSettings,
);
const authType =
loadedSettings.merged.security.auth.selectedType || AuthType.USE_GEMINI;
let isAuthenticated = false;
let authErrorMessage = '';
try {
await config.refreshAuth(authType);
isAuthenticated = true;
// Extra validation for Gemini API key
const contentGeneratorConfig = config.getContentGeneratorConfig();
if (
authType === AuthType.USE_GEMINI &&
(!contentGeneratorConfig || !contentGeneratorConfig.apiKey)
) {
isAuthenticated = false;
authErrorMessage = 'Gemini API key is missing or not configured.';
}
} catch (e) {
isAuthenticated = false;
authErrorMessage = getErrorMessage(e);
debugLogger.error(
`Authentication failed: ${e instanceof Error ? e.stack : e}`,
);
}
if (!isAuthenticated) {
throw new acp.RequestError(
401,
authErrorMessage || 'Authentication required.',
);
}
if (this.clientCapabilities?.fs) {
const acpFileSystemService = new AcpFileSystemService(
this.connection,
@@ -168,6 +207,9 @@ export class GeminiAgent {
config.setFileSystemService(acpFileSystemService);
}
await config.initialize();
startupProfiler.flush(config);
const geminiClient = config.getGeminiClient();
const chat = await geminiClient.startChat();
const session = new Session(sessionId, chat, config, this.connection);
@@ -264,8 +306,10 @@ export class GeminiAgent {
sessionId: string,
cwd: string,
mcpServers: acp.McpServer[],
loadedSettings?: LoadedSettings,
): Promise<Config> {
const mergedMcpServers = { ...this.settings.merged.mcpServers };
const currentSettings = loadedSettings || this.settings;
const mergedMcpServers = { ...currentSettings.merged.mcpServers };
for (const server of mcpServers) {
if (
@@ -300,7 +344,10 @@ export class GeminiAgent {
}
}
const settings = { ...this.settings.merged, mcpServers: mergedMcpServers };
const settings = {
...currentSettings.merged,
mcpServers: mergedMcpServers,
};
const config = await loadCliConfig(settings, sessionId, this.argv, { cwd });
@@ -497,7 +544,10 @@ export class Session {
return { stopReason: 'cancelled' };
}
throw error;
throw new acp.RequestError(
getErrorStatus(error) || 500,
getErrorMessage(error),
);
}
if (functionCalls.length > 0) {