@google/gemini-cli 0.41.0-preview.1 → 0.42.0-nightly.20260501.gcaa046641
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/{chunk-36LZQV4W.js → chunk-2HOG45IA.js} +1047 -1240
- package/bundle/{chunk-NGB7ZVQL.js → chunk-2WK6K7H4.js} +67 -507
- package/bundle/{chunk-DOHALVIP.js → chunk-3Y7ZPPS2.js} +1047 -1240
- package/bundle/chunk-4SBF4FWA.js +512 -0
- package/bundle/{chunk-XRLFHCHC.js → chunk-533APETE.js} +30 -12
- package/bundle/{chunk-T5I4M6M4.js → chunk-747IFMEA.js} +3 -3
- package/bundle/chunk-CTSXRP2T.js +512 -0
- package/bundle/{chunk-DCHOW6BK.js → chunk-CVJABGPV.js} +2 -2
- package/bundle/{chunk-VWYB6GSK.js → chunk-DDX3KSOF.js} +67 -507
- package/bundle/{chunk-DAEE6Y5T.js → chunk-EGV36KAI.js} +1047 -1240
- package/bundle/chunk-ESRGVL52.js +512 -0
- package/bundle/{chunk-SAJ72M2G.js → chunk-FABHOVMY.js} +23 -7
- package/bundle/chunk-FNLKMX3W.js +391 -0
- package/bundle/chunk-FTIY7CSS.js +391 -0
- package/bundle/{chunk-C5CRFFTY.js → chunk-GXIITUGM.js} +1 -1
- package/bundle/{chunk-45OGXTFK.js → chunk-HIYYW6PF.js} +3 -3
- package/bundle/chunk-IDYSRNE5.js +511 -0
- package/bundle/{chunk-QRSHDIRX.js → chunk-IJA7QQHF.js} +1 -1
- package/bundle/{chunk-U6WUS35U.js → chunk-ILECTCCH.js} +2 -2
- package/bundle/{chunk-R4LSW45D.js → chunk-J44J2AAV.js} +1 -1
- package/bundle/{chunk-KCDF3RDO.js → chunk-JPGLBVDA.js} +3 -3
- package/bundle/{chunk-VJ6K3S57.js → chunk-K5CA5JX2.js} +2 -2
- package/bundle/{chunk-6NFVEILC.js → chunk-L6URBAMF.js} +262 -81
- package/bundle/{chunk-5Z2T77EB.js → chunk-NNAHWZGK.js} +66 -507
- package/bundle/{chunk-KJ4M7JXR.js → chunk-SFDJ7FIE.js} +2 -2
- package/bundle/{chunk-QY23ZEK3.js → chunk-SYZNFSS3.js} +262 -81
- package/bundle/chunk-TBIPLAJP.js +391 -0
- package/bundle/{chunk-FFVUMIL3.js → chunk-TMQACI5N.js} +1047 -1240
- package/bundle/{chunk-XO6NKGWV.js → chunk-UCTXAZT6.js} +262 -81
- package/bundle/{chunk-VLSVN2FJ.js → chunk-USFRINC4.js} +1 -1
- package/bundle/chunk-VJOUKBFO.js +391 -0
- package/bundle/{chunk-EQSLZT5Z.js → chunk-VUMF52YD.js} +271 -81
- package/bundle/{chunk-5QI3ZXQB.js → chunk-WGWUS5AF.js} +67 -507
- package/bundle/{chunk-TBBDQEFQ.js → chunk-WTLXL6OZ.js} +3 -3
- package/bundle/{cleanup-3COTQVPP.js → cleanup-GQXJGC2H.js} +3 -3
- package/bundle/{cleanup-FIE6MCAE.js → cleanup-OSSEOJVY.js} +3 -3
- package/bundle/{cleanup-PREOBLFK.js → cleanup-TDBASRR5.js} +3 -3
- package/bundle/{cleanup-YY2EUT56.js → cleanup-XLWNSNLT.js} +3 -3
- package/bundle/{core-GZOFEER4.js → core-JH4LXS4F.js} +8 -2
- package/bundle/{devtoolsService-QXOHXSMJ.js → devtoolsService-DFWZ34A5.js} +3 -3
- package/bundle/{devtoolsService-DV36S632.js → devtoolsService-KZLK5WRW.js} +3 -3
- package/bundle/{devtoolsService-JPBL5I7F.js → devtoolsService-XIWMIEMB.js} +3 -3
- package/bundle/{devtoolsService-M4LZEBZD.js → devtoolsService-ZV5MJUBY.js} +3 -3
- package/bundle/{dist-HASTHPE3.js → dist-ATBEVH4R.js} +8 -2
- package/bundle/{dist-JVRDP7SO.js → dist-BOCIGIGG.js} +8 -2
- package/bundle/{dist-NSJ6AA4L.js → dist-TDGPCKNF.js} +8 -2
- package/bundle/docs/changelogs/index.md +18 -0
- package/bundle/docs/changelogs/latest.md +167 -242
- package/bundle/docs/changelogs/preview.md +99 -385
- package/bundle/docs/cli/cli-reference.md +1 -0
- package/bundle/docs/cli/creating-skills.md +165 -38
- package/bundle/docs/cli/custom-commands.md +1 -0
- package/bundle/docs/cli/model-routing.md +3 -3
- package/bundle/docs/cli/plan-mode.md +2 -1
- package/bundle/docs/cli/skills-best-practices.md +78 -0
- package/bundle/docs/cli/skills.md +98 -93
- package/bundle/docs/cli/tutorials/session-management.md +13 -0
- package/bundle/docs/cli/tutorials/skills-getting-started.md +140 -92
- package/bundle/docs/cli/using-agent-skills.md +89 -0
- package/bundle/docs/core/gemma-setup.md +83 -0
- package/bundle/docs/core/index.md +3 -2
- package/bundle/docs/core/local-model-routing.md +14 -7
- package/bundle/docs/reference/commands.md +14 -4
- package/bundle/docs/reference/configuration.md +76 -4
- package/bundle/docs/reference/keyboard-shortcuts.md +1 -1
- package/bundle/docs/reference/policy-engine.md +14 -3
- package/bundle/docs/sidebar.json +24 -2
- package/bundle/docs/tools/activate-skill.md +1 -1
- package/bundle/{gemini-IGRTXHCM.js → gemini-ETBA6M7V.js} +1067 -850
- package/bundle/{gemini-KIM7O55W.js → gemini-FUGMMZB7.js} +1067 -850
- package/bundle/{gemini-SFFHSCEY.js → gemini-QDNEMFTK.js} +1067 -850
- package/bundle/{gemini-FTUVOUHP.js → gemini-TZ26TZKD.js} +1067 -848
- package/bundle/gemini.js +20 -13
- package/bundle/{interactiveCli-LTPR447O.js → interactiveCli-74QXEIGP.js} +682 -609
- package/bundle/{interactiveCli-K4FIT7TA.js → interactiveCli-IBVICRF7.js} +682 -609
- package/bundle/{interactiveCli-7HPLINVC.js → interactiveCli-OKS4NPC7.js} +682 -609
- package/bundle/{interactiveCli-JOX7MFFH.js → interactiveCli-ZS4ZQWNV.js} +682 -609
- package/bundle/{liteRtServerManager-BENLLSF2.js → liteRtServerManager-I5CSGWRL.js} +5 -4
- package/bundle/{liteRtServerManager-KDO6UAQ5.js → liteRtServerManager-IDNLXYHP.js} +5 -4
- package/bundle/{liteRtServerManager-MQIQXXZQ.js → liteRtServerManager-J33F7APP.js} +5 -4
- package/bundle/{liteRtServerManager-VGYEHFUE.js → liteRtServerManager-RJF74BUI.js} +5 -4
- package/bundle/{memoryDiscovery-FN3IAPBT.js → memoryDiscovery-LIJKMASE.js} +1 -1
- package/bundle/{memoryDiscovery-R7PAR2NY.js → memoryDiscovery-WVH7QDNJ.js} +1 -1
- package/bundle/node_modules/@google/gemini-cli-devtools/package.json +1 -1
- package/bundle/{oauth2-provider-JPCBTTS2.js → oauth2-provider-7UM3XCQ4.js} +2 -2
- package/bundle/{oauth2-provider-EWMNT6D6.js → oauth2-provider-BFW5HE2U.js} +2 -2
- package/bundle/{oauth2-provider-M3WV4GJM.js → oauth2-provider-LONBXYVY.js} +2 -2
- package/bundle/{oauth2-provider-UVXCM7G3.js → oauth2-provider-N65VILW5.js} +2 -2
- package/bundle/{start-4MSISK2E.js → start-3B4FNGNM.js} +7 -6
- package/bundle/{start-ATOE57Z4.js → start-3OM5OXD2.js} +7 -6
- package/bundle/{start-AVEON6UU.js → start-N3S3BSEF.js} +7 -6
- package/bundle/{start-KBB2UTE5.js → start-PLPHF43U.js} +7 -6
- package/package.json +1 -1
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
INSTALL_WARNING_MESSAGE,
|
|
10
10
|
McpPromptLoader,
|
|
11
11
|
McpServerEnablementManager,
|
|
12
|
-
RELAUNCH_EXIT_CODE,
|
|
13
12
|
canLoadServer,
|
|
14
13
|
checkForAllExtensionUpdates,
|
|
15
14
|
checkForExtensionUpdate,
|
|
@@ -42,18 +41,18 @@ import {
|
|
|
42
41
|
updateAllUpdatableExtensions,
|
|
43
42
|
updateExtension,
|
|
44
43
|
validateAuthMethod
|
|
45
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-EGV36KAI.js";
|
|
46
45
|
import {
|
|
47
46
|
appEvents
|
|
48
47
|
} from "./chunk-5PS3AYFU.js";
|
|
49
48
|
import {
|
|
50
49
|
startCommand,
|
|
51
50
|
startServer
|
|
52
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-HIYYW6PF.js";
|
|
53
52
|
import {
|
|
54
53
|
exitCli,
|
|
55
54
|
require_source
|
|
56
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-J44J2AAV.js";
|
|
57
56
|
import {
|
|
58
57
|
DEFAULT_PORT,
|
|
59
58
|
GEMMA_MODEL_NAME,
|
|
@@ -87,7 +86,11 @@ import {
|
|
|
87
86
|
readServerProcessInfo,
|
|
88
87
|
resolveGemmaConfig,
|
|
89
88
|
saveModelChange
|
|
90
|
-
} from "./chunk-
|
|
89
|
+
} from "./chunk-2WK6K7H4.js";
|
|
90
|
+
import {
|
|
91
|
+
RELAUNCH_EXIT_CODE
|
|
92
|
+
} from "./chunk-FTIY7CSS.js";
|
|
93
|
+
import "./chunk-ESRGVL52.js";
|
|
91
94
|
import {
|
|
92
95
|
cleanupCheckpoints,
|
|
93
96
|
registerCleanup,
|
|
@@ -96,7 +99,7 @@ import {
|
|
|
96
99
|
runExitCleanup,
|
|
97
100
|
runSyncCleanup,
|
|
98
101
|
setupSignalHandlers
|
|
99
|
-
} from "./chunk-
|
|
102
|
+
} from "./chunk-K5CA5JX2.js";
|
|
100
103
|
import {
|
|
101
104
|
AuthType,
|
|
102
105
|
ChatRecordingService,
|
|
@@ -113,7 +116,6 @@ import {
|
|
|
113
116
|
JsonFormatter,
|
|
114
117
|
JsonStreamEventType,
|
|
115
118
|
LegacyAgentSession,
|
|
116
|
-
LlmRole,
|
|
117
119
|
Logger,
|
|
118
120
|
MCPServerConfig,
|
|
119
121
|
MCPServerStatus,
|
|
@@ -125,7 +127,7 @@ import {
|
|
|
125
127
|
SessionEndReason,
|
|
126
128
|
SessionStartSource,
|
|
127
129
|
ShellExecutionService,
|
|
128
|
-
|
|
130
|
+
SimpleExtensionLoader,
|
|
129
131
|
StreamJsonFormatter,
|
|
130
132
|
ToolCallEvent,
|
|
131
133
|
TrustLevel,
|
|
@@ -167,6 +169,7 @@ import {
|
|
|
167
169
|
getVersion,
|
|
168
170
|
isGeminiWorktree,
|
|
169
171
|
isHeadlessMode,
|
|
172
|
+
isTextPart,
|
|
170
173
|
isWithinRoot,
|
|
171
174
|
listExtensions,
|
|
172
175
|
listInboxPatches,
|
|
@@ -195,7 +198,7 @@ import {
|
|
|
195
198
|
updatePolicy,
|
|
196
199
|
writeToStderr,
|
|
197
200
|
writeToStdout
|
|
198
|
-
} from "./chunk-
|
|
201
|
+
} from "./chunk-SYZNFSS3.js";
|
|
199
202
|
import {
|
|
200
203
|
ASK_USER_TOOL_NAME,
|
|
201
204
|
ApprovalMode,
|
|
@@ -243,7 +246,7 @@ import {
|
|
|
243
246
|
loadServerHierarchicalMemory,
|
|
244
247
|
resolveToRealPath,
|
|
245
248
|
setGeminiMdFilename
|
|
246
|
-
} from "./chunk-
|
|
249
|
+
} from "./chunk-FABHOVMY.js";
|
|
247
250
|
import "./chunk-664ZODQF.js";
|
|
248
251
|
import "./chunk-RJTRUG2J.js";
|
|
249
252
|
import "./chunk-IUUIT4SU.js";
|
|
@@ -7822,7 +7825,7 @@ async function loadSandboxConfig(settings, argv) {
|
|
|
7822
7825
|
}
|
|
7823
7826
|
const command2 = getSandboxCommand(sandboxValue);
|
|
7824
7827
|
const packageJson = await getPackageJson(__dirname3);
|
|
7825
|
-
const image = process.env["GEMINI_SANDBOX_IMAGE"] ?? "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.
|
|
7828
|
+
const image = process.env["GEMINI_SANDBOX_IMAGE"] ?? "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.42.0-nightly.20260428.g59b2dea0e" ?? customImage ?? packageJson?.config?.sandboxImageUri;
|
|
7826
7829
|
const isNative = command2 === "windows-native" || command2 === "sandbox-exec" || command2 === "lxc";
|
|
7827
7830
|
return command2 && (image || isNative) ? { enabled: true, allowedPaths, networkAccess, command: command2, image } : void 0;
|
|
7828
7831
|
}
|
|
@@ -8224,7 +8227,7 @@ function isDebugMode(argv) {
|
|
|
8224
8227
|
);
|
|
8225
8228
|
}
|
|
8226
8229
|
async function loadCliConfig(settings, sessionId, argv, options = {}) {
|
|
8227
|
-
const { cwd = process3.cwd(), projectHooks } = options;
|
|
8230
|
+
const { cwd = process3.cwd(), projectHooks, skipExtensions = false } = options;
|
|
8228
8231
|
const debugMode = isDebugMode(argv);
|
|
8229
8232
|
const worktreeSettings = options.worktreeSettings ?? await resolveWorktreeSettings(cwd);
|
|
8230
8233
|
if (argv.sandbox) {
|
|
@@ -8270,18 +8273,21 @@ async function loadCliConfig(settings, sessionId, argv, options = {}) {
|
|
|
8270
8273
|
});
|
|
8271
8274
|
includeDirectories.push(...ideFolders);
|
|
8272
8275
|
}
|
|
8273
|
-
|
|
8274
|
-
|
|
8275
|
-
|
|
8276
|
-
|
|
8277
|
-
|
|
8278
|
-
|
|
8279
|
-
|
|
8280
|
-
|
|
8281
|
-
|
|
8282
|
-
|
|
8283
|
-
|
|
8284
|
-
|
|
8276
|
+
let extensionManager;
|
|
8277
|
+
if (!skipExtensions) {
|
|
8278
|
+
extensionManager = new ExtensionManager({
|
|
8279
|
+
settings,
|
|
8280
|
+
requestConsent: requestConsentNonInteractive,
|
|
8281
|
+
requestSetting: promptForSetting,
|
|
8282
|
+
workspaceDir: cwd,
|
|
8283
|
+
enabledExtensionOverrides: argv.extensions,
|
|
8284
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
8285
|
+
eventEmitter: coreEvents,
|
|
8286
|
+
clientVersion: await getVersion()
|
|
8287
|
+
});
|
|
8288
|
+
await extensionManager.loadExtensions();
|
|
8289
|
+
}
|
|
8290
|
+
const extensionPlanSettings = extensionManager?.getExtensions()?.find((ext) => ext.isActive && ext.plan?.directory)?.plan;
|
|
8285
8291
|
const experimentalJitContext = settings.experimental.jitContext ?? true;
|
|
8286
8292
|
let extensionRegistryURI = process3.env["GEMINI_CLI_EXTENSION_REGISTRY_URI"] ?? (trustedFolder ? settings.experimental?.extensionRegistryURI : void 0);
|
|
8287
8293
|
if (extensionRegistryURI && !extensionRegistryURI.startsWith("http")) {
|
|
@@ -8292,12 +8298,13 @@ async function loadCliConfig(settings, sessionId, argv, options = {}) {
|
|
|
8292
8298
|
let memoryContent = "";
|
|
8293
8299
|
let fileCount = 0;
|
|
8294
8300
|
let filePaths = [];
|
|
8301
|
+
const finalExtensionLoader = extensionManager ?? new SimpleExtensionLoader([]);
|
|
8295
8302
|
if (!experimentalJitContext) {
|
|
8296
8303
|
const result = await loadServerHierarchicalMemory(
|
|
8297
8304
|
cwd,
|
|
8298
8305
|
settings.context?.loadMemoryFromIncludeDirectories || false ? includeDirectories : [],
|
|
8299
8306
|
fileService,
|
|
8300
|
-
|
|
8307
|
+
finalExtensionLoader,
|
|
8301
8308
|
trustedFolder,
|
|
8302
8309
|
memoryImportFormat,
|
|
8303
8310
|
memoryFileFiltering,
|
|
@@ -8481,7 +8488,13 @@ async function loadCliConfig(settings, sessionId, argv, options = {}) {
|
|
|
8481
8488
|
const ide = detectIdeFromEnv();
|
|
8482
8489
|
if (ide && (ide.name !== "vscode" || process3.env["TERM_PROGRAM"] === "vscode")) {
|
|
8483
8490
|
clientName = `acp-${ide.name}`;
|
|
8491
|
+
} else {
|
|
8492
|
+
clientName = "acp";
|
|
8484
8493
|
}
|
|
8494
|
+
} else if (argv.isCommand) {
|
|
8495
|
+
clientName = "cli-command";
|
|
8496
|
+
} else {
|
|
8497
|
+
clientName = "tui";
|
|
8485
8498
|
}
|
|
8486
8499
|
let profileSelector = void 0;
|
|
8487
8500
|
if (settings.experimental?.stressTestProfile) {
|
|
@@ -8555,7 +8568,7 @@ async function loadCliConfig(settings, sessionId, argv, options = {}) {
|
|
|
8555
8568
|
listSessions: argv.listSessions || false,
|
|
8556
8569
|
deleteSession: argv.deleteSession,
|
|
8557
8570
|
enabledExtensions: argv.extensions,
|
|
8558
|
-
extensionLoader:
|
|
8571
|
+
extensionLoader: finalExtensionLoader,
|
|
8559
8572
|
extensionRegistryURI,
|
|
8560
8573
|
enableExtensionReloading: settings.experimental?.extensionReloading,
|
|
8561
8574
|
enableAgents: settings.experimental?.enableAgents,
|
|
@@ -8676,6 +8689,15 @@ async function resolveWorktreeSettings(cwd) {
|
|
|
8676
8689
|
}
|
|
8677
8690
|
|
|
8678
8691
|
// packages/cli/src/utils/readStdin.ts
|
|
8692
|
+
function truncateUtf8Bytes(str, maxBytes) {
|
|
8693
|
+
const buf = Buffer.from(str, "utf8");
|
|
8694
|
+
if (buf.length <= maxBytes) return str;
|
|
8695
|
+
let end = maxBytes;
|
|
8696
|
+
while (end > 0 && (buf[end] & 192) === 128) {
|
|
8697
|
+
end--;
|
|
8698
|
+
}
|
|
8699
|
+
return buf.subarray(0, end).toString("utf8");
|
|
8700
|
+
}
|
|
8679
8701
|
async function readStdin() {
|
|
8680
8702
|
const MAX_STDIN_SIZE = 8 * 1024 * 1024;
|
|
8681
8703
|
return new Promise((resolve9, reject) => {
|
|
@@ -8693,9 +8715,10 @@ async function readStdin() {
|
|
|
8693
8715
|
clearTimeout(pipedInputTimerId);
|
|
8694
8716
|
pipedInputTimerId = null;
|
|
8695
8717
|
}
|
|
8696
|
-
|
|
8697
|
-
|
|
8698
|
-
|
|
8718
|
+
const chunkByteLength = Buffer.byteLength(chunk, "utf8");
|
|
8719
|
+
if (totalSize + chunkByteLength > MAX_STDIN_SIZE) {
|
|
8720
|
+
const remainingBytes = MAX_STDIN_SIZE - totalSize;
|
|
8721
|
+
data += truncateUtf8Bytes(chunk, remainingBytes);
|
|
8699
8722
|
debugLogger.warn(
|
|
8700
8723
|
`Warning: stdin input truncated to ${MAX_STDIN_SIZE} bytes.`
|
|
8701
8724
|
);
|
|
@@ -8704,7 +8727,7 @@ async function readStdin() {
|
|
|
8704
8727
|
break;
|
|
8705
8728
|
}
|
|
8706
8729
|
data += chunk;
|
|
8707
|
-
totalSize +=
|
|
8730
|
+
totalSize += chunkByteLength;
|
|
8708
8731
|
}
|
|
8709
8732
|
};
|
|
8710
8733
|
const onEnd = () => {
|
|
@@ -10199,7 +10222,7 @@ async function runNonInteractive({
|
|
|
10199
10222
|
}
|
|
10200
10223
|
});
|
|
10201
10224
|
if (process.env["GEMINI_CLI_ACTIVITY_LOG_TARGET"]) {
|
|
10202
|
-
const { setupInitialActivityLogger } = await import("./devtoolsService-
|
|
10225
|
+
const { setupInitialActivityLogger } = await import("./devtoolsService-KZLK5WRW.js");
|
|
10203
10226
|
setupInitialActivityLogger(config);
|
|
10204
10227
|
}
|
|
10205
10228
|
const { stdout: workingStdout } = createWorkingStdio();
|
|
@@ -10386,7 +10409,13 @@ async function runNonInteractive({
|
|
|
10386
10409
|
const formatter = new JsonFormatter();
|
|
10387
10410
|
const stats = uiTelemetryService.getMetrics();
|
|
10388
10411
|
textOutput.write(
|
|
10389
|
-
formatter.format(
|
|
10412
|
+
formatter.format(
|
|
10413
|
+
config.getSessionId(),
|
|
10414
|
+
responseText,
|
|
10415
|
+
stats,
|
|
10416
|
+
void 0,
|
|
10417
|
+
warnings
|
|
10418
|
+
)
|
|
10390
10419
|
);
|
|
10391
10420
|
} else {
|
|
10392
10421
|
textOutput.ensureTrailingNewline();
|
|
@@ -10457,6 +10486,7 @@ async function runNonInteractive({
|
|
|
10457
10486
|
let responseText = "";
|
|
10458
10487
|
let preToolResponseText;
|
|
10459
10488
|
let streamEnded = false;
|
|
10489
|
+
const warnings = [];
|
|
10460
10490
|
for await (const event of session.stream({ streamId })) {
|
|
10461
10491
|
if (streamEnded) break;
|
|
10462
10492
|
switch (event.type) {
|
|
@@ -10555,10 +10585,19 @@ async function runNonInteractive({
|
|
|
10555
10585
|
}
|
|
10556
10586
|
const errorCode = event._meta?.["code"];
|
|
10557
10587
|
if (errorCode === "AGENT_EXECUTION_BLOCKED") {
|
|
10588
|
+
const blockMessage = `Agent execution blocked: ${event.message.trim()}`;
|
|
10558
10589
|
if (config.getOutputFormat() === OutputFormat.TEXT) {
|
|
10559
|
-
process.stderr.write(`[WARNING] ${
|
|
10590
|
+
process.stderr.write(`[WARNING] ${blockMessage}
|
|
10560
10591
|
`);
|
|
10592
|
+
} else if (streamFormatter) {
|
|
10593
|
+
streamFormatter.emitEvent({
|
|
10594
|
+
type: JsonStreamEventType.ERROR,
|
|
10595
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10596
|
+
severity: "warning",
|
|
10597
|
+
message: stripAnsi(blockMessage)
|
|
10598
|
+
});
|
|
10561
10599
|
}
|
|
10600
|
+
warnings.push(blockMessage);
|
|
10562
10601
|
break;
|
|
10563
10602
|
}
|
|
10564
10603
|
const severity = event.status === "RESOURCE_EXHAUSTED" ? "error" : "warning";
|
|
@@ -10571,9 +10610,10 @@ async function runNonInteractive({
|
|
|
10571
10610
|
type: JsonStreamEventType.ERROR,
|
|
10572
10611
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10573
10612
|
severity,
|
|
10574
|
-
message: event.message
|
|
10613
|
+
message: stripAnsi(event.message)
|
|
10575
10614
|
});
|
|
10576
10615
|
}
|
|
10616
|
+
warnings.push(event.message);
|
|
10577
10617
|
break;
|
|
10578
10618
|
}
|
|
10579
10619
|
case "agent_end": {
|
|
@@ -10650,7 +10690,7 @@ async function runNonInteractive2(params) {
|
|
|
10650
10690
|
}
|
|
10651
10691
|
});
|
|
10652
10692
|
if (process.env["GEMINI_CLI_ACTIVITY_LOG_TARGET"]) {
|
|
10653
|
-
const { setupInitialActivityLogger } = await import("./devtoolsService-
|
|
10693
|
+
const { setupInitialActivityLogger } = await import("./devtoolsService-KZLK5WRW.js");
|
|
10654
10694
|
setupInitialActivityLogger(config);
|
|
10655
10695
|
}
|
|
10656
10696
|
const { stdout: workingStdout } = createWorkingStdio();
|
|
@@ -10793,6 +10833,8 @@ async function runNonInteractive2(params) {
|
|
|
10793
10833
|
}
|
|
10794
10834
|
let currentMessages = [{ role: "user", parts: query }];
|
|
10795
10835
|
let turnCount = 0;
|
|
10836
|
+
let invalidStreamError;
|
|
10837
|
+
const warnings = [];
|
|
10796
10838
|
while (true) {
|
|
10797
10839
|
turnCount++;
|
|
10798
10840
|
if (config.getMaxSessionTurns() >= 0 && turnCount > config.getMaxSessionTurns()) {
|
|
@@ -10842,23 +10884,27 @@ async function runNonInteractive2(params) {
|
|
|
10842
10884
|
}
|
|
10843
10885
|
toolCallRequests.push(event.value);
|
|
10844
10886
|
} else if (event.type === GeminiEventType.LoopDetected) {
|
|
10887
|
+
const message = "Loop detected, stopping execution";
|
|
10845
10888
|
if (streamFormatter) {
|
|
10846
10889
|
streamFormatter.emitEvent({
|
|
10847
10890
|
type: JsonStreamEventType.ERROR,
|
|
10848
10891
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10849
10892
|
severity: "warning",
|
|
10850
|
-
message
|
|
10893
|
+
message
|
|
10851
10894
|
});
|
|
10852
10895
|
}
|
|
10896
|
+
warnings.push(message);
|
|
10853
10897
|
} else if (event.type === GeminiEventType.MaxSessionTurns) {
|
|
10898
|
+
const message = "Maximum session turns exceeded";
|
|
10854
10899
|
if (streamFormatter) {
|
|
10855
10900
|
streamFormatter.emitEvent({
|
|
10856
10901
|
type: JsonStreamEventType.ERROR,
|
|
10857
10902
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10858
10903
|
severity: "error",
|
|
10859
|
-
message
|
|
10904
|
+
message
|
|
10860
10905
|
});
|
|
10861
10906
|
}
|
|
10907
|
+
warnings.push(message);
|
|
10862
10908
|
} else if (event.type === GeminiEventType.Error) {
|
|
10863
10909
|
throw event.value.error;
|
|
10864
10910
|
} else if (event.type === GeminiEventType.AgentExecutionStopped) {
|
|
@@ -10885,8 +10931,31 @@ async function runNonInteractive2(params) {
|
|
|
10885
10931
|
const blockMessage = `Agent execution blocked: ${event.value.systemMessage?.trim() || event.value.reason}`;
|
|
10886
10932
|
if (config.getOutputFormat() === OutputFormat.TEXT) {
|
|
10887
10933
|
process.stderr.write(`[WARNING] ${blockMessage}
|
|
10934
|
+
`);
|
|
10935
|
+
} else if (streamFormatter) {
|
|
10936
|
+
streamFormatter.emitEvent({
|
|
10937
|
+
type: JsonStreamEventType.ERROR,
|
|
10938
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10939
|
+
severity: "warning",
|
|
10940
|
+
message: stripAnsi(blockMessage)
|
|
10941
|
+
});
|
|
10942
|
+
}
|
|
10943
|
+
warnings.push(blockMessage);
|
|
10944
|
+
} else if (event.type === GeminiEventType.InvalidStream) {
|
|
10945
|
+
invalidStreamError = "Invalid stream: The model returned an empty response or malformed tool call.";
|
|
10946
|
+
if (streamFormatter) {
|
|
10947
|
+
streamFormatter.emitEvent({
|
|
10948
|
+
type: JsonStreamEventType.ERROR,
|
|
10949
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10950
|
+
severity: "error",
|
|
10951
|
+
message: invalidStreamError
|
|
10952
|
+
});
|
|
10953
|
+
} else if (config.getOutputFormat() === OutputFormat.TEXT) {
|
|
10954
|
+
process.stderr.write(`[ERROR] ${invalidStreamError}
|
|
10888
10955
|
`);
|
|
10889
10956
|
}
|
|
10957
|
+
toolCallRequests.length = 0;
|
|
10958
|
+
break;
|
|
10890
10959
|
}
|
|
10891
10960
|
}
|
|
10892
10961
|
if (toolCallRequests.length > 0) {
|
|
@@ -10959,7 +11028,13 @@ async function runNonInteractive2(params) {
|
|
|
10959
11028
|
const formatter = new JsonFormatter();
|
|
10960
11029
|
const stats = uiTelemetryService.getMetrics();
|
|
10961
11030
|
textOutput.write(
|
|
10962
|
-
formatter.format(
|
|
11031
|
+
formatter.format(
|
|
11032
|
+
config.getSessionId(),
|
|
11033
|
+
responseText,
|
|
11034
|
+
stats,
|
|
11035
|
+
void 0,
|
|
11036
|
+
warnings
|
|
11037
|
+
)
|
|
10963
11038
|
);
|
|
10964
11039
|
} else {
|
|
10965
11040
|
textOutput.ensureTrailingNewline();
|
|
@@ -10974,14 +11049,20 @@ async function runNonInteractive2(params) {
|
|
|
10974
11049
|
streamFormatter.emitEvent({
|
|
10975
11050
|
type: JsonStreamEventType.RESULT,
|
|
10976
11051
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10977
|
-
status: "success",
|
|
11052
|
+
status: invalidStreamError ? "error" : "success",
|
|
10978
11053
|
stats: streamFormatter.convertToStreamStats(metrics, durationMs)
|
|
10979
11054
|
});
|
|
10980
11055
|
} else if (config.getOutputFormat() === OutputFormat.JSON) {
|
|
10981
11056
|
const formatter = new JsonFormatter();
|
|
10982
11057
|
const stats = uiTelemetryService.getMetrics();
|
|
10983
11058
|
textOutput.write(
|
|
10984
|
-
formatter.format(
|
|
11059
|
+
formatter.format(
|
|
11060
|
+
config.getSessionId(),
|
|
11061
|
+
responseText,
|
|
11062
|
+
stats,
|
|
11063
|
+
invalidStreamError ? { type: "INVALID_STREAM", message: invalidStreamError } : void 0,
|
|
11064
|
+
warnings
|
|
11065
|
+
)
|
|
10985
11066
|
);
|
|
10986
11067
|
} else {
|
|
10987
11068
|
textOutput.ensureTrailingNewline();
|
|
@@ -12540,59 +12621,8 @@ var RequestError = class _RequestError extends Error {
|
|
|
12540
12621
|
}
|
|
12541
12622
|
};
|
|
12542
12623
|
|
|
12543
|
-
// packages/cli/src/acp/
|
|
12544
|
-
import
|
|
12545
|
-
import path10 from "node:path";
|
|
12546
|
-
var AcpFileSystemService = class {
|
|
12547
|
-
constructor(connection, sessionId, capabilities, fallback, root) {
|
|
12548
|
-
this.connection = connection;
|
|
12549
|
-
this.sessionId = sessionId;
|
|
12550
|
-
this.capabilities = capabilities;
|
|
12551
|
-
this.fallback = fallback;
|
|
12552
|
-
this.root = root;
|
|
12553
|
-
}
|
|
12554
|
-
geminiDir = path10.join(os5.homedir(), ".gemini");
|
|
12555
|
-
shouldUseFallback(filePath) {
|
|
12556
|
-
return !isWithinRoot(filePath, this.root) || isWithinRoot(filePath, this.geminiDir);
|
|
12557
|
-
}
|
|
12558
|
-
normalizeFileSystemError(err) {
|
|
12559
|
-
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
12560
|
-
if (errorMessage.includes("Resource not found") || errorMessage.includes("ENOENT") || errorMessage.includes("does not exist") || errorMessage.includes("No such file")) {
|
|
12561
|
-
const newErr = new Error(errorMessage);
|
|
12562
|
-
newErr.code = "ENOENT";
|
|
12563
|
-
throw newErr;
|
|
12564
|
-
}
|
|
12565
|
-
throw err;
|
|
12566
|
-
}
|
|
12567
|
-
async readTextFile(filePath) {
|
|
12568
|
-
if (!this.capabilities.readTextFile || this.shouldUseFallback(filePath)) {
|
|
12569
|
-
return this.fallback.readTextFile(filePath);
|
|
12570
|
-
}
|
|
12571
|
-
try {
|
|
12572
|
-
const response = await this.connection.readTextFile({
|
|
12573
|
-
path: filePath,
|
|
12574
|
-
sessionId: this.sessionId
|
|
12575
|
-
});
|
|
12576
|
-
return response.content;
|
|
12577
|
-
} catch (err) {
|
|
12578
|
-
this.normalizeFileSystemError(err);
|
|
12579
|
-
}
|
|
12580
|
-
}
|
|
12581
|
-
async writeTextFile(filePath, content) {
|
|
12582
|
-
if (!this.capabilities.writeTextFile || this.shouldUseFallback(filePath)) {
|
|
12583
|
-
return this.fallback.writeTextFile(filePath, content);
|
|
12584
|
-
}
|
|
12585
|
-
try {
|
|
12586
|
-
await this.connection.writeTextFile({
|
|
12587
|
-
path: filePath,
|
|
12588
|
-
content,
|
|
12589
|
-
sessionId: this.sessionId
|
|
12590
|
-
});
|
|
12591
|
-
} catch (err) {
|
|
12592
|
-
this.normalizeFileSystemError(err);
|
|
12593
|
-
}
|
|
12594
|
-
}
|
|
12595
|
-
};
|
|
12624
|
+
// packages/cli/src/acp/acpStdioTransport.ts
|
|
12625
|
+
import { Readable, Writable } from "node:stream";
|
|
12596
12626
|
|
|
12597
12627
|
// packages/cli/src/acp/acpErrors.ts
|
|
12598
12628
|
function getAcpErrorMessage(error) {
|
|
@@ -12614,10 +12644,12 @@ function extractRecursiveMessage(input) {
|
|
|
12614
12644
|
return input;
|
|
12615
12645
|
}
|
|
12616
12646
|
|
|
12617
|
-
// packages/cli/src/acp/
|
|
12618
|
-
import {
|
|
12647
|
+
// packages/cli/src/acp/acpSessionManager.ts
|
|
12648
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
12649
|
+
|
|
12650
|
+
// packages/cli/src/acp/acpSession.ts
|
|
12619
12651
|
import * as fs12 from "node:fs/promises";
|
|
12620
|
-
import * as
|
|
12652
|
+
import * as path12 from "node:path";
|
|
12621
12653
|
import { randomUUID } from "node:crypto";
|
|
12622
12654
|
|
|
12623
12655
|
// packages/cli/src/acp/commands/commandRegistry.ts
|
|
@@ -13089,7 +13121,7 @@ var UpdateExtensionCommand = class {
|
|
|
13089
13121
|
|
|
13090
13122
|
// packages/cli/src/acp/commands/init.ts
|
|
13091
13123
|
import * as fs10 from "node:fs";
|
|
13092
|
-
import * as
|
|
13124
|
+
import * as path10 from "node:path";
|
|
13093
13125
|
var InitCommand = class {
|
|
13094
13126
|
name = "init";
|
|
13095
13127
|
description = "Analyzes the project and creates a tailored GEMINI.md file";
|
|
@@ -13099,7 +13131,7 @@ var InitCommand = class {
|
|
|
13099
13131
|
if (!targetDir) {
|
|
13100
13132
|
throw new Error("Command requires a workspace.");
|
|
13101
13133
|
}
|
|
13102
|
-
const geminiMdPath =
|
|
13134
|
+
const geminiMdPath = path10.join(targetDir, "GEMINI.md");
|
|
13103
13135
|
const result = performInit(fs10.existsSync(geminiMdPath));
|
|
13104
13136
|
switch (result.type) {
|
|
13105
13137
|
case "message":
|
|
@@ -13132,7 +13164,7 @@ ${result.content}`
|
|
|
13132
13164
|
|
|
13133
13165
|
// packages/cli/src/acp/commands/restore.ts
|
|
13134
13166
|
import * as fs11 from "node:fs/promises";
|
|
13135
|
-
import * as
|
|
13167
|
+
import * as path11 from "node:path";
|
|
13136
13168
|
var RestoreCommand = class {
|
|
13137
13169
|
name = "restore";
|
|
13138
13170
|
description = "Restore to a previous checkpoint, or list available checkpoints to restore. This will reset the conversation and file history to the state it was in when the checkpoint was created";
|
|
@@ -13154,7 +13186,7 @@ var RestoreCommand = class {
|
|
|
13154
13186
|
}
|
|
13155
13187
|
const selectedFile = argsStr.endsWith(".json") ? argsStr : `${argsStr}.json`;
|
|
13156
13188
|
const checkpointDir = config.storage.getProjectTempCheckpointsDir();
|
|
13157
|
-
const filePath =
|
|
13189
|
+
const filePath = path11.join(checkpointDir, selectedFile);
|
|
13158
13190
|
let data;
|
|
13159
13191
|
try {
|
|
13160
13192
|
data = await fs11.readFile(filePath, "utf-8");
|
|
@@ -13228,7 +13260,7 @@ var ListCheckpointsCommand = class {
|
|
|
13228
13260
|
}
|
|
13229
13261
|
const checkpointFiles = /* @__PURE__ */ new Map();
|
|
13230
13262
|
for (const file of jsonFiles) {
|
|
13231
|
-
const filePath =
|
|
13263
|
+
const filePath = path11.join(checkpointDir, file);
|
|
13232
13264
|
const data = await fs11.readFile(filePath, "utf-8");
|
|
13233
13265
|
checkpointFiles.set(file, data);
|
|
13234
13266
|
}
|
|
@@ -13335,7 +13367,7 @@ var HelpCommand = class {
|
|
|
13335
13367
|
}
|
|
13336
13368
|
};
|
|
13337
13369
|
|
|
13338
|
-
// packages/cli/src/acp/
|
|
13370
|
+
// packages/cli/src/acp/acpCommandHandler.ts
|
|
13339
13371
|
var CommandHandler = class _CommandHandler {
|
|
13340
13372
|
registry;
|
|
13341
13373
|
constructor() {
|
|
@@ -13422,7 +13454,7 @@ var CommandHandler = class _CommandHandler {
|
|
|
13422
13454
|
}
|
|
13423
13455
|
};
|
|
13424
13456
|
|
|
13425
|
-
// packages/cli/src/acp/
|
|
13457
|
+
// packages/cli/src/acp/acpUtils.ts
|
|
13426
13458
|
function hasMeta(obj) {
|
|
13427
13459
|
return typeof obj === "object" && obj !== null && "_meta" in obj;
|
|
13428
13460
|
}
|
|
@@ -13435,380 +13467,273 @@ var RequestPermissionResponseSchema = external_exports.object({
|
|
|
13435
13467
|
})
|
|
13436
13468
|
])
|
|
13437
13469
|
});
|
|
13438
|
-
|
|
13439
|
-
|
|
13440
|
-
|
|
13441
|
-
const stdin = Readable.toWeb(process.stdin);
|
|
13442
|
-
const stream = ndJsonStream(stdout, stdin);
|
|
13443
|
-
const connection = new AgentSideConnection(
|
|
13444
|
-
(connection2) => new GeminiAgent(config, settings, argv, connection2),
|
|
13445
|
-
stream
|
|
13446
|
-
);
|
|
13447
|
-
await connection.closed.finally(runExitCleanup);
|
|
13448
|
-
}
|
|
13449
|
-
var GeminiAgent = class _GeminiAgent {
|
|
13450
|
-
constructor(context, settings, argv, connection) {
|
|
13451
|
-
this.context = context;
|
|
13452
|
-
this.settings = settings;
|
|
13453
|
-
this.argv = argv;
|
|
13454
|
-
this.connection = connection;
|
|
13455
|
-
}
|
|
13456
|
-
static callIdCounter = 0;
|
|
13457
|
-
static generateCallId(name) {
|
|
13458
|
-
return `${name}-${Date.now()}-${++_GeminiAgent.callIdCounter}`;
|
|
13470
|
+
function toToolCallContent(toolResult) {
|
|
13471
|
+
if (toolResult.error?.message) {
|
|
13472
|
+
throw new Error(toolResult.error.message);
|
|
13459
13473
|
}
|
|
13460
|
-
|
|
13461
|
-
|
|
13462
|
-
|
|
13463
|
-
|
|
13464
|
-
|
|
13465
|
-
|
|
13466
|
-
|
|
13467
|
-
|
|
13468
|
-
|
|
13469
|
-
|
|
13470
|
-
|
|
13471
|
-
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
name: "Gemini API key",
|
|
13476
|
-
description: "Use an API key with Gemini Developer API",
|
|
13477
|
-
_meta: {
|
|
13478
|
-
"api-key": {
|
|
13479
|
-
provider: "google"
|
|
13480
|
-
}
|
|
13481
|
-
}
|
|
13482
|
-
},
|
|
13483
|
-
{
|
|
13484
|
-
id: AuthType.USE_VERTEX_AI,
|
|
13485
|
-
name: "Vertex AI",
|
|
13486
|
-
description: "Use an API key with Vertex AI GenAI API"
|
|
13487
|
-
},
|
|
13488
|
-
{
|
|
13489
|
-
id: AuthType.GATEWAY,
|
|
13490
|
-
name: "AI API Gateway",
|
|
13491
|
-
description: "Use a custom AI API Gateway",
|
|
13492
|
-
_meta: {
|
|
13493
|
-
gateway: {
|
|
13494
|
-
protocol: "google",
|
|
13495
|
-
restartRequired: "false"
|
|
13474
|
+
if (toolResult.returnDisplay) {
|
|
13475
|
+
if (typeof toolResult.returnDisplay === "string") {
|
|
13476
|
+
return {
|
|
13477
|
+
type: "content",
|
|
13478
|
+
content: { type: "text", text: toolResult.returnDisplay }
|
|
13479
|
+
};
|
|
13480
|
+
} else {
|
|
13481
|
+
if ("fileName" in toolResult.returnDisplay) {
|
|
13482
|
+
return {
|
|
13483
|
+
type: "diff",
|
|
13484
|
+
path: toolResult.returnDisplay.filePath ?? toolResult.returnDisplay.fileName,
|
|
13485
|
+
oldText: toolResult.returnDisplay.originalContent,
|
|
13486
|
+
newText: toolResult.returnDisplay.newContent,
|
|
13487
|
+
_meta: {
|
|
13488
|
+
kind: !toolResult.returnDisplay.originalContent ? "add" : toolResult.returnDisplay.newContent === "" ? "delete" : "modify"
|
|
13496
13489
|
}
|
|
13497
|
-
}
|
|
13498
|
-
}
|
|
13499
|
-
];
|
|
13500
|
-
await this.context.config.initialize();
|
|
13501
|
-
const version = await getVersion();
|
|
13502
|
-
return {
|
|
13503
|
-
protocolVersion: PROTOCOL_VERSION,
|
|
13504
|
-
authMethods,
|
|
13505
|
-
agentInfo: {
|
|
13506
|
-
name: "gemini-cli",
|
|
13507
|
-
title: "Gemini CLI",
|
|
13508
|
-
version
|
|
13509
|
-
},
|
|
13510
|
-
agentCapabilities: {
|
|
13511
|
-
loadSession: true,
|
|
13512
|
-
promptCapabilities: {
|
|
13513
|
-
image: true,
|
|
13514
|
-
audio: true,
|
|
13515
|
-
embeddedContext: true
|
|
13516
|
-
},
|
|
13517
|
-
mcpCapabilities: {
|
|
13518
|
-
http: true,
|
|
13519
|
-
sse: true
|
|
13520
|
-
}
|
|
13521
|
-
}
|
|
13522
|
-
};
|
|
13523
|
-
}
|
|
13524
|
-
async authenticate(req) {
|
|
13525
|
-
const { methodId } = req;
|
|
13526
|
-
const method = external_exports.nativeEnum(AuthType).parse(methodId);
|
|
13527
|
-
const selectedAuthType = this.settings.merged.security.auth.selectedType;
|
|
13528
|
-
if (selectedAuthType && selectedAuthType !== method) {
|
|
13529
|
-
await clearCachedCredentialFile();
|
|
13530
|
-
}
|
|
13531
|
-
const meta = hasMeta(req) ? req._meta : void 0;
|
|
13532
|
-
const apiKey = typeof meta?.["api-key"] === "string" ? meta["api-key"] : void 0;
|
|
13533
|
-
try {
|
|
13534
|
-
if (apiKey) {
|
|
13535
|
-
this.apiKey = apiKey;
|
|
13536
|
-
}
|
|
13537
|
-
const gatewaySchema = external_exports.object({
|
|
13538
|
-
baseUrl: external_exports.string().optional(),
|
|
13539
|
-
headers: external_exports.record(external_exports.string()).optional()
|
|
13540
|
-
});
|
|
13541
|
-
let baseUrl;
|
|
13542
|
-
let headers;
|
|
13543
|
-
if (meta?.["gateway"]) {
|
|
13544
|
-
const result = gatewaySchema.safeParse(meta["gateway"]);
|
|
13545
|
-
if (result.success) {
|
|
13546
|
-
baseUrl = result.data.baseUrl;
|
|
13547
|
-
headers = result.data.headers;
|
|
13548
|
-
} else {
|
|
13549
|
-
throw new RequestError(
|
|
13550
|
-
-32602,
|
|
13551
|
-
`Malformed gateway payload: ${result.error.message}`
|
|
13552
|
-
);
|
|
13553
|
-
}
|
|
13490
|
+
};
|
|
13554
13491
|
}
|
|
13555
|
-
|
|
13556
|
-
this.customHeaders = headers;
|
|
13557
|
-
await this.context.config.refreshAuth(
|
|
13558
|
-
method,
|
|
13559
|
-
apiKey ?? this.apiKey,
|
|
13560
|
-
baseUrl,
|
|
13561
|
-
headers
|
|
13562
|
-
);
|
|
13563
|
-
} catch (e) {
|
|
13564
|
-
throw new RequestError(-32e3, getAcpErrorMessage(e));
|
|
13492
|
+
return null;
|
|
13565
13493
|
}
|
|
13566
|
-
|
|
13567
|
-
|
|
13568
|
-
"security.auth.selectedType",
|
|
13569
|
-
method
|
|
13570
|
-
);
|
|
13494
|
+
} else {
|
|
13495
|
+
return null;
|
|
13571
13496
|
}
|
|
13572
|
-
|
|
13573
|
-
|
|
13574
|
-
|
|
13575
|
-
|
|
13576
|
-
|
|
13577
|
-
|
|
13578
|
-
|
|
13579
|
-
|
|
13580
|
-
|
|
13581
|
-
|
|
13582
|
-
|
|
13583
|
-
);
|
|
13584
|
-
const authType = loadedSettings.merged.security.auth.selectedType || AuthType.USE_GEMINI;
|
|
13585
|
-
let isAuthenticated = false;
|
|
13586
|
-
let authErrorMessage = "";
|
|
13587
|
-
try {
|
|
13588
|
-
await config.refreshAuth(
|
|
13589
|
-
authType,
|
|
13590
|
-
this.apiKey,
|
|
13591
|
-
this.baseUrl,
|
|
13592
|
-
this.customHeaders
|
|
13593
|
-
);
|
|
13594
|
-
isAuthenticated = true;
|
|
13595
|
-
const contentGeneratorConfig = config.getContentGeneratorConfig();
|
|
13596
|
-
if (authType === AuthType.USE_GEMINI && (!contentGeneratorConfig || !contentGeneratorConfig.apiKey)) {
|
|
13597
|
-
isAuthenticated = false;
|
|
13598
|
-
authErrorMessage = "Gemini API key is missing or not configured.";
|
|
13599
|
-
}
|
|
13600
|
-
} catch (e) {
|
|
13601
|
-
isAuthenticated = false;
|
|
13602
|
-
authErrorMessage = getAcpErrorMessage(e);
|
|
13603
|
-
debugLogger.error(
|
|
13604
|
-
`Authentication failed: ${e instanceof Error ? e.stack : e}`
|
|
13605
|
-
);
|
|
13606
|
-
}
|
|
13607
|
-
if (!isAuthenticated) {
|
|
13608
|
-
throw new RequestError(
|
|
13609
|
-
-32e3,
|
|
13610
|
-
authErrorMessage || "Authentication required."
|
|
13611
|
-
);
|
|
13612
|
-
}
|
|
13613
|
-
if (this.clientCapabilities?.fs) {
|
|
13614
|
-
const acpFileSystemService = new AcpFileSystemService(
|
|
13615
|
-
this.connection,
|
|
13616
|
-
sessionId,
|
|
13617
|
-
this.clientCapabilities.fs,
|
|
13618
|
-
config.getFileSystemService(),
|
|
13619
|
-
cwd
|
|
13620
|
-
);
|
|
13621
|
-
config.setFileSystemService(acpFileSystemService);
|
|
13622
|
-
}
|
|
13623
|
-
await config.initialize();
|
|
13624
|
-
startupProfiler.flush(config);
|
|
13625
|
-
startAutoMemoryIfEnabled(config);
|
|
13626
|
-
const geminiClient = config.getGeminiClient();
|
|
13627
|
-
const chat = await geminiClient.startChat();
|
|
13628
|
-
const session = new Session(
|
|
13629
|
-
sessionId,
|
|
13630
|
-
chat,
|
|
13631
|
-
config,
|
|
13632
|
-
this.connection,
|
|
13633
|
-
this.settings
|
|
13634
|
-
);
|
|
13635
|
-
this.sessions.set(sessionId, session);
|
|
13636
|
-
setTimeout(() => {
|
|
13637
|
-
session.sendAvailableCommands();
|
|
13638
|
-
}, 0);
|
|
13639
|
-
const { availableModels, currentModelId } = buildAvailableModels(
|
|
13640
|
-
config,
|
|
13641
|
-
loadedSettings
|
|
13642
|
-
);
|
|
13643
|
-
const response = {
|
|
13644
|
-
sessionId,
|
|
13645
|
-
modes: {
|
|
13646
|
-
availableModes: buildAvailableModes(config.isPlanEnabled()),
|
|
13647
|
-
currentModeId: config.getApprovalMode()
|
|
13648
|
-
},
|
|
13649
|
-
models: {
|
|
13650
|
-
availableModels,
|
|
13651
|
-
currentModelId
|
|
13652
|
-
}
|
|
13653
|
-
};
|
|
13654
|
-
return response;
|
|
13655
|
-
}
|
|
13656
|
-
async loadSession({
|
|
13657
|
-
sessionId,
|
|
13658
|
-
cwd,
|
|
13659
|
-
mcpServers
|
|
13660
|
-
}) {
|
|
13661
|
-
const config = await this.initializeSessionConfig(
|
|
13662
|
-
sessionId,
|
|
13663
|
-
cwd,
|
|
13664
|
-
mcpServers
|
|
13665
|
-
);
|
|
13666
|
-
const sessionSelector = new SessionSelector(config.storage);
|
|
13667
|
-
const { sessionData, sessionPath } = await sessionSelector.resolveSession(sessionId);
|
|
13668
|
-
const clientHistory = convertSessionToClientHistory(sessionData.messages);
|
|
13669
|
-
const geminiClient = config.getGeminiClient();
|
|
13670
|
-
await geminiClient.initialize();
|
|
13671
|
-
await geminiClient.resumeChat(clientHistory, {
|
|
13672
|
-
conversation: sessionData,
|
|
13673
|
-
filePath: sessionPath
|
|
13674
|
-
});
|
|
13675
|
-
const session = new Session(
|
|
13676
|
-
sessionId,
|
|
13677
|
-
geminiClient.getChat(),
|
|
13678
|
-
config,
|
|
13679
|
-
this.connection,
|
|
13680
|
-
this.settings
|
|
13681
|
-
);
|
|
13682
|
-
this.sessions.set(sessionId, session);
|
|
13683
|
-
session.streamHistory(sessionData.messages);
|
|
13684
|
-
setTimeout(() => {
|
|
13685
|
-
session.sendAvailableCommands();
|
|
13686
|
-
}, 0);
|
|
13687
|
-
const { availableModels, currentModelId } = buildAvailableModels(
|
|
13688
|
-
config,
|
|
13689
|
-
this.settings
|
|
13690
|
-
);
|
|
13691
|
-
const response = {
|
|
13692
|
-
modes: {
|
|
13693
|
-
availableModes: buildAvailableModes(config.isPlanEnabled()),
|
|
13694
|
-
currentModeId: config.getApprovalMode()
|
|
13695
|
-
},
|
|
13696
|
-
models: {
|
|
13697
|
-
availableModels,
|
|
13698
|
-
currentModelId
|
|
13699
|
-
}
|
|
13700
|
-
};
|
|
13701
|
-
return response;
|
|
13702
|
-
}
|
|
13703
|
-
async initializeSessionConfig(sessionId, cwd, mcpServers) {
|
|
13704
|
-
const selectedAuthType = this.settings.merged.security.auth.selectedType;
|
|
13705
|
-
if (!selectedAuthType) {
|
|
13706
|
-
throw RequestError.authRequired();
|
|
13707
|
-
}
|
|
13708
|
-
const config = await this.newSessionConfig(sessionId, cwd, mcpServers);
|
|
13709
|
-
try {
|
|
13710
|
-
await config.refreshAuth(
|
|
13711
|
-
selectedAuthType,
|
|
13712
|
-
this.apiKey,
|
|
13713
|
-
this.baseUrl,
|
|
13714
|
-
this.customHeaders
|
|
13715
|
-
);
|
|
13716
|
-
} catch (e) {
|
|
13717
|
-
debugLogger.error(`Authentication failed: ${e}`);
|
|
13718
|
-
throw RequestError.authRequired();
|
|
13719
|
-
}
|
|
13720
|
-
if (this.clientCapabilities?.fs) {
|
|
13721
|
-
const acpFileSystemService = new AcpFileSystemService(
|
|
13722
|
-
this.connection,
|
|
13723
|
-
sessionId,
|
|
13724
|
-
this.clientCapabilities.fs,
|
|
13725
|
-
config.getFileSystemService(),
|
|
13726
|
-
cwd
|
|
13727
|
-
);
|
|
13728
|
-
config.setFileSystemService(acpFileSystemService);
|
|
13729
|
-
}
|
|
13730
|
-
await config.initialize();
|
|
13731
|
-
startupProfiler.flush(config);
|
|
13732
|
-
startAutoMemoryIfEnabled(config);
|
|
13733
|
-
return config;
|
|
13497
|
+
}
|
|
13498
|
+
var basicPermissionOptions = [
|
|
13499
|
+
{
|
|
13500
|
+
optionId: ToolConfirmationOutcome.ProceedOnce,
|
|
13501
|
+
name: "Allow",
|
|
13502
|
+
kind: "allow_once"
|
|
13503
|
+
},
|
|
13504
|
+
{
|
|
13505
|
+
optionId: ToolConfirmationOutcome.Cancel,
|
|
13506
|
+
name: "Reject",
|
|
13507
|
+
kind: "reject_once"
|
|
13734
13508
|
}
|
|
13735
|
-
|
|
13736
|
-
|
|
13737
|
-
|
|
13738
|
-
|
|
13739
|
-
|
|
13740
|
-
|
|
13741
|
-
|
|
13742
|
-
|
|
13743
|
-
|
|
13744
|
-
|
|
13745
|
-
|
|
13746
|
-
|
|
13747
|
-
|
|
13748
|
-
|
|
13749
|
-
|
|
13750
|
-
|
|
13751
|
-
|
|
13752
|
-
|
|
13753
|
-
// url (sse)
|
|
13754
|
-
server.type === "http" ? server.url : void 0,
|
|
13755
|
-
// httpUrl
|
|
13756
|
-
headers
|
|
13757
|
-
);
|
|
13758
|
-
} else if ("command" in server) {
|
|
13759
|
-
const env2 = {};
|
|
13760
|
-
for (const { name: envName, value } of server.env) {
|
|
13761
|
-
env2[envName] = value;
|
|
13509
|
+
];
|
|
13510
|
+
function toPermissionOptions(confirmation, config, enablePermanentToolApproval = false) {
|
|
13511
|
+
const disableAlwaysAllow = config.getDisableAlwaysAllow();
|
|
13512
|
+
const options = [];
|
|
13513
|
+
if (!disableAlwaysAllow) {
|
|
13514
|
+
switch (confirmation.type) {
|
|
13515
|
+
case "edit":
|
|
13516
|
+
options.push({
|
|
13517
|
+
optionId: ToolConfirmationOutcome.ProceedAlways,
|
|
13518
|
+
name: "Allow for this session",
|
|
13519
|
+
kind: "allow_always"
|
|
13520
|
+
});
|
|
13521
|
+
if (enablePermanentToolApproval) {
|
|
13522
|
+
options.push({
|
|
13523
|
+
optionId: ToolConfirmationOutcome.ProceedAlwaysAndSave,
|
|
13524
|
+
name: "Allow for this file in all future sessions",
|
|
13525
|
+
kind: "allow_always"
|
|
13526
|
+
});
|
|
13762
13527
|
}
|
|
13763
|
-
|
|
13764
|
-
|
|
13765
|
-
|
|
13766
|
-
|
|
13767
|
-
|
|
13528
|
+
break;
|
|
13529
|
+
case "exec":
|
|
13530
|
+
options.push({
|
|
13531
|
+
optionId: ToolConfirmationOutcome.ProceedAlways,
|
|
13532
|
+
name: "Allow for this session",
|
|
13533
|
+
kind: "allow_always"
|
|
13534
|
+
});
|
|
13535
|
+
if (enablePermanentToolApproval) {
|
|
13536
|
+
options.push({
|
|
13537
|
+
optionId: ToolConfirmationOutcome.ProceedAlwaysAndSave,
|
|
13538
|
+
name: "Allow this command for all future sessions",
|
|
13539
|
+
kind: "allow_always"
|
|
13540
|
+
});
|
|
13541
|
+
}
|
|
13542
|
+
break;
|
|
13543
|
+
case "mcp":
|
|
13544
|
+
options.push(
|
|
13545
|
+
{
|
|
13546
|
+
optionId: ToolConfirmationOutcome.ProceedAlwaysServer,
|
|
13547
|
+
name: "Allow all server tools for this session",
|
|
13548
|
+
kind: "allow_always"
|
|
13549
|
+
},
|
|
13550
|
+
{
|
|
13551
|
+
optionId: ToolConfirmationOutcome.ProceedAlwaysTool,
|
|
13552
|
+
name: "Allow tool for this session",
|
|
13553
|
+
kind: "allow_always"
|
|
13554
|
+
}
|
|
13768
13555
|
);
|
|
13769
|
-
|
|
13556
|
+
if (enablePermanentToolApproval) {
|
|
13557
|
+
options.push({
|
|
13558
|
+
optionId: ToolConfirmationOutcome.ProceedAlwaysAndSave,
|
|
13559
|
+
name: "Allow tool for all future sessions",
|
|
13560
|
+
kind: "allow_always"
|
|
13561
|
+
});
|
|
13562
|
+
}
|
|
13563
|
+
break;
|
|
13564
|
+
case "info":
|
|
13565
|
+
options.push({
|
|
13566
|
+
optionId: ToolConfirmationOutcome.ProceedAlways,
|
|
13567
|
+
name: "Allow for this session",
|
|
13568
|
+
kind: "allow_always"
|
|
13569
|
+
});
|
|
13570
|
+
if (enablePermanentToolApproval) {
|
|
13571
|
+
options.push({
|
|
13572
|
+
optionId: ToolConfirmationOutcome.ProceedAlwaysAndSave,
|
|
13573
|
+
name: "Allow for all future sessions",
|
|
13574
|
+
kind: "allow_always"
|
|
13575
|
+
});
|
|
13576
|
+
}
|
|
13577
|
+
break;
|
|
13578
|
+
case "ask_user":
|
|
13579
|
+
case "exit_plan_mode":
|
|
13580
|
+
break;
|
|
13581
|
+
default:
|
|
13582
|
+
break;
|
|
13770
13583
|
}
|
|
13771
|
-
const settings = {
|
|
13772
|
-
...currentSettings.merged,
|
|
13773
|
-
mcpServers: mergedMcpServers
|
|
13774
|
-
};
|
|
13775
|
-
const config = await loadCliConfig(settings, sessionId, this.argv, { cwd });
|
|
13776
|
-
createPolicyUpdater2(
|
|
13777
|
-
config.getPolicyEngine(),
|
|
13778
|
-
config.messageBus,
|
|
13779
|
-
config.storage
|
|
13780
|
-
);
|
|
13781
|
-
return config;
|
|
13782
13584
|
}
|
|
13783
|
-
|
|
13784
|
-
|
|
13785
|
-
|
|
13786
|
-
|
|
13585
|
+
options.push(...basicPermissionOptions);
|
|
13586
|
+
switch (confirmation.type) {
|
|
13587
|
+
case "edit":
|
|
13588
|
+
case "exec":
|
|
13589
|
+
case "mcp":
|
|
13590
|
+
case "info":
|
|
13591
|
+
case "ask_user":
|
|
13592
|
+
case "exit_plan_mode":
|
|
13593
|
+
case "sandbox_expansion":
|
|
13594
|
+
break;
|
|
13595
|
+
default: {
|
|
13596
|
+
const unreachable = confirmation;
|
|
13597
|
+
throw new Error(`Unexpected: ${unreachable}`);
|
|
13787
13598
|
}
|
|
13788
|
-
await session.cancelPendingPrompt();
|
|
13789
13599
|
}
|
|
13790
|
-
|
|
13791
|
-
|
|
13792
|
-
|
|
13793
|
-
|
|
13600
|
+
return options;
|
|
13601
|
+
}
|
|
13602
|
+
function toAcpToolKind(kind) {
|
|
13603
|
+
switch (kind) {
|
|
13604
|
+
case Kind.Read:
|
|
13605
|
+
case Kind.Edit:
|
|
13606
|
+
case Kind.Execute:
|
|
13607
|
+
case Kind.Search:
|
|
13608
|
+
case Kind.Delete:
|
|
13609
|
+
case Kind.Move:
|
|
13610
|
+
case Kind.Think:
|
|
13611
|
+
case Kind.Fetch:
|
|
13612
|
+
case Kind.SwitchMode:
|
|
13613
|
+
case Kind.Other:
|
|
13614
|
+
return kind;
|
|
13615
|
+
case Kind.Agent:
|
|
13616
|
+
return "think";
|
|
13617
|
+
case Kind.Plan:
|
|
13618
|
+
case Kind.Communicate:
|
|
13619
|
+
default:
|
|
13620
|
+
return "other";
|
|
13621
|
+
}
|
|
13622
|
+
}
|
|
13623
|
+
function buildAvailableModes(isPlanEnabled) {
|
|
13624
|
+
const modes = [
|
|
13625
|
+
{
|
|
13626
|
+
id: ApprovalMode.DEFAULT,
|
|
13627
|
+
name: "Default",
|
|
13628
|
+
description: "Prompts for approval"
|
|
13629
|
+
},
|
|
13630
|
+
{
|
|
13631
|
+
id: ApprovalMode.AUTO_EDIT,
|
|
13632
|
+
name: "Auto Edit",
|
|
13633
|
+
description: "Auto-approves edit tools"
|
|
13634
|
+
},
|
|
13635
|
+
{
|
|
13636
|
+
id: ApprovalMode.YOLO,
|
|
13637
|
+
name: "YOLO",
|
|
13638
|
+
description: "Auto-approves all tools"
|
|
13794
13639
|
}
|
|
13795
|
-
|
|
13640
|
+
];
|
|
13641
|
+
if (isPlanEnabled) {
|
|
13642
|
+
modes.push({
|
|
13643
|
+
id: ApprovalMode.PLAN,
|
|
13644
|
+
name: "Plan",
|
|
13645
|
+
description: "Read-only mode"
|
|
13646
|
+
});
|
|
13796
13647
|
}
|
|
13797
|
-
|
|
13798
|
-
|
|
13799
|
-
|
|
13800
|
-
|
|
13648
|
+
return modes;
|
|
13649
|
+
}
|
|
13650
|
+
function buildAvailableModels(config, settings) {
|
|
13651
|
+
const preferredModel = config.getModel() || DEFAULT_GEMINI_MODEL_AUTO;
|
|
13652
|
+
const shouldShowPreviewModels = config.getHasAccessToPreviewModel();
|
|
13653
|
+
const useGemini31 = config.getGemini31LaunchedSync?.() ?? false;
|
|
13654
|
+
const useGemini31FlashLite = config.getGemini31FlashLiteLaunchedSync?.() ?? false;
|
|
13655
|
+
const selectedAuthType = settings.merged.security.auth.selectedType;
|
|
13656
|
+
const useCustomToolModel = useGemini31 && selectedAuthType === AuthType.USE_GEMINI;
|
|
13657
|
+
if (config.getExperimentalDynamicModelConfiguration?.() === true && config.getModelConfigService) {
|
|
13658
|
+
const options = config.getModelConfigService().getAvailableModelOptions({
|
|
13659
|
+
useGemini3_1: useGemini31,
|
|
13660
|
+
useGemini3_1FlashLite: useGemini31FlashLite,
|
|
13661
|
+
useCustomTools: useCustomToolModel,
|
|
13662
|
+
hasAccessToPreview: shouldShowPreviewModels
|
|
13663
|
+
});
|
|
13664
|
+
return {
|
|
13665
|
+
availableModels: options,
|
|
13666
|
+
currentModelId: preferredModel
|
|
13667
|
+
};
|
|
13668
|
+
}
|
|
13669
|
+
const mainOptions = [
|
|
13670
|
+
{
|
|
13671
|
+
value: DEFAULT_GEMINI_MODEL_AUTO,
|
|
13672
|
+
title: getDisplayString(DEFAULT_GEMINI_MODEL_AUTO),
|
|
13673
|
+
description: "Let Gemini CLI decide the best model for the task: gemini-2.5-pro, gemini-2.5-flash"
|
|
13801
13674
|
}
|
|
13802
|
-
|
|
13675
|
+
];
|
|
13676
|
+
if (shouldShowPreviewModels) {
|
|
13677
|
+
mainOptions.unshift({
|
|
13678
|
+
value: PREVIEW_GEMINI_MODEL_AUTO,
|
|
13679
|
+
title: getDisplayString(PREVIEW_GEMINI_MODEL_AUTO),
|
|
13680
|
+
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"
|
|
13681
|
+
});
|
|
13803
13682
|
}
|
|
13804
|
-
|
|
13805
|
-
|
|
13806
|
-
|
|
13807
|
-
|
|
13683
|
+
const manualOptions = [
|
|
13684
|
+
{
|
|
13685
|
+
value: DEFAULT_GEMINI_MODEL,
|
|
13686
|
+
title: getDisplayString(DEFAULT_GEMINI_MODEL)
|
|
13687
|
+
},
|
|
13688
|
+
{
|
|
13689
|
+
value: DEFAULT_GEMINI_FLASH_MODEL,
|
|
13690
|
+
title: getDisplayString(DEFAULT_GEMINI_FLASH_MODEL)
|
|
13691
|
+
},
|
|
13692
|
+
{
|
|
13693
|
+
value: DEFAULT_GEMINI_FLASH_LITE_MODEL,
|
|
13694
|
+
title: getDisplayString(DEFAULT_GEMINI_FLASH_LITE_MODEL)
|
|
13808
13695
|
}
|
|
13809
|
-
|
|
13696
|
+
];
|
|
13697
|
+
if (shouldShowPreviewModels) {
|
|
13698
|
+
const previewProModel = useGemini31 ? PREVIEW_GEMINI_3_1_MODEL : PREVIEW_GEMINI_MODEL;
|
|
13699
|
+
const previewProValue = useCustomToolModel ? PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL : previewProModel;
|
|
13700
|
+
const previewOptions = [
|
|
13701
|
+
{
|
|
13702
|
+
value: previewProValue,
|
|
13703
|
+
title: getDisplayString(previewProModel)
|
|
13704
|
+
},
|
|
13705
|
+
{
|
|
13706
|
+
value: PREVIEW_GEMINI_FLASH_MODEL,
|
|
13707
|
+
title: getDisplayString(PREVIEW_GEMINI_FLASH_MODEL)
|
|
13708
|
+
}
|
|
13709
|
+
];
|
|
13710
|
+
if (useGemini31FlashLite) {
|
|
13711
|
+
previewOptions.push({
|
|
13712
|
+
value: PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL,
|
|
13713
|
+
title: getDisplayString(PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL)
|
|
13714
|
+
});
|
|
13715
|
+
}
|
|
13716
|
+
manualOptions.unshift(...previewOptions);
|
|
13810
13717
|
}
|
|
13811
|
-
|
|
13718
|
+
const scaleOptions = (options) => options.map((o) => ({
|
|
13719
|
+
modelId: o.value,
|
|
13720
|
+
name: o.title,
|
|
13721
|
+
description: o.description
|
|
13722
|
+
}));
|
|
13723
|
+
return {
|
|
13724
|
+
availableModels: [
|
|
13725
|
+
...scaleOptions(mainOptions),
|
|
13726
|
+
...scaleOptions(manualOptions)
|
|
13727
|
+
],
|
|
13728
|
+
currentModelId: preferredModel
|
|
13729
|
+
};
|
|
13730
|
+
}
|
|
13731
|
+
|
|
13732
|
+
// packages/cli/src/acp/acpSession.ts
|
|
13733
|
+
var StructuredErrorSchema = external_exports.object({
|
|
13734
|
+
status: external_exports.number().optional(),
|
|
13735
|
+
message: external_exports.string().optional()
|
|
13736
|
+
});
|
|
13812
13737
|
var Session = class {
|
|
13813
13738
|
constructor(id, chat, context, connection, settings) {
|
|
13814
13739
|
this.id = id;
|
|
@@ -13819,6 +13744,10 @@ var Session = class {
|
|
|
13819
13744
|
}
|
|
13820
13745
|
pendingPrompt = null;
|
|
13821
13746
|
commandHandler = new CommandHandler();
|
|
13747
|
+
callIdCounter = 0;
|
|
13748
|
+
generateCallId(name) {
|
|
13749
|
+
return `${name}-${Date.now()}-${++this.callIdCounter}`;
|
|
13750
|
+
}
|
|
13822
13751
|
async cancelPendingPrompt() {
|
|
13823
13752
|
if (!this.pendingPrompt) {
|
|
13824
13753
|
throw new Error("Not currently generating");
|
|
@@ -13919,16 +13848,13 @@ ${thought.description}`;
|
|
|
13919
13848
|
this.pendingPrompt = pendingSend;
|
|
13920
13849
|
await this.context.config.waitForMcpInit();
|
|
13921
13850
|
const promptId = Math.random().toString(16).slice(2);
|
|
13922
|
-
const chat = this.chat;
|
|
13923
13851
|
const parts = await this.#resolvePrompt(params.prompt, pendingSend.signal);
|
|
13924
13852
|
let commandText = "";
|
|
13925
13853
|
for (const part of parts) {
|
|
13926
13854
|
if (typeof part === "object" && part !== null) {
|
|
13927
|
-
if (
|
|
13855
|
+
if (isTextPart(part)) {
|
|
13928
13856
|
const text = part.text;
|
|
13929
|
-
|
|
13930
|
-
commandText += text;
|
|
13931
|
-
}
|
|
13857
|
+
commandText += text;
|
|
13932
13858
|
} else {
|
|
13933
13859
|
break;
|
|
13934
13860
|
}
|
|
@@ -13952,80 +13878,108 @@ ${thought.description}`;
|
|
|
13952
13878
|
let totalInputTokens = 0;
|
|
13953
13879
|
let totalOutputTokens = 0;
|
|
13954
13880
|
const modelUsageMap = /* @__PURE__ */ new Map();
|
|
13955
|
-
let
|
|
13956
|
-
|
|
13881
|
+
let currentParts = parts;
|
|
13882
|
+
let turnCount = 0;
|
|
13883
|
+
const maxTurns = this.context.config.getMaxSessionTurns();
|
|
13884
|
+
while (true) {
|
|
13885
|
+
turnCount++;
|
|
13886
|
+
if (maxTurns >= 0 && turnCount > maxTurns) {
|
|
13887
|
+
return {
|
|
13888
|
+
stopReason: "max_turn_requests",
|
|
13889
|
+
_meta: {
|
|
13890
|
+
quota: {
|
|
13891
|
+
token_count: {
|
|
13892
|
+
input_tokens: totalInputTokens,
|
|
13893
|
+
output_tokens: totalOutputTokens
|
|
13894
|
+
},
|
|
13895
|
+
model_usage: Array.from(modelUsageMap.entries()).map(
|
|
13896
|
+
([modelName, counts]) => ({
|
|
13897
|
+
model: modelName,
|
|
13898
|
+
token_count: {
|
|
13899
|
+
input_tokens: counts.input,
|
|
13900
|
+
output_tokens: counts.output
|
|
13901
|
+
}
|
|
13902
|
+
})
|
|
13903
|
+
)
|
|
13904
|
+
}
|
|
13905
|
+
}
|
|
13906
|
+
};
|
|
13907
|
+
}
|
|
13957
13908
|
if (pendingSend.signal.aborted) {
|
|
13958
|
-
|
|
13959
|
-
return { stopReason: CoreToolCallStatus.Cancelled };
|
|
13909
|
+
return { stopReason: "cancelled" };
|
|
13960
13910
|
}
|
|
13961
|
-
const
|
|
13911
|
+
const toolCallRequests = [];
|
|
13912
|
+
let stopReason = "end_turn";
|
|
13913
|
+
let turnModelId = this.context.config.getModel();
|
|
13914
|
+
let turnInputTokens = 0;
|
|
13915
|
+
let turnOutputTokens = 0;
|
|
13962
13916
|
try {
|
|
13963
|
-
const
|
|
13964
|
-
|
|
13965
|
-
/*curated=*/
|
|
13966
|
-
true
|
|
13967
|
-
),
|
|
13968
|
-
request: nextMessage?.parts ?? [],
|
|
13969
|
-
signal: pendingSend.signal,
|
|
13970
|
-
requestedModel: this.context.config.getModel()
|
|
13971
|
-
};
|
|
13972
|
-
const router = this.context.config.getModelRouterService();
|
|
13973
|
-
const { model } = await router.route(routingContext);
|
|
13974
|
-
const responseStream = await chat.sendMessageStream(
|
|
13975
|
-
{ model },
|
|
13976
|
-
nextMessage?.parts ?? [],
|
|
13977
|
-
promptId,
|
|
13917
|
+
const responseStream = this.context.geminiClient.sendMessageStream(
|
|
13918
|
+
currentParts,
|
|
13978
13919
|
pendingSend.signal,
|
|
13979
|
-
|
|
13920
|
+
promptId
|
|
13980
13921
|
);
|
|
13981
|
-
|
|
13982
|
-
let turnInputTokens = 0;
|
|
13983
|
-
let turnOutputTokens = 0;
|
|
13984
|
-
let turnModelId = model;
|
|
13985
|
-
for await (const resp of responseStream) {
|
|
13922
|
+
for await (const event of responseStream) {
|
|
13986
13923
|
if (pendingSend.signal.aborted) {
|
|
13987
|
-
return { stopReason:
|
|
13988
|
-
}
|
|
13989
|
-
if (resp.type === StreamEventType.CHUNK && resp.value.usageMetadata) {
|
|
13990
|
-
turnInputTokens = resp.value.usageMetadata.promptTokenCount ?? turnInputTokens;
|
|
13991
|
-
turnOutputTokens = resp.value.usageMetadata.candidatesTokenCount ?? turnOutputTokens;
|
|
13992
|
-
if (resp.value.modelVersion) {
|
|
13993
|
-
turnModelId = resp.value.modelVersion;
|
|
13994
|
-
}
|
|
13924
|
+
return { stopReason: "cancelled" };
|
|
13995
13925
|
}
|
|
13996
|
-
|
|
13997
|
-
|
|
13998
|
-
for (const part of candidate.content?.parts ?? []) {
|
|
13999
|
-
if (!part.text) {
|
|
14000
|
-
continue;
|
|
14001
|
-
}
|
|
13926
|
+
switch (event.type) {
|
|
13927
|
+
case GeminiEventType.Content: {
|
|
14002
13928
|
const content = {
|
|
14003
13929
|
type: "text",
|
|
14004
|
-
text:
|
|
13930
|
+
text: event.value
|
|
14005
13931
|
};
|
|
14006
|
-
this.sendUpdate({
|
|
14007
|
-
sessionUpdate:
|
|
13932
|
+
await this.sendUpdate({
|
|
13933
|
+
sessionUpdate: "agent_message_chunk",
|
|
14008
13934
|
content
|
|
14009
13935
|
});
|
|
13936
|
+
break;
|
|
13937
|
+
}
|
|
13938
|
+
case GeminiEventType.Thought: {
|
|
13939
|
+
const thoughtText = `**${event.value.subject}**
|
|
13940
|
+
${event.value.description}`;
|
|
13941
|
+
await this.sendUpdate({
|
|
13942
|
+
sessionUpdate: "agent_thought_chunk",
|
|
13943
|
+
content: { type: "text", text: thoughtText }
|
|
13944
|
+
});
|
|
13945
|
+
break;
|
|
14010
13946
|
}
|
|
13947
|
+
case GeminiEventType.ToolCallRequest:
|
|
13948
|
+
toolCallRequests.push(event.value);
|
|
13949
|
+
break;
|
|
13950
|
+
case GeminiEventType.Finished: {
|
|
13951
|
+
const usage2 = event.value.usageMetadata;
|
|
13952
|
+
if (usage2) {
|
|
13953
|
+
turnInputTokens = usage2.promptTokenCount ?? turnInputTokens;
|
|
13954
|
+
turnOutputTokens = usage2.candidatesTokenCount ?? turnOutputTokens;
|
|
13955
|
+
}
|
|
13956
|
+
break;
|
|
13957
|
+
}
|
|
13958
|
+
case GeminiEventType.ModelInfo:
|
|
13959
|
+
turnModelId = event.value;
|
|
13960
|
+
break;
|
|
13961
|
+
case GeminiEventType.MaxSessionTurns:
|
|
13962
|
+
stopReason = "max_turn_requests";
|
|
13963
|
+
break;
|
|
13964
|
+
case GeminiEventType.LoopDetected:
|
|
13965
|
+
stopReason = "max_turn_requests";
|
|
13966
|
+
break;
|
|
13967
|
+
case GeminiEventType.ContextWindowWillOverflow:
|
|
13968
|
+
stopReason = "max_tokens";
|
|
13969
|
+
break;
|
|
13970
|
+
case GeminiEventType.Error: {
|
|
13971
|
+
const parseResult = StructuredErrorSchema.safeParse(
|
|
13972
|
+
event.value.error
|
|
13973
|
+
);
|
|
13974
|
+
const errData = parseResult.success ? parseResult.data : {};
|
|
13975
|
+
throw new RequestError(
|
|
13976
|
+
errData.status ?? 500,
|
|
13977
|
+
errData.message ?? "Unknown stream execution error."
|
|
13978
|
+
);
|
|
13979
|
+
}
|
|
13980
|
+
default:
|
|
13981
|
+
break;
|
|
14011
13982
|
}
|
|
14012
|
-
if (resp.type === StreamEventType.CHUNK && resp.value.functionCalls) {
|
|
14013
|
-
functionCalls.push(...resp.value.functionCalls);
|
|
14014
|
-
}
|
|
14015
|
-
}
|
|
14016
|
-
totalInputTokens += turnInputTokens;
|
|
14017
|
-
totalOutputTokens += turnOutputTokens;
|
|
14018
|
-
if (turnInputTokens > 0 || turnOutputTokens > 0) {
|
|
14019
|
-
const existing = modelUsageMap.get(turnModelId) ?? {
|
|
14020
|
-
input: 0,
|
|
14021
|
-
output: 0
|
|
14022
|
-
};
|
|
14023
|
-
existing.input += turnInputTokens;
|
|
14024
|
-
existing.output += turnOutputTokens;
|
|
14025
|
-
modelUsageMap.set(turnModelId, existing);
|
|
14026
|
-
}
|
|
14027
|
-
if (pendingSend.signal.aborted) {
|
|
14028
|
-
return { stopReason: CoreToolCallStatus.Cancelled };
|
|
14029
13983
|
}
|
|
14030
13984
|
} catch (error) {
|
|
14031
13985
|
if (getErrorStatus(error) === 429) {
|
|
@@ -14035,7 +13989,10 @@ ${thought.description}`;
|
|
|
14035
13989
|
);
|
|
14036
13990
|
}
|
|
14037
13991
|
if (pendingSend.signal.aborted || error instanceof Error && error.name === "AbortError") {
|
|
14038
|
-
return { stopReason:
|
|
13992
|
+
return { stopReason: "cancelled" };
|
|
13993
|
+
}
|
|
13994
|
+
if (error instanceof RequestError) {
|
|
13995
|
+
throw error;
|
|
14039
13996
|
}
|
|
14040
13997
|
if (error instanceof InvalidStreamError || error && typeof error === "object" && "type" in error && (error.type === "NO_RESPONSE_TEXT" || error.type === "NO_FINISH_REASON" || error.type === "MALFORMED_FUNCTION_CALL" || error.type === "UNEXPECTED_TOOL_CALL")) {
|
|
14041
13998
|
return {
|
|
@@ -14064,14 +14021,53 @@ ${thought.description}`;
|
|
|
14064
14021
|
getAcpErrorMessage(error)
|
|
14065
14022
|
);
|
|
14066
14023
|
}
|
|
14067
|
-
|
|
14068
|
-
|
|
14069
|
-
|
|
14070
|
-
|
|
14071
|
-
|
|
14072
|
-
|
|
14073
|
-
|
|
14024
|
+
totalInputTokens += turnInputTokens;
|
|
14025
|
+
totalOutputTokens += turnOutputTokens;
|
|
14026
|
+
if (turnInputTokens > 0 || turnOutputTokens > 0) {
|
|
14027
|
+
const existing = modelUsageMap.get(turnModelId) ?? {
|
|
14028
|
+
input: 0,
|
|
14029
|
+
output: 0
|
|
14030
|
+
};
|
|
14031
|
+
existing.input += turnInputTokens;
|
|
14032
|
+
existing.output += turnOutputTokens;
|
|
14033
|
+
modelUsageMap.set(turnModelId, existing);
|
|
14034
|
+
}
|
|
14035
|
+
if (stopReason !== "end_turn") {
|
|
14036
|
+
return {
|
|
14037
|
+
stopReason,
|
|
14038
|
+
_meta: {
|
|
14039
|
+
quota: {
|
|
14040
|
+
token_count: {
|
|
14041
|
+
input_tokens: totalInputTokens,
|
|
14042
|
+
output_tokens: totalOutputTokens
|
|
14043
|
+
},
|
|
14044
|
+
model_usage: Array.from(modelUsageMap.entries()).map(
|
|
14045
|
+
([modelName, counts]) => ({
|
|
14046
|
+
model: modelName,
|
|
14047
|
+
token_count: {
|
|
14048
|
+
input_tokens: counts.input,
|
|
14049
|
+
output_tokens: counts.output
|
|
14050
|
+
}
|
|
14051
|
+
})
|
|
14052
|
+
)
|
|
14053
|
+
}
|
|
14054
|
+
}
|
|
14055
|
+
};
|
|
14056
|
+
}
|
|
14057
|
+
if (toolCallRequests.length === 0) {
|
|
14058
|
+
break;
|
|
14059
|
+
}
|
|
14060
|
+
const toolResponseParts = [];
|
|
14061
|
+
for (const tReq of toolCallRequests) {
|
|
14062
|
+
const fc = {
|
|
14063
|
+
id: tReq.callId,
|
|
14064
|
+
name: tReq.name,
|
|
14065
|
+
args: tReq.args
|
|
14066
|
+
};
|
|
14067
|
+
const response = await this.runTool(pendingSend.signal, promptId, fc);
|
|
14068
|
+
toolResponseParts.push(...response);
|
|
14074
14069
|
}
|
|
14070
|
+
currentParts = toolResponseParts;
|
|
14075
14071
|
}
|
|
14076
14072
|
const modelUsageArray = Array.from(modelUsageMap.entries()).map(
|
|
14077
14073
|
([modelName, counts]) => ({
|
|
@@ -14118,7 +14114,7 @@ ${thought.description}`;
|
|
|
14118
14114
|
await this.connection.sessionUpdate(params);
|
|
14119
14115
|
}
|
|
14120
14116
|
async runTool(abortSignal, promptId, fc) {
|
|
14121
|
-
const callId = fc.id ??
|
|
14117
|
+
const callId = fc.id ?? this.generateCallId(fc.name || "unknown");
|
|
14122
14118
|
const args = fc.args ?? {};
|
|
14123
14119
|
const startTime = Date.now();
|
|
14124
14120
|
const errorResponse = (error) => {
|
|
@@ -14410,7 +14406,7 @@ ${thought.description}`;
|
|
|
14410
14406
|
let resolvedSuccessfully = false;
|
|
14411
14407
|
let readDirectly = false;
|
|
14412
14408
|
try {
|
|
14413
|
-
const absolutePath =
|
|
14409
|
+
const absolutePath = path12.resolve(
|
|
14414
14410
|
this.context.config.getTargetDir(),
|
|
14415
14411
|
pathName
|
|
14416
14412
|
);
|
|
@@ -14486,7 +14482,7 @@ ${thought.description}`;
|
|
|
14486
14482
|
}
|
|
14487
14483
|
}
|
|
14488
14484
|
if (!validationError) {
|
|
14489
|
-
if ((
|
|
14485
|
+
if ((path12.isAbsolute(pathName) || !isWithinRoot(
|
|
14490
14486
|
absolutePath,
|
|
14491
14487
|
this.context.config.getTargetDir()
|
|
14492
14488
|
)) && !readDirectly) {
|
|
@@ -14590,7 +14586,7 @@ ${contentToPush}`;
|
|
|
14590
14586
|
const lines = globResult.llmContent.split("\n");
|
|
14591
14587
|
if (lines.length > 1 && lines[1]) {
|
|
14592
14588
|
const firstMatchAbsolute = lines[1].trim();
|
|
14593
|
-
currentPathSpec =
|
|
14589
|
+
currentPathSpec = path12.relative(
|
|
14594
14590
|
this.context.config.getTargetDir(),
|
|
14595
14591
|
firstMatchAbsolute
|
|
14596
14592
|
);
|
|
@@ -14672,7 +14668,7 @@ ${contentToPush}`;
|
|
|
14672
14668
|
const toolArgs = {
|
|
14673
14669
|
include: pathSpecsToRead
|
|
14674
14670
|
};
|
|
14675
|
-
const callId =
|
|
14671
|
+
const callId = this.generateCallId(readManyFilesTool.name);
|
|
14676
14672
|
try {
|
|
14677
14673
|
const invocation = readManyFilesTool.build(toolArgs);
|
|
14678
14674
|
await this.sendUpdate({
|
|
@@ -14750,321 +14746,524 @@ Content from @${filePathSpecInContent}:
|
|
|
14750
14746
|
throw error;
|
|
14751
14747
|
}
|
|
14752
14748
|
}
|
|
14753
|
-
if (directContents.length > 0) {
|
|
14754
|
-
const hasReferenceStart = processedQueryParts.some(
|
|
14755
|
-
(p) => "text" in p && typeof p.text === "string" && p.text.includes(REFERENCE_CONTENT_START)
|
|
14749
|
+
if (directContents.length > 0) {
|
|
14750
|
+
const hasReferenceStart = processedQueryParts.some(
|
|
14751
|
+
(p) => "text" in p && typeof p.text === "string" && p.text.includes(REFERENCE_CONTENT_START)
|
|
14752
|
+
);
|
|
14753
|
+
if (!hasReferenceStart) {
|
|
14754
|
+
processedQueryParts.push({
|
|
14755
|
+
text: `
|
|
14756
|
+
${REFERENCE_CONTENT_START}`
|
|
14757
|
+
});
|
|
14758
|
+
}
|
|
14759
|
+
for (const item of directContents) {
|
|
14760
|
+
processedQueryParts.push({
|
|
14761
|
+
text: `
|
|
14762
|
+
Content from @${item.spec}:
|
|
14763
|
+
`
|
|
14764
|
+
});
|
|
14765
|
+
if (item.content) {
|
|
14766
|
+
processedQueryParts.push({ text: item.content });
|
|
14767
|
+
} else if (item.part) {
|
|
14768
|
+
processedQueryParts.push(item.part);
|
|
14769
|
+
}
|
|
14770
|
+
}
|
|
14771
|
+
}
|
|
14772
|
+
if (embeddedContext.length > 0) {
|
|
14773
|
+
processedQueryParts.push({
|
|
14774
|
+
text: "\n--- Content from referenced context ---"
|
|
14775
|
+
});
|
|
14776
|
+
for (const contextPart of embeddedContext) {
|
|
14777
|
+
processedQueryParts.push({
|
|
14778
|
+
text: `
|
|
14779
|
+
Content from @${contextPart.uri}:
|
|
14780
|
+
`
|
|
14781
|
+
});
|
|
14782
|
+
if ("text" in contextPart) {
|
|
14783
|
+
processedQueryParts.push({
|
|
14784
|
+
text: contextPart.text
|
|
14785
|
+
});
|
|
14786
|
+
} else {
|
|
14787
|
+
processedQueryParts.push({
|
|
14788
|
+
inlineData: {
|
|
14789
|
+
mimeType: contextPart.mimeType ?? "application/octet-stream",
|
|
14790
|
+
data: contextPart.blob
|
|
14791
|
+
}
|
|
14792
|
+
});
|
|
14793
|
+
}
|
|
14794
|
+
}
|
|
14795
|
+
}
|
|
14796
|
+
return processedQueryParts;
|
|
14797
|
+
}
|
|
14798
|
+
debug(msg) {
|
|
14799
|
+
if (this.context.config.getDebugMode()) {
|
|
14800
|
+
debugLogger.warn(msg);
|
|
14801
|
+
}
|
|
14802
|
+
}
|
|
14803
|
+
};
|
|
14804
|
+
|
|
14805
|
+
// packages/cli/src/acp/acpFileSystemService.ts
|
|
14806
|
+
import os5 from "node:os";
|
|
14807
|
+
import path13 from "node:path";
|
|
14808
|
+
var AcpFileSystemService = class {
|
|
14809
|
+
constructor(connection, sessionId, capabilities, fallback, root) {
|
|
14810
|
+
this.connection = connection;
|
|
14811
|
+
this.sessionId = sessionId;
|
|
14812
|
+
this.capabilities = capabilities;
|
|
14813
|
+
this.fallback = fallback;
|
|
14814
|
+
this.root = root;
|
|
14815
|
+
}
|
|
14816
|
+
geminiDir = path13.join(os5.homedir(), ".gemini");
|
|
14817
|
+
shouldUseFallback(filePath) {
|
|
14818
|
+
return !isWithinRoot(filePath, this.root) || isWithinRoot(filePath, this.geminiDir);
|
|
14819
|
+
}
|
|
14820
|
+
normalizeFileSystemError(err) {
|
|
14821
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
14822
|
+
if (errorMessage.includes("Resource not found") || errorMessage.includes("ENOENT") || errorMessage.includes("does not exist") || errorMessage.includes("No such file")) {
|
|
14823
|
+
const newErr = new Error(errorMessage);
|
|
14824
|
+
newErr.code = "ENOENT";
|
|
14825
|
+
throw newErr;
|
|
14826
|
+
}
|
|
14827
|
+
throw err;
|
|
14828
|
+
}
|
|
14829
|
+
async readTextFile(filePath) {
|
|
14830
|
+
if (!this.capabilities.readTextFile || this.shouldUseFallback(filePath)) {
|
|
14831
|
+
return this.fallback.readTextFile(filePath);
|
|
14832
|
+
}
|
|
14833
|
+
try {
|
|
14834
|
+
const response = await this.connection.readTextFile({
|
|
14835
|
+
path: filePath,
|
|
14836
|
+
sessionId: this.sessionId
|
|
14837
|
+
});
|
|
14838
|
+
return response.content;
|
|
14839
|
+
} catch (err) {
|
|
14840
|
+
this.normalizeFileSystemError(err);
|
|
14841
|
+
}
|
|
14842
|
+
}
|
|
14843
|
+
async writeTextFile(filePath, content) {
|
|
14844
|
+
if (!this.capabilities.writeTextFile || this.shouldUseFallback(filePath)) {
|
|
14845
|
+
return this.fallback.writeTextFile(filePath, content);
|
|
14846
|
+
}
|
|
14847
|
+
try {
|
|
14848
|
+
await this.connection.writeTextFile({
|
|
14849
|
+
path: filePath,
|
|
14850
|
+
content,
|
|
14851
|
+
sessionId: this.sessionId
|
|
14852
|
+
});
|
|
14853
|
+
} catch (err) {
|
|
14854
|
+
this.normalizeFileSystemError(err);
|
|
14855
|
+
}
|
|
14856
|
+
}
|
|
14857
|
+
};
|
|
14858
|
+
|
|
14859
|
+
// packages/cli/src/acp/acpSessionManager.ts
|
|
14860
|
+
var AcpSessionManager = class {
|
|
14861
|
+
constructor(settings, argv, connection) {
|
|
14862
|
+
this.settings = settings;
|
|
14863
|
+
this.argv = argv;
|
|
14864
|
+
this.connection = connection;
|
|
14865
|
+
}
|
|
14866
|
+
sessions = /* @__PURE__ */ new Map();
|
|
14867
|
+
clientCapabilities;
|
|
14868
|
+
setClientCapabilities(capabilities) {
|
|
14869
|
+
this.clientCapabilities = capabilities;
|
|
14870
|
+
}
|
|
14871
|
+
getSession(sessionId) {
|
|
14872
|
+
return this.sessions.get(sessionId);
|
|
14873
|
+
}
|
|
14874
|
+
async newSession({ cwd, mcpServers }, authDetails) {
|
|
14875
|
+
const sessionId = randomUUID2();
|
|
14876
|
+
const loadedSettings = loadSettings(cwd);
|
|
14877
|
+
const config = await this.newSessionConfig(
|
|
14878
|
+
sessionId,
|
|
14879
|
+
cwd,
|
|
14880
|
+
mcpServers,
|
|
14881
|
+
loadedSettings
|
|
14882
|
+
);
|
|
14883
|
+
const authType = loadedSettings.merged.security.auth.selectedType || AuthType.USE_GEMINI;
|
|
14884
|
+
let isAuthenticated = false;
|
|
14885
|
+
let authErrorMessage = "";
|
|
14886
|
+
try {
|
|
14887
|
+
await config.refreshAuth(
|
|
14888
|
+
authType,
|
|
14889
|
+
authDetails.apiKey,
|
|
14890
|
+
authDetails.baseUrl,
|
|
14891
|
+
authDetails.customHeaders
|
|
14892
|
+
);
|
|
14893
|
+
isAuthenticated = true;
|
|
14894
|
+
const contentGeneratorConfig = config.getContentGeneratorConfig();
|
|
14895
|
+
if (authType === AuthType.USE_GEMINI && (!contentGeneratorConfig || !contentGeneratorConfig.apiKey)) {
|
|
14896
|
+
isAuthenticated = false;
|
|
14897
|
+
authErrorMessage = "Gemini API key is missing or not configured.";
|
|
14898
|
+
}
|
|
14899
|
+
} catch (e) {
|
|
14900
|
+
isAuthenticated = false;
|
|
14901
|
+
authErrorMessage = getAcpErrorMessage(e);
|
|
14902
|
+
debugLogger.error(
|
|
14903
|
+
`Authentication failed: ${e instanceof Error ? e.stack : e}`
|
|
14904
|
+
);
|
|
14905
|
+
}
|
|
14906
|
+
if (!isAuthenticated) {
|
|
14907
|
+
throw new RequestError(
|
|
14908
|
+
-32e3,
|
|
14909
|
+
authErrorMessage || "Authentication required."
|
|
14910
|
+
);
|
|
14911
|
+
}
|
|
14912
|
+
if (this.clientCapabilities?.fs) {
|
|
14913
|
+
const acpFileSystemService = new AcpFileSystemService(
|
|
14914
|
+
this.connection,
|
|
14915
|
+
sessionId,
|
|
14916
|
+
this.clientCapabilities.fs,
|
|
14917
|
+
config.getFileSystemService(),
|
|
14918
|
+
cwd
|
|
14919
|
+
);
|
|
14920
|
+
config.setFileSystemService(acpFileSystemService);
|
|
14921
|
+
}
|
|
14922
|
+
await config.initialize();
|
|
14923
|
+
startupProfiler.flush(config);
|
|
14924
|
+
startAutoMemoryIfEnabled(config);
|
|
14925
|
+
const geminiClient = config.getGeminiClient();
|
|
14926
|
+
const chat = await geminiClient.startChat();
|
|
14927
|
+
const session = new Session(
|
|
14928
|
+
sessionId,
|
|
14929
|
+
chat,
|
|
14930
|
+
config,
|
|
14931
|
+
this.connection,
|
|
14932
|
+
this.settings
|
|
14933
|
+
);
|
|
14934
|
+
this.sessions.set(sessionId, session);
|
|
14935
|
+
setTimeout(() => {
|
|
14936
|
+
session.sendAvailableCommands();
|
|
14937
|
+
}, 0);
|
|
14938
|
+
const { availableModels, currentModelId } = buildAvailableModels(
|
|
14939
|
+
config,
|
|
14940
|
+
loadedSettings
|
|
14941
|
+
);
|
|
14942
|
+
const response = {
|
|
14943
|
+
sessionId,
|
|
14944
|
+
modes: {
|
|
14945
|
+
availableModes: buildAvailableModes(config.isPlanEnabled()),
|
|
14946
|
+
currentModeId: config.getApprovalMode()
|
|
14947
|
+
},
|
|
14948
|
+
models: {
|
|
14949
|
+
availableModels,
|
|
14950
|
+
currentModelId
|
|
14951
|
+
}
|
|
14952
|
+
};
|
|
14953
|
+
return response;
|
|
14954
|
+
}
|
|
14955
|
+
async loadSession({ sessionId, cwd, mcpServers }, authDetails) {
|
|
14956
|
+
const config = await this.initializeSessionConfig(
|
|
14957
|
+
sessionId,
|
|
14958
|
+
cwd,
|
|
14959
|
+
mcpServers,
|
|
14960
|
+
authDetails
|
|
14961
|
+
);
|
|
14962
|
+
const sessionSelector = new SessionSelector(config.storage);
|
|
14963
|
+
const { sessionData, sessionPath } = await sessionSelector.resolveSession(sessionId);
|
|
14964
|
+
const clientHistory = convertSessionToClientHistory(sessionData.messages);
|
|
14965
|
+
const geminiClient = config.getGeminiClient();
|
|
14966
|
+
await geminiClient.initialize();
|
|
14967
|
+
await geminiClient.resumeChat(clientHistory, {
|
|
14968
|
+
conversation: sessionData,
|
|
14969
|
+
filePath: sessionPath
|
|
14970
|
+
});
|
|
14971
|
+
const session = new Session(
|
|
14972
|
+
sessionId,
|
|
14973
|
+
geminiClient.getChat(),
|
|
14974
|
+
config,
|
|
14975
|
+
this.connection,
|
|
14976
|
+
this.settings
|
|
14977
|
+
);
|
|
14978
|
+
this.sessions.set(sessionId, session);
|
|
14979
|
+
session.streamHistory(sessionData.messages);
|
|
14980
|
+
setTimeout(() => {
|
|
14981
|
+
session.sendAvailableCommands();
|
|
14982
|
+
}, 0);
|
|
14983
|
+
const { availableModels, currentModelId } = buildAvailableModels(
|
|
14984
|
+
config,
|
|
14985
|
+
this.settings
|
|
14986
|
+
);
|
|
14987
|
+
const response = {
|
|
14988
|
+
modes: {
|
|
14989
|
+
availableModes: buildAvailableModes(config.isPlanEnabled()),
|
|
14990
|
+
currentModeId: config.getApprovalMode()
|
|
14991
|
+
},
|
|
14992
|
+
models: {
|
|
14993
|
+
availableModels,
|
|
14994
|
+
currentModelId
|
|
14995
|
+
}
|
|
14996
|
+
};
|
|
14997
|
+
return response;
|
|
14998
|
+
}
|
|
14999
|
+
async initializeSessionConfig(sessionId, cwd, mcpServers, authDetails) {
|
|
15000
|
+
const selectedAuthType = this.settings.merged.security.auth.selectedType;
|
|
15001
|
+
if (!selectedAuthType) {
|
|
15002
|
+
throw RequestError.authRequired();
|
|
15003
|
+
}
|
|
15004
|
+
const config = await this.newSessionConfig(sessionId, cwd, mcpServers);
|
|
15005
|
+
try {
|
|
15006
|
+
await config.refreshAuth(
|
|
15007
|
+
selectedAuthType,
|
|
15008
|
+
authDetails.apiKey,
|
|
15009
|
+
authDetails.baseUrl,
|
|
15010
|
+
authDetails.customHeaders
|
|
15011
|
+
);
|
|
15012
|
+
} catch (e) {
|
|
15013
|
+
debugLogger.error(`Authentication failed: ${e}`);
|
|
15014
|
+
throw RequestError.authRequired();
|
|
15015
|
+
}
|
|
15016
|
+
if (this.clientCapabilities?.fs) {
|
|
15017
|
+
const acpFileSystemService = new AcpFileSystemService(
|
|
15018
|
+
this.connection,
|
|
15019
|
+
sessionId,
|
|
15020
|
+
this.clientCapabilities.fs,
|
|
15021
|
+
config.getFileSystemService(),
|
|
15022
|
+
cwd
|
|
14756
15023
|
);
|
|
14757
|
-
|
|
14758
|
-
processedQueryParts.push({
|
|
14759
|
-
text: `
|
|
14760
|
-
${REFERENCE_CONTENT_START}`
|
|
14761
|
-
});
|
|
14762
|
-
}
|
|
14763
|
-
for (const item of directContents) {
|
|
14764
|
-
processedQueryParts.push({
|
|
14765
|
-
text: `
|
|
14766
|
-
Content from @${item.spec}:
|
|
14767
|
-
`
|
|
14768
|
-
});
|
|
14769
|
-
if (item.content) {
|
|
14770
|
-
processedQueryParts.push({ text: item.content });
|
|
14771
|
-
} else if (item.part) {
|
|
14772
|
-
processedQueryParts.push(item.part);
|
|
14773
|
-
}
|
|
14774
|
-
}
|
|
15024
|
+
config.setFileSystemService(acpFileSystemService);
|
|
14775
15025
|
}
|
|
14776
|
-
|
|
14777
|
-
|
|
14778
|
-
|
|
14779
|
-
|
|
14780
|
-
|
|
14781
|
-
|
|
14782
|
-
|
|
14783
|
-
|
|
14784
|
-
|
|
14785
|
-
|
|
14786
|
-
|
|
14787
|
-
|
|
14788
|
-
|
|
14789
|
-
|
|
14790
|
-
|
|
14791
|
-
|
|
14792
|
-
|
|
14793
|
-
|
|
14794
|
-
|
|
14795
|
-
|
|
14796
|
-
|
|
15026
|
+
await config.initialize();
|
|
15027
|
+
startupProfiler.flush(config);
|
|
15028
|
+
startAutoMemoryIfEnabled(config);
|
|
15029
|
+
return config;
|
|
15030
|
+
}
|
|
15031
|
+
async newSessionConfig(sessionId, cwd, mcpServers, loadedSettings) {
|
|
15032
|
+
const currentSettings = loadedSettings || this.settings;
|
|
15033
|
+
const mergedMcpServers = { ...currentSettings.merged.mcpServers };
|
|
15034
|
+
for (const server of mcpServers) {
|
|
15035
|
+
if ("type" in server && (server.type === "sse" || server.type === "http")) {
|
|
15036
|
+
const headers = Object.fromEntries(
|
|
15037
|
+
server.headers.map(({ name, value }) => [name, value])
|
|
15038
|
+
);
|
|
15039
|
+
mergedMcpServers[server.name] = new MCPServerConfig(
|
|
15040
|
+
void 0,
|
|
15041
|
+
// command
|
|
15042
|
+
void 0,
|
|
15043
|
+
// args
|
|
15044
|
+
void 0,
|
|
15045
|
+
// env
|
|
15046
|
+
void 0,
|
|
15047
|
+
// cwd
|
|
15048
|
+
server.type === "sse" ? server.url : void 0,
|
|
15049
|
+
// url (sse)
|
|
15050
|
+
server.type === "http" ? server.url : void 0,
|
|
15051
|
+
// httpUrl
|
|
15052
|
+
headers
|
|
15053
|
+
);
|
|
15054
|
+
} else if ("command" in server) {
|
|
15055
|
+
const env2 = {};
|
|
15056
|
+
for (const { name: envName, value } of server.env) {
|
|
15057
|
+
env2[envName] = value;
|
|
14797
15058
|
}
|
|
15059
|
+
mergedMcpServers[server.name] = new MCPServerConfig(
|
|
15060
|
+
server.command,
|
|
15061
|
+
server.args,
|
|
15062
|
+
env2,
|
|
15063
|
+
cwd
|
|
15064
|
+
);
|
|
14798
15065
|
}
|
|
14799
15066
|
}
|
|
14800
|
-
|
|
14801
|
-
|
|
14802
|
-
|
|
14803
|
-
|
|
14804
|
-
|
|
14805
|
-
|
|
15067
|
+
const settings = {
|
|
15068
|
+
...currentSettings.merged,
|
|
15069
|
+
mcpServers: mergedMcpServers
|
|
15070
|
+
};
|
|
15071
|
+
const config = await loadCliConfig(settings, sessionId, this.argv, { cwd });
|
|
15072
|
+
createPolicyUpdater(
|
|
15073
|
+
config.getPolicyEngine(),
|
|
15074
|
+
config.messageBus,
|
|
15075
|
+
config.storage
|
|
15076
|
+
);
|
|
15077
|
+
return config;
|
|
14806
15078
|
}
|
|
14807
15079
|
};
|
|
14808
|
-
|
|
14809
|
-
|
|
14810
|
-
|
|
15080
|
+
|
|
15081
|
+
// packages/cli/src/acp/acpRpcDispatcher.ts
|
|
15082
|
+
var GeminiAgent = class {
|
|
15083
|
+
constructor(context, settings, argv, connection) {
|
|
15084
|
+
this.context = context;
|
|
15085
|
+
this.settings = settings;
|
|
15086
|
+
this.sessionManager = new AcpSessionManager(settings, argv, connection);
|
|
14811
15087
|
}
|
|
14812
|
-
|
|
14813
|
-
|
|
14814
|
-
|
|
14815
|
-
|
|
14816
|
-
|
|
14817
|
-
|
|
14818
|
-
|
|
14819
|
-
if ("fileName" in toolResult.returnDisplay) {
|
|
14820
|
-
return {
|
|
14821
|
-
type: "diff",
|
|
14822
|
-
path: toolResult.returnDisplay.filePath ?? toolResult.returnDisplay.fileName,
|
|
14823
|
-
oldText: toolResult.returnDisplay.originalContent,
|
|
14824
|
-
newText: toolResult.returnDisplay.newContent,
|
|
14825
|
-
_meta: {
|
|
14826
|
-
kind: !toolResult.returnDisplay.originalContent ? "add" : toolResult.returnDisplay.newContent === "" ? "delete" : "modify"
|
|
14827
|
-
}
|
|
14828
|
-
};
|
|
14829
|
-
}
|
|
14830
|
-
return null;
|
|
15088
|
+
apiKey;
|
|
15089
|
+
baseUrl;
|
|
15090
|
+
customHeaders;
|
|
15091
|
+
sessionManager;
|
|
15092
|
+
async initialize(args) {
|
|
15093
|
+
if (args.clientCapabilities) {
|
|
15094
|
+
this.sessionManager.setClientCapabilities(args.clientCapabilities);
|
|
14831
15095
|
}
|
|
14832
|
-
|
|
14833
|
-
|
|
14834
|
-
|
|
14835
|
-
|
|
14836
|
-
|
|
14837
|
-
|
|
14838
|
-
|
|
14839
|
-
|
|
14840
|
-
|
|
14841
|
-
|
|
14842
|
-
|
|
14843
|
-
|
|
14844
|
-
|
|
14845
|
-
|
|
14846
|
-
}
|
|
14847
|
-
];
|
|
14848
|
-
function toPermissionOptions(confirmation, config, enablePermanentToolApproval = false) {
|
|
14849
|
-
const disableAlwaysAllow = config.getDisableAlwaysAllow();
|
|
14850
|
-
const options = [];
|
|
14851
|
-
if (!disableAlwaysAllow) {
|
|
14852
|
-
switch (confirmation.type) {
|
|
14853
|
-
case "edit":
|
|
14854
|
-
options.push({
|
|
14855
|
-
optionId: ToolConfirmationOutcome.ProceedAlways,
|
|
14856
|
-
name: "Allow for this session",
|
|
14857
|
-
kind: "allow_always"
|
|
14858
|
-
});
|
|
14859
|
-
if (enablePermanentToolApproval) {
|
|
14860
|
-
options.push({
|
|
14861
|
-
optionId: ToolConfirmationOutcome.ProceedAlwaysAndSave,
|
|
14862
|
-
name: "Allow for this file in all future sessions",
|
|
14863
|
-
kind: "allow_always"
|
|
14864
|
-
});
|
|
14865
|
-
}
|
|
14866
|
-
break;
|
|
14867
|
-
case "exec":
|
|
14868
|
-
options.push({
|
|
14869
|
-
optionId: ToolConfirmationOutcome.ProceedAlways,
|
|
14870
|
-
name: "Allow for this session",
|
|
14871
|
-
kind: "allow_always"
|
|
14872
|
-
});
|
|
14873
|
-
if (enablePermanentToolApproval) {
|
|
14874
|
-
options.push({
|
|
14875
|
-
optionId: ToolConfirmationOutcome.ProceedAlwaysAndSave,
|
|
14876
|
-
name: "Allow this command for all future sessions",
|
|
14877
|
-
kind: "allow_always"
|
|
14878
|
-
});
|
|
15096
|
+
const authMethods = [
|
|
15097
|
+
{
|
|
15098
|
+
id: AuthType.LOGIN_WITH_GOOGLE,
|
|
15099
|
+
name: "Log in with Google",
|
|
15100
|
+
description: "Log in with your Google account"
|
|
15101
|
+
},
|
|
15102
|
+
{
|
|
15103
|
+
id: AuthType.USE_GEMINI,
|
|
15104
|
+
name: "Gemini API key",
|
|
15105
|
+
description: "Use an API key with Gemini Developer API",
|
|
15106
|
+
_meta: {
|
|
15107
|
+
"api-key": {
|
|
15108
|
+
provider: "google"
|
|
15109
|
+
}
|
|
14879
15110
|
}
|
|
14880
|
-
|
|
14881
|
-
|
|
14882
|
-
|
|
14883
|
-
|
|
14884
|
-
|
|
14885
|
-
|
|
14886
|
-
|
|
14887
|
-
|
|
14888
|
-
|
|
14889
|
-
|
|
14890
|
-
|
|
14891
|
-
|
|
15111
|
+
},
|
|
15112
|
+
{
|
|
15113
|
+
id: AuthType.USE_VERTEX_AI,
|
|
15114
|
+
name: "Vertex AI",
|
|
15115
|
+
description: "Use an API key with Vertex AI GenAI API"
|
|
15116
|
+
},
|
|
15117
|
+
{
|
|
15118
|
+
id: AuthType.GATEWAY,
|
|
15119
|
+
name: "AI API Gateway",
|
|
15120
|
+
description: "Use a custom AI API Gateway",
|
|
15121
|
+
_meta: {
|
|
15122
|
+
gateway: {
|
|
15123
|
+
protocol: "google",
|
|
15124
|
+
restartRequired: "false"
|
|
14892
15125
|
}
|
|
14893
|
-
);
|
|
14894
|
-
if (enablePermanentToolApproval) {
|
|
14895
|
-
options.push({
|
|
14896
|
-
optionId: ToolConfirmationOutcome.ProceedAlwaysAndSave,
|
|
14897
|
-
name: "Allow tool for all future sessions",
|
|
14898
|
-
kind: "allow_always"
|
|
14899
|
-
});
|
|
14900
15126
|
}
|
|
14901
|
-
|
|
14902
|
-
|
|
14903
|
-
|
|
14904
|
-
|
|
14905
|
-
|
|
14906
|
-
|
|
14907
|
-
|
|
14908
|
-
|
|
14909
|
-
|
|
14910
|
-
|
|
14911
|
-
|
|
14912
|
-
|
|
14913
|
-
|
|
15127
|
+
}
|
|
15128
|
+
];
|
|
15129
|
+
await this.context.config.initialize();
|
|
15130
|
+
const version = await getVersion();
|
|
15131
|
+
return {
|
|
15132
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
15133
|
+
authMethods,
|
|
15134
|
+
agentInfo: {
|
|
15135
|
+
name: "gemini-cli",
|
|
15136
|
+
title: "Gemini CLI",
|
|
15137
|
+
version
|
|
15138
|
+
},
|
|
15139
|
+
agentCapabilities: {
|
|
15140
|
+
loadSession: true,
|
|
15141
|
+
promptCapabilities: {
|
|
15142
|
+
image: true,
|
|
15143
|
+
audio: true,
|
|
15144
|
+
embeddedContext: true
|
|
15145
|
+
},
|
|
15146
|
+
mcpCapabilities: {
|
|
15147
|
+
http: true,
|
|
15148
|
+
sse: true
|
|
14914
15149
|
}
|
|
14915
|
-
|
|
14916
|
-
|
|
14917
|
-
case "exit_plan_mode":
|
|
14918
|
-
break;
|
|
14919
|
-
default:
|
|
14920
|
-
break;
|
|
14921
|
-
}
|
|
15150
|
+
}
|
|
15151
|
+
};
|
|
14922
15152
|
}
|
|
14923
|
-
|
|
14924
|
-
|
|
14925
|
-
|
|
14926
|
-
|
|
14927
|
-
|
|
14928
|
-
|
|
14929
|
-
case "ask_user":
|
|
14930
|
-
case "exit_plan_mode":
|
|
14931
|
-
case "sandbox_expansion":
|
|
14932
|
-
break;
|
|
14933
|
-
default: {
|
|
14934
|
-
const unreachable = confirmation;
|
|
14935
|
-
throw new Error(`Unexpected: ${unreachable}`);
|
|
15153
|
+
async authenticate(req) {
|
|
15154
|
+
const { methodId } = req;
|
|
15155
|
+
const method = external_exports.nativeEnum(AuthType).parse(methodId);
|
|
15156
|
+
const selectedAuthType = this.settings.merged.security.auth.selectedType;
|
|
15157
|
+
if (selectedAuthType && selectedAuthType !== method) {
|
|
15158
|
+
await clearCachedCredentialFile();
|
|
14936
15159
|
}
|
|
14937
|
-
|
|
14938
|
-
|
|
14939
|
-
|
|
14940
|
-
|
|
14941
|
-
|
|
14942
|
-
|
|
14943
|
-
|
|
14944
|
-
|
|
14945
|
-
|
|
14946
|
-
|
|
14947
|
-
|
|
14948
|
-
|
|
14949
|
-
|
|
14950
|
-
|
|
14951
|
-
|
|
14952
|
-
|
|
14953
|
-
|
|
14954
|
-
|
|
14955
|
-
|
|
14956
|
-
|
|
14957
|
-
|
|
14958
|
-
|
|
14959
|
-
|
|
14960
|
-
}
|
|
14961
|
-
|
|
14962
|
-
|
|
14963
|
-
|
|
14964
|
-
|
|
14965
|
-
|
|
14966
|
-
|
|
14967
|
-
|
|
14968
|
-
|
|
14969
|
-
|
|
14970
|
-
|
|
14971
|
-
description: "Auto-approves edit tools"
|
|
14972
|
-
},
|
|
14973
|
-
{
|
|
14974
|
-
id: ApprovalMode.YOLO,
|
|
14975
|
-
name: "YOLO",
|
|
14976
|
-
description: "Auto-approves all tools"
|
|
15160
|
+
const meta = hasMeta(req) ? req._meta : void 0;
|
|
15161
|
+
const apiKey = typeof meta?.["api-key"] === "string" ? meta["api-key"] : void 0;
|
|
15162
|
+
try {
|
|
15163
|
+
if (apiKey) {
|
|
15164
|
+
this.apiKey = apiKey;
|
|
15165
|
+
}
|
|
15166
|
+
const gatewaySchema = external_exports.object({
|
|
15167
|
+
baseUrl: external_exports.string().optional(),
|
|
15168
|
+
headers: external_exports.record(external_exports.string()).optional()
|
|
15169
|
+
});
|
|
15170
|
+
let baseUrl;
|
|
15171
|
+
let headers;
|
|
15172
|
+
if (meta?.["gateway"]) {
|
|
15173
|
+
const result = gatewaySchema.safeParse(meta["gateway"]);
|
|
15174
|
+
if (result.success) {
|
|
15175
|
+
baseUrl = result.data.baseUrl;
|
|
15176
|
+
headers = result.data.headers;
|
|
15177
|
+
} else {
|
|
15178
|
+
throw new RequestError(
|
|
15179
|
+
-32602,
|
|
15180
|
+
`Malformed gateway payload: ${result.error.message}`
|
|
15181
|
+
);
|
|
15182
|
+
}
|
|
15183
|
+
}
|
|
15184
|
+
this.baseUrl = baseUrl;
|
|
15185
|
+
this.customHeaders = headers;
|
|
15186
|
+
await this.context.config.refreshAuth(
|
|
15187
|
+
method,
|
|
15188
|
+
apiKey ?? this.apiKey,
|
|
15189
|
+
baseUrl,
|
|
15190
|
+
headers
|
|
15191
|
+
);
|
|
15192
|
+
} catch (e) {
|
|
15193
|
+
throw new RequestError(-32e3, getAcpErrorMessage(e));
|
|
14977
15194
|
}
|
|
14978
|
-
|
|
14979
|
-
|
|
14980
|
-
|
|
14981
|
-
|
|
14982
|
-
|
|
14983
|
-
description: "Read-only mode"
|
|
14984
|
-
});
|
|
15195
|
+
this.settings.setValue(
|
|
15196
|
+
"User" /* User */,
|
|
15197
|
+
"security.auth.selectedType",
|
|
15198
|
+
method
|
|
15199
|
+
);
|
|
14985
15200
|
}
|
|
14986
|
-
|
|
14987
|
-
}
|
|
14988
|
-
function buildAvailableModels(config, settings) {
|
|
14989
|
-
const preferredModel = config.getModel() || DEFAULT_GEMINI_MODEL_AUTO;
|
|
14990
|
-
const shouldShowPreviewModels = config.getHasAccessToPreviewModel();
|
|
14991
|
-
const useGemini31 = config.getGemini31LaunchedSync?.() ?? false;
|
|
14992
|
-
const useGemini31FlashLite = config.getGemini31FlashLiteLaunchedSync?.() ?? false;
|
|
14993
|
-
const selectedAuthType = settings.merged.security.auth.selectedType;
|
|
14994
|
-
const useCustomToolModel = useGemini31 && selectedAuthType === AuthType.USE_GEMINI;
|
|
14995
|
-
if (config.getExperimentalDynamicModelConfiguration?.() === true && config.getModelConfigService) {
|
|
14996
|
-
const options = config.getModelConfigService().getAvailableModelOptions({
|
|
14997
|
-
useGemini3_1: useGemini31,
|
|
14998
|
-
useGemini3_1FlashLite: useGemini31FlashLite,
|
|
14999
|
-
useCustomTools: useCustomToolModel,
|
|
15000
|
-
hasAccessToPreview: shouldShowPreviewModels
|
|
15001
|
-
});
|
|
15201
|
+
getAuthDetails() {
|
|
15002
15202
|
return {
|
|
15003
|
-
|
|
15004
|
-
|
|
15203
|
+
apiKey: this.apiKey,
|
|
15204
|
+
baseUrl: this.baseUrl,
|
|
15205
|
+
customHeaders: this.customHeaders
|
|
15005
15206
|
};
|
|
15006
15207
|
}
|
|
15007
|
-
|
|
15008
|
-
|
|
15009
|
-
|
|
15010
|
-
|
|
15011
|
-
|
|
15208
|
+
async newSession(params) {
|
|
15209
|
+
return this.sessionManager.newSession(params, this.getAuthDetails());
|
|
15210
|
+
}
|
|
15211
|
+
async loadSession(params) {
|
|
15212
|
+
return this.sessionManager.loadSession(params, this.getAuthDetails());
|
|
15213
|
+
}
|
|
15214
|
+
async cancel(params) {
|
|
15215
|
+
const session = this.sessionManager.getSession(params.sessionId);
|
|
15216
|
+
if (!session) {
|
|
15217
|
+
throw new RequestError(
|
|
15218
|
+
-32602,
|
|
15219
|
+
`Session not found: ${params.sessionId}`
|
|
15220
|
+
);
|
|
15012
15221
|
}
|
|
15013
|
-
|
|
15014
|
-
if (shouldShowPreviewModels) {
|
|
15015
|
-
mainOptions.unshift({
|
|
15016
|
-
value: PREVIEW_GEMINI_MODEL_AUTO,
|
|
15017
|
-
title: getDisplayString(PREVIEW_GEMINI_MODEL_AUTO),
|
|
15018
|
-
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"
|
|
15019
|
-
});
|
|
15222
|
+
await session.cancelPendingPrompt();
|
|
15020
15223
|
}
|
|
15021
|
-
|
|
15022
|
-
|
|
15023
|
-
|
|
15024
|
-
|
|
15025
|
-
|
|
15026
|
-
|
|
15027
|
-
|
|
15028
|
-
title: getDisplayString(DEFAULT_GEMINI_FLASH_MODEL)
|
|
15029
|
-
},
|
|
15030
|
-
{
|
|
15031
|
-
value: DEFAULT_GEMINI_FLASH_LITE_MODEL,
|
|
15032
|
-
title: getDisplayString(DEFAULT_GEMINI_FLASH_LITE_MODEL)
|
|
15224
|
+
async prompt(params) {
|
|
15225
|
+
const session = this.sessionManager.getSession(params.sessionId);
|
|
15226
|
+
if (!session) {
|
|
15227
|
+
throw new RequestError(
|
|
15228
|
+
-32602,
|
|
15229
|
+
`Session not found: ${params.sessionId}`
|
|
15230
|
+
);
|
|
15033
15231
|
}
|
|
15034
|
-
|
|
15035
|
-
|
|
15036
|
-
|
|
15037
|
-
const
|
|
15038
|
-
|
|
15039
|
-
|
|
15040
|
-
|
|
15041
|
-
|
|
15042
|
-
|
|
15043
|
-
{
|
|
15044
|
-
value: PREVIEW_GEMINI_FLASH_MODEL,
|
|
15045
|
-
title: getDisplayString(PREVIEW_GEMINI_FLASH_MODEL)
|
|
15046
|
-
}
|
|
15047
|
-
];
|
|
15048
|
-
if (useGemini31FlashLite) {
|
|
15049
|
-
previewOptions.push({
|
|
15050
|
-
value: PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL,
|
|
15051
|
-
title: getDisplayString(PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL)
|
|
15052
|
-
});
|
|
15232
|
+
return session.prompt(params);
|
|
15233
|
+
}
|
|
15234
|
+
async setSessionMode(params) {
|
|
15235
|
+
const session = this.sessionManager.getSession(params.sessionId);
|
|
15236
|
+
if (!session) {
|
|
15237
|
+
throw new RequestError(
|
|
15238
|
+
-32602,
|
|
15239
|
+
`Session not found: ${params.sessionId}`
|
|
15240
|
+
);
|
|
15053
15241
|
}
|
|
15054
|
-
|
|
15242
|
+
return session.setMode(params.modeId);
|
|
15055
15243
|
}
|
|
15056
|
-
|
|
15057
|
-
|
|
15058
|
-
|
|
15059
|
-
|
|
15060
|
-
|
|
15061
|
-
|
|
15062
|
-
|
|
15063
|
-
|
|
15064
|
-
|
|
15065
|
-
|
|
15066
|
-
|
|
15067
|
-
|
|
15244
|
+
async unstable_setSessionModel(params) {
|
|
15245
|
+
const session = this.sessionManager.getSession(params.sessionId);
|
|
15246
|
+
if (!session) {
|
|
15247
|
+
throw new RequestError(
|
|
15248
|
+
-32602,
|
|
15249
|
+
`Session not found: ${params.sessionId}`
|
|
15250
|
+
);
|
|
15251
|
+
}
|
|
15252
|
+
return session.setModel(params.modelId);
|
|
15253
|
+
}
|
|
15254
|
+
};
|
|
15255
|
+
|
|
15256
|
+
// packages/cli/src/acp/acpStdioTransport.ts
|
|
15257
|
+
async function runAcpClient(config, settings, argv) {
|
|
15258
|
+
const { stdout: workingStdout } = createWorkingStdio();
|
|
15259
|
+
const stdout = Writable.toWeb(workingStdout);
|
|
15260
|
+
const stdin = Readable.toWeb(process.stdin);
|
|
15261
|
+
const stream = ndJsonStream(stdout, stdin);
|
|
15262
|
+
const connection = new AgentSideConnection(
|
|
15263
|
+
(connection2) => new GeminiAgent(config, settings, argv, connection2),
|
|
15264
|
+
stream
|
|
15265
|
+
);
|
|
15266
|
+
await connection.closed.finally(runExitCleanup);
|
|
15068
15267
|
}
|
|
15069
15268
|
|
|
15070
15269
|
// packages/cli/src/validateNonInterActiveAuth.ts
|
|
@@ -15426,7 +15625,7 @@ function getNodeMemoryArgs(isDebugMode2) {
|
|
|
15426
15625
|
`Current heap size ${currentMaxOldSpaceSizeMb.toFixed(2)} MB`
|
|
15427
15626
|
);
|
|
15428
15627
|
}
|
|
15429
|
-
if (process.env["GEMINI_CLI_NO_RELAUNCH"]) {
|
|
15628
|
+
if (process.env["IS_BINARY"] === "true" || process.env["GEMINI_CLI_NO_RELAUNCH"] || process.env["SANDBOX"]) {
|
|
15430
15629
|
return [];
|
|
15431
15630
|
}
|
|
15432
15631
|
const args = [];
|
|
@@ -15511,7 +15710,7 @@ async function resolveSessionId(resumeArg, sessionIdArg) {
|
|
|
15511
15710
|
}
|
|
15512
15711
|
}
|
|
15513
15712
|
async function startInteractiveUI(config, settings, startupWarnings, workspaceRoot = process.cwd(), resumedSessionData, initializationResult) {
|
|
15514
|
-
const { startInteractiveUI: doStartUI } = await import("./interactiveCli-
|
|
15713
|
+
const { startInteractiveUI: doStartUI } = await import("./interactiveCli-74QXEIGP.js");
|
|
15515
15714
|
await doStartUI(
|
|
15516
15715
|
config,
|
|
15517
15716
|
settings,
|
|
@@ -15522,12 +15721,13 @@ async function startInteractiveUI(config, settings, startupWarnings, workspaceRo
|
|
|
15522
15721
|
);
|
|
15523
15722
|
}
|
|
15524
15723
|
async function main() {
|
|
15724
|
+
let config;
|
|
15525
15725
|
const cliStartupHandle = startupProfiler.start("cli_startup");
|
|
15526
15726
|
const adminControlsListner = setupAdminControlsListener();
|
|
15527
15727
|
registerCleanup(adminControlsListner.cleanup);
|
|
15528
15728
|
const cleanupStdio = patchStdio();
|
|
15529
15729
|
registerSyncCleanup(() => {
|
|
15530
|
-
initializeOutputListenersAndFlush();
|
|
15730
|
+
initializeOutputListenersAndFlush(config);
|
|
15531
15731
|
cleanupStdio();
|
|
15532
15732
|
});
|
|
15533
15733
|
setupUnhandledRejectionHandler();
|
|
@@ -15622,7 +15822,8 @@ async function main() {
|
|
|
15622
15822
|
}
|
|
15623
15823
|
}
|
|
15624
15824
|
const partialConfig = await loadCliConfig(settings.merged, sessionId, argv, {
|
|
15625
|
-
projectHooks: settings.workspace.settings.hooks
|
|
15825
|
+
projectHooks: settings.workspace.settings.hooks,
|
|
15826
|
+
skipExtensions: true
|
|
15626
15827
|
});
|
|
15627
15828
|
adminControlsListner.setConfig(partialConfig);
|
|
15628
15829
|
let initialAuthFailed = false;
|
|
@@ -15707,7 +15908,7 @@ ${finalArgs[promptIndex + 1]}`;
|
|
|
15707
15908
|
}
|
|
15708
15909
|
{
|
|
15709
15910
|
const loadConfigHandle = startupProfiler.start("load_cli_config");
|
|
15710
|
-
|
|
15911
|
+
config = await loadCliConfig(settings.merged, sessionId, argv, {
|
|
15711
15912
|
projectHooks: settings.workspace.settings.hooks,
|
|
15712
15913
|
worktreeSettings: worktreeInfo
|
|
15713
15914
|
});
|
|
@@ -15715,7 +15916,7 @@ ${finalArgs[promptIndex + 1]}`;
|
|
|
15715
15916
|
await config.storage.initialize();
|
|
15716
15917
|
adminControlsListner.setConfig(config);
|
|
15717
15918
|
if (config.isInteractive() && settings.merged.general.devtools) {
|
|
15718
|
-
const { setupInitialActivityLogger } = await import("./devtoolsService-
|
|
15919
|
+
const { setupInitialActivityLogger } = await import("./devtoolsService-KZLK5WRW.js");
|
|
15719
15920
|
setupInitialActivityLogger(config);
|
|
15720
15921
|
}
|
|
15721
15922
|
registerTelemetryConfig(config);
|
|
@@ -15774,7 +15975,7 @@ ${finalArgs[promptIndex + 1]}`;
|
|
|
15774
15975
|
const initAppHandle = startupProfiler.start("initialize_app");
|
|
15775
15976
|
const initializationResult = await initializeApp(config, settings);
|
|
15776
15977
|
initAppHandle?.end();
|
|
15777
|
-
import("./liteRtServerManager-
|
|
15978
|
+
import("./liteRtServerManager-J33F7APP.js").then(({ LiteRtServerManager }) => {
|
|
15778
15979
|
const mergedGemma = settings.merged.experimental?.gemmaModelRouter;
|
|
15779
15980
|
if (!mergedGemma) return;
|
|
15780
15981
|
const userGemma = settings.forScope("User" /* User */).settings.experimental?.gemmaModelRouter;
|
|
@@ -15881,7 +16082,7 @@ ${input}` : wrappedContext;
|
|
|
15881
16082
|
if (config.getDebugMode()) {
|
|
15882
16083
|
debugLogger.log("Session ID: %s", sessionId);
|
|
15883
16084
|
}
|
|
15884
|
-
initializeOutputListenersAndFlush();
|
|
16085
|
+
initializeOutputListenersAndFlush(config);
|
|
15885
16086
|
await runNonInteractive2({
|
|
15886
16087
|
config,
|
|
15887
16088
|
settings,
|
|
@@ -15893,7 +16094,7 @@ ${input}` : wrappedContext;
|
|
|
15893
16094
|
process.exit(ExitCodes.SUCCESS);
|
|
15894
16095
|
}
|
|
15895
16096
|
}
|
|
15896
|
-
function initializeOutputListenersAndFlush() {
|
|
16097
|
+
function initializeOutputListenersAndFlush(config) {
|
|
15897
16098
|
if (coreEvents.listenerCount(CoreEvent.Output) === 0) {
|
|
15898
16099
|
coreEvents.on(CoreEvent.Output, (payload) => {
|
|
15899
16100
|
if (payload.isStderr) {
|
|
@@ -15902,22 +16103,38 @@ function initializeOutputListenersAndFlush() {
|
|
|
15902
16103
|
writeToStdout(payload.chunk, payload.encoding);
|
|
15903
16104
|
}
|
|
15904
16105
|
});
|
|
15905
|
-
|
|
15906
|
-
|
|
15907
|
-
|
|
15908
|
-
|
|
15909
|
-
|
|
15910
|
-
|
|
16106
|
+
}
|
|
16107
|
+
if (coreEvents.listenerCount(CoreEvent.ConsoleLog) === 0) {
|
|
16108
|
+
coreEvents.on(CoreEvent.ConsoleLog, (payload) => {
|
|
16109
|
+
if (payload.type === "error" || payload.type === "warn") {
|
|
16110
|
+
writeToStderr(payload.content + "\n");
|
|
16111
|
+
} else {
|
|
16112
|
+
writeToStderr(payload.content + "\n");
|
|
16113
|
+
}
|
|
16114
|
+
});
|
|
16115
|
+
}
|
|
16116
|
+
if (coreEvents.listenerCount(CoreEvent.UserFeedback) === 0) {
|
|
16117
|
+
coreEvents.on(CoreEvent.UserFeedback, (payload) => {
|
|
16118
|
+
writeToStderr(payload.message + "\n");
|
|
16119
|
+
});
|
|
16120
|
+
}
|
|
16121
|
+
const outputFormat = config?.getOutputFormat();
|
|
16122
|
+
const forceToStderr = outputFormat === "json" || config === void 0;
|
|
16123
|
+
coreEvents.drainBacklogs(
|
|
16124
|
+
(event, args) => {
|
|
16125
|
+
if (forceToStderr && event === CoreEvent.Output) {
|
|
16126
|
+
const payload = args[0];
|
|
16127
|
+
if (!payload.isStderr) {
|
|
16128
|
+
return {
|
|
16129
|
+
event,
|
|
16130
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
16131
|
+
args: [{ ...payload, isStderr: true }]
|
|
16132
|
+
};
|
|
15911
16133
|
}
|
|
15912
|
-
}
|
|
15913
|
-
|
|
15914
|
-
if (coreEvents.listenerCount(CoreEvent.UserFeedback) === 0) {
|
|
15915
|
-
coreEvents.on(CoreEvent.UserFeedback, (payload) => {
|
|
15916
|
-
writeToStderr(payload.message + "\n");
|
|
15917
|
-
});
|
|
16134
|
+
}
|
|
16135
|
+
return { event, args };
|
|
15918
16136
|
}
|
|
15919
|
-
|
|
15920
|
-
coreEvents.drainBacklogs();
|
|
16137
|
+
);
|
|
15921
16138
|
}
|
|
15922
16139
|
function setupAdminControlsListener() {
|
|
15923
16140
|
let pendingSettings;
|