@google/gemini-cli 0.54.0-preview.0 → 0.54.0

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.
Files changed (50) hide show
  1. package/bundle/{chunk-PMUWVEQP.js → chunk-2MRUXBJ5.js} +7 -7
  2. package/bundle/{chunk-XTGYOEM3.js → chunk-43HYOV6F.js} +1 -1
  3. package/bundle/{chunk-CPVZILP2.js → chunk-5SMD2SLQ.js} +2 -2
  4. package/bundle/{chunk-K7T2IFNS.js → chunk-BBNFLOXC.js} +1 -1
  5. package/bundle/{chunk-UOZMJZMA.js → chunk-F6IU45OZ.js} +180 -39
  6. package/bundle/{chunk-KU7W3PYO.js → chunk-G7VQ6O6G.js} +1 -1
  7. package/bundle/{chunk-4GNXWN36.js → chunk-GOQJOV4P.js} +1 -1
  8. package/bundle/{chunk-HM6J5QFA.js → chunk-HS7THREL.js} +208 -42
  9. package/bundle/{chunk-GMYSSSFG.js → chunk-IM5WJKYT.js} +1 -1
  10. package/bundle/{chunk-JKXIXUUH.js → chunk-JPCDQXHB.js} +1 -1
  11. package/bundle/{chunk-I2F6JPKA.js → chunk-LH73BY77.js} +7 -7
  12. package/bundle/{chunk-ZJJUEIJO.js → chunk-MOGTJC2T.js} +1 -1
  13. package/bundle/{chunk-CZ6IKC6W.js → chunk-MZBH35ZS.js} +1 -1
  14. package/bundle/{chunk-HYGO4QEK.js → chunk-NZ6P6XKP.js} +2 -2
  15. package/bundle/{chunk-24AZRO3S.js → chunk-OYZ2XVON.js} +3 -3
  16. package/bundle/{chunk-S2XDE4E6.js → chunk-RHINAWEP.js} +7 -7
  17. package/bundle/{chunk-X7LEASVK.js → chunk-SHZORH3T.js} +1 -1
  18. package/bundle/{chunk-5X6WKNCA.js → chunk-SQWRALPF.js} +1 -1
  19. package/bundle/{chunk-ANCJ47GY.js → chunk-TZAOURRV.js} +1 -1
  20. package/bundle/{chunk-KFW7GOXJ.js → chunk-UTXCUPDT.js} +2 -2
  21. package/bundle/{chunk-BMD42WWR.js → chunk-UW4NSSB6.js} +3 -3
  22. package/bundle/{chunk-QZ32DOIY.js → chunk-VIQEWLM4.js} +1 -1
  23. package/bundle/{chunk-YVWOOS5D.js → chunk-WJKZRJIC.js} +3 -3
  24. package/bundle/{chunk-YOK6TS2W.js → chunk-YYWWE5GW.js} +208 -42
  25. package/bundle/{cleanup-CI4EZBGK.js → cleanup-5UYKVLIF.js} +2 -2
  26. package/bundle/{cleanup-NW33L7BG.js → cleanup-6OO5MA6W.js} +2 -2
  27. package/bundle/{cleanup-WCECJVAH.js → cleanup-ODOGWYRM.js} +2 -2
  28. package/bundle/{core-X6AKTKZS.js → core-JL633Z4N.js} +15 -1
  29. package/bundle/{dist-FM4XWKSV.js → core-S5B3NEKC.js} +15 -1
  30. package/bundle/{devtoolsService-HT4GPBRA.js → devtoolsService-FUTPYP6V.js} +2 -2
  31. package/bundle/{devtoolsService-YWDOWAQ7.js → devtoolsService-NZQZUVCI.js} +2 -2
  32. package/bundle/{devtoolsService-I4VSDXDZ.js → devtoolsService-YWNTGRUE.js} +2 -2
  33. package/bundle/{core-JXOKFSQM.js → dist-DB6LWOKZ.js} +15 -1
  34. package/bundle/{gemini-6QYTVAVR.js → gemini-AQASGK5V.js} +84 -20
  35. package/bundle/{gemini-LAE4PTZV.js → gemini-D3BRVDVJ.js} +84 -20
  36. package/bundle/{gemini-M37ESLGX.js → gemini-PPNY5YY6.js} +84 -20
  37. package/bundle/gemini.js +7 -7
  38. package/bundle/{interactiveCli-353YNM5T.js → interactiveCli-CXCZMXKQ.js} +99 -9
  39. package/bundle/{interactiveCli-D26FIBDY.js → interactiveCli-P7QQLIDS.js} +99 -9
  40. package/bundle/{interactiveCli-OZI3EOZ3.js → interactiveCli-RU7LCVXL.js} +99 -9
  41. package/bundle/{liteRtServerManager-CHOKKKD7.js → liteRtServerManager-FIVLVXQJ.js} +4 -4
  42. package/bundle/{liteRtServerManager-QZER65XK.js → liteRtServerManager-ISKYY742.js} +4 -4
  43. package/bundle/{liteRtServerManager-5L6ZKYIO.js → liteRtServerManager-MPPOFOTR.js} +4 -4
  44. package/bundle/{oauth2-provider-DOSOCLE2.js → oauth2-provider-DOIL6PEC.js} +1 -1
  45. package/bundle/{oauth2-provider-2DMHCM63.js → oauth2-provider-G6DF4NEU.js} +1 -1
  46. package/bundle/{oauth2-provider-RYXZZKGA.js → oauth2-provider-XR5UQYQV.js} +1 -1
  47. package/bundle/{start-GSFOK3MC.js → start-AJW7OVPU.js} +6 -6
  48. package/bundle/{start-H6TOQQTQ.js → start-S77W5RNK.js} +6 -6
  49. package/bundle/{start-6KDQYY22.js → start-YWT3TSZW.js} +6 -6
  50. package/package.json +1 -1
@@ -2,7 +2,7 @@ const require = (await import('node:module')).createRequire(import.meta.url); co
2
2
  import {
3
3
  exitCli,
4
4
  require_source
5
- } from "./chunk-ZJJUEIJO.js";
5
+ } from "./chunk-G7VQ6O6G.js";
6
6
  import {
7
7
  AppEvent,
8
8
  appEvents
@@ -59,14 +59,14 @@ import {
59
59
  stripUnsafeCharacters,
60
60
  toCodePoints,
61
61
  validateCustomTheme
62
- } from "./chunk-4GNXWN36.js";
62
+ } from "./chunk-GOQJOV4P.js";
63
63
  import {
64
64
  isDevelopment
65
- } from "./chunk-HYGO4QEK.js";
65
+ } from "./chunk-5SMD2SLQ.js";
66
66
  import {
67
67
  emptyIcon,
68
68
  require_react
69
- } from "./chunk-CZ6IKC6W.js";
69
+ } from "./chunk-MZBH35ZS.js";
70
70
  import {
71
71
  ALL_EDITORS,
72
72
  ApprovalMode,
@@ -243,7 +243,7 @@ import {
243
243
  tokenLimit,
244
244
  uiTelemetryService,
245
245
  unescapePath
246
- } from "./chunk-UOZMJZMA.js";
246
+ } from "./chunk-F6IU45OZ.js";
247
247
  import {
248
248
  require_src
249
249
  } from "./chunk-TUDYL3X4.js";
@@ -77176,7 +77176,7 @@ var authCommand = {
77176
77176
  import process29 from "node:process";
77177
77177
 
77178
77178
  // packages/cli/src/generated/git-commit.ts
77179
- var GIT_COMMIT_INFO = "5f9c117de";
77179
+ var GIT_COMMIT_INFO = "a74b483d1";
77180
77180
 
77181
77181
  // packages/cli/src/ui/utils/historyExportUtils.ts
77182
77182
  import * as fsPromises from "node:fs/promises";
@@ -82957,7 +82957,7 @@ Use /mcp auth <server-name> to authenticate.`
82957
82957
  type: "info",
82958
82958
  text: `Starting OAuth authentication for MCP server '${serverName}'...`
82959
82959
  });
82960
- const { MCPOAuthProvider } = await import("./dist-FM4XWKSV.js");
82960
+ const { MCPOAuthProvider } = await import("./dist-DB6LWOKZ.js");
82961
82961
  let oauthConfig = server.oauth;
82962
82962
  if (!oauthConfig) {
82963
82963
  oauthConfig = { enabled: false };
@@ -5,7 +5,7 @@ import {
5
5
  isTelemetrySdkInitialized,
6
6
  resetBrowserSession,
7
7
  shutdownTelemetry
8
- } from "./chunk-YOK6TS2W.js";
8
+ } from "./chunk-HS7THREL.js";
9
9
 
10
10
  // packages/cli/src/utils/cleanup.ts
11
11
  import { promises as fs } from "node:fs";
@@ -1,13 +1,13 @@
1
1
  const require = (await import('node:module')).createRequire(import.meta.url); const __chunk_filename = (await import('node:url')).fileURLToPath(import.meta.url); const __chunk_dirname = (await import('node:path')).dirname(__chunk_filename);
2
2
  import {
3
3
  runExitCleanup
4
- } from "./chunk-GMYSSSFG.js";
4
+ } from "./chunk-IM5WJKYT.js";
5
5
  import {
6
6
  RELEASE_CHANNEL_STABILITY,
7
7
  debugLogger,
8
8
  getChannelFromVersion,
9
9
  isGitRepository
10
- } from "./chunk-HM6J5QFA.js";
10
+ } from "./chunk-F6IU45OZ.js";
11
11
 
12
12
  // packages/cli/src/utils/installationInfo.ts
13
13
  import * as fs from "node:fs";
@@ -1,7 +1,7 @@
1
1
  const require = (await import('node:module')).createRequire(import.meta.url); const __chunk_filename = (await import('node:url')).fileURLToPath(import.meta.url); const __chunk_dirname = (await import('node:path')).dirname(__chunk_filename);
2
2
  import {
3
3
  runExitCleanup
4
- } from "./chunk-GMYSSSFG.js";
4
+ } from "./chunk-43HYOV6F.js";
5
5
  import {
6
6
  __commonJS,
7
7
  __require
@@ -253529,6 +253529,13 @@ var REFERENCE_CONTENT_END = "--- End of content ---";
253529
253529
  var DEFAULT_MAX_LINES_TEXT_FILE = 2e3;
253530
253530
  var MAX_LINE_LENGTH_TEXT_FILE = 2e3;
253531
253531
  var MAX_FILE_SIZE_MB = 20;
253532
+ var EMPTY_RESPONSE_COMPRESS_SUGGESTION = "The model returned an empty text response. If your context window is near capacity, try using /compress.";
253533
+ var THINKING_ONLY_COMPRESS_SUGGESTION = "The model returned reasoning thoughts but no final response text. If your context window is near capacity, try using /compress.";
253534
+ var MAX_TOKENS_EXCEEDED_SUGGESTION = "Model response was truncated because it exceeded the token limit. Try using /compress to free up context space.";
253535
+ var SAFETY_BLOCKED_MESSAGE = "The model response was blocked due to safety settings.";
253536
+ var RECITATION_BLOCKED_MESSAGE = "The model response was blocked due to recitation/copyright filters.";
253537
+ var OTHER_BLOCKED_MESSAGE = "The model response was blocked due to other policy settings.";
253538
+ var TRUE_EMPTY_RESPONSE_MESSAGE = "The model returned an empty response with no text or thoughts. This may be a transient API issue; please try again.";
253532
253539
 
253533
253540
  // packages/core/dist/src/utils/fileUtils.js
253534
253541
  var requireModule = createModuleRequire(import.meta.url);
@@ -282503,8 +282510,8 @@ function isValidToolName(name3, options = {}) {
282503
282510
  }
282504
282511
 
282505
282512
  // packages/core/dist/src/generated/git-commit.js
282506
- var GIT_COMMIT_INFO = "d29268d36";
282507
- var CLI_VERSION = "0.54.0-preview.0";
282513
+ var GIT_COMMIT_INFO = "a81db2768";
282514
+ var CLI_VERSION = "0.54.0";
282508
282515
 
282509
282516
  // packages/core/dist/src/ide/detect-ide.js
282510
282517
  var IDE_DEFINITIONS = {
@@ -284981,6 +284988,15 @@ var AgentChatHistory = class {
284981
284988
  clear() {
284982
284989
  this.history = [];
284983
284990
  }
284991
+ /**
284992
+ * Rolls back the history to a specified length.
284993
+ * Useful when a stream fails and we need to remove the un-responded turn(s).
284994
+ */
284995
+ rollback(length) {
284996
+ if (length >= 0 && length <= this.history.length) {
284997
+ this.history = this.history.slice(0, length);
284998
+ }
284999
+ }
284984
285000
  get() {
284985
285001
  return this.history;
284986
285002
  }
@@ -285849,7 +285865,8 @@ var createInitialModelMetrics = () => ({
285849
285865
  api: {
285850
285866
  totalRequests: 0,
285851
285867
  totalErrors: 0,
285852
- totalLatencyMs: 0
285868
+ totalLatencyMs: 0,
285869
+ errorsByType: {}
285853
285870
  },
285854
285871
  tokens: {
285855
285872
  input: 0,
@@ -285904,6 +285921,19 @@ var UiTelemetryService = class extends EventEmitter3 {
285904
285921
  lastPromptTokenCount: this.#lastPromptTokenCount
285905
285922
  });
285906
285923
  }
285924
+ recordSemanticValidationError(model, errorType) {
285925
+ const modelMetrics = this.getOrCreateModelMetrics(model);
285926
+ modelMetrics.api.totalErrors++;
285927
+ if (!modelMetrics.api.errorsByType) {
285928
+ modelMetrics.api.errorsByType = {};
285929
+ }
285930
+ const type2 = errorType || "INVALID_STREAM";
285931
+ modelMetrics.api.errorsByType[type2] = (modelMetrics.api.errorsByType[type2] || 0) + 1;
285932
+ this.emit("update", {
285933
+ metrics: this.#metrics,
285934
+ lastPromptTokenCount: this.#lastPromptTokenCount
285935
+ });
285936
+ }
285907
285937
  getMetrics() {
285908
285938
  return this.#metrics;
285909
285939
  }
@@ -286025,6 +286055,11 @@ var UiTelemetryService = class extends EventEmitter3 {
286025
286055
  modelMetrics.api.totalRequests++;
286026
286056
  modelMetrics.api.totalErrors++;
286027
286057
  modelMetrics.api.totalLatencyMs += event.duration_ms;
286058
+ if (!modelMetrics.api.errorsByType) {
286059
+ modelMetrics.api.errorsByType = {};
286060
+ }
286061
+ const errorType = event.error_type || "UNKNOWN";
286062
+ modelMetrics.api.errorsByType[errorType] = (modelMetrics.api.errorsByType[errorType] || 0) + 1;
286028
286063
  if (event.role) {
286029
286064
  if (!modelMetrics.roles[event.role]) {
286030
286065
  modelMetrics.roles[event.role] = createInitialRoleMetrics();
@@ -305685,7 +305720,7 @@ function getVersion() {
305685
305720
  }
305686
305721
  versionPromise = (async () => {
305687
305722
  const pkgJson = await getPackageJson(__dirname4);
305688
- return "0.54.0-preview.0";
305723
+ return "0.54.0";
305689
305724
  })();
305690
305725
  return versionPromise;
305691
305726
  }
@@ -306435,6 +306470,11 @@ function classifyGoogleError(error40) {
306435
306470
  if (errorInfo.reason === "INSUFFICIENT_G1_CREDITS_BALANCE") {
306436
306471
  return new TerminalQuotaError(googleApiError.message, googleApiError, delaySeconds, errorInfo.reason);
306437
306472
  }
306473
+ if (errorInfo.reason === "MODEL_CAPACITY_EXHAUSTED" || errorInfo.reason === "MODEL_CAPACITY_EXCEEDED") {
306474
+ if (delaySeconds === void 0) {
306475
+ return new TerminalQuotaError(googleApiError.message, googleApiError, delaySeconds, errorInfo.reason);
306476
+ }
306477
+ }
306438
306478
  if (errorInfo.domain) {
306439
306479
  if (isCloudCodeDomain(errorInfo.domain)) {
306440
306480
  if (errorInfo.reason === "RATE_LIMIT_EXCEEDED") {
@@ -329884,10 +329924,10 @@ import { randomUUID as randomUUID6 } from "node:crypto";
329884
329924
 
329885
329925
  // packages/core/dist/src/utils/messageInspectors.js
329886
329926
  function isFunctionResponse(content) {
329887
- return content.role === "user" && !!content.parts && content.parts.every((part) => !!part.functionResponse);
329927
+ return content.role === "user" && !!content.parts && content.parts.some((part) => !!part.functionResponse);
329888
329928
  }
329889
329929
  function isFunctionCall(content) {
329890
- return content.role === "model" && !!content.parts && content.parts.every((part) => !!part.functionCall);
329930
+ return content.role === "model" && !!content.parts && content.parts.length > 0 && content.parts.every((part) => !!part.functionCall);
329891
329931
  }
329892
329932
 
329893
329933
  // packages/core/dist/src/utils/historyHardening.js
@@ -330407,15 +330447,18 @@ var GeminiChat = class {
330407
330447
  */
330408
330448
  async sendMessageStream(modelConfigKey, message, prompt_id, signal, role, displayContent, apiHistoryOverride) {
330409
330449
  await this.sendPromise;
330450
+ const historyLengthBefore = this.agentHistory.length;
330451
+ const baselinePromptTokenCount = this.lastPromptTokenCount;
330410
330452
  let streamDoneResolver;
330411
330453
  const streamDonePromise = new Promise((resolve29) => {
330412
330454
  streamDoneResolver = resolve29;
330413
330455
  });
330414
330456
  this.sendPromise = streamDonePromise;
330415
330457
  let userContent = createUserContent(message);
330458
+ const isOriginalFunctionResponse = isFunctionResponse(userContent);
330416
330459
  const { model } = this.context.config.modelConfigService.getResolvedConfig(modelConfigKey);
330417
330460
  const isContextManagementEnabled = this.context.config.isContextManagementEnabled();
330418
- if (!isFunctionResponse(userContent)) {
330461
+ if (!isOriginalFunctionResponse) {
330419
330462
  const userMessageParts = userContent.parts || [];
330420
330463
  const userMessageContent = partListUnionToString(userMessageParts);
330421
330464
  let finalDisplayContent = void 0;
@@ -330494,13 +330537,14 @@ var GeminiChat = class {
330494
330537
  const streamWithRetries = async function* () {
330495
330538
  try {
330496
330539
  const maxAttempts = this.context.config.getMaxAttempts();
330540
+ let lastStreamError = void 0;
330497
330541
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
330498
330542
  let isConnectionPhase = true;
330499
330543
  try {
330500
330544
  if (attempt > 0) {
330501
330545
  yield { type: StreamEventType.RETRY };
330502
330546
  }
330503
- const currentConfigKey = attempt > 0 ? { ...modelConfigKey, isRetry: true } : modelConfigKey;
330547
+ const currentConfigKey = attempt > 0 ? { ...modelConfigKey, isRetry: true, lastStreamError } : modelConfigKey;
330504
330548
  isConnectionPhase = true;
330505
330549
  const stream2 = await this.makeApiCallAndProcessStream(currentConfigKey, requestHistory, prompt_id, signal, role, apiHistoryOverride);
330506
330550
  isConnectionPhase = false;
@@ -330509,6 +330553,9 @@ var GeminiChat = class {
330509
330553
  }
330510
330554
  return;
330511
330555
  } catch (error40) {
330556
+ if (error40 instanceof InvalidStreamError) {
330557
+ lastStreamError = error40;
330558
+ }
330512
330559
  if (error40 instanceof AgentExecutionStoppedError) {
330513
330560
  yield {
330514
330561
  type: StreamEventType.AGENT_EXECUTION_STOPPED,
@@ -330534,7 +330581,7 @@ var GeminiChat = class {
330534
330581
  }
330535
330582
  const isRetryable = isRetryableError(error40, this.context.config.getRetryFetchErrors());
330536
330583
  const isContentError = error40 instanceof InvalidStreamError;
330537
- const isRetryableContentError = isContentError && error40.type !== "NO_RESPONSE_TEXT";
330584
+ const isRetryableContentError = isContentError;
330538
330585
  const errorType = isContentError ? error40.type : getRetryErrorType(error40);
330539
330586
  if (isRetryableContentError || isRetryable && !signal.aborted) {
330540
330587
  const maxMidStreamAttempts = MID_STREAM_RETRY_OPTIONS.maxAttempts;
@@ -330563,6 +330610,13 @@ var GeminiChat = class {
330563
330610
  throw error40;
330564
330611
  }
330565
330612
  }
330613
+ } catch (error40) {
330614
+ if (!isOriginalFunctionResponse) {
330615
+ this.agentHistory.rollback(historyLengthBefore);
330616
+ this.chatRecordingService.updateMessagesFromHistory(this.agentHistory.get());
330617
+ this.lastPromptTokenCount = baselinePromptTokenCount;
330618
+ }
330619
+ throw error40;
330566
330620
  } finally {
330567
330621
  streamDoneResolver();
330568
330622
  }
@@ -330621,6 +330675,22 @@ var GeminiChat = class {
330621
330675
  tools: this.tools,
330622
330676
  abortSignal
330623
330677
  };
330678
+ if (modelConfigKey.isRetry && modelConfigKey.lastStreamError instanceof InvalidStreamError) {
330679
+ const lastError = modelConfigKey.lastStreamError;
330680
+ let nudgeMessage = "";
330681
+ if (lastError.type === "THINKING_ONLY_RESPONSE") {
330682
+ nudgeMessage = "\n[System: You previously generated thoughts but failed to provide a final user-facing response. Please ensure you provide your final answer or call a tool now.]";
330683
+ } else if (lastError.type === "NO_RESPONSE_TEXT") {
330684
+ nudgeMessage = "\n[System: You previously returned an empty response with no text or thoughts. Please ensure you provide your final answer or call a tool now.]";
330685
+ }
330686
+ if (nudgeMessage) {
330687
+ if (typeof config2.systemInstruction === "string") {
330688
+ config2.systemInstruction += nudgeMessage;
330689
+ } else if (config2.systemInstruction === void 0) {
330690
+ config2.systemInstruction = nudgeMessage;
330691
+ }
330692
+ }
330693
+ }
330624
330694
  let contentsToUse = supportsModernFeatures(modelToUse) || isGemini2Model(modelToUse) ? [...contentsForPreviewModel] : [...requestContents];
330625
330695
  const hookSystem = this.context.config.getHookSystem();
330626
330696
  if (hookSystem) {
@@ -330870,6 +330940,8 @@ This error was probably caused by cyclic schema references in one of the followi
330870
330940
  let hasToolCall = false;
330871
330941
  let hasThoughts = false;
330872
330942
  let finishReason;
330943
+ const bufferedThoughts = [];
330944
+ let bufferedUsageMetadata = void 0;
330873
330945
  const finalFunctionCallsMap = /* @__PURE__ */ new Map();
330874
330946
  const legacyFunctionCalls = [];
330875
330947
  const callIndexToId = /* @__PURE__ */ new Map();
@@ -330915,7 +330987,10 @@ This error was probably caused by cyclic schema references in one of the followi
330915
330987
  if (content?.parts) {
330916
330988
  if (content.parts.some((part) => part.thought)) {
330917
330989
  hasThoughts = true;
330918
- this.recordThoughtFromContent(content);
330990
+ const thought = this.extractThoughtFromContent(content);
330991
+ if (thought) {
330992
+ bufferedThoughts.push(thought);
330993
+ }
330919
330994
  }
330920
330995
  if (content.parts.some((part) => part.functionCall)) {
330921
330996
  hasToolCall = true;
@@ -330937,10 +331012,7 @@ This error was probably caused by cyclic schema references in one of the followi
330937
331012
  }
330938
331013
  }
330939
331014
  if (chunk.usageMetadata) {
330940
- this.chatRecordingService.recordMessageTokens(chunk.usageMetadata);
330941
- if (chunk.usageMetadata.promptTokenCount !== void 0) {
330942
- this.lastPromptTokenCount = chunk.usageMetadata.promptTokenCount;
330943
- }
331015
+ bufferedUsageMetadata = chunk.usageMetadata;
330944
331016
  }
330945
331017
  const hookSystem = this.context.config.getHookSystem();
330946
331018
  if (originalRequest && chunk && hookSystem) {
@@ -330996,17 +331068,14 @@ This error was probably caused by cyclic schema references in one of the followi
330996
331068
  }
330997
331069
  }
330998
331070
  }
330999
- const responseText = consolidatedParts.filter((part) => part.text).map((part) => part.text).join("").trim();
331000
- let id;
331001
- if (responseText || hasThoughts || hasToolCall) {
331002
- id = this.chatRecordingService.recordMessage({
331003
- model,
331004
- type: "gemini",
331005
- content: responseText
331006
- });
331007
- } else {
331008
- id = this.chatRecordingService.recordSyntheticMessage("gemini", consolidatedParts);
331009
- }
331071
+ const rawResponseText = consolidatedParts.filter((part) => part.text).map((part) => part.text).join("");
331072
+ let responseText = rawResponseText.replace(/[\u200B-\u200D\uFEFF\u200E\u200F]/g, "");
331073
+ let previous;
331074
+ do {
331075
+ previous = responseText;
331076
+ responseText = responseText.replace(/<!--[\s\S]*?-->/g, "");
331077
+ } while (responseText !== previous);
331078
+ responseText = responseText.trim();
331010
331079
  if (!hasToolCall) {
331011
331080
  if (!finishReason) {
331012
331081
  throw new InvalidStreamError("Model stream ended without a finish reason.", "NO_FINISH_REASON");
@@ -331018,9 +331087,43 @@ This error was probably caused by cyclic schema references in one of the followi
331018
331087
  throw new InvalidStreamError("Model stream ended with unexpected tool call.", "UNEXPECTED_TOOL_CALL");
331019
331088
  }
331020
331089
  if (!responseText) {
331090
+ if (finishReason === FinishReason.MAX_TOKENS) {
331091
+ throw new InvalidStreamError("Model stream ended due to token limit exhaustion (MAX_TOKENS) with empty response text.", "MAX_TOKENS_EXCEEDED");
331092
+ }
331093
+ if (finishReason === FinishReason.SAFETY) {
331094
+ throw new InvalidStreamError("Model stream ended due to safety settings (SAFETY) with empty response text.", "SAFETY_BLOCKED");
331095
+ }
331096
+ if (finishReason === FinishReason.RECITATION) {
331097
+ throw new InvalidStreamError("Model stream ended due to recitation settings (RECITATION) with empty response text.", "RECITATION_BLOCKED");
331098
+ }
331099
+ if (finishReason === FinishReason.OTHER) {
331100
+ throw new InvalidStreamError("Model stream ended due to other settings (OTHER) with empty response text.", "OTHER_BLOCKED");
331101
+ }
331102
+ if (hasThoughts) {
331103
+ throw new InvalidStreamError("Model stream ended with empty response text but contained reasoning thoughts.", "THINKING_ONLY_RESPONSE");
331104
+ }
331021
331105
  throw new InvalidStreamError("Model stream ended with empty response text.", "NO_RESPONSE_TEXT");
331022
331106
  }
331023
331107
  }
331108
+ for (const thought of bufferedThoughts) {
331109
+ this.chatRecordingService.recordThought(thought);
331110
+ }
331111
+ if (bufferedUsageMetadata) {
331112
+ this.chatRecordingService.recordMessageTokens(bufferedUsageMetadata);
331113
+ if (bufferedUsageMetadata.promptTokenCount !== void 0) {
331114
+ this.lastPromptTokenCount = bufferedUsageMetadata.promptTokenCount;
331115
+ }
331116
+ }
331117
+ let id;
331118
+ if (responseText || hasThoughts || hasToolCall) {
331119
+ id = this.chatRecordingService.recordMessage({
331120
+ model,
331121
+ type: "gemini",
331122
+ content: responseText
331123
+ });
331124
+ } else {
331125
+ id = this.chatRecordingService.recordSyntheticMessage("gemini", consolidatedParts);
331126
+ }
331024
331127
  this.agentHistory.push({
331025
331128
  id,
331026
331129
  content: { role: "model", parts: consolidatedParts }
@@ -331058,11 +331161,11 @@ This error was probably caused by cyclic schema references in one of the followi
331058
331161
  this.chatRecordingService.recordToolCalls(model, toolCallRecords);
331059
331162
  }
331060
331163
  /**
331061
- * Extracts and records thought from thought content.
331164
+ * Extracts thought from thought content.
331062
331165
  */
331063
- recordThoughtFromContent(content) {
331166
+ extractThoughtFromContent(content) {
331064
331167
  if (!content.parts || content.parts.length === 0) {
331065
- return;
331168
+ return void 0;
331066
331169
  }
331067
331170
  const thoughtPart = content.parts[0];
331068
331171
  if (thoughtPart.text) {
@@ -331070,11 +331173,12 @@ This error was probably caused by cyclic schema references in one of the followi
331070
331173
  const subjectStringMatches = rawText.match(/\*\*(.*?)\*\*/s);
331071
331174
  const subject = subjectStringMatches ? subjectStringMatches[1].trim() : "";
331072
331175
  const description = rawText.replace(/\*\*(.*?)\*\*/s, "").trim();
331073
- this.chatRecordingService.recordThought({
331176
+ return {
331074
331177
  subject,
331075
331178
  description
331076
- });
331179
+ };
331077
331180
  }
331181
+ return void 0;
331078
331182
  }
331079
331183
  };
331080
331184
  function isSchemaDepthError(errorMessage) {
@@ -331392,7 +331496,13 @@ ${[...this.pendingCitations].sort().join("\n")}`
331392
331496
  return;
331393
331497
  }
331394
331498
  if (e2 instanceof InvalidStreamError) {
331395
- yield { type: GeminiEventType.InvalidStream };
331499
+ yield {
331500
+ type: GeminiEventType.InvalidStream,
331501
+ value: {
331502
+ type: e2.type,
331503
+ message: e2.message
331504
+ }
331505
+ };
331396
331506
  return;
331397
331507
  }
331398
331508
  const error40 = toFriendlyError(e2);
@@ -331738,6 +331848,16 @@ function renderOperationalGuidelines(options) {
331738
331848
  - **Security First:** Always apply security best practices. Never introduce code that exposes, logs, or commits secrets, API keys, or other sensitive information.
331739
331849
 
331740
331850
  ## Tool Usage
331851
+ - **Tool Execution Response Rules:**
331852
+ 1. After receiving a \`functionResponse\`, you MUST ALWAYS execute one of the following two actions:
331853
+ a) Call another tool to proceed with the task.
331854
+ b) Provide a user-facing text response explaining the tool output, your analysis, and next steps.
331855
+ 2. You MUST NEVER return an empty response with no text and no tool calls.
331856
+ - **Post-Edit Response Rules:**
331857
+ 1. After an edit tool execution (e.g. ${formatToolName(EDIT_TOOL_NAME)}, ${formatToolName(WRITE_FILE_TOOL_NAME)}), you MUST ALWAYS generate a user-facing text response summarizing:
331858
+ - What changes were made to the file.
331859
+ - Your verification plan or next steps (e.g. running tests).
331860
+ 2. You MUST NEVER return an empty response with 0 text tokens after completing an edit.
331741
331861
  - **Parallelism & Sequencing:** Tools execute in parallel by default. Execute multiple independent tool calls in parallel when feasible (e.g., searching, reading files, independent shell commands, or editing *different* files). If a tool depends on the output or side-effects of a previous tool in the same turn (e.g., running a shell command that depends on the success of a previous command), you MUST set the \`wait_for_previous\` parameter to \`true\` on the dependent tool to ensure sequential execution.
331742
331862
  - **File Editing Collisions:** Do NOT make multiple calls to the ${formatToolName(EDIT_TOOL_NAME)} tool for the SAME file in a single turn. To make multiple edits to the same file, you MUST perform them sequentially across multiple conversational turns to prevent race conditions and ensure the file state is accurate before each edit.
331743
331863
  - **Command Execution:** Use the ${formatToolName(SHELL_TOOL_NAME)} tool for running shell commands, remembering the safety rule to explain modifying commands first.${toolUsageInteractive(options.interactive, options.interactiveShellEnabled)}${toolUsageRememberingFacts(options)}
@@ -338285,7 +338405,7 @@ var A2AAuthProviderFactory = class _A2AAuthProviderFactory {
338285
338405
  return provider;
338286
338406
  }
338287
338407
  case "oauth2": {
338288
- const { OAuth2AuthProvider } = await import("./oauth2-provider-2DMHCM63.js");
338408
+ const { OAuth2AuthProvider } = await import("./oauth2-provider-G6DF4NEU.js");
338289
338409
  const provider = new OAuth2AuthProvider(authConfig, options.agentName ?? "unknown", agentCard, options.agentCardUrl);
338290
338410
  await provider.initialize();
338291
338411
  return provider;
@@ -345695,6 +345815,7 @@ var Scheduler = class {
345695
345815
  for (const activeCall of activeCalls) {
345696
345816
  if (!this.isTerminal(activeCall.status)) {
345697
345817
  this.state.updateStatus(activeCall.request.callId, CoreToolCallStatus.Cancelled, "Operation cancelled by user");
345818
+ this.state.finalizeCall(activeCall.request.callId);
345698
345819
  }
345699
345820
  }
345700
345821
  this.state.cancelAllQueued("Operation cancelled by user");
@@ -345809,6 +345930,12 @@ var Scheduler = class {
345809
345930
  */
345810
345931
  async _processNextItem(signal) {
345811
345932
  if (signal.aborted || this.isCancelling) {
345933
+ const activeCalls2 = this.state.allActiveCalls;
345934
+ for (const call of activeCalls2) {
345935
+ if (this.isTerminal(call.status)) {
345936
+ this.state.finalizeCall(call.request.callId);
345937
+ }
345938
+ }
345812
345939
  this.state.cancelAllQueued("Operation cancelled");
345813
345940
  return false;
345814
345941
  }
@@ -386518,8 +386645,13 @@ function translateEvent(event, state) {
386518
386645
  ensureStreamStart(state, out2);
386519
386646
  out2.push(makeEvent("error", state, {
386520
386647
  status: "INTERNAL",
386521
- message: "Invalid stream received from model",
386522
- fatal: true
386648
+ message: event.value?.message?.trim() || "Invalid stream received from model",
386649
+ fatal: true,
386650
+ _meta: {
386651
+ code: "INVALID_STREAM",
386652
+ errorType: event.value?.type,
386653
+ rawMessage: event.value?.message
386654
+ }
386523
386655
  }));
386524
386656
  break;
386525
386657
  case GeminiEventType.ToolCallRequest:
@@ -386778,6 +386910,7 @@ var LegacyAgentProtocol = class {
386778
386910
  return;
386779
386911
  }
386780
386912
  const toolCallRequests = [];
386913
+ let finishedReason = void 0;
386781
386914
  const responseStream = this._client.sendMessageStream(currentParts, this._abortController.signal, this._promptId, void 0, currentDisplayContent);
386782
386915
  currentDisplayContent = void 0;
386783
386916
  for await (const event of responseStream) {
@@ -386796,10 +386929,7 @@ var LegacyAgentProtocol = class {
386796
386929
  this._finishStream("failed");
386797
386930
  return;
386798
386931
  case GeminiEventType.Finished:
386799
- if (toolCallRequests.length === 0) {
386800
- this._finishStream(mapFinishReason(event.value.reason));
386801
- return;
386802
- }
386932
+ finishedReason = event.value.reason;
386803
386933
  break;
386804
386934
  case GeminiEventType.AgentExecutionStopped:
386805
386935
  case GeminiEventType.UserCancelled:
@@ -386815,7 +386945,11 @@ var LegacyAgentProtocol = class {
386815
386945
  return;
386816
386946
  }
386817
386947
  if (toolCallRequests.length === 0) {
386818
- this._finishStream("completed");
386948
+ if (finishedReason !== void 0) {
386949
+ this._finishStream(mapFinishReason(finishedReason));
386950
+ } else {
386951
+ this._finishStream("completed");
386952
+ }
386819
386953
  return;
386820
386954
  }
386821
386955
  const completedToolCalls = await this._scheduler.schedule(toolCallRequests, this._abortController.signal);
@@ -395274,6 +395408,13 @@ export {
395274
395408
  DEFAULT_MAX_LINES_TEXT_FILE,
395275
395409
  MAX_LINE_LENGTH_TEXT_FILE,
395276
395410
  MAX_FILE_SIZE_MB,
395411
+ EMPTY_RESPONSE_COMPRESS_SUGGESTION,
395412
+ THINKING_ONLY_COMPRESS_SUGGESTION,
395413
+ MAX_TOKENS_EXCEEDED_SUGGESTION,
395414
+ SAFETY_BLOCKED_MESSAGE,
395415
+ RECITATION_BLOCKED_MESSAGE,
395416
+ OTHER_BLOCKED_MESSAGE,
395417
+ TRUE_EMPTY_RESPONSE_MESSAGE,
395277
395418
  readWasmBinaryFromDisk,
395278
395419
  loadWasmBinary,
395279
395420
  DEFAULT_ENCODING,
@@ -1,7 +1,7 @@
1
1
  const require = (await import('node:module')).createRequire(import.meta.url); const __chunk_filename = (await import('node:url')).fileURLToPath(import.meta.url); const __chunk_dirname = (await import('node:path')).dirname(__chunk_filename);
2
2
  import {
3
3
  runExitCleanup
4
- } from "./chunk-XTGYOEM3.js";
4
+ } from "./chunk-IM5WJKYT.js";
5
5
  import {
6
6
  __commonJS,
7
7
  __require
@@ -31,7 +31,7 @@ import {
31
31
  partListUnionToString,
32
32
  require_strip_json_comments,
33
33
  sanitizeFilenamePart
34
- } from "./chunk-UOZMJZMA.js";
34
+ } from "./chunk-F6IU45OZ.js";
35
35
  import {
36
36
  __commonJS,
37
37
  __require,