@google/gemini-cli-a2a-server 0.42.0-preview.2 → 0.43.0-preview.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.
@@ -28586,7 +28586,7 @@ var require_object_inspect = __commonJS({
28586
28586
  if (isBoolean2(obj)) {
28587
28587
  return markBoxed(booleanValueOf.call(obj));
28588
28588
  }
28589
- if (isString(obj)) {
28589
+ if (isString2(obj)) {
28590
28590
  return markBoxed(inspect2(String(obj)));
28591
28591
  }
28592
28592
  if (typeof window !== "undefined" && obj === window) {
@@ -28635,7 +28635,7 @@ var require_object_inspect = __commonJS({
28635
28635
  function isError(obj) {
28636
28636
  return toStr(obj) === "[object Error]" && canTrustToString(obj);
28637
28637
  }
28638
- function isString(obj) {
28638
+ function isString2(obj) {
28639
28639
  return toStr(obj) === "[object String]" && canTrustToString(obj);
28640
28640
  }
28641
28641
  function isNumber3(obj) {
@@ -54326,8 +54326,8 @@ var require_copy_sync = __commonJS({
54326
54326
  return getStats(destStat, src, dest, opts);
54327
54327
  }
54328
54328
  function getStats(destStat, src, dest, opts) {
54329
- const statSync5 = opts.dereference ? fs87.statSync : fs87.lstatSync;
54330
- const srcStat = statSync5(src);
54329
+ const statSync6 = opts.dereference ? fs87.statSync : fs87.lstatSync;
54330
+ const srcStat = statSync6(src);
54331
54331
  if (srcStat.isDirectory()) return onDir(srcStat, destStat, src, dest, opts);
54332
54332
  else if (srcStat.isFile() || srcStat.isCharacterDevice() || srcStat.isBlockDevice()) return onFile(srcStat, destStat, src, dest, opts);
54333
54333
  else if (srcStat.isSymbolicLink()) return onLink(destStat, src, dest, opts);
@@ -65579,7 +65579,7 @@ var require_lib8 = __commonJS({
65579
65579
  return numMessages > 0;
65580
65580
  }
65581
65581
  async function isBinaryFile2(file, size) {
65582
- if (isString(file)) {
65582
+ if (isString2(file)) {
65583
65583
  const stat5 = await statAsync(file);
65584
65584
  isStatFile(stat5);
65585
65585
  const fileDescriptor = await openAsync(file, "r");
@@ -65607,7 +65607,7 @@ var require_lib8 = __commonJS({
65607
65607
  }
65608
65608
  exports2.isBinaryFile = isBinaryFile2;
65609
65609
  function isBinaryFileSync(file, size) {
65610
- if (isString(file)) {
65610
+ if (isString2(file)) {
65611
65611
  const stat5 = fs87.statSync(file);
65612
65612
  isStatFile(stat5);
65613
65613
  const fileDescriptor = fs87.openSync(file, "r");
@@ -65687,7 +65687,7 @@ var require_lib8 = __commonJS({
65687
65687
  }
65688
65688
  return false;
65689
65689
  }
65690
- function isString(x2) {
65690
+ function isString2(x2) {
65691
65691
  return typeof x2 === "string";
65692
65692
  }
65693
65693
  function isStatFile(stat5) {
@@ -113158,14 +113158,16 @@ function makeRelative(targetPath, rootDirectory) {
113158
113158
  function getProjectHash(projectRoot) {
113159
113159
  return crypto9.createHash("sha256").update(projectRoot).digest("hex");
113160
113160
  }
113161
+ function toAbsolutePath(p2) {
113162
+ const isWindows2 = process.platform === "win32";
113163
+ const pathModule = isWindows2 ? path3.win32 : path3;
113164
+ return pathModule.resolve(p2).replace(/\\/g, "/");
113165
+ }
113161
113166
  function normalizePath(p2) {
113167
+ const absolute = toAbsolutePath(p2);
113162
113168
  const platform9 = process.platform;
113163
- const isWindows2 = platform9 === "win32";
113164
- const pathModule = isWindows2 ? path3.win32 : path3;
113165
- const resolved = pathModule.resolve(p2);
113166
- const normalized = resolved.replace(/\\/g, "/");
113167
- const isCaseInsensitive = isWindows2 || platform9 === "darwin";
113168
- return isCaseInsensitive ? normalized.toLowerCase() : normalized;
113169
+ const isCaseInsensitive = platform9 === "win32" || platform9 === "darwin";
113170
+ return isCaseInsensitive ? absolute.toLowerCase() : absolute;
113169
113171
  }
113170
113172
  function isSubpath(parentPath, childPath) {
113171
113173
  const platform9 = process.platform;
@@ -114307,9 +114309,9 @@ function parseResponseData(error2) {
114307
114309
  return void 0;
114308
114310
  }
114309
114311
  function isAuthenticationError(error2) {
114310
- if (error2 && typeof error2 === "object" && "code" in error2 && typeof error2.code === "number") {
114311
- const errorCode = error2.code;
114312
- if (errorCode === 401) {
114312
+ if (error2 && typeof error2 === "object" && "code" in error2) {
114313
+ const errorCode = error2["code"];
114314
+ if (typeof errorCode === "number" && errorCode === 401) {
114313
114315
  return true;
114314
114316
  }
114315
114317
  }
@@ -114392,13 +114394,17 @@ import { randomUUID as randomUUID4 } from "node:crypto";
114392
114394
  import * as fs9 from "node:fs";
114393
114395
  import * as path4 from "node:path";
114394
114396
  import * as os3 from "node:os";
114395
- var import_proper_lockfile, PROJECT_ROOT_FILE, LOCK_TIMEOUT_MS, LOCK_RETRY_DELAY_MS, ProjectRegistry;
114397
+ var import_proper_lockfile, registryDataSchema, PROJECT_ROOT_FILE, LOCK_TIMEOUT_MS, LOCK_RETRY_DELAY_MS, ProjectRegistry;
114396
114398
  var init_projectRegistry = __esm({
114397
114399
  "packages/core/dist/src/config/projectRegistry.js"() {
114398
114400
  "use strict";
114399
114401
  import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
114402
+ init_zod();
114400
114403
  init_debugLogger();
114401
114404
  init_errors2();
114405
+ registryDataSchema = external_exports.object({
114406
+ projects: external_exports.record(external_exports.string(), external_exports.string().regex(/^[a-z0-9-]+$/))
114407
+ });
114402
114408
  PROJECT_ROOT_FILE = ".project_root";
114403
114409
  LOCK_TIMEOUT_MS = 1e4;
114404
114410
  LOCK_RETRY_DELAY_MS = 100;
@@ -114429,7 +114435,12 @@ var init_projectRegistry = __esm({
114429
114435
  async loadData() {
114430
114436
  try {
114431
114437
  const content = await fs9.promises.readFile(this.registryPath, "utf8");
114432
- return JSON.parse(content);
114438
+ const parsed = JSON.parse(content);
114439
+ if (this.isValidRegistryData(parsed)) {
114440
+ return parsed;
114441
+ }
114442
+ debugLogger.warn(`Project registry at ${this.registryPath} has an invalid schema, resetting to empty.`);
114443
+ return { projects: {} };
114433
114444
  } catch (error2) {
114434
114445
  if (isNodeError(error2) && error2.code === "ENOENT") {
114435
114446
  return { projects: {} };
@@ -114670,6 +114681,9 @@ var init_projectRegistry = __esm({
114670
114681
  slugify(text) {
114671
114682
  return text.toLowerCase().replace(/[^a-z0-9]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "") || "project";
114672
114683
  }
114684
+ isValidRegistryData(data) {
114685
+ return registryDataSchema.safeParse(data).success;
114686
+ }
114673
114687
  };
114674
114688
  }
114675
114689
  });
@@ -115696,7 +115710,7 @@ function isProModel(model, config3) {
115696
115710
  }
115697
115711
  function isGemini3Model(model, config3) {
115698
115712
  if (config3?.getExperimentalDynamicModelConfiguration?.() === true) {
115699
- const resolved2 = resolveModel(model);
115713
+ const resolved2 = resolveModel(model, false, false, false, true, config3);
115700
115714
  return config3.modelConfigService.getModelDefinition(resolved2)?.family === "gemini-3";
115701
115715
  }
115702
115716
  const resolved = resolveModel(model);
@@ -117627,11 +117641,13 @@ var init_default_legacy = __esm({
117627
117641
  },
117628
117642
  [READ_FILE_PARAM_START_LINE]: {
117629
117643
  description: "Optional: The 1-based line number to start reading from.",
117630
- type: "number"
117644
+ type: "integer",
117645
+ minimum: 1
117631
117646
  },
117632
117647
  [READ_FILE_PARAM_END_LINE]: {
117633
117648
  description: "Optional: The 1-based line number to end reading at (inclusive).",
117634
- type: "number"
117649
+ type: "integer",
117650
+ minimum: 1
117635
117651
  }
117636
117652
  },
117637
117653
  required: [PARAM_FILE_PATH]
@@ -117733,7 +117749,8 @@ var init_default_legacy = __esm({
117733
117749
  },
117734
117750
  [GREP_PARAM_CONTEXT]: {
117735
117751
  description: "Show this many lines of context around each match (equivalent to grep -C). Defaults to 0 if omitted.",
117736
- type: "integer"
117752
+ type: "integer",
117753
+ minimum: 0
117737
117754
  },
117738
117755
  [GREP_PARAM_AFTER]: {
117739
117756
  description: "Show this many lines after each match (equivalent to grep -A). Defaults to 0 if omitted.",
@@ -118267,11 +118284,13 @@ var init_gemini_3 = __esm({
118267
118284
  },
118268
118285
  [READ_FILE_PARAM_START_LINE]: {
118269
118286
  description: "Optional: The 1-based line number to start reading from.",
118270
- type: "number"
118287
+ type: "integer",
118288
+ minimum: 1
118271
118289
  },
118272
118290
  [READ_FILE_PARAM_END_LINE]: {
118273
118291
  description: "Optional: The 1-based line number to end reading at (inclusive).",
118274
- type: "number"
118292
+ type: "integer",
118293
+ minimum: 1
118275
118294
  }
118276
118295
  },
118277
118296
  required: [PARAM_FILE_PATH]
@@ -118279,7 +118298,7 @@ var init_gemini_3 = __esm({
118279
118298
  },
118280
118299
  write_file: {
118281
118300
  name: WRITE_FILE_TOOL_NAME,
118282
- description: `Writes the complete content to a file, automatically creating missing parent directories. Overwrites existing files. The user has the ability to modify 'content' before it is saved. Best for new or small files; use '${EDIT_TOOL_NAME}' for targeted edits to large files.`,
118301
+ description: `Writes the complete content to a file, automatically creating missing parent directories. Overwrites existing files. The user has the ability to modify 'content' before it is saved. Best for new or small files; use '${EDIT_TOOL_NAME}' for targeted edits to large files to minimize token usage and simplify reviews.`,
118283
118302
  parametersJsonSchema: {
118284
118303
  type: "object",
118285
118304
  properties: {
@@ -118371,7 +118390,8 @@ var init_gemini_3 = __esm({
118371
118390
  },
118372
118391
  [GREP_PARAM_CONTEXT]: {
118373
118392
  description: "Show this many lines of context around each match (equivalent to grep -C). Defaults to 0 if omitted.",
118374
- type: "integer"
118393
+ type: "integer",
118394
+ minimum: 0
118375
118395
  },
118376
118396
  [GREP_PARAM_AFTER]: {
118377
118397
  description: "Show this many lines after each match (equivalent to grep -A). Defaults to 0 if omitted.",
@@ -118469,7 +118489,7 @@ var init_gemini_3 = __esm({
118469
118489
  run_shell_command: (enableInteractiveShell, enableEfficiency, enableToolSandboxing) => getShellDeclaration(enableInteractiveShell, enableEfficiency, enableToolSandboxing),
118470
118490
  replace: {
118471
118491
  name: EDIT_TOOL_NAME,
118472
- description: `Replaces text within a file. By default, the tool expects to find and replace exactly ONE occurrence of \`old_string\`. If you want to replace multiple occurrences of the exact same string, set \`allow_multiple\` to true. This tool requires providing significant context around the change to ensure precise targeting.
118492
+ description: `Replaces text within a file. By default, the tool expects to find and replace exactly ONE occurrence of \`old_string\`. If you want to replace multiple occurrences of the exact same string, set \`allow_multiple\` to true. This tool is preferred for surgical edits to existing files as it minimizes token usage, simplifies code reviews, and avoids accidental deletions. This tool requires providing significant context around the change to ensure precise targeting.
118473
118493
  The user has the ability to modify the \`new_string\` content. If modified, this will be stated in the response.`,
118474
118494
  parametersJsonSchema: {
118475
118495
  type: "object",
@@ -119821,6 +119841,8 @@ var init_ignorePatterns = __esm({
119821
119841
  "**/*.bz2",
119822
119842
  "**/*.rar",
119823
119843
  "**/*.7z",
119844
+ "**/*.pak",
119845
+ "**/*.rpa",
119824
119846
  "**/*.doc",
119825
119847
  "**/*.docx",
119826
119848
  "**/*.xls",
@@ -120777,8 +120799,14 @@ function escapeShellArg(arg, shell) {
120777
120799
  }
120778
120800
  switch (shell) {
120779
120801
  case "powershell":
120802
+ if (/^[a-zA-Z0-9\-_.]+$/.test(arg)) {
120803
+ return arg;
120804
+ }
120780
120805
  return `'${arg.replace(/'/g, "''")}'`;
120781
120806
  case "cmd":
120807
+ if (/^[a-zA-Z0-9\-_.]+$/.test(arg)) {
120808
+ return arg;
120809
+ }
120782
120810
  return `"${arg.replace(/"/g, '""')}"`;
120783
120811
  case "bash":
120784
120812
  default:
@@ -128063,7 +128091,8 @@ function recordModelRoutingMetrics(config3, event) {
128063
128091
  "routing.approval_mode": event.approval_mode
128064
128092
  };
128065
128093
  if (event.reasoning) {
128066
- attributes["routing.reasoning"] = event.reasoning;
128094
+ const isStrictTelemetry = process.env["GEMINI_STRICT_TELEMETRY_LIMITS"] === "true";
128095
+ attributes["routing.reasoning"] = isStrictTelemetry && event.reasoning.length > 1e3 ? event.reasoning.substring(0, 1e3) + "..." : event.reasoning;
128067
128096
  }
128068
128097
  if (event.enable_numerical_routing !== void 0) {
128069
128098
  attributes["routing.enable_numerical_routing"] = event.enable_numerical_routing;
@@ -128073,9 +128102,10 @@ function recordModelRoutingMetrics(config3, event) {
128073
128102
  }
128074
128103
  modelRoutingLatencyHistogram.record(event.routing_latency_ms, attributes);
128075
128104
  if (event.failed) {
128105
+ const isStrictTelemetry = process.env["GEMINI_STRICT_TELEMETRY_LIMITS"] === "true";
128076
128106
  modelRoutingFailureCounter.add(1, {
128077
128107
  ...attributes,
128078
- "routing.error_message": event.error_message
128108
+ "routing.error_message": isStrictTelemetry && event.error_message && event.error_message.length > 1e3 ? event.error_message.substring(0, 1e3) + "..." : event.error_message
128079
128109
  });
128080
128110
  }
128081
128111
  }
@@ -133049,7 +133079,7 @@ var init_keychainService = __esm({
133049
133079
  if (await this.isKeychainFunctional(keychainModule)) {
133050
133080
  return keychainModule;
133051
133081
  }
133052
- debugLogger.debug("Keychain functional verification failed");
133082
+ debugLogger.debug("Keychain functional verification failed or timed out");
133053
133083
  return null;
133054
133084
  } catch (error2) {
133055
133085
  const message = error2 instanceof Error ? error2.message : String(error2);
@@ -133070,13 +133100,22 @@ var init_keychainService = __esm({
133070
133100
  return null;
133071
133101
  }
133072
133102
  // Performs a set-get-delete cycle to verify keychain functionality.
133103
+ // Capped with a 2s timeout so a non-responsive Secret Service (common on
133104
+ // headless Linux: WSL/SSH/Docker without gnome-keyring or D-Bus) falls back
133105
+ // to FileKeychain instead of hanging the CLI indefinitely.
133073
133106
  async isKeychainFunctional(keychain) {
133074
133107
  const testAccount = `${KEYCHAIN_TEST_PREFIX}${crypto12.randomBytes(8).toString("hex")}`;
133075
133108
  const testPassword = "test";
133076
- await keychain.setPassword(this.serviceName, testAccount, testPassword);
133077
- const retrieved = await keychain.getPassword(this.serviceName, testAccount);
133078
- const deleted = await keychain.deletePassword(this.serviceName, testAccount);
133079
- return deleted && retrieved === testPassword;
133109
+ const probe = async () => {
133110
+ await keychain.setPassword(this.serviceName, testAccount, testPassword);
133111
+ const retrieved = await keychain.getPassword(this.serviceName, testAccount);
133112
+ const deleted = await keychain.deletePassword(this.serviceName, testAccount);
133113
+ return deleted && retrieved === testPassword;
133114
+ };
133115
+ return Promise.race([
133116
+ probe(),
133117
+ new Promise((resolve24) => setTimeout(() => resolve24(false), 2e3).unref())
133118
+ ]);
133080
133119
  }
133081
133120
  /**
133082
133121
  * MacOS-specific check to detect if a default keychain is available.
@@ -133588,7 +133627,8 @@ async function triggerPostAuthCallbacks(tokens) {
133588
133627
  refresh_token: tokens.refresh_token ?? void 0,
133589
133628
  // Ensure null is not passed
133590
133629
  type: "authorized_user",
133591
- client_email: userAccountManager2.getCachedGoogleAccount() ?? void 0
133630
+ client_email: userAccountManager2.getCachedGoogleAccount() ?? void 0,
133631
+ quota_project_id: process.env["GOOGLE_CLOUD_QUOTA_PROJECT"] || process.env["GOOGLE_CLOUD_PROJECT"] || process.env["GOOGLE_CLOUD_PROJECT_ID"]
133592
133632
  };
133593
133633
  authEvents.emit("post_auth", jwtInput);
133594
133634
  }
@@ -141419,7 +141459,7 @@ var require_minimal = __commonJS({
141419
141459
  function isInteger3(value) {
141420
141460
  return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
141421
141461
  };
141422
- util5.isString = function isString(value) {
141462
+ util5.isString = function isString2(value) {
141423
141463
  return typeof value === "string" || value instanceof String;
141424
141464
  };
141425
141465
  util5.isObject = function isObject5(value) {
@@ -159920,7 +159960,7 @@ var require_minimal2 = __commonJS({
159920
159960
  function isInteger3(value) {
159921
159961
  return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
159922
159962
  };
159923
- util5.isString = function isString(value) {
159963
+ util5.isString = function isString2(value) {
159924
159964
  return typeof value === "string" || value instanceof String;
159925
159965
  };
159926
159966
  util5.isObject = function isObject5(value) {
@@ -209438,8 +209478,8 @@ var GIT_COMMIT_INFO, CLI_VERSION;
209438
209478
  var init_git_commit = __esm({
209439
209479
  "packages/core/dist/src/generated/git-commit.js"() {
209440
209480
  "use strict";
209441
- GIT_COMMIT_INFO = "6837b08a0";
209442
- CLI_VERSION = "0.42.0-preview.2";
209481
+ GIT_COMMIT_INFO = "022e8baef";
209482
+ CLI_VERSION = "0.43.0-preview.0";
209443
209483
  }
209444
209484
  });
209445
209485
 
@@ -279504,6 +279544,22 @@ var require_src57 = __commonJS({
279504
279544
  });
279505
279545
 
279506
279546
  // packages/core/dist/src/telemetry/gcp-exporters.js
279547
+ function truncateLogPayload(payload, limit = 2e5) {
279548
+ if (typeof payload === "string") {
279549
+ return payload.length > limit ? payload.substring(0, limit) + "... (truncated due to size)" : payload;
279550
+ }
279551
+ if (Array.isArray(payload)) {
279552
+ return payload.map((item) => truncateLogPayload(item, limit));
279553
+ }
279554
+ if (payload !== null && typeof payload === "object") {
279555
+ const truncatedObj = {};
279556
+ for (const [key, value] of Object.entries(payload)) {
279557
+ truncatedObj[key] = truncateLogPayload(value, limit);
279558
+ }
279559
+ return truncatedObj;
279560
+ }
279561
+ return payload;
279562
+ }
279507
279563
  var import_google_auth_library9, import_opentelemetry_cloud_trace_exporter, import_opentelemetry_cloud_monitoring_exporter, import_logging, import_core5, GcpTraceExporter, GcpMetricExporter, GcpLogExporter;
279508
279564
  var init_gcp_exporters = __esm({
279509
279565
  "packages/core/dist/src/telemetry/gcp-exporters.js"() {
@@ -279530,6 +279586,18 @@ var init_gcp_exporters = __esm({
279530
279586
  prefix: "custom.googleapis.com/gemini_cli"
279531
279587
  });
279532
279588
  }
279589
+ export(metrics2, resultCallback) {
279590
+ super.export(metrics2, (result2) => {
279591
+ if (result2.code === import_core5.ExportResultCode.FAILED && result2.error) {
279592
+ const errorMessage = result2.error.message || String(result2.error);
279593
+ if (process.env["GEMINI_STRICT_TELEMETRY_LIMITS"] === "true" && errorMessage.includes("written more frequently than the maximum sampling period")) {
279594
+ resultCallback({ code: import_core5.ExportResultCode.SUCCESS });
279595
+ return;
279596
+ }
279597
+ }
279598
+ resultCallback(result2);
279599
+ });
279600
+ }
279533
279601
  };
279534
279602
  GcpLogExporter = class {
279535
279603
  logging;
@@ -279542,20 +279610,46 @@ var init_gcp_exporters = __esm({
279542
279610
  export(logs3, resultCallback) {
279543
279611
  try {
279544
279612
  const entries = logs3.map((log) => {
279545
- const entry = this.log.entry({
279546
- severity: this.mapSeverityToCloudLogging(log.severityNumber),
279547
- timestamp: new Date((0, import_core5.hrTimeToMilliseconds)(log.hrTime)),
279548
- resource: {
279549
- type: "global",
279550
- labels: {
279551
- project_id: this.logging.projectId
279552
- }
279553
- }
279554
- }, {
279613
+ const rawPayload = {
279555
279614
  ...log.attributes,
279556
279615
  ...log.resource?.attributes,
279557
279616
  message: log.body
279558
- });
279617
+ };
279618
+ const isStrictTelemetry = process.env["GEMINI_STRICT_TELEMETRY_LIMITS"] === "true";
279619
+ let finalPayload = rawPayload;
279620
+ if (isStrictTelemetry) {
279621
+ let safePayload = truncateLogPayload(rawPayload, 1e4);
279622
+ let payloadString = JSON.stringify(safePayload);
279623
+ if (payloadString && payloadString.length > 1e5) {
279624
+ safePayload = truncateLogPayload(rawPayload, 2e3);
279625
+ payloadString = JSON.stringify(safePayload);
279626
+ if (payloadString && payloadString.length > 1e5) {
279627
+ safePayload = truncateLogPayload(rawPayload, 5e3);
279628
+ payloadString = JSON.stringify(safePayload);
279629
+ if (payloadString && payloadString.length > 1e5) {
279630
+ safePayload = {
279631
+ _warning: "Payload heavily truncated due to strict limits",
279632
+ data: payloadString.substring(0, 5e4) + "... (truncated)"
279633
+ };
279634
+ }
279635
+ }
279636
+ }
279637
+ finalPayload = safePayload;
279638
+ }
279639
+ const entry = this.log.entry(
279640
+ {
279641
+ severity: this.mapSeverityToCloudLogging(log.severityNumber),
279642
+ timestamp: new Date((0, import_core5.hrTimeToMilliseconds)(log.hrTime)),
279643
+ resource: {
279644
+ type: "global",
279645
+ labels: {
279646
+ project_id: this.logging.projectId
279647
+ }
279648
+ }
279649
+ },
279650
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
279651
+ finalPayload
279652
+ );
279559
279653
  return entry;
279560
279654
  });
279561
279655
  const writePromise = this.log.write(entries).then(() => {
@@ -329508,7 +329602,7 @@ function getVersion() {
329508
329602
  }
329509
329603
  versionPromise = (async () => {
329510
329604
  const pkgJson = await getPackageJson(__dirname4);
329511
- return "0.42.0-preview.2";
329605
+ return "0.43.0-preview.0";
329512
329606
  })();
329513
329607
  return versionPromise;
329514
329608
  }
@@ -330453,18 +330547,30 @@ var init_policyCatalog = __esm({
330453
330547
  }
330454
330548
  });
330455
330549
 
330550
+ // packages/core/dist/src/utils/modelUtils.js
330551
+ function normalizeModelId(modelId) {
330552
+ return modelId.startsWith("models/") ? modelId.slice(7) : modelId;
330553
+ }
330554
+ var init_modelUtils = __esm({
330555
+ "packages/core/dist/src/utils/modelUtils.js"() {
330556
+ "use strict";
330557
+ }
330558
+ });
330559
+
330456
330560
  // packages/core/dist/src/availability/policyHelpers.js
330457
330561
  function resolvePolicyChain(config3, preferredModel, wrapsAround = false) {
330458
- const modelFromConfig = preferredModel ?? config3.getActiveModel?.() ?? config3.getModel();
330459
- const configuredModel = config3.getModel();
330562
+ const normalizedPreferredModel = preferredModel ? normalizeModelId(preferredModel) : void 0;
330563
+ const modelFromConfig = normalizeModelId(normalizedPreferredModel ?? config3.getActiveModel?.() ?? config3.getModel());
330564
+ const configuredModel = normalizeModelId(config3.getModel());
330460
330565
  let chain2;
330461
330566
  const useGemini31 = config3.getGemini31LaunchedSync?.() ?? false;
330462
330567
  const useGemini31FlashLite = config3.getGemini31FlashLiteLaunchedSync?.() ?? false;
330463
330568
  const useCustomToolModel = config3.getUseCustomToolModelSync?.() ?? false;
330464
330569
  const hasAccessToPreview = config3.getHasAccessToPreviewModel?.() ?? true;
330465
- const resolvedModel = resolveModel(modelFromConfig, useGemini31, useGemini31FlashLite, useCustomToolModel, hasAccessToPreview, config3);
330466
- const isAutoPreferred = preferredModel ? isAutoModel(preferredModel, config3) : false;
330570
+ const resolvedModel = normalizeModelId(resolveModel(modelFromConfig, useGemini31, useGemini31FlashLite, useCustomToolModel, hasAccessToPreview, config3));
330571
+ const isAutoPreferred = normalizedPreferredModel ? isAutoModel(normalizedPreferredModel, config3) : false;
330467
330572
  const isAutoConfigured = isAutoModel(configuredModel, config3);
330573
+ const effectiveWrapsAround = wrapsAround || isAutoPreferred || isAutoConfigured || isGemini3Model(resolvedModel, config3);
330468
330574
  if (config3.getExperimentalDynamicModelConfiguration?.() === true) {
330469
330575
  const context2 = {
330470
330576
  useGemini3_1: useGemini31,
@@ -330473,13 +330579,13 @@ function resolvePolicyChain(config3, preferredModel, wrapsAround = false) {
330473
330579
  };
330474
330580
  if (resolvedModel === DEFAULT_GEMINI_FLASH_LITE_MODEL) {
330475
330581
  chain2 = config3.modelConfigService.resolveChain("lite", context2);
330476
- } else if (isGemini3Model(resolvedModel, config3) || isAutoPreferred || isAutoConfigured) {
330582
+ } else if (isGemini3Model(normalizeModelId(resolvedModel), config3) || isAutoPreferred || isAutoConfigured) {
330477
330583
  if (isAutoConfigured && config3.modelConfigService.getModelChain(configuredModel)) {
330478
330584
  chain2 = config3.modelConfigService.resolveChain(configuredModel, context2);
330479
330585
  }
330480
330586
  if (!chain2) {
330481
330587
  const isAutoSelection = isAutoPreferred || isAutoConfigured;
330482
- const previewEnabled = hasAccessToPreview && (isGemini3Model(resolvedModel, config3) || preferredModel === PREVIEW_GEMINI_MODEL_AUTO || configuredModel === PREVIEW_GEMINI_MODEL_AUTO);
330588
+ const previewEnabled = hasAccessToPreview && (isGemini3Model(resolvedModel, config3) || normalizedPreferredModel === PREVIEW_GEMINI_MODEL_AUTO || configuredModel === PREVIEW_GEMINI_MODEL_AUTO);
330483
330589
  const autoPrefix = isAutoSelection ? "auto-" : "";
330484
330590
  const chainKey = previewEnabled ? "preview" : "default";
330485
330591
  chain2 = config3.modelConfigService.resolveChain(`${autoPrefix}${chainKey}`, context2);
@@ -330488,14 +330594,14 @@ function resolvePolicyChain(config3, preferredModel, wrapsAround = false) {
330488
330594
  if (!chain2) {
330489
330595
  chain2 = createSingleModelChain(modelFromConfig);
330490
330596
  }
330491
- chain2 = applyDynamicSlicing(chain2, resolvedModel, wrapsAround);
330597
+ chain2 = applyDynamicSlicing(chain2, resolvedModel, effectiveWrapsAround);
330492
330598
  } else {
330493
330599
  if (resolvedModel === DEFAULT_GEMINI_FLASH_LITE_MODEL) {
330494
330600
  chain2 = getFlashLitePolicyChain();
330495
330601
  } else if (isGemini3Model(resolvedModel, config3) || isAutoPreferred || isAutoConfigured) {
330496
330602
  const isAutoSelection = isAutoPreferred || isAutoConfigured;
330497
330603
  if (hasAccessToPreview) {
330498
- const previewEnabled = isGemini3Model(resolvedModel, config3) || preferredModel === PREVIEW_GEMINI_MODEL_AUTO || configuredModel === PREVIEW_GEMINI_MODEL_AUTO;
330604
+ const previewEnabled = isGemini3Model(resolvedModel, config3) || normalizedPreferredModel === PREVIEW_GEMINI_MODEL_AUTO || configuredModel === PREVIEW_GEMINI_MODEL_AUTO;
330499
330605
  chain2 = getModelPolicyChain({
330500
330606
  previewEnabled,
330501
330607
  isAutoSelection,
@@ -330517,7 +330623,7 @@ function resolvePolicyChain(config3, preferredModel, wrapsAround = false) {
330517
330623
  } else {
330518
330624
  chain2 = createSingleModelChain(modelFromConfig);
330519
330625
  }
330520
- chain2 = applyDynamicSlicing(chain2, resolvedModel, wrapsAround);
330626
+ chain2 = applyDynamicSlicing(chain2, resolvedModel, effectiveWrapsAround);
330521
330627
  }
330522
330628
  if (config3?.getApprovalMode?.() === ApprovalMode.PLAN) {
330523
330629
  return chain2.map((policy) => ({
@@ -330528,14 +330634,16 @@ function resolvePolicyChain(config3, preferredModel, wrapsAround = false) {
330528
330634
  return chain2;
330529
330635
  }
330530
330636
  function applyDynamicSlicing(chain2, resolvedModel, wrapsAround) {
330531
- const activeIndex = chain2.findIndex((policy) => policy.model === resolvedModel);
330637
+ const normalizedResolved = normalizeModelId(resolvedModel);
330638
+ const activeIndex = chain2.findIndex((policy) => normalizeModelId(policy.model) === normalizedResolved);
330532
330639
  if (activeIndex !== -1) {
330533
330640
  return wrapsAround ? [...chain2.slice(activeIndex), ...chain2.slice(0, activeIndex)] : [...chain2.slice(activeIndex)];
330534
330641
  }
330535
330642
  return [createDefaultPolicy(resolvedModel, { isLastResort: true })];
330536
330643
  }
330537
330644
  function buildFallbackPolicyContext(chain2, failedModel, wrapsAround = false) {
330538
- const index = chain2.findIndex((policy) => policy.model === failedModel);
330645
+ const normalizedFailed = normalizeModelId(failedModel);
330646
+ const index = chain2.findIndex((policy) => normalizeModelId(policy.model) === normalizedFailed);
330539
330647
  if (index === -1) {
330540
330648
  return { failedPolicy: void 0, candidates: chain2 };
330541
330649
  }
@@ -330614,6 +330722,7 @@ var init_policyHelpers = __esm({
330614
330722
  "use strict";
330615
330723
  init_policyCatalog();
330616
330724
  init_models();
330725
+ init_modelUtils();
330617
330726
  init_types2();
330618
330727
  }
330619
330728
  });
@@ -331186,6 +331295,15 @@ var init_baseLlmClient = __esm({
331186
331295
  }
331187
331296
  return text;
331188
331297
  }
331298
+ async countTokens(options) {
331299
+ const model = options.modelConfigKey ? this.config.modelConfigService.getResolvedConfig(options.modelConfigKey).model : this.config.getActiveModel();
331300
+ const result2 = await this.contentGenerator.countTokens({
331301
+ model,
331302
+ contents: options.contents,
331303
+ config: options.abortSignal ? { abortSignal: options.abortSignal } : void 0
331304
+ });
331305
+ return { totalTokens: result2.totalTokens || 0 };
331306
+ }
331189
331307
  async generateContent(options) {
331190
331308
  const { modelConfigKey, contents, systemInstruction, abortSignal, promptId, role, maxAttempts } = options;
331191
331309
  const shouldRetryOnContent = (response) => {
@@ -331890,6 +332008,9 @@ function getErrorReplaceResult(params, occurrences, finalOldString, finalNewStri
331890
332008
  }
331891
332009
  return error2;
331892
332010
  }
332011
+ function fileDiffToSummary(diff, editData) {
332012
+ return diff.diffStat ? `${diff.diffStat.model_added_lines} added, ${diff.diffStat.model_removed_lines} removed` : `${editData.occurrences} replacements`;
332013
+ }
331893
332014
  function stripWhitespace(str2) {
331894
332015
  return str2.replace(/\s/g, "");
331895
332016
  }
@@ -332399,8 +332520,20 @@ ${snippet2}`);
332399
332520
  if (jitContext) {
332400
332521
  llmContent = appendJitContext(llmContent, jitContext);
332401
332522
  }
332523
+ const resultSummary = typeof displayResult === "string" ? displayResult : fileDiffToSummary(displayResult, editData);
332402
332524
  return {
332403
332525
  llmContent,
332526
+ display: {
332527
+ name: this._toolDisplayName,
332528
+ description: this.getDescription(),
332529
+ resultSummary,
332530
+ result: {
332531
+ type: "diff",
332532
+ path: this.resolvedPath,
332533
+ beforeText: editData.currentContent ?? "",
332534
+ afterText: editData.newContent
332535
+ }
332536
+ },
332404
332537
  returnDisplay: displayResult
332405
332538
  };
332406
332539
  } catch (error2) {
@@ -332860,6 +332993,17 @@ ${snippet2}`);
332860
332993
  }
332861
332994
  return {
332862
332995
  llmContent,
332996
+ display: {
332997
+ name: WRITE_FILE_DISPLAY_NAME,
332998
+ description: this.getDescription(),
332999
+ resultSummary: diffStat ? `${diffStat.model_added_lines} added, ${diffStat.model_removed_lines} removed` : "Written",
333000
+ result: {
333001
+ type: "diff",
333002
+ path: this.resolvedPath,
333003
+ beforeText: correctedContentResult.originalContent ?? "",
333004
+ afterText: correctedContentResult.correctedContent
333005
+ }
333006
+ },
332863
333007
  returnDisplay: displayResult
332864
333008
  };
332865
333009
  } catch (error2) {
@@ -333554,6 +333698,9 @@ var init_cache = __esm({
333554
333698
  // packages/core/dist/src/code_assist/setup.js
333555
333699
  async function setupUser(client, config3, httpOptions = {}) {
333556
333700
  const projectId = process.env["GOOGLE_CLOUD_PROJECT"] || process.env["GOOGLE_CLOUD_PROJECT_ID"] || void 0;
333701
+ if (projectId && /^\d+$/.test(projectId)) {
333702
+ throw new InvalidNumericProjectIdError(projectId);
333703
+ }
333557
333704
  const projectCache = userDataCache.getOrCreate(client, () => createCache({
333558
333705
  storage: "map",
333559
333706
  defaultTtl: 3e4
@@ -333700,7 +333847,7 @@ function validateLoadCodeAssistResponse(res) {
333700
333847
  }
333701
333848
  }
333702
333849
  }
333703
- var ProjectIdRequiredError, ValidationCancelledError, IneligibleTierError, userDataCache;
333850
+ var ProjectIdRequiredError, InvalidNumericProjectIdError, ValidationCancelledError, IneligibleTierError, userDataCache;
333704
333851
  var init_setup = __esm({
333705
333852
  "packages/core/dist/src/code_assist/setup.js"() {
333706
333853
  "use strict";
@@ -333717,6 +333864,12 @@ var init_setup = __esm({
333717
333864
  this.name = "ProjectIdRequiredError";
333718
333865
  }
333719
333866
  };
333867
+ InvalidNumericProjectIdError = class extends Error {
333868
+ constructor(projectId) {
333869
+ super(`Invalid Google Cloud Project ID: "${projectId}". The GOOGLE_CLOUD_PROJECT (or GOOGLE_CLOUD_PROJECT_ID) environment variable must be set to your string-based Project ID (e.g., "my-project-123"), not your numeric Project Number. Please update your environment variables.`);
333870
+ this.name = "InvalidNumericProjectIdError";
333871
+ }
333872
+ };
333720
333873
  ValidationCancelledError = class extends Error {
333721
333874
  constructor() {
333722
333875
  super("User cancelled account validation");
@@ -333740,13 +333893,26 @@ var init_setup = __esm({
333740
333893
 
333741
333894
  // packages/core/dist/src/utils/quotaErrorDetection.js
333742
333895
  function isApiError(error2) {
333743
- return typeof error2 === "object" && error2 !== null && "error" in error2 && // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
333744
- typeof error2.error === "object" && // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
333745
- "message" in error2.error;
333896
+ if (typeof error2 !== "object" || error2 === null || !("error" in error2)) {
333897
+ return false;
333898
+ }
333899
+ const errorProp = error2.error;
333900
+ if (typeof errorProp !== "object" || errorProp === null) {
333901
+ return false;
333902
+ }
333903
+ return "code" in errorProp && typeof errorProp.code === "number" && "message" in errorProp && typeof errorProp.message === "string" && "status" in errorProp && typeof errorProp.status === "string";
333746
333904
  }
333747
333905
  function isStructuredError(error2) {
333748
- return typeof error2 === "object" && error2 !== null && "message" in error2 && // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
333749
- typeof error2.message === "string";
333906
+ if (typeof error2 !== "object" || error2 === null || !("message" in error2)) {
333907
+ return false;
333908
+ }
333909
+ if (typeof error2.message !== "string") {
333910
+ return false;
333911
+ }
333912
+ if ("status" in error2 && typeof error2.status !== "number") {
333913
+ return false;
333914
+ }
333915
+ return true;
333750
333916
  }
333751
333917
  var init_quotaErrorDetection = __esm({
333752
333918
  "packages/core/dist/src/utils/quotaErrorDetection.js"() {
@@ -333760,9 +333926,10 @@ function estimateTextTokens(text, charsPerToken) {
333760
333926
  return text.length / charsPerToken;
333761
333927
  }
333762
333928
  let tokens = 0;
333929
+ const asciiTokensPerChar = 1 / charsPerToken;
333763
333930
  for (let i3 = 0; i3 < text.length; i3++) {
333764
333931
  if (text.charCodeAt(i3) <= 127) {
333765
- tokens += ASCII_TOKENS_PER_CHAR;
333932
+ tokens += asciiTokensPerChar;
333766
333933
  } else {
333767
333934
  tokens += NON_ASCII_TOKENS_PER_CHAR;
333768
333935
  }
@@ -334424,10 +334591,6 @@ function validateBaseUrl(baseUrl) {
334424
334591
  }
334425
334592
  }
334426
334593
  async function createContentGeneratorConfig(config3, authType, apiKey, baseUrl, customHeaders, vertexAiRouting) {
334427
- const geminiApiKey = apiKey || process.env["GEMINI_API_KEY"] || await loadApiKey() || void 0;
334428
- const googleApiKey = process.env["GOOGLE_API_KEY"] || void 0;
334429
- const googleCloudProject = process.env["GOOGLE_CLOUD_PROJECT"] || process.env["GOOGLE_CLOUD_PROJECT_ID"] || void 0;
334430
- const googleCloudLocation = process.env["GOOGLE_CLOUD_LOCATION"] || void 0;
334431
334594
  const contentGeneratorConfig = {
334432
334595
  authType,
334433
334596
  proxy: config3?.getProxy(),
@@ -334438,6 +334601,10 @@ async function createContentGeneratorConfig(config3, authType, apiKey, baseUrl,
334438
334601
  if (authType === AuthType2.LOGIN_WITH_GOOGLE || authType === AuthType2.COMPUTE_ADC) {
334439
334602
  return contentGeneratorConfig;
334440
334603
  }
334604
+ const geminiApiKey = apiKey || process.env["GEMINI_API_KEY"] || await loadApiKey() || void 0;
334605
+ const googleApiKey = process.env["GOOGLE_API_KEY"] || void 0;
334606
+ const googleCloudProject = process.env["GOOGLE_CLOUD_PROJECT"] || process.env["GOOGLE_CLOUD_PROJECT_ID"] || void 0;
334607
+ const googleCloudLocation = process.env["GOOGLE_CLOUD_LOCATION"] || void 0;
334441
334608
  if (authType === AuthType2.USE_GEMINI && geminiApiKey) {
334442
334609
  contentGeneratorConfig.apiKey = geminiApiKey;
334443
334610
  contentGeneratorConfig.vertexai = false;
@@ -335478,6 +335645,11 @@ ${directoryContent}`;
335478
335645
  }
335479
335646
  return {
335480
335647
  llmContent: resultMessage,
335648
+ display: {
335649
+ name: LS_DISPLAY_NAME,
335650
+ description: this.getDescription(),
335651
+ resultSummary: displayMessage
335652
+ },
335481
335653
  returnDisplay: {
335482
335654
  summary: displayMessage,
335483
335655
  files: entries.map((entry) => `${entry.isDirectory ? "[DIR] " : ""}${entry.name}`)
@@ -335733,8 +335905,8 @@ var require_ignore = __commonJS({
335733
335905
  (prev, [matcher, replacer]) => prev.replace(matcher, replacer.bind(pattern)),
335734
335906
  pattern
335735
335907
  );
335736
- var isString = (subject) => typeof subject === "string";
335737
- var checkPattern = (pattern) => pattern && isString(pattern) && !REGEX_TEST_BLANK_LINE.test(pattern) && !REGEX_INVALID_TRAILING_BACKSLASH.test(pattern) && pattern.indexOf("#") !== 0;
335908
+ var isString2 = (subject) => typeof subject === "string";
335909
+ var checkPattern = (pattern) => pattern && isString2(pattern) && !REGEX_TEST_BLANK_LINE.test(pattern) && !REGEX_INVALID_TRAILING_BACKSLASH.test(pattern) && pattern.indexOf("#") !== 0;
335738
335910
  var splitPattern = (pattern) => pattern.split(REGEX_SPLITALL_CRLF).filter(Boolean);
335739
335911
  var IgnoreRule = class {
335740
335912
  constructor(pattern, mark, body2, ignoreCase, negative, prefix) {
@@ -335801,7 +335973,7 @@ var require_ignore = __commonJS({
335801
335973
  this._added = true;
335802
335974
  return;
335803
335975
  }
335804
- if (isString(pattern)) {
335976
+ if (isString2(pattern)) {
335805
335977
  pattern = {
335806
335978
  pattern
335807
335979
  };
@@ -335816,7 +335988,7 @@ var require_ignore = __commonJS({
335816
335988
  add(pattern) {
335817
335989
  this._added = false;
335818
335990
  makeArray(
335819
- isString(pattern) ? splitPattern(pattern) : pattern
335991
+ isString2(pattern) ? splitPattern(pattern) : pattern
335820
335992
  ).forEach(this._add, this);
335821
335993
  return this._added;
335822
335994
  }
@@ -335858,7 +336030,7 @@ var require_ignore = __commonJS({
335858
336030
  throw new Ctor(message);
335859
336031
  };
335860
336032
  var checkPath = (path95, originalPath, doThrow) => {
335861
- if (!isString(path95)) {
336033
+ if (!isString2(path95)) {
335862
336034
  return doThrow(
335863
336035
  `path must be a string, but got \`${originalPath}\``,
335864
336036
  TypeError
@@ -336189,7 +336361,7 @@ var init_ignoreFileParser = __esm({
336189
336361
  return this.patterns;
336190
336362
  }
336191
336363
  getIgnoreFilePaths() {
336192
- return this.fileNames.slice().reverse().map((fileName) => path47.join(this.projectRoot, fileName)).filter((filePath) => fs46.existsSync(filePath));
336364
+ return this.fileNames.slice().reverse().map((fileName) => path47.join(this.projectRoot, fileName)).filter((filePath) => fs46.statSync(filePath, { throwIfNoEntry: false })?.isFile() ?? false);
336193
336365
  }
336194
336366
  /**
336195
336367
  * Returns true if at least one ignore file exists and has patterns.
@@ -336405,7 +336577,8 @@ var init_fileDiscoveryService = __esm({
336405
336577
  const paths = [];
336406
336578
  if (this.gitIgnoreFilter && this.defaultFilterFileOptions.respectGitIgnore) {
336407
336579
  const gitIgnorePath = path49.join(this.projectRoot, ".gitignore");
336408
- if (fs48.existsSync(gitIgnorePath)) {
336580
+ const stat5 = fs48.statSync(gitIgnorePath, { throwIfNoEntry: false });
336581
+ if (stat5?.isFile()) {
336409
336582
  paths.push(gitIgnorePath);
336410
336583
  }
336411
336584
  }
@@ -336511,8 +336684,15 @@ ${result2.llmContent}`;
336511
336684
  llmContent = appendJitContextToParts(llmContent, jitContext);
336512
336685
  }
336513
336686
  }
336687
+ const displayResultSummary = result2.isTruncated ? `${result2.linesShown[0]}-${result2.linesShown[1]} of ${result2.originalLineCount}` : lines !== void 0 ? `${lines} lines` : void 0;
336514
336688
  return {
336515
336689
  llmContent,
336690
+ display: {
336691
+ name: READ_FILE_DISPLAY_NAME,
336692
+ description: this.getDescription(),
336693
+ resultSummary: displayResultSummary,
336694
+ result: { type: "text", text: result2.returnDisplay || "" }
336695
+ },
336516
336696
  returnDisplay: result2.returnDisplay || ""
336517
336697
  };
336518
336698
  }
@@ -336535,12 +336715,6 @@ ${result2.llmContent}`;
336535
336715
  if (validationError) {
336536
336716
  return validationError;
336537
336717
  }
336538
- if (params.start_line !== void 0 && params.start_line < 1) {
336539
- return "start_line must be at least 1";
336540
- }
336541
- if (params.end_line !== void 0 && params.end_line < 1) {
336542
- return "end_line must be at least 1";
336543
- }
336544
336718
  if (params.start_line !== void 0 && params.end_line !== void 0 && params.start_line > params.end_line) {
336545
336719
  return "start_line cannot be greater than end_line";
336546
336720
  }
@@ -344065,7 +344239,19 @@ var init_grep = __esm({
344065
344239
  } else {
344066
344240
  searchLocationDescription = `in path "${searchDirDisplay}"`;
344067
344241
  }
344068
- return await formatGrepResults(allMatches, this.params, searchLocationDescription, totalMaxMatches);
344242
+ const result2 = await formatGrepResults(allMatches, this.params, searchLocationDescription, totalMaxMatches);
344243
+ return {
344244
+ ...result2,
344245
+ display: {
344246
+ name: this._toolDisplayName,
344247
+ description: this.getDescription(),
344248
+ resultSummary: result2.returnDisplay.summary,
344249
+ result: {
344250
+ type: "text",
344251
+ text: result2.llmContent.split("\n---\n").slice(1).join("\n---\n")
344252
+ }
344253
+ }
344254
+ };
344069
344255
  } catch (error2) {
344070
344256
  debugLogger.warn(`Error during GrepLogic execution: ${error2}`);
344071
344257
  const errorMessage = getErrorMessage(error2);
@@ -344544,7 +344730,19 @@ var init_ripGrep = __esm({
344544
344730
  const matchCount = allMatches.filter((m3) => !m3.isContext).length;
344545
344731
  allMatches = await this.enrichWithRipgrepAutoContext(allMatches, matchCount, totalMaxMatches, searchDirAbs, timeoutController.signal);
344546
344732
  const searchLocationDescription = `in path "${searchDirDisplay}"`;
344547
- return await formatGrepResults(allMatches, this.params, searchLocationDescription, totalMaxMatches);
344733
+ const result2 = await formatGrepResults(allMatches, this.params, searchLocationDescription, totalMaxMatches);
344734
+ return {
344735
+ ...result2,
344736
+ display: {
344737
+ name: this._toolDisplayName,
344738
+ description: this.getDescription(),
344739
+ resultSummary: result2.returnDisplay.summary,
344740
+ result: {
344741
+ type: "text",
344742
+ text: result2.llmContent.split("\n---\n").slice(1).join("\n---\n")
344743
+ }
344744
+ }
344745
+ };
344548
344746
  } catch (error2) {
344549
344747
  debugLogger.warn(`Error during GrepLogic execution: ${error2}`);
344550
344748
  const errorMessage = getErrorMessage(error2);
@@ -357219,8 +357417,18 @@ ${result2.output}`;
357219
357417
  ...executionError
357220
357418
  };
357221
357419
  }
357420
+ const displayResultSummary = result2.backgrounded ? `PID: ${result2.pid}` : result2.exitCode !== null && result2.exitCode !== 0 ? `Exit Code: ${result2.exitCode}` : void 0;
357222
357421
  return {
357223
357422
  llmContent,
357423
+ display: {
357424
+ name: "Shell",
357425
+ description: this.getDescription(),
357426
+ resultSummary: displayResultSummary,
357427
+ result: typeof returnDisplay === "string" ? { type: "text", text: returnDisplay } : (
357428
+ // TODO: Add support for terminal display type (AnsiOutput)
357429
+ void 0
357430
+ )
357431
+ },
357224
357432
  returnDisplay,
357225
357433
  data,
357226
357434
  ...executionError
@@ -363637,6 +363845,11 @@ Strategic Intent: ${strategicIntent.trim()}`;
363637
363845
  }
363638
363846
  return {
363639
363847
  llmContent,
363848
+ display: {
363849
+ format: "notice",
363850
+ name: title || UPDATE_TOPIC_DISPLAY_NAME,
363851
+ description: this.getDescription()
363852
+ },
363640
363853
  returnDisplay
363641
363854
  };
363642
363855
  }
@@ -364072,6 +364285,37 @@ function isSchemaDepthError(errorMessage) {
364072
364285
  function isInvalidArgumentError(errorMessage) {
364073
364286
  return errorMessage.includes("Request contains an invalid argument");
364074
364287
  }
364288
+ function stripToolCallIdPrefixes(contents) {
364289
+ return contents.map((content) => ({
364290
+ ...content,
364291
+ parts: (content.parts || []).map((part) => {
364292
+ const newPart = { ...part };
364293
+ if (newPart.functionCall) {
364294
+ const fc = newPart.functionCall;
364295
+ const name3 = fc.name?.trim() || "generic_tool";
364296
+ if (fc.id && fc.id.startsWith(`${name3}__`)) {
364297
+ newPart.functionCall = {
364298
+ name: fc.name,
364299
+ args: fc.args,
364300
+ id: fc.id.substring(name3.length + 2)
364301
+ };
364302
+ }
364303
+ }
364304
+ if (newPart.functionResponse) {
364305
+ const fr2 = newPart.functionResponse;
364306
+ const name3 = fr2.name?.trim() || "generic_tool";
364307
+ if (fr2.id && fr2.id.startsWith(`${name3}__`)) {
364308
+ newPart.functionResponse = {
364309
+ name: fr2.name,
364310
+ response: fr2.response,
364311
+ id: fr2.id.substring(name3.length + 2)
364312
+ };
364313
+ }
364314
+ }
364315
+ return newPart;
364316
+ })
364317
+ }));
364318
+ }
364075
364319
  var StreamEventType, MID_STREAM_RETRY_OPTIONS, SYNTHETIC_THOUGHT_SIGNATURE2, InvalidStreamError, AgentExecutionStoppedError, AgentExecutionBlockedError, GeminiChat;
364076
364320
  var init_geminiChat = __esm({
364077
364321
  "packages/core/dist/src/core/geminiChat.js"() {
@@ -364155,6 +364399,9 @@ var init_geminiChat = __esm({
364155
364399
  this.chatRecordingService = new ChatRecordingService(context2);
364156
364400
  this.lastPromptTokenCount = estimateTokenCountSync(this.agentHistory.flatMap((c2) => c2.parts || []));
364157
364401
  }
364402
+ get loopContext() {
364403
+ return this.context;
364404
+ }
364158
364405
  async initialize(resumedSessionData, kind = "main") {
364159
364406
  await this.chatRecordingService.initialize(resumedSessionData, kind);
364160
364407
  }
@@ -364412,9 +364659,10 @@ var init_geminiChat = __esm({
364412
364659
  lastModelToUse = modelToUse;
364413
364660
  lastConfig = config3;
364414
364661
  lastContentsToUse = contentsToUse;
364662
+ const finalContents = stripToolCallIdPrefixes(contentsToUse);
364415
364663
  return this.context.config.getContentGenerator().generateContentStream({
364416
364664
  model: modelToUse,
364417
- contents: contentsToUse,
364665
+ contents: finalContents,
364418
364666
  config: config3
364419
364667
  }, prompt_id, role);
364420
364668
  };
@@ -364583,7 +364831,9 @@ This error was probably caused by cyclic schema references in one of the followi
364583
364831
  const finalFunctionCallsMap = /* @__PURE__ */ new Map();
364584
364832
  const legacyFunctionCalls = [];
364585
364833
  const callIndexToId = /* @__PURE__ */ new Map();
364834
+ let runningFunctionCallCounter = 0;
364586
364835
  for await (const chunk of streamResponse) {
364836
+ const currentChunkStartCounter = runningFunctionCallCounter;
364587
364837
  const candidateWithReason = chunk?.candidates?.find((candidate) => candidate.finishReason);
364588
364838
  if (candidateWithReason) {
364589
364839
  finishReason = candidateWithReason.finishReason;
@@ -364592,18 +364842,30 @@ This error was probably caused by cyclic schema references in one of the followi
364592
364842
  if (this.context.config.isContextManagementEnabled()) {
364593
364843
  for (let i3 = 0; i3 < chunk.functionCalls.length; i3++) {
364594
364844
  const fnCall = chunk.functionCalls[i3];
364845
+ const globalIndex = currentChunkStartCounter + i3;
364595
364846
  if (!fnCall.id) {
364596
- let id = callIndexToId.get(i3);
364847
+ let id = callIndexToId.get(globalIndex);
364597
364848
  if (!id) {
364598
364849
  id = `synth_${this.context.promptId}_${Date.now()}_${this.callCounter++}`;
364599
- callIndexToId.set(i3, id);
364600
- debugLogger.log(`[GeminiChat] Assigned synthetic ID: ${id} to tool at index ${i3}: ${fnCall.name}`);
364850
+ callIndexToId.set(globalIndex, id);
364851
+ debugLogger.log(`[GeminiChat] Assigned synthetic ID: ${id} to tool at index ${globalIndex}: ${fnCall.name}`);
364601
364852
  }
364602
364853
  fnCall.id = id;
364603
364854
  }
364855
+ const name3 = fnCall.name?.trim() || "generic_tool";
364856
+ if (fnCall.id && !fnCall.id.startsWith(`${name3}__`)) {
364857
+ fnCall.id = `${name3}__${fnCall.id}`;
364858
+ }
364604
364859
  finalFunctionCallsMap.set(fnCall.id, fnCall);
364605
364860
  }
364861
+ runningFunctionCallCounter += chunk.functionCalls.length;
364606
364862
  } else {
364863
+ for (const fnCall of chunk.functionCalls) {
364864
+ const name3 = fnCall.name?.trim() || "generic_tool";
364865
+ if (fnCall.id && !fnCall.id.startsWith(`${name3}__`)) {
364866
+ fnCall.id = `${name3}__${fnCall.id}`;
364867
+ }
364868
+ }
364607
364869
  legacyFunctionCalls.push(...chunk.functionCalls);
364608
364870
  }
364609
364871
  }
@@ -364617,13 +364879,18 @@ This error was probably caused by cyclic schema references in one of the followi
364617
364879
  if (content.parts.some((part) => part.functionCall)) {
364618
364880
  hasToolCall = true;
364619
364881
  }
364882
+ let localFunctionCallCounter = 0;
364620
364883
  modelResponseParts.push(...content.parts.filter((part) => !part.thought).map((part) => {
364621
364884
  if (!this.context.config.isContextManagementEnabled()) {
364622
364885
  return part;
364623
364886
  }
364887
+ let callIndex;
364888
+ if (part.functionCall) {
364889
+ callIndex = currentChunkStartCounter + localFunctionCallCounter++;
364890
+ }
364624
364891
  return {
364625
364892
  ...part,
364626
- callIndex: chunk.functionCalls?.findIndex((fc) => fc.name === part.functionCall?.name)
364893
+ callIndex
364627
364894
  };
364628
364895
  }));
364629
364896
  }
@@ -364767,6 +365034,41 @@ This error was probably caused by cyclic schema references in one of the followi
364767
365034
  }
364768
365035
  });
364769
365036
 
365037
+ // packages/core/dist/src/agent/tool-display-utils.js
365038
+ function populateToolDisplay({ name: name3, invocation, resultDisplay, displayName, display: prevDisplay }) {
365039
+ const display = {
365040
+ name: displayName || name3,
365041
+ description: invocation?.getDescription?.(),
365042
+ ...prevDisplay
365043
+ };
365044
+ if (resultDisplay !== void 0 && display.result === void 0) {
365045
+ display.result = toolResultDisplayToDisplayContent(resultDisplay);
365046
+ }
365047
+ return display;
365048
+ }
365049
+ function toolResultDisplayToDisplayContent(resultDisplay) {
365050
+ if (typeof resultDisplay === "string") {
365051
+ return { type: "text", text: resultDisplay };
365052
+ }
365053
+ if (typeof resultDisplay === "object" && resultDisplay !== null && "fileDiff" in resultDisplay && "newContent" in resultDisplay) {
365054
+ return {
365055
+ type: "diff",
365056
+ path: resultDisplay.filePath || resultDisplay.fileName,
365057
+ beforeText: resultDisplay.originalContent ?? "",
365058
+ afterText: resultDisplay.newContent
365059
+ };
365060
+ }
365061
+ return {
365062
+ type: "text",
365063
+ text: JSON.stringify(resultDisplay)
365064
+ };
365065
+ }
365066
+ var init_tool_display_utils = __esm({
365067
+ "packages/core/dist/src/agent/tool-display-utils.js"() {
365068
+ "use strict";
365069
+ }
365070
+ });
365071
+
364770
365072
  // packages/core/dist/src/core/turn.js
364771
365073
  var GeminiEventType, CompressionStatus, Turn;
364772
365074
  var init_turn = __esm({
@@ -364780,6 +365082,7 @@ var init_turn = __esm({
364780
365082
  init_thoughtUtils();
364781
365083
  init_generateContentResponseUtilities();
364782
365084
  init_types7();
365085
+ init_tool_display_utils();
364783
365086
  init_types5();
364784
365087
  (function(GeminiEventType2) {
364785
365088
  GeminiEventType2["Content"] = "content";
@@ -364934,13 +365237,33 @@ ${[...this.pendingCitations].sort().join("\n")}`
364934
365237
  }
364935
365238
  }
364936
365239
  handlePendingFunctionCall(fnCall, traceId) {
364937
- const name3 = fnCall.name || "undefined_tool_name";
365240
+ const name3 = fnCall.name?.trim() || "generic_tool";
364938
365241
  const args2 = fnCall.args || {};
364939
- const callId = fnCall.id ?? (this.chat.context.config.isContextManagementEnabled() ? `synth_${this.prompt_id}_${Date.now()}_${this.callCounter++}` : `${name3}_${Date.now()}_${this.callCounter++}`);
365242
+ const rawCallId = fnCall.id ?? (this.chat.context.config.isContextManagementEnabled() ? `synth_${this.prompt_id}_${Date.now()}_${this.callCounter++}` : `${name3}_${Date.now()}_${this.callCounter++}`);
365243
+ const callId = rawCallId.startsWith(`${name3}__`) ? rawCallId : `${name3}__${rawCallId}`;
365244
+ fnCall.id = callId;
365245
+ const tool = this.chat.loopContext.toolRegistry.getTool(name3);
365246
+ let display;
365247
+ if (tool) {
365248
+ let invocation;
365249
+ try {
365250
+ invocation = tool.build(args2);
365251
+ } catch {
365252
+ }
365253
+ display = populateToolDisplay({
365254
+ name: name3,
365255
+ invocation,
365256
+ displayName: tool.displayName
365257
+ });
365258
+ if (!display.description) {
365259
+ display.description = tool.description;
365260
+ }
365261
+ }
364940
365262
  const toolCallRequest = {
364941
365263
  callId,
364942
365264
  name: name3,
364943
365265
  args: args2,
365266
+ display,
364944
365267
  isClientInitiated: false,
364945
365268
  prompt_id: this.prompt_id,
364946
365269
  traceId
@@ -365086,7 +365409,7 @@ Use the following guidelines to optimize your search and read patterns.
365086
365409
  - Prefer using tools like ${GREP_TOOL_NAME} to identify points of interest instead of reading lots of files individually.
365087
365410
  - If you need to read multiple ranges in a file, do so parallel, in as few turns as possible.
365088
365411
  - It is more important to reduce extra turns, but please also try to minimize unnecessarily large file reads and search results, when doing so doesn't result in extra turns. Do this by always providing conservative limits and scopes to tools like ${READ_FILE_TOOL_NAME} and ${GREP_TOOL_NAME}.
365089
- - ${READ_FILE_TOOL_NAME} fails if ${EDIT_PARAM_OLD_STRING} is ambiguous, causing extra turns. Take care to read enough with ${READ_FILE_TOOL_NAME} and ${GREP_TOOL_NAME} to make the edit unambiguous.
365412
+ - ${EDIT_TOOL_NAME} fails if ${EDIT_PARAM_OLD_STRING} is ambiguous, causing extra turns. Take care to read enough with ${READ_FILE_TOOL_NAME} and ${GREP_TOOL_NAME} to make the edit unambiguous.
365090
365413
  - You can compensate for the risk of missing results with scoped or limited searches by doing multiple searches in parallel.
365091
365414
  - Your primary goal is still to do your best quality work. Efficiency is an important, but secondary concern.
365092
365415
  </guidelines>
@@ -367643,7 +367966,7 @@ function getRemoteAgentTargetUrl(def) {
367643
367966
  }
367644
367967
  return void 0;
367645
367968
  }
367646
- var AgentTerminateMode, DEFAULT_QUERY_STRING, DEFAULT_MAX_TURNS, DEFAULT_MAX_TIME_MINUTES, SubagentActivityErrorType, SUBAGENT_REJECTED_ERROR_PREFIX, SUBAGENT_CANCELLED_ERROR_MESSAGE;
367969
+ var AgentTerminateMode, DEFAULT_QUERY_STRING, DEFAULT_MAX_TURNS, DEFAULT_MAX_TIME_MINUTES, SubagentActivityErrorType, SUBAGENT_REJECTED_ERROR_PREFIX, SUBAGENT_CANCELLED_ERROR_MESSAGE, SubagentState;
367647
367970
  var init_types14 = __esm({
367648
367971
  "packages/core/dist/src/agents/types.js"() {
367649
367972
  "use strict";
@@ -367665,6 +367988,12 @@ var init_types14 = __esm({
367665
367988
  })(SubagentActivityErrorType || (SubagentActivityErrorType = {}));
367666
367989
  SUBAGENT_REJECTED_ERROR_PREFIX = "User rejected this operation.";
367667
367990
  SUBAGENT_CANCELLED_ERROR_MESSAGE = "Request cancelled.";
367991
+ (function(SubagentState2) {
367992
+ SubagentState2["RUNNING"] = "running";
367993
+ SubagentState2["COMPLETED"] = "completed";
367994
+ SubagentState2["ERROR"] = "error";
367995
+ SubagentState2["CANCELLED"] = "cancelled";
367996
+ })(SubagentState || (SubagentState = {}));
367668
367997
  }
367669
367998
  });
367670
367999
 
@@ -377158,8 +377487,10 @@ var init_state_manager = __esm({
377158
377487
  const call = this.activeCalls.get(callId);
377159
377488
  if (!call || call.status === CoreToolCallStatus.Error)
377160
377489
  return;
377490
+ const display = call.request.display ? { ...call.request.display } : { name: call.request.name };
377491
+ display.description = newInvocation.getDescription();
377161
377492
  this.activeCalls.set(callId, this.patchCall(call, {
377162
- request: { ...call.request, args: newArgs },
377493
+ request: { ...call.request, args: newArgs, display },
377163
377494
  invocation: newInvocation
377164
377495
  }));
377165
377496
  this.emitUpdate();
@@ -379616,54 +379947,297 @@ var init_nodeDistillationProcessor = __esm({
379616
379947
  }
379617
379948
  });
379618
379949
 
379950
+ // packages/core/dist/src/context/utils/formatNodesForLlm.js
379951
+ function getSemanticToolWrapper(toolName) {
379952
+ if (toolName.includes("search") || toolName.includes("grep"))
379953
+ return `SEARCH RESULTS`;
379954
+ if (toolName.includes("list") || toolName.includes("dir"))
379955
+ return `WORKSPACE STRUCTURE`;
379956
+ if (toolName.includes("shell") || toolName.includes("cmd"))
379957
+ return `SHELL EXECUTION`;
379958
+ if (toolName.includes("read") || toolName.includes("fetch"))
379959
+ return `FILE/WEB CONTENT`;
379960
+ return `TOOL RESPONSE`;
379961
+ }
379962
+ function formatNodesForLlm(nodes, options = {}) {
379963
+ const maxToolChars = options.maxToolResponseChars ?? 2e3;
379964
+ let transcript = "";
379965
+ const uniqueTurns = Array.from(new Set(nodes.map((n2) => n2.turnId).filter(Boolean)));
379966
+ for (const node of nodes) {
379967
+ const payload = node.payload;
379968
+ let nodeContent = "";
379969
+ if (payload.text) {
379970
+ nodeContent = payload.text;
379971
+ } else if (payload.functionCall) {
379972
+ nodeContent = `CALL: ${payload.functionCall.name}(${JSON.stringify(payload.functionCall.args)})`;
379973
+ } else if (payload.functionResponse) {
379974
+ const toolName = payload.functionResponse.name || "unknown_tool";
379975
+ const rawResponse = JSON.stringify(payload.functionResponse.response);
379976
+ const semanticWrapper = getSemanticToolWrapper(toolName);
379977
+ let formattedResponse = rawResponse;
379978
+ if (rawResponse.length > maxToolChars) {
379979
+ const half = Math.floor(maxToolChars / 2);
379980
+ const truncatedCount = rawResponse.length - maxToolChars;
379981
+ formattedResponse = `${rawResponse.substring(0, half)}... [TRUNCATED ${truncatedCount} chars] ...${rawResponse.substring(rawResponse.length - half)}`;
379982
+ }
379983
+ nodeContent = `[${semanticWrapper} (${toolName})]: ${formattedResponse}`;
379984
+ } else {
379985
+ nodeContent = JSON.stringify(payload);
379986
+ }
379987
+ const role = (node.role || "system").toUpperCase();
379988
+ let turnMarker = "";
379989
+ if (node.turnId) {
379990
+ const idx = uniqueTurns.indexOf(node.turnId);
379991
+ if (idx !== -1) {
379992
+ const relativeIdx = idx - (uniqueTurns.length - 1);
379993
+ turnMarker = `[Turn ${relativeIdx}] `;
379994
+ }
379995
+ }
379996
+ transcript += `${turnMarker}[${role}] [${node.type}]: ${nodeContent}
379997
+ `;
379998
+ }
379999
+ return transcript;
380000
+ }
380001
+ var init_formatNodesForLlm = __esm({
380002
+ "packages/core/dist/src/context/utils/formatNodesForLlm.js"() {
380003
+ "use strict";
380004
+ }
380005
+ });
380006
+
379619
380007
  // packages/core/dist/src/context/utils/snapshotGenerator.js
380008
+ import { randomUUID as randomUUID12 } from "node:crypto";
380009
+ function isStringArray(value) {
380010
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
380011
+ }
380012
+ function isNumberArray(value) {
380013
+ return Array.isArray(value) && value.every((item) => typeof item === "number");
380014
+ }
380015
+ function isTaskArray(value) {
380016
+ return Array.isArray(value) && value.every((item) => {
380017
+ if (!isRecord(item))
380018
+ return false;
380019
+ const id = item["id"];
380020
+ const desc = item["description"];
380021
+ return typeof id === "string" && typeof desc === "string";
380022
+ });
380023
+ }
380024
+ function isString(value) {
380025
+ return typeof value === "string";
380026
+ }
380027
+ function findLatestSnapshotBaseline(targets) {
380028
+ const lastSnapshotNode = [...targets].reverse().find((n2) => n2.type === NodeType.SNAPSHOT && n2.payload.text);
380029
+ if (lastSnapshotNode?.payload.text) {
380030
+ return {
380031
+ text: lastSnapshotNode.payload.text,
380032
+ abstractsIds: lastSnapshotNode.abstractsIds ? [...lastSnapshotNode.abstractsIds] : [],
380033
+ id: lastSnapshotNode.id
380034
+ };
380035
+ }
380036
+ return void 0;
380037
+ }
379620
380038
  var SnapshotGenerator;
379621
380039
  var init_snapshotGenerator = __esm({
379622
380040
  "packages/core/dist/src/context/utils/snapshotGenerator.js"() {
379623
380041
  "use strict";
380042
+ init_types15();
379624
380043
  init_llmRole();
380044
+ init_formatNodesForLlm();
380045
+ init_markdownUtils();
379625
380046
  SnapshotGenerator = class {
379626
380047
  env;
379627
380048
  constructor(env) {
379628
380049
  this.env = env;
379629
380050
  }
379630
- async synthesizeSnapshot(nodes, systemInstruction) {
379631
- const systemPrompt = systemInstruction ?? `You are an expert Context Memory Manager. You will be provided with a raw transcript of older conversation turns between a user and an AI assistant.
379632
- Your task is to synthesize these turns into a single, dense, factual snapshot that preserves all critical context, preferences, active tasks, and factual knowledge.
380051
+ async synthesizeSnapshot(nodes, previousStateJson, options = {}) {
380052
+ const emptyState = {
380053
+ active_tasks: [],
380054
+ discovered_facts: [],
380055
+ constraints_and_preferences: [],
380056
+ recent_arc: []
380057
+ };
380058
+ let previousState = emptyState;
380059
+ if (previousStateJson) {
380060
+ try {
380061
+ const parsed = JSON.parse(previousStateJson);
380062
+ if (isRecord(parsed)) {
380063
+ let loadedArc = [];
380064
+ if (isStringArray(parsed["recent_arc"])) {
380065
+ loadedArc = parsed["recent_arc"];
380066
+ } else if (isString(parsed["summary"]) && parsed["summary"]) {
380067
+ loadedArc = [parsed["summary"]];
380068
+ }
380069
+ previousState = {
380070
+ active_tasks: isTaskArray(parsed["active_tasks"]) ? parsed["active_tasks"] : [],
380071
+ discovered_facts: isStringArray(parsed["discovered_facts"]) ? parsed["discovered_facts"] : [],
380072
+ constraints_and_preferences: isStringArray(parsed["constraints_and_preferences"]) ? parsed["constraints_and_preferences"] : [],
380073
+ recent_arc: loadedArc
380074
+ };
380075
+ }
380076
+ } catch {
380077
+ }
380078
+ }
380079
+ let pressureWarning = "";
380080
+ const stateString = JSON.stringify(previousState);
380081
+ const estimatedTokens = this.env.tokenCalculator.estimateTokensForString(stateString);
380082
+ const maxTokens = options.maxStateTokens ?? 4e3;
380083
+ if (estimatedTokens > maxTokens * 0.8) {
380084
+ pressureWarning = `
379633
380085
 
379634
- Discard conversational filler, pleasantries, and redundant back-and-forth iterations. Output ONLY the raw factual snapshot, formatted compactly. Do not include markdown wrappers, prefixes like "Here is the snapshot", or conversational elements.`;
379635
- let userPromptText = "TRANSCRIPT TO SNAPSHOT:\n\n";
379636
- for (const node of nodes) {
379637
- const payload = node.payload;
379638
- let nodeContent = "";
379639
- if (payload.text) {
379640
- nodeContent = payload.text;
379641
- } else if (payload.functionCall) {
379642
- nodeContent = `CALL: ${payload.functionCall.name}(${JSON.stringify(payload.functionCall.args)})`;
379643
- } else if (payload.functionResponse) {
379644
- nodeContent = `RESPONSE: ${JSON.stringify(payload.functionResponse.response)}`;
379645
- }
379646
- userPromptText += `[${node.type}]: ${nodeContent}
379647
- `;
380086
+ [CRITICAL WARNING]: The Master State is currently at ${(estimatedTokens / maxTokens * 100).toFixed(0)}% of its maximum capacity! You MUST aggressively prune obsolete, irrelevant, or overly granular facts and constraints using \`obsolete_fact_indices\` and \`obsolete_constraint_indices\`.`;
379648
380087
  }
379649
- const response = await this.env.llmClient.generateContent({
379650
- role: LlmRole.UTILITY_STATE_SNAPSHOT_PROCESSOR,
379651
- modelConfigKey: { model: "gemini-3-flash-base" },
379652
- contents: [{ role: "user", parts: [{ text: userPromptText }] }],
379653
- systemInstruction: { role: "system", parts: [{ text: systemPrompt }] },
379654
- promptId: this.env.promptId,
379655
- abortSignal: new AbortController().signal
379656
- });
379657
- const candidate = response.candidates?.[0];
379658
- const textPart = candidate?.content?.parts?.[0];
379659
- return textPart?.text || "";
380088
+ const systemPrompt = `You are an expert Context Memory Manager. You maintain the long-term "Master State" of the AI agent's memory.
380089
+ You will be provided with the CURRENT Master State and a raw transcript of new conversation turns.
380090
+ Your task is to generate a JSON Delta Patch representing what has changed in the transcript.${pressureWarning}
380091
+
380092
+ CRITICAL OPERATIONAL RULES:
380093
+ 1. FACTS: Extract explicit empirical facts (file paths, exact error codes, specific configs).
380094
+ 2. PRUNING: Keep facts dense. Use obsolete indices to aggressively delete facts that are no longer relevant to the current objective.
380095
+ 3. TASKS: Add any new active user requests to "new_tasks".
380096
+ 4. TASK RESOLUTION: A task may ONLY be placed in "resolved_task_ids" if a success message or explicit confirmation was provided in the transcript. If the task was being worked on but no final confirmation exists, it MUST remain active. Do not prematurely resolve tasks.`;
380097
+ const userPromptText = `CURRENT MASTER STATE:
380098
+ ${JSON.stringify(previousState, null, 2)}
380099
+
380100
+ TRANSCRIPT OF NEW TURNS:
380101
+ ${formatNodesForLlm(nodes)}`;
380102
+ const patchSchema = {
380103
+ type: "object",
380104
+ properties: {
380105
+ new_facts: {
380106
+ type: "array",
380107
+ items: { type: "string" },
380108
+ description: "New specific, empirical facts discovered in this transcript chunk."
380109
+ },
380110
+ new_constraints: {
380111
+ type: "array",
380112
+ items: { type: "string" },
380113
+ description: "New specific rules or instructions provided by the user in this chunk."
380114
+ },
380115
+ new_tasks: {
380116
+ type: "array",
380117
+ items: {
380118
+ type: "object",
380119
+ properties: {
380120
+ description: {
380121
+ type: "string",
380122
+ description: "The task goal/description."
380123
+ }
380124
+ }
380125
+ }
380126
+ },
380127
+ resolved_task_ids: {
380128
+ type: "array",
380129
+ items: { type: "string" },
380130
+ description: "IDs of tasks from the CURRENT MASTER STATE that were explicitly completed or abandoned in this transcript chunk."
380131
+ },
380132
+ obsolete_fact_indices: {
380133
+ type: "array",
380134
+ items: { type: "number" },
380135
+ description: "Array indices of facts from CURRENT MASTER STATE that are no longer true or relevant and should be deleted."
380136
+ },
380137
+ obsolete_constraint_indices: {
380138
+ type: "array",
380139
+ items: { type: "number" },
380140
+ description: "Array indices of constraints from CURRENT MASTER STATE that are no longer true or relevant and should be deleted."
380141
+ },
380142
+ chronological_summary: {
380143
+ type: "string",
380144
+ description: "A 1-2 sentence summary of the mechanical actions taken in this transcript chunk."
380145
+ }
380146
+ }
380147
+ };
380148
+ let patch = {};
380149
+ try {
380150
+ const result2 = await this.env.llmClient.generateJson({
380151
+ role: LlmRole.UTILITY_STATE_SNAPSHOT_PROCESSOR,
380152
+ modelConfigKey: { model: "context-snapshotter" },
380153
+ contents: [{ role: "user", parts: [{ text: userPromptText }] }],
380154
+ systemInstruction: { role: "system", parts: [{ text: systemPrompt }] },
380155
+ schema: patchSchema,
380156
+ promptId: this.env.promptId,
380157
+ abortSignal: new AbortController().signal
380158
+ });
380159
+ if (isRecord(result2)) {
380160
+ patch = result2;
380161
+ }
380162
+ } catch {
380163
+ return JSON.stringify(previousState);
380164
+ }
380165
+ const newState = {
380166
+ active_tasks: [...previousState.active_tasks],
380167
+ discovered_facts: [...previousState.discovered_facts],
380168
+ constraints_and_preferences: [
380169
+ ...previousState.constraints_and_preferences
380170
+ ],
380171
+ recent_arc: [...previousState.recent_arc]
380172
+ };
380173
+ const resolvedIds = patch["resolved_task_ids"];
380174
+ if (isStringArray(resolvedIds)) {
380175
+ const resolvedSet = new Set(resolvedIds);
380176
+ newState.active_tasks = newState.active_tasks.filter((t3) => !resolvedSet.has(t3.id));
380177
+ }
380178
+ const obsFacts = patch["obsolete_fact_indices"];
380179
+ if (isNumberArray(obsFacts)) {
380180
+ const dropSet = new Set(obsFacts);
380181
+ newState.discovered_facts = newState.discovered_facts.filter((_2, i3) => !dropSet.has(i3));
380182
+ }
380183
+ const obsConstraints = patch["obsolete_constraint_indices"];
380184
+ if (isNumberArray(obsConstraints)) {
380185
+ const dropSet = new Set(obsConstraints);
380186
+ newState.constraints_and_preferences = newState.constraints_and_preferences.filter((_2, i3) => !dropSet.has(i3));
380187
+ }
380188
+ const newTasks = patch["new_tasks"];
380189
+ if (Array.isArray(newTasks)) {
380190
+ for (const t3 of newTasks) {
380191
+ if (isRecord(t3)) {
380192
+ const desc = t3["description"];
380193
+ if (typeof desc === "string" && desc) {
380194
+ newState.active_tasks.push({
380195
+ id: `task_${randomUUID12().slice(0, 8)}`,
380196
+ description: desc
380197
+ });
380198
+ }
380199
+ }
380200
+ }
380201
+ }
380202
+ const newFacts = patch["new_facts"];
380203
+ if (isStringArray(newFacts)) {
380204
+ newState.discovered_facts.push(...newFacts);
380205
+ }
380206
+ const newConstraints = patch["new_constraints"];
380207
+ if (isStringArray(newConstraints)) {
380208
+ newState.constraints_and_preferences.push(...newConstraints);
380209
+ }
380210
+ const chronoSummary = patch["chronological_summary"];
380211
+ if (typeof chronoSummary === "string" && chronoSummary) {
380212
+ newState.recent_arc.push(chronoSummary);
380213
+ const maxTurns = options.maxSummaryTurns ?? 5;
380214
+ if (newState.recent_arc.length > maxTurns) {
380215
+ newState.recent_arc = newState.recent_arc.slice(-maxTurns);
380216
+ }
380217
+ }
380218
+ let currentTokens = this.env.tokenCalculator.estimateTokensForString(JSON.stringify(newState));
380219
+ while (currentTokens > maxTokens) {
380220
+ if (newState.discovered_facts.length > 0) {
380221
+ newState.discovered_facts.shift();
380222
+ } else if (newState.constraints_and_preferences.length > 0) {
380223
+ newState.constraints_and_preferences.shift();
380224
+ } else if (newState.recent_arc.length > 0) {
380225
+ newState.recent_arc.shift();
380226
+ } else if (newState.active_tasks.length > 0) {
380227
+ newState.active_tasks.shift();
380228
+ } else {
380229
+ break;
380230
+ }
380231
+ currentTokens = this.env.tokenCalculator.estimateTokensForString(JSON.stringify(newState));
380232
+ }
380233
+ return JSON.stringify(newState);
379660
380234
  }
379661
380235
  };
379662
380236
  }
379663
380237
  });
379664
380238
 
379665
380239
  // packages/core/dist/src/context/processors/stateSnapshotProcessor.js
379666
- import { randomUUID as randomUUID12 } from "node:crypto";
380240
+ import { randomUUID as randomUUID13 } from "node:crypto";
379667
380241
  function createStateSnapshotProcessor(id, env, options) {
379668
380242
  const generator = new SnapshotGenerator(env);
379669
380243
  return {
@@ -379684,7 +380258,7 @@ function createStateSnapshotProcessor(id, env, options) {
379684
380258
  const targetIds = new Set(targets.map((t3) => t3.id));
379685
380259
  const isValid2 = consumedIds.every((id2) => targetIds.has(id2));
379686
380260
  if (isValid2) {
379687
- const newId = randomUUID12();
380261
+ const newId = randomUUID13();
379688
380262
  const snapshotNode = {
379689
380263
  id: newId,
379690
380264
  turnId: newId,
@@ -379725,9 +380299,29 @@ function createStateSnapshotProcessor(id, env, options) {
379725
380299
  }
379726
380300
  if (nodesToSummarize.length < 2)
379727
380301
  return targets;
380302
+ let previousStateJson = void 0;
380303
+ let baselineIdToConsume = void 0;
380304
+ const baseline = findLatestSnapshotBaseline(targets);
380305
+ if (baseline) {
380306
+ previousStateJson = baseline.text;
380307
+ const summaryIdx = nodesToSummarize.findIndex((n2) => n2.id === baseline.id);
380308
+ if (summaryIdx !== -1) {
380309
+ baselineIdToConsume = baseline.id;
380310
+ nodesToSummarize.splice(summaryIdx, 1);
380311
+ }
380312
+ } else {
380313
+ debugLogger.log("[StateSnapshotProcessor] No previous snapshot found in context graph. Initializing new Master State baseline.");
380314
+ }
379728
380315
  try {
379729
- const snapshotText = await generator.synthesizeSnapshot(nodesToSummarize, options.systemInstruction);
379730
- const newId = randomUUID12();
380316
+ const snapshotText = await generator.synthesizeSnapshot(nodesToSummarize, previousStateJson, {
380317
+ maxSummaryTurns: options.maxSummaryTurns,
380318
+ maxStateTokens: options.maxStateTokens
380319
+ });
380320
+ const newId = randomUUID13();
380321
+ const consumedIds = nodesToSummarize.map((n2) => n2.id);
380322
+ if (baselineIdToConsume && !consumedIds.includes(baselineIdToConsume)) {
380323
+ consumedIds.push(baselineIdToConsume);
380324
+ }
379731
380325
  const snapshotNode = {
379732
380326
  id: newId,
379733
380327
  turnId: newId,
@@ -379735,9 +380329,8 @@ function createStateSnapshotProcessor(id, env, options) {
379735
380329
  timestamp: nodesToSummarize[nodesToSummarize.length - 1].timestamp,
379736
380330
  role: "user",
379737
380331
  payload: { text: snapshotText },
379738
- abstractsIds: nodesToSummarize.map((n2) => n2.id)
380332
+ abstractsIds: [...consumedIds]
379739
380333
  };
379740
- const consumedIds = nodesToSummarize.map((n2) => n2.id);
379741
380334
  const returnedNodes = targets.filter((t3) => !consumedIds.includes(t3.id));
379742
380335
  const firstRemovedIdx = targets.findIndex((t3) => consumedIds.includes(t3.id));
379743
380336
  if (firstRemovedIdx !== -1) {
@@ -379771,7 +380364,9 @@ var init_stateSnapshotProcessor = __esm({
379771
380364
  },
379772
380365
  freeTokensTarget: { type: "number", nullable: true },
379773
380366
  model: { type: "string", nullable: true },
379774
- systemInstruction: { type: "string", nullable: true }
380367
+ systemInstruction: { type: "string", nullable: true },
380368
+ maxSummaryTurns: { type: "number", nullable: true },
380369
+ maxStateTokens: { type: "number", nullable: true }
379775
380370
  },
379776
380371
  required: []
379777
380372
  };
@@ -379779,7 +380374,6 @@ var init_stateSnapshotProcessor = __esm({
379779
380374
  });
379780
380375
 
379781
380376
  // packages/core/dist/src/context/processors/stateSnapshotAsyncProcessor.js
379782
- import { randomUUID as randomUUID13 } from "node:crypto";
379783
380377
  function createStateSnapshotAsyncProcessor(id, env, options) {
379784
380378
  const generator = new SnapshotGenerator(env);
379785
380379
  return {
@@ -379789,9 +380383,10 @@ function createStateSnapshotAsyncProcessor(id, env, options) {
379789
380383
  if (targets.length === 0)
379790
380384
  return;
379791
380385
  try {
379792
- let nodesToSummarize = [...targets];
379793
380386
  let previousConsumedIds = [];
379794
380387
  const processorType = options.type ?? "point-in-time";
380388
+ const nodesToSummarize = [...targets];
380389
+ let previousStateJson = void 0;
379795
380390
  if (processorType === "accumulate") {
379796
380391
  const proposedSnapshots = inbox.getMessages("PROPOSED_SNAPSHOT");
379797
380392
  const accumulateSnapshots = proposedSnapshots.filter((s5) => s5.payload.type === "accumulate");
@@ -379800,19 +380395,29 @@ function createStateSnapshotAsyncProcessor(id, env, options) {
379800
380395
  inbox.consume(latest.id);
379801
380396
  env.inbox.drainConsumed(/* @__PURE__ */ new Set([latest.id]));
379802
380397
  previousConsumedIds = latest.payload.consumedIds;
379803
- const snapshotId = randomUUID13();
379804
- const previousStateNode = {
379805
- id: snapshotId,
379806
- turnId: snapshotId,
379807
- type: NodeType.SNAPSHOT,
379808
- timestamp: latest.timestamp,
379809
- role: "user",
379810
- payload: { text: latest.payload.newText }
379811
- };
379812
- nodesToSummarize = [previousStateNode, ...targets];
380398
+ previousStateJson = latest.payload.newText;
380399
+ } else {
380400
+ const baseline = findLatestSnapshotBaseline(targets);
380401
+ if (baseline) {
380402
+ previousStateJson = baseline.text;
380403
+ previousConsumedIds = [...baseline.abstractsIds];
380404
+ } else {
380405
+ debugLogger.log("[StateSnapshotAsyncProcessor] No previous snapshot found in Inbox or Graph. Initializing new Master State baseline in background.");
380406
+ }
380407
+ }
380408
+ }
380409
+ if (previousStateJson) {
380410
+ const summaryIdx = nodesToSummarize.findIndex((n2) => n2.type === NodeType.SNAPSHOT && n2.payload.text === previousStateJson);
380411
+ if (summaryIdx !== -1) {
380412
+ nodesToSummarize.splice(summaryIdx, 1);
379813
380413
  }
379814
380414
  }
379815
- const snapshotText = await generator.synthesizeSnapshot(nodesToSummarize, options.systemInstruction);
380415
+ if (nodesToSummarize.length === 0)
380416
+ return;
380417
+ const snapshotText = await generator.synthesizeSnapshot(nodesToSummarize, previousStateJson, {
380418
+ maxSummaryTurns: options.maxSummaryTurns,
380419
+ maxStateTokens: options.maxStateTokens
380420
+ });
379816
380421
  const newConsumedIds = [
379817
380422
  ...previousConsumedIds,
379818
380423
  ...targets.map((t3) => t3.id)
@@ -379833,9 +380438,9 @@ var StateSnapshotAsyncProcessorOptionsSchema;
379833
380438
  var init_stateSnapshotAsyncProcessor = __esm({
379834
380439
  "packages/core/dist/src/context/processors/stateSnapshotAsyncProcessor.js"() {
379835
380440
  "use strict";
379836
- init_types15();
379837
380441
  init_snapshotGenerator();
379838
380442
  init_debugLogger();
380443
+ init_types15();
379839
380444
  StateSnapshotAsyncProcessorOptionsSchema = {
379840
380445
  type: "object",
379841
380446
  properties: {
@@ -379844,7 +380449,9 @@ var init_stateSnapshotAsyncProcessor = __esm({
379844
380449
  enum: ["accumulate", "point-in-time"],
379845
380450
  nullable: true
379846
380451
  },
379847
- systemInstruction: { type: "string", nullable: true }
380452
+ systemInstruction: { type: "string", nullable: true },
380453
+ maxSummaryTurns: { type: "number", nullable: true },
380454
+ maxStateTokens: { type: "number", nullable: true }
379848
380455
  },
379849
380456
  required: []
379850
380457
  };
@@ -379920,7 +380527,9 @@ var init_profiles = __esm({
379920
380527
  triggers: ["gc_backstop"],
379921
380528
  processors: [
379922
380529
  createStateSnapshotProcessor("StateSnapshotSync", env, resolveProcessorOptions(config3, "StateSnapshotSync", {
379923
- target: "max"
380530
+ target: "max",
380531
+ maxStateTokens: 4e3,
380532
+ maxSummaryTurns: 5
379924
380533
  }))
379925
380534
  ]
379926
380535
  }
@@ -379932,7 +380541,9 @@ var init_profiles = __esm({
379932
380541
  triggers: ["nodes_aged_out"],
379933
380542
  processors: [
379934
380543
  createStateSnapshotAsyncProcessor("StateSnapshotAsync", env, resolveProcessorOptions(config3, "StateSnapshotAsync", {
379935
- type: "accumulate"
380544
+ type: "accumulate",
380545
+ maxStateTokens: 4e3,
380546
+ maxSummaryTurns: 5
379936
380547
  }))
379937
380548
  ]
379938
380549
  }
@@ -380157,6 +380768,12 @@ var init_eventBus = __esm({
380157
380768
  "packages/core/dist/src/context/eventBus.js"() {
380158
380769
  "use strict";
380159
380770
  ContextEventBus = class extends EventEmitter6 {
380771
+ emitTokenGroundTruth(event) {
380772
+ this.emit("TOKEN_GROUND_TRUTH", event);
380773
+ }
380774
+ onTokenGroundTruth(listener) {
380775
+ this.on("TOKEN_GROUND_TRUTH", listener);
380776
+ }
380160
380777
  emitPristineHistoryUpdated(event) {
380161
380778
  this.emit("PRISTINE_HISTORY_UPDATED", event);
380162
380779
  }
@@ -380185,156 +380802,6 @@ var init_eventBus = __esm({
380185
380802
  }
380186
380803
  });
380187
380804
 
380188
- // packages/core/dist/src/context/utils/contextTokenCalculator.js
380189
- var ContextTokenCalculator;
380190
- var init_contextTokenCalculator = __esm({
380191
- "packages/core/dist/src/context/utils/contextTokenCalculator.js"() {
380192
- "use strict";
380193
- init_tokenCalculation();
380194
- ContextTokenCalculator = class {
380195
- charsPerToken;
380196
- registry;
380197
- tokenCache = /* @__PURE__ */ new Map();
380198
- constructor(charsPerToken, registry2) {
380199
- this.charsPerToken = charsPerToken;
380200
- this.registry = registry2;
380201
- }
380202
- /**
380203
- * Estimates tokens for a simple string based on character count.
380204
- * Fast, but inherently inaccurate compared to real model tokenization.
380205
- */
380206
- estimateTokensForString(text) {
380207
- return Math.ceil(text.length / this.charsPerToken);
380208
- }
380209
- /**
380210
- * Fast, simple heuristic conversion from tokens to expected character length.
380211
- * Useful for calculating truncation thresholds.
380212
- */
380213
- tokensToChars(tokens) {
380214
- return tokens * this.charsPerToken;
380215
- }
380216
- /**
380217
- * Pre-calculates and caches the token cost of a newly minted node.
380218
- * Because nodes are immutable, this cost never changes for this node ID.
380219
- */
380220
- /**
380221
- * Removes cached token counts for any nodes that are no longer in the given live set.
380222
- * This prevents unbounded memory growth during long sessions.
380223
- */
380224
- garbageCollectCache(liveNodeIds) {
380225
- for (const [id] of this.tokenCache) {
380226
- if (!liveNodeIds.has(id)) {
380227
- this.tokenCache.delete(id);
380228
- }
380229
- }
380230
- }
380231
- cacheNodeTokens(node) {
380232
- const behavior = this.registry.get(node.type);
380233
- const parts2 = behavior.getEstimatableParts(node);
380234
- const tokens = this.estimateTokensForParts(parts2);
380235
- this.tokenCache.set(node.id, tokens);
380236
- return tokens;
380237
- }
380238
- /**
380239
- * Retrieves the token cost of a single node from the cache.
380240
- * If it misses the cache, it computes it and caches it.
380241
- */
380242
- getTokenCost(node) {
380243
- const cached2 = this.tokenCache.get(node.id);
380244
- if (cached2 !== void 0)
380245
- return cached2;
380246
- return this.cacheNodeTokens(node);
380247
- }
380248
- /**
380249
- * Calculates a detailed breakdown of tokens by category for a list of nodes.
380250
- * Useful for calibration tracing and debugging overestimation.
380251
- */
380252
- calculateTokenBreakdown(nodes) {
380253
- const breakdown = { total: 0, text: 0, media: 0, tool: 0, overhead: 0 };
380254
- const seenIds = /* @__PURE__ */ new Set();
380255
- const seenTurnIds = /* @__PURE__ */ new Set();
380256
- for (const node of nodes) {
380257
- if (seenIds.has(node.id))
380258
- continue;
380259
- seenIds.add(node.id);
380260
- if (node.turnId) {
380261
- if (!seenTurnIds.has(node.turnId)) {
380262
- seenTurnIds.add(node.turnId);
380263
- breakdown.overhead += MSG_OVERHEAD_TOKENS;
380264
- breakdown.total += MSG_OVERHEAD_TOKENS;
380265
- }
380266
- }
380267
- const cost = this.getTokenCost(node);
380268
- breakdown.total += cost;
380269
- const behavior = this.registry.get(node.type);
380270
- const parts2 = behavior.getEstimatableParts(node);
380271
- for (const part of parts2) {
380272
- if (typeof part.text === "string") {
380273
- breakdown.text += estimateTokenCountSync([part], 0, this.charsPerToken);
380274
- } else if (part.inlineData?.mimeType?.startsWith("image/") || part.fileData?.mimeType?.startsWith("image/")) {
380275
- breakdown.media += estimateTokenCountSync([part], 0, this.charsPerToken);
380276
- } else if (part.functionCall || part.functionResponse) {
380277
- breakdown.tool += estimateTokenCountSync([part], 0, this.charsPerToken);
380278
- } else {
380279
- breakdown.overhead += estimateTokenCountSync([part], 0, this.charsPerToken);
380280
- }
380281
- }
380282
- }
380283
- return breakdown;
380284
- }
380285
- /**
380286
- * Fast calculation for a flat array of ConcreteNodes (The Nodes).
380287
- * It relies entirely on the O(1) sidecar token cache.
380288
- */
380289
- calculateConcreteListTokens(nodes) {
380290
- let tokens = 0;
380291
- const seenIds = /* @__PURE__ */ new Set();
380292
- const seenTurnIds = /* @__PURE__ */ new Set();
380293
- for (const node of nodes) {
380294
- if (!seenIds.has(node.id)) {
380295
- seenIds.add(node.id);
380296
- tokens += this.getTokenCost(node);
380297
- if (node.turnId) {
380298
- if (!seenTurnIds.has(node.turnId)) {
380299
- seenTurnIds.add(node.turnId);
380300
- tokens += MSG_OVERHEAD_TOKENS;
380301
- }
380302
- }
380303
- }
380304
- }
380305
- return tokens;
380306
- }
380307
- /**
380308
- * Calculates the token cost for a single Gemini Content object.
380309
- */
380310
- calculateContentTokens(content) {
380311
- return this.estimateTokensForParts(content.parts || []) + MSG_OVERHEAD_TOKENS;
380312
- }
380313
- /**
380314
- * Slower, precise estimation for a Gemini Content/Part graph.
380315
- * Deeply inspects the nested structure and uses the base tokenization math.
380316
- */
380317
- partTokenCache = /* @__PURE__ */ new WeakMap();
380318
- estimateTokensForParts(parts2) {
380319
- let total = 0;
380320
- for (const part of parts2) {
380321
- if (part !== null && typeof part === "object") {
380322
- let cost = this.partTokenCache.get(part);
380323
- if (cost === void 0) {
380324
- cost = estimateTokenCountSync([part], 0, this.charsPerToken);
380325
- this.partTokenCache.set(part, cost);
380326
- }
380327
- total += cost;
380328
- } else {
380329
- total += estimateTokenCountSync([part], 0, this.charsPerToken);
380330
- }
380331
- }
380332
- return total;
380333
- }
380334
- };
380335
- }
380336
- });
380337
-
380338
380805
  // packages/core/dist/src/context/pipeline/inbox.js
380339
380806
  import { randomUUID as randomUUID15 } from "node:crypto";
380340
380807
  var LiveInbox, InboxSnapshotImpl;
@@ -380378,94 +380845,6 @@ var init_inbox = __esm({
380378
380845
  }
380379
380846
  });
380380
380847
 
380381
- // packages/core/dist/src/context/graph/behaviorRegistry.js
380382
- var NodeBehaviorRegistry;
380383
- var init_behaviorRegistry = __esm({
380384
- "packages/core/dist/src/context/graph/behaviorRegistry.js"() {
380385
- "use strict";
380386
- NodeBehaviorRegistry = class {
380387
- behaviors = /* @__PURE__ */ new Map();
380388
- register(behavior) {
380389
- this.behaviors.set(behavior.type, behavior);
380390
- }
380391
- get(type2) {
380392
- const behavior = this.behaviors.get(type2);
380393
- if (!behavior) {
380394
- throw new Error(`Unregistered Node type: ${type2}`);
380395
- }
380396
- return behavior;
380397
- }
380398
- };
380399
- }
380400
- });
380401
-
380402
- // packages/core/dist/src/context/graph/builtinBehaviors.js
380403
- function registerBuiltInBehaviors(registry2) {
380404
- registry2.register(UserPromptBehavior);
380405
- registry2.register(AgentThoughtBehavior);
380406
- registry2.register(ToolExecutionBehavior);
380407
- registry2.register(MaskedToolBehavior);
380408
- registry2.register(AgentYieldBehavior);
380409
- registry2.register(SystemEventBehavior);
380410
- registry2.register(SnapshotBehavior);
380411
- registry2.register(RollingSummaryBehavior);
380412
- }
380413
- var UserPromptBehavior, AgentThoughtBehavior, ToolExecutionBehavior, MaskedToolBehavior, AgentYieldBehavior, SystemEventBehavior, SnapshotBehavior, RollingSummaryBehavior;
380414
- var init_builtinBehaviors = __esm({
380415
- "packages/core/dist/src/context/graph/builtinBehaviors.js"() {
380416
- "use strict";
380417
- init_types15();
380418
- UserPromptBehavior = {
380419
- type: NodeType.USER_PROMPT,
380420
- getEstimatableParts(node) {
380421
- return [node.payload];
380422
- }
380423
- };
380424
- AgentThoughtBehavior = {
380425
- type: NodeType.AGENT_THOUGHT,
380426
- getEstimatableParts(node) {
380427
- return [node.payload];
380428
- }
380429
- };
380430
- ToolExecutionBehavior = {
380431
- type: NodeType.TOOL_EXECUTION,
380432
- getEstimatableParts(node) {
380433
- return [node.payload];
380434
- }
380435
- };
380436
- MaskedToolBehavior = {
380437
- type: NodeType.MASKED_TOOL,
380438
- getEstimatableParts(node) {
380439
- return [node.payload];
380440
- }
380441
- };
380442
- AgentYieldBehavior = {
380443
- type: NodeType.AGENT_YIELD,
380444
- getEstimatableParts() {
380445
- return [];
380446
- }
380447
- };
380448
- SystemEventBehavior = {
380449
- type: NodeType.SYSTEM_EVENT,
380450
- getEstimatableParts(node) {
380451
- return [node.payload];
380452
- }
380453
- };
380454
- SnapshotBehavior = {
380455
- type: NodeType.SNAPSHOT,
380456
- getEstimatableParts(node) {
380457
- return [node.payload];
380458
- }
380459
- };
380460
- RollingSummaryBehavior = {
380461
- type: NodeType.ROLLING_SUMMARY,
380462
- getEstimatableParts(node) {
380463
- return [node.payload];
380464
- }
380465
- };
380466
- }
380467
- });
380468
-
380469
380848
  // packages/core/dist/src/context/graph/toGraph.js
380470
380849
  import { randomUUID as randomUUID16, createHash as createHash14 } from "node:crypto";
380471
380850
  function isTextPart2(part) {
@@ -380541,9 +380920,9 @@ var init_toGraph = __esm({
380541
380920
  const msg = history[turnIdx];
380542
380921
  if (!msg.parts)
380543
380922
  continue;
380544
- if (turnIdx === 0 && msg.role === "user" && msg.parts.length === 1) {
380923
+ if (msg.role === "user" && msg.parts.length === 1) {
380545
380924
  const text = msg.parts[0].text;
380546
- if (text?.startsWith("<session_context>") && text?.includes("This is the Gemini CLI.")) {
380925
+ if (text?.startsWith("<session_context>") && text?.includes("This is the Gemini CLI")) {
380547
380926
  debugLogger.log("[ContextGraphBuilder] Skipping legacy environment header turn from graph.");
380548
380927
  continue;
380549
380928
  }
@@ -380653,10 +381032,7 @@ var ContextEnvironmentImpl;
380653
381032
  var init_environmentImpl = __esm({
380654
381033
  "packages/core/dist/src/context/pipeline/environmentImpl.js"() {
380655
381034
  "use strict";
380656
- init_contextTokenCalculator();
380657
381035
  init_inbox();
380658
- init_behaviorRegistry();
380659
- init_builtinBehaviors();
380660
381036
  init_mapper();
380661
381037
  ContextEnvironmentImpl = class {
380662
381038
  llmClientProvider;
@@ -380668,10 +381044,11 @@ var init_environmentImpl = __esm({
380668
381044
  charsPerToken;
380669
381045
  eventBus;
380670
381046
  tokenCalculator;
380671
- inbox;
380672
381047
  behaviorRegistry;
381048
+ renderOptions;
381049
+ inbox;
380673
381050
  graphMapper;
380674
- constructor(llmClientProvider, sessionId, promptId, traceDir, projectTempDir, tracer, charsPerToken, eventBus) {
381051
+ constructor(llmClientProvider, sessionId, promptId, traceDir, projectTempDir, tracer, charsPerToken, eventBus, tokenCalculator, behaviorRegistry, renderOptions) {
380675
381052
  this.llmClientProvider = llmClientProvider;
380676
381053
  this.sessionId = sessionId;
380677
381054
  this.promptId = promptId;
@@ -380680,9 +381057,9 @@ var init_environmentImpl = __esm({
380680
381057
  this.tracer = tracer;
380681
381058
  this.charsPerToken = charsPerToken;
380682
381059
  this.eventBus = eventBus;
380683
- this.behaviorRegistry = new NodeBehaviorRegistry();
380684
- registerBuiltInBehaviors(this.behaviorRegistry);
380685
- this.tokenCalculator = new ContextTokenCalculator(this.charsPerToken, this.behaviorRegistry);
381060
+ this.tokenCalculator = tokenCalculator;
381061
+ this.behaviorRegistry = behaviorRegistry;
381062
+ this.renderOptions = renderOptions;
380686
381063
  this.inbox = new LiveInbox();
380687
381064
  this.graphMapper = new ContextGraphMapper();
380688
381065
  }
@@ -380726,30 +381103,6 @@ var init_contextWorkingBuffer = __esm({
380726
381103
  }
380727
381104
  return new _ContextWorkingBufferImpl(pristineNodes, pristineMap, initialProvenance, []);
380728
381105
  }
380729
- /**
380730
- * Appends newly observed pristine nodes (e.g. from a user message) to the working buffer.
380731
- * Ensures they are tracked in the pristine map and point to themselves in provenance.
380732
- */
380733
- appendPristineNodes(newNodes) {
380734
- if (newNodes.length === 0)
380735
- return this;
380736
- const newPristineMap = new Map(this.pristineNodesMap);
380737
- const newProvenanceMap = new Map(this.provenanceMap);
380738
- const existingIds = new Set(this.nodes.map((n2) => n2.id));
380739
- const nodesToAdd = [];
380740
- const batchIds = /* @__PURE__ */ new Set();
380741
- for (const node of newNodes) {
380742
- if (!existingIds.has(node.id) && !batchIds.has(node.id)) {
380743
- newPristineMap.set(node.id, node);
380744
- newProvenanceMap.set(node.id, /* @__PURE__ */ new Set([node.id]));
380745
- nodesToAdd.push(node);
380746
- batchIds.add(node.id);
380747
- }
380748
- }
380749
- if (nodesToAdd.length === 0)
380750
- return this;
380751
- return new _ContextWorkingBufferImpl([...this.nodes, ...nodesToAdd], newPristineMap, newProvenanceMap, [...this.history]);
380752
- }
380753
381106
  /**
380754
381107
  * Generates an entirely new buffer instance by calculating the delta between the processor's input and output.
380755
381108
  */
@@ -380827,10 +381180,90 @@ var init_contextWorkingBuffer = __esm({
380827
381180
  finalPristineMap = prunedPristineMap;
380828
381181
  return new _ContextWorkingBufferImpl(newGraph, finalPristineMap, newProvenanceMap, [...this.history, mutation]);
380829
381182
  }
380830
- /** Removes nodes from the working buffer that were completely dropped from the upstream pristine history */
380831
- prunePristineNodes(retainedIds) {
380832
- const newGraph = this.nodes.filter((n2) => retainedIds.has(n2.id) || !this.pristineNodesMap.has(n2.id));
381183
+ /**
381184
+ * Rebuilds the working buffer in the exact chronological order of the authoritative pristine history,
381185
+ * while preserving injected/summarized nodes at their relative positions.
381186
+ */
381187
+ syncPristineHistory(authoritativePristineNodes) {
381188
+ const newPristineMap = new Map(this.pristineNodesMap);
380833
381189
  const newProvenanceMap = new Map(this.provenanceMap);
381190
+ const authoritativeIds = new Set(authoritativePristineNodes.map((n2) => n2.id));
381191
+ for (const node of authoritativePristineNodes) {
381192
+ if (!newPristineMap.has(node.id)) {
381193
+ newPristineMap.set(node.id, node);
381194
+ newProvenanceMap.set(node.id, /* @__PURE__ */ new Set([node.id]));
381195
+ }
381196
+ }
381197
+ const survivingCurrentNodes = this.nodes.filter((n2) => {
381198
+ if (authoritativeIds.has(n2.id))
381199
+ return true;
381200
+ if (!this.pristineNodesMap.has(n2.id))
381201
+ return true;
381202
+ const roots = newProvenanceMap.get(n2.id);
381203
+ return !roots || roots.size === 0;
381204
+ }).filter((n2) => {
381205
+ if (!authoritativeIds.has(n2.id) && !this.pristineNodesMap.has(n2.id)) {
381206
+ const roots = newProvenanceMap.get(n2.id);
381207
+ if (roots && roots.size > 0) {
381208
+ for (const root of roots) {
381209
+ if (!authoritativeIds.has(root)) {
381210
+ return false;
381211
+ }
381212
+ }
381213
+ }
381214
+ }
381215
+ return true;
381216
+ });
381217
+ const coveredPristineIds = /* @__PURE__ */ new Set();
381218
+ for (const node of survivingCurrentNodes) {
381219
+ if (!authoritativeIds.has(node.id)) {
381220
+ const roots = newProvenanceMap.get(node.id);
381221
+ if (roots) {
381222
+ for (const root of roots) {
381223
+ coveredPristineIds.add(root);
381224
+ }
381225
+ }
381226
+ }
381227
+ }
381228
+ const pristineIndexMap = new Map(authoritativePristineNodes.map((n2, idx) => [n2.id, idx]));
381229
+ const getPristineIndex = (nodeId) => {
381230
+ const roots = newProvenanceMap.get(nodeId);
381231
+ if (!roots || roots.size === 0)
381232
+ return -1;
381233
+ let maxIndex = -1;
381234
+ for (const root of roots) {
381235
+ const idx = pristineIndexMap.get(root);
381236
+ if (idx !== void 0 && idx > maxIndex) {
381237
+ maxIndex = idx;
381238
+ }
381239
+ }
381240
+ return maxIndex;
381241
+ };
381242
+ const nodeOrder = new Array();
381243
+ for (let i3 = 0; i3 < authoritativePristineNodes.length; i3++) {
381244
+ const node = authoritativePristineNodes[i3];
381245
+ if (!coveredPristineIds.has(node.id)) {
381246
+ nodeOrder.push({ node, sortKey: i3, originalIndex: -1 });
381247
+ }
381248
+ }
381249
+ for (let i3 = 0; i3 < survivingCurrentNodes.length; i3++) {
381250
+ const node = survivingCurrentNodes[i3];
381251
+ if (!authoritativeIds.has(node.id)) {
381252
+ const baseSortKey = getPristineIndex(node.id);
381253
+ nodeOrder.push({
381254
+ node,
381255
+ sortKey: baseSortKey === -1 ? -1 : baseSortKey + 0.5,
381256
+ // Interleave after pristine roots, or at start if injected
381257
+ originalIndex: i3
381258
+ });
381259
+ }
381260
+ }
381261
+ nodeOrder.sort((a, b2) => {
381262
+ if (a.sortKey !== b2.sortKey)
381263
+ return a.sortKey - b2.sortKey;
381264
+ return a.originalIndex - b2.originalIndex;
381265
+ });
381266
+ const newGraph = nodeOrder.map((item) => item.node);
380834
381267
  const reachablePristineIds = /* @__PURE__ */ new Set();
380835
381268
  const reachableCurrentIds = /* @__PURE__ */ new Set();
380836
381269
  for (const node of newGraph) {
@@ -380838,7 +381271,7 @@ var init_contextWorkingBuffer = __esm({
380838
381271
  const roots = newProvenanceMap.get(node.id);
380839
381272
  if (roots) {
380840
381273
  for (const root of roots) {
380841
- if (retainedIds.has(root) || !this.pristineNodesMap.has(root)) {
381274
+ if (authoritativeIds.has(root) || !this.pristineNodesMap.has(root)) {
380842
381275
  reachablePristineIds.add(root);
380843
381276
  }
380844
381277
  }
@@ -380851,7 +381284,7 @@ var init_contextWorkingBuffer = __esm({
380851
381284
  }
380852
381285
  const prunedPristineMap = /* @__PURE__ */ new Map();
380853
381286
  for (const id of reachablePristineIds) {
380854
- const node = this.pristineNodesMap.get(id);
381287
+ const node = newPristineMap.get(id);
380855
381288
  if (node)
380856
381289
  prunedPristineMap.set(id, node);
380857
381290
  }
@@ -380887,6 +381320,7 @@ var init_orchestrator = __esm({
380887
381320
  activeTimers = [];
380888
381321
  pendingPipelines = /* @__PURE__ */ new Map();
380889
381322
  pipelineMutex = /* @__PURE__ */ new Map();
381323
+ pipelineScheduled = /* @__PURE__ */ new Set();
380890
381324
  nodeProvider;
380891
381325
  constructor(pipelines, asyncPipelines, env, eventBus, tracer) {
380892
381326
  this.pipelines = pipelines;
@@ -380927,25 +381361,37 @@ var init_orchestrator = __esm({
380927
381361
  this.activeTimers.push(timer);
380928
381362
  } else if (trigger === "retained_exceeded" || trigger === "nodes_aged_out") {
380929
381363
  this.eventBus.onConsolidationNeeded((event) => {
380930
- executeFn(pipeline3, event.nodes, event.targetNodeIds, /* @__PURE__ */ new Set());
381364
+ void executeFn(pipeline3, event.nodes, event.targetNodeIds, /* @__PURE__ */ new Set());
380931
381365
  });
380932
381366
  } else if (trigger === "new_message" || trigger === "nodes_added") {
380933
381367
  this.eventBus.onChunkReceived((event) => {
380934
- executeFn(pipeline3, event.nodes, event.targetNodeIds, /* @__PURE__ */ new Set());
381368
+ void executeFn(pipeline3, event.nodes, event.targetNodeIds, /* @__PURE__ */ new Set());
380935
381369
  });
380936
381370
  }
380937
381371
  }
380938
381372
  }
380939
381373
  };
380940
- bindTriggers(this.pipelines, (pipeline3, nodes, targets, protectedIds) => {
381374
+ const handleSyncExecution = async (pipeline3, nodes, targets, protectedIds) => {
381375
+ if (this.pipelineScheduled.has(pipeline3.name)) {
381376
+ debugLogger.log(`[Orchestrator] Pipeline ${pipeline3.name} already scheduled (sync), dropping.`);
381377
+ return;
381378
+ }
381379
+ this.pipelineScheduled.add(pipeline3.name);
380941
381380
  const existing = this.pipelineMutex.get(pipeline3.name) || Promise.resolve();
380942
381381
  const nextPromise = (async () => {
380943
381382
  try {
380944
381383
  await existing;
380945
- const latestNodes = this.nodeProvider();
381384
+ this.pipelineScheduled.delete(pipeline3.name);
381385
+ const latestNodes = this.nodeProvider ? this.nodeProvider() : nodes;
381386
+ const latestTargets = latestNodes.filter((n2) => targets.has(n2.id));
381387
+ debugLogger.log(`[Orchestrator] Executing sync pipeline ${pipeline3.name} with ${latestTargets.length} latest targets.`);
381388
+ if (latestTargets.length === 0) {
381389
+ debugLogger.log(`[Orchestrator] No latest targets for sync pipeline ${pipeline3.name}, returning.`);
381390
+ return;
381391
+ }
380946
381392
  await this.executePipelineAsync(pipeline3, latestNodes, new Set(targets), new Set(protectedIds));
380947
381393
  } catch (e3) {
380948
- debugLogger.error(`Pipeline chain ${pipeline3.name} failed:`, e3);
381394
+ debugLogger.error(`Sync pipeline chain ${pipeline3.name} failed:`, e3);
380949
381395
  }
380950
381396
  })();
380951
381397
  this.pipelineMutex.set(pipeline3.name, nextPromise);
@@ -380957,18 +381403,47 @@ var init_orchestrator = __esm({
380957
381403
  this.pipelineMutex.delete(pipeline3.name);
380958
381404
  }
380959
381405
  });
380960
- });
380961
- bindTriggers(this.asyncPipelines, (pipeline3, nodes, targetIds) => {
380962
- const inboxSnapshot = new InboxSnapshotImpl(this.env.inbox.getMessages() || []);
380963
- const targets = nodes.filter((n2) => targetIds.has(n2.id));
380964
- for (const processor of pipeline3.processors) {
380965
- processor.process({
380966
- targets,
380967
- inbox: inboxSnapshot,
380968
- buffer: ContextWorkingBufferImpl.initialize(nodes)
380969
- }).catch((e3) => debugLogger.error(`AsyncProcessor ${processor.name} failed:`, e3));
381406
+ };
381407
+ const handleAsyncExecution = async (pipeline3, nodes, targets) => {
381408
+ if (this.pipelineScheduled.has(pipeline3.name)) {
381409
+ debugLogger.log(`[Orchestrator] Pipeline ${pipeline3.name} already scheduled (async), dropping.`);
381410
+ return;
380970
381411
  }
380971
- });
381412
+ this.pipelineScheduled.add(pipeline3.name);
381413
+ const existing = this.pipelineMutex.get(pipeline3.name) || Promise.resolve();
381414
+ const nextPromise = (async () => {
381415
+ try {
381416
+ await existing;
381417
+ this.pipelineScheduled.delete(pipeline3.name);
381418
+ const latestNodes = this.nodeProvider ? this.nodeProvider() : nodes;
381419
+ const latestTargets = latestNodes.filter((n2) => targets.has(n2.id));
381420
+ debugLogger.log(`[Orchestrator] Executing async pipeline ${pipeline3.name} with ${latestTargets.length} latest targets.`);
381421
+ const inboxSnapshot = new InboxSnapshotImpl(this.env.inbox.getMessages() || []);
381422
+ for (const processor of pipeline3.processors) {
381423
+ debugLogger.log(`[Orchestrator] Running async processor ${processor.id}`);
381424
+ await processor.process({
381425
+ targets: latestTargets,
381426
+ inbox: inboxSnapshot,
381427
+ buffer: ContextWorkingBufferImpl.initialize(latestNodes)
381428
+ });
381429
+ }
381430
+ this.env.inbox.drainConsumed(inboxSnapshot.getConsumedIds());
381431
+ } catch (e3) {
381432
+ debugLogger.error(`Async pipeline chain ${pipeline3.name} failed:`, e3);
381433
+ }
381434
+ })();
381435
+ this.pipelineMutex.set(pipeline3.name, nextPromise);
381436
+ const pipelineId = `${pipeline3.name}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
381437
+ this.pendingPipelines.set(pipelineId, nextPromise);
381438
+ void nextPromise.finally(() => {
381439
+ this.pendingPipelines.delete(pipelineId);
381440
+ if (this.pipelineMutex.get(pipeline3.name) === nextPromise) {
381441
+ this.pipelineMutex.delete(pipeline3.name);
381442
+ }
381443
+ });
381444
+ };
381445
+ bindTriggers(this.pipelines, (pipeline3, nodes, targets, protectedIds) => handleSyncExecution(pipeline3, nodes, targets, protectedIds));
381446
+ bindTriggers(this.asyncPipelines, (pipeline3, nodes, targets) => handleAsyncExecution(pipeline3, nodes, targets));
380972
381447
  }
380973
381448
  shutdown() {
380974
381449
  for (const timer of this.activeTimers) {
@@ -381131,17 +381606,60 @@ var init_historyObserver = __esm({
381131
381606
  }
381132
381607
  });
381133
381608
 
381609
+ // packages/core/dist/src/context/utils/tokenCalibration.js
381610
+ function performCalibration(env, finalNodes, finalContents) {
381611
+ if (!env.renderOptions?.calibrateTokenCalculation) {
381612
+ return;
381613
+ }
381614
+ void (async () => {
381615
+ try {
381616
+ const exactResp = await env.llmClient.countTokens({
381617
+ contents: finalContents
381618
+ });
381619
+ const exactTokens = typeof exactResp.totalTokens === "number" ? exactResp.totalTokens : 0;
381620
+ const estimatedTokens = env.tokenCalculator.calculateConcreteListTokens(finalNodes);
381621
+ const delta = Math.abs(exactTokens - estimatedTokens);
381622
+ const tolerance = Math.max(exactTokens, estimatedTokens) * 0.2;
381623
+ env.tracer.logEvent("Render", "Token Calibration Measurement", {
381624
+ exactTokens,
381625
+ estimatedTokens,
381626
+ delta,
381627
+ isWithinTolerance: delta <= tolerance
381628
+ });
381629
+ if (delta > tolerance) {
381630
+ debugLogger.error(`[Token Calibration] Large deviation detected: exact ${exactTokens} vs estimated ${estimatedTokens} (delta: ${delta})`);
381631
+ }
381632
+ } catch {
381633
+ }
381634
+ })();
381635
+ }
381636
+ var init_tokenCalibration = __esm({
381637
+ "packages/core/dist/src/context/utils/tokenCalibration.js"() {
381638
+ "use strict";
381639
+ init_debugLogger();
381640
+ }
381641
+ });
381642
+
381134
381643
  // packages/core/dist/src/context/graph/render.js
381135
- async function render2(nodes, orchestrator, sidecar, tracer, env, protectionReasons = /* @__PURE__ */ new Map(), headerTokens = 0) {
381644
+ async function render2(nodes, orchestrator, sidecar, tracer, env, advancedTokenCalculator, protectionReasons = /* @__PURE__ */ new Map(), header, previewNodeIds = /* @__PURE__ */ new Set()) {
381645
+ let headerTokens = 0;
381646
+ let headerBaseUnits = 0;
381647
+ if (header) {
381648
+ const costs = advancedTokenCalculator.calculateContentTokensAndBaseUnits(header);
381649
+ headerTokens = costs.tokens;
381650
+ headerBaseUnits = costs.baseUnits;
381651
+ }
381136
381652
  if (!sidecar.config.budget) {
381137
- const contents2 = env.graphMapper.fromGraph(nodes);
381653
+ const visibleNodes2 = nodes.filter((n2) => !previewNodeIds.has(n2.id));
381654
+ const contents2 = env.graphMapper.fromGraph(visibleNodes2);
381138
381655
  tracer.logEvent("Render", "Render Context to LLM (No Budget)", {
381139
381656
  renderedContext: contents2
381140
381657
  });
381141
- return { history: contents2, didApplyManagement: false };
381658
+ const baseUnits = advancedTokenCalculator.getRawBaseUnits(nodes) + headerBaseUnits;
381659
+ return { history: contents2, didApplyManagement: false, baseUnits };
381142
381660
  }
381143
381661
  const maxTokens = sidecar.config.budget.maxTokens;
381144
- const graphTokens = env.tokenCalculator.calculateConcreteListTokens(nodes);
381662
+ const { tokens: graphTokens, baseUnits: graphBaseUnits } = advancedTokenCalculator.calculateTokensAndBaseUnits(nodes);
381145
381663
  const currentTokens = graphTokens + headerTokens;
381146
381664
  const protectedIds = new Set(protectionReasons.keys());
381147
381665
  tracer.logEvent("Render", "Budget Audit", {
@@ -381161,11 +381679,17 @@ async function render2(nodes, orchestrator, sidecar, tracer, env, protectionReas
381161
381679
  });
381162
381680
  if (currentTokens <= maxTokens) {
381163
381681
  tracer.logEvent("Render", `View is within maxTokens (${currentTokens} <= ${maxTokens}). Returning view.`);
381164
- const contents2 = env.graphMapper.fromGraph(nodes);
381682
+ const visibleNodes2 = nodes.filter((n2) => !previewNodeIds.has(n2.id));
381683
+ const contents2 = env.graphMapper.fromGraph(visibleNodes2);
381165
381684
  tracer.logEvent("Render", "Render Context for LLM", {
381166
381685
  renderedContext: contents2
381167
381686
  });
381168
- return { history: contents2, didApplyManagement: false };
381687
+ performCalibration(env, visibleNodes2, contents2);
381688
+ return {
381689
+ history: contents2,
381690
+ didApplyManagement: false,
381691
+ baseUnits: graphBaseUnits + headerBaseUnits
381692
+ };
381169
381693
  }
381170
381694
  const targetDelta = currentTokens - sidecar.config.budget.retainedTokens;
381171
381695
  tracer.logEvent("Render", `View exceeds maxTokens (${currentTokens} > ${maxTokens}). Hitting Synchronous Pressure Barrier.`, { targetDelta });
@@ -381173,9 +381697,10 @@ async function render2(nodes, orchestrator, sidecar, tracer, env, protectionReas
381173
381697
  let rollingTokens = 0;
381174
381698
  for (let i3 = nodes.length - 1; i3 >= 0; i3--) {
381175
381699
  const node = nodes[i3];
381700
+ const priorTokens = rollingTokens;
381176
381701
  const nodeTokens = env.tokenCalculator.calculateConcreteListTokens([node]);
381177
381702
  rollingTokens += nodeTokens;
381178
- if (rollingTokens > sidecar.config.budget.retainedTokens) {
381703
+ if (priorTokens > sidecar.config.budget.retainedTokens) {
381179
381704
  agedOutNodes.add(node.id);
381180
381705
  }
381181
381706
  }
@@ -381187,16 +381712,22 @@ async function render2(nodes, orchestrator, sidecar, tracer, env, protectionReas
381187
381712
  skipList.add(id);
381188
381713
  }
381189
381714
  }
381190
- const visibleNodes = processedNodes.filter((n2) => !skipList.has(n2.id));
381715
+ const visibleNodes = processedNodes.filter((n2) => !skipList.has(n2.id) && !previewNodeIds.has(n2.id));
381191
381716
  const contents = env.graphMapper.fromGraph(visibleNodes);
381192
381717
  tracer.logEvent("Render", "Render Sanitized Context for LLM", {
381193
381718
  renderedContextSanitized: contents
381194
381719
  });
381195
- return { history: contents, didApplyManagement: true };
381720
+ performCalibration(env, visibleNodes, contents);
381721
+ return {
381722
+ history: contents,
381723
+ didApplyManagement: true,
381724
+ baseUnits: advancedTokenCalculator.getRawBaseUnits(visibleNodes) + headerBaseUnits
381725
+ };
381196
381726
  }
381197
381727
  var init_render = __esm({
381198
381728
  "packages/core/dist/src/context/graph/render.js"() {
381199
381729
  "use strict";
381730
+ init_tokenCalibration();
381200
381731
  }
381201
381732
  });
381202
381733
 
@@ -381247,6 +381778,7 @@ var init_contextManager = __esm({
381247
381778
  sidecar;
381248
381779
  env;
381249
381780
  tracer;
381781
+ advancedTokenCalculator;
381250
381782
  headerProvider;
381251
381783
  // The master state containing the pristine graph and current active graph.
381252
381784
  buffer = ContextWorkingBufferImpl.initialize([]);
@@ -381254,24 +381786,23 @@ var init_contextManager = __esm({
381254
381786
  // Internal sub-components
381255
381787
  orchestrator;
381256
381788
  historyObserver;
381789
+ // Hysteresis tracking to prevent utility call churn
381790
+ lastTriggeredDeficit = 0;
381257
381791
  // Cache for Anomaly 3 (Redundant Renders)
381258
381792
  lastRenderCache;
381259
- constructor(sidecar, env, tracer, orchestrator, chatHistory, headerProvider) {
381793
+ hasPerformedHotStart = false;
381794
+ constructor(sidecar, env, tracer, orchestrator, chatHistory, advancedTokenCalculator, headerProvider) {
381260
381795
  this.sidecar = sidecar;
381261
381796
  this.env = env;
381262
381797
  this.tracer = tracer;
381798
+ this.advancedTokenCalculator = advancedTokenCalculator;
381263
381799
  this.headerProvider = headerProvider;
381264
381800
  this.eventBus = env.eventBus;
381265
381801
  this.orchestrator = orchestrator;
381266
381802
  this.orchestrator.setNodeProvider(() => this.buffer.nodes);
381267
381803
  this.historyObserver = new HistoryObserver(chatHistory, this.env.eventBus, this.tracer, this.env.graphMapper);
381268
381804
  this.eventBus.onPristineHistoryUpdated((event) => {
381269
- const newIds = new Set(event.nodes.map((n2) => n2.id));
381270
- const addedNodes = event.nodes.filter((n2) => event.newNodes.has(n2.id));
381271
- this.buffer = this.buffer.prunePristineNodes(newIds);
381272
- if (addedNodes.length > 0) {
381273
- this.buffer = this.buffer.appendPristineNodes(addedNodes);
381274
- }
381805
+ this.buffer = this.buffer.syncPristineHistory(event.nodes);
381275
381806
  this.evaluateTriggers(event.newNodes);
381276
381807
  });
381277
381808
  this.eventBus.onProcessorResult((event) => {
@@ -381315,10 +381846,11 @@ var init_contextManager = __esm({
381315
381846
  }
381316
381847
  for (let i3 = this.buffer.nodes.length - 1; i3 >= 0; i3--) {
381317
381848
  const node = this.buffer.nodes[i3];
381849
+ const priorTokens = rollingTokens;
381318
381850
  rollingTokens += this.env.tokenCalculator.calculateConcreteListTokens([
381319
381851
  node
381320
381852
  ]);
381321
- if (rollingTokens > this.sidecar.config.budget.retainedTokens) {
381853
+ if (priorTokens > this.sidecar.config.budget.retainedTokens) {
381322
381854
  if (!protectedIds.has(node.id)) {
381323
381855
  agedOutNodes.add(node.id);
381324
381856
  }
@@ -381326,8 +381858,13 @@ var init_contextManager = __esm({
381326
381858
  }
381327
381859
  if (agedOutNodes.size > 0) {
381328
381860
  const targetDeficit = currentTokens - this.sidecar.config.budget.retainedTokens;
381861
+ if (targetDeficit < this.lastTriggeredDeficit) {
381862
+ this.lastTriggeredDeficit = targetDeficit;
381863
+ }
381329
381864
  const threshold = this.sidecar.config.budget.coalescingThresholdTokens || 0;
381330
- if (targetDeficit >= threshold) {
381865
+ const growthSinceLast = targetDeficit - this.lastTriggeredDeficit;
381866
+ if (targetDeficit >= threshold && (growthSinceLast >= threshold || this.lastTriggeredDeficit === 0)) {
381867
+ this.lastTriggeredDeficit = targetDeficit;
381331
381868
  this.env.tokenCalculator.garbageCollectCache(new Set(this.buffer.nodes.map((n2) => n2.id)));
381332
381869
  this.eventBus.emitConsolidationNeeded({
381333
381870
  nodes: this.buffer.nodes,
@@ -381335,6 +381872,8 @@ var init_contextManager = __esm({
381335
381872
  targetNodeIds: agedOutNodes
381336
381873
  });
381337
381874
  }
381875
+ } else {
381876
+ this.lastTriggeredDeficit = 0;
381338
381877
  }
381339
381878
  }
381340
381879
  }
@@ -381391,24 +381930,42 @@ var init_contextManager = __esm({
381391
381930
  getNodes() {
381392
381931
  return [...this.buffer.nodes];
381393
381932
  }
381933
+ getEnvironment() {
381934
+ return this.env;
381935
+ }
381394
381936
  /**
381395
381937
  * Executes the final 'gc_backstop' pipeline if necessary, enforcing the token budget,
381396
381938
  * and maps the Episodic Context Graph back into a raw Gemini Content[] array for transmission.
381397
381939
  * This is the primary method called by the agent framework before sending a request.
381398
381940
  */
381399
- async renderHistory(pendingRequest, activeTaskIds = /* @__PURE__ */ new Set()) {
381941
+ async renderHistory(pendingRequest, activeTaskIds = /* @__PURE__ */ new Set(), abortSignal) {
381400
381942
  this.tracer.logEvent("ContextManager", "Starting rendering of LLM context");
381401
- await this.orchestrator.waitForPipelines();
381402
- let nodes = this.buffer.nodes;
381943
+ let previewNodes = [];
381403
381944
  if (pendingRequest) {
381404
- const previewNodes = this.env.graphMapper.applyEvent({
381945
+ previewNodes = this.env.graphMapper.applyEvent({
381405
381946
  type: "PUSH",
381406
381947
  payload: [pendingRequest]
381407
381948
  });
381949
+ }
381950
+ const hotStartPromise = (async () => {
381951
+ if (!this.hasPerformedHotStart) {
381952
+ this.hasPerformedHotStart = true;
381953
+ if (this.buffer.nodes.length > 0) {
381954
+ const nodesForHotStart = [...this.buffer.nodes, ...previewNodes];
381955
+ await this.performHotStartCalibration(nodesForHotStart, abortSignal);
381956
+ }
381957
+ }
381958
+ })();
381959
+ await Promise.all([this.orchestrator.waitForPipelines(), hotStartPromise]);
381960
+ let nodes = this.buffer.nodes;
381961
+ const previewNodeIds = /* @__PURE__ */ new Set();
381962
+ if (previewNodes.length > 0) {
381963
+ for (const n2 of previewNodes) {
381964
+ previewNodeIds.add(n2.id);
381965
+ }
381408
381966
  nodes = [...nodes, ...previewNodes];
381409
381967
  }
381410
381968
  const header = this.headerProvider ? await this.headerProvider() : void 0;
381411
- const headerTokens = header ? this.env.tokenCalculator.calculateContentTokens(header) : 0;
381412
381969
  const graphHash = nodes.map((n2) => n2.id).join("|");
381413
381970
  const headerHash = header ? JSON.stringify(header.parts) : "no-header";
381414
381971
  const totalHash = `${graphHash}::${headerHash}`;
@@ -381417,7 +381974,7 @@ var init_contextManager = __esm({
381417
381974
  return this.lastRenderCache.result;
381418
381975
  }
381419
381976
  const protectionReasons = this.getProtectedNodeIds(nodes, activeTaskIds);
381420
- const { history: renderedHistory, didApplyManagement } = await render2(nodes, this.orchestrator, this.sidecar, this.tracer, this.env, protectionReasons, headerTokens);
381977
+ const { history: renderedHistory, didApplyManagement, baseUnits } = await render2(nodes, this.orchestrator, this.sidecar, this.tracer, this.env, this.advancedTokenCalculator, protectionReasons, header, previewNodeIds);
381421
381978
  checkContextInvariants(this.buffer.nodes, "RenderHistory");
381422
381979
  this.tracer.logEvent("ContextManager", "Finished rendering");
381423
381980
  const combinedHistory = header ? [header, ...renderedHistory] : renderedHistory;
@@ -381425,11 +381982,35 @@ var init_contextManager = __esm({
381425
381982
  history: hardenHistory(combinedHistory, {
381426
381983
  sentinels: this.sidecar.sentinels
381427
381984
  }),
381428
- didApplyManagement
381985
+ didApplyManagement,
381986
+ baseUnits
381429
381987
  };
381430
381988
  this.lastRenderCache = { nodesHash: totalHash, result: result2 };
381431
381989
  return result2;
381432
381990
  }
381991
+ async performHotStartCalibration(nodes, abortSignal) {
381992
+ try {
381993
+ this.tracer.logEvent("ContextManager", "Performing Hot Start Token Calibration");
381994
+ const contents = this.env.graphMapper.fromGraph(nodes);
381995
+ const header = this.headerProvider ? await this.headerProvider() : void 0;
381996
+ const combinedHistory = header ? [header, ...contents] : contents;
381997
+ const baseUnits = this.advancedTokenCalculator.getRawBaseUnits(nodes) + (header ? this.advancedTokenCalculator.getRawBaseUnitsForContent(header) : 0);
381998
+ if (combinedHistory.length > 0) {
381999
+ const result2 = await this.env.llmClient.countTokens({
382000
+ contents: combinedHistory,
382001
+ abortSignal
382002
+ });
382003
+ if (result2.totalTokens > 0) {
382004
+ this.env.eventBus.emitTokenGroundTruth({
382005
+ actualTokens: result2.totalTokens,
382006
+ promptBaseUnits: baseUnits
382007
+ });
382008
+ }
382009
+ }
382010
+ } catch (error2) {
382011
+ this.tracer.logEvent("ContextManager", "Hot Start Token Calibration Failed (Ignored)", { error: error2 });
382012
+ }
382013
+ }
381433
382014
  };
381434
382015
  }
381435
382016
  });
@@ -381462,6 +382043,7 @@ var init_rollingSummaryProcessor = __esm({
381462
382043
  init_types15();
381463
382044
  init_debugLogger();
381464
382045
  init_llmRole();
382046
+ init_formatNodesForLlm();
381465
382047
  RollingSummaryProcessorOptionsSchema = {
381466
382048
  type: "object",
381467
382049
  properties: {
@@ -381479,6 +382061,365 @@ var init_rollingSummaryProcessor = __esm({
381479
382061
  }
381480
382062
  });
381481
382063
 
382064
+ // packages/core/dist/src/context/utils/contextTokenCalculator.js
382065
+ var StaticTokenCalculator;
382066
+ var init_contextTokenCalculator = __esm({
382067
+ "packages/core/dist/src/context/utils/contextTokenCalculator.js"() {
382068
+ "use strict";
382069
+ init_tokenCalculation();
382070
+ StaticTokenCalculator = class {
382071
+ charsPerToken;
382072
+ registry;
382073
+ tokenCache = /* @__PURE__ */ new Map();
382074
+ constructor(charsPerToken, registry2) {
382075
+ this.charsPerToken = charsPerToken;
382076
+ this.registry = registry2;
382077
+ }
382078
+ /**
382079
+ * Estimates tokens for a simple string based on character count.
382080
+ * Fast, but inherently inaccurate compared to real model tokenization.
382081
+ */
382082
+ estimateTokensForString(text) {
382083
+ return Math.ceil(text.length / this.charsPerToken);
382084
+ }
382085
+ /**
382086
+ * Fast, simple heuristic conversion from tokens to expected character length.
382087
+ * Useful for calculating truncation thresholds.
382088
+ */
382089
+ tokensToChars(tokens) {
382090
+ return tokens * this.charsPerToken;
382091
+ }
382092
+ /**
382093
+ * Pre-calculates and caches the token cost of a newly minted node.
382094
+ * Because nodes are immutable, this cost never changes for this node ID.
382095
+ */
382096
+ /**
382097
+ * Removes cached token counts for any nodes that are no longer in the given live set.
382098
+ * This prevents unbounded memory growth during long sessions.
382099
+ */
382100
+ garbageCollectCache(liveNodeIds) {
382101
+ for (const [id] of this.tokenCache) {
382102
+ if (!liveNodeIds.has(id)) {
382103
+ this.tokenCache.delete(id);
382104
+ }
382105
+ }
382106
+ }
382107
+ cacheNodeTokens(node) {
382108
+ const behavior = this.registry.get(node.type);
382109
+ const parts2 = behavior.getEstimatableParts(node);
382110
+ const tokens = this.estimateTokensForParts(parts2);
382111
+ this.tokenCache.set(node.id, tokens);
382112
+ return tokens;
382113
+ }
382114
+ /**
382115
+ * Retrieves the token cost of a single node from the cache.
382116
+ * If it misses the cache, it computes it and caches it.
382117
+ */
382118
+ getTokenCost(node) {
382119
+ const cached2 = this.tokenCache.get(node.id);
382120
+ if (cached2 !== void 0)
382121
+ return cached2;
382122
+ return this.cacheNodeTokens(node);
382123
+ }
382124
+ /**
382125
+ * Calculates a detailed breakdown of tokens by category for a list of nodes.
382126
+ * Useful for calibration tracing and debugging overestimation.
382127
+ */
382128
+ calculateTokenBreakdown(nodes) {
382129
+ const breakdown = { total: 0, text: 0, media: 0, tool: 0, overhead: 0 };
382130
+ const seenIds = /* @__PURE__ */ new Set();
382131
+ const seenTurnIds = /* @__PURE__ */ new Set();
382132
+ for (const node of nodes) {
382133
+ if (seenIds.has(node.id))
382134
+ continue;
382135
+ seenIds.add(node.id);
382136
+ if (node.turnId) {
382137
+ if (!seenTurnIds.has(node.turnId)) {
382138
+ seenTurnIds.add(node.turnId);
382139
+ breakdown.overhead += MSG_OVERHEAD_TOKENS;
382140
+ breakdown.total += MSG_OVERHEAD_TOKENS;
382141
+ }
382142
+ }
382143
+ const cost = this.getTokenCost(node);
382144
+ breakdown.total += cost;
382145
+ const behavior = this.registry.get(node.type);
382146
+ const parts2 = behavior.getEstimatableParts(node);
382147
+ for (const part of parts2) {
382148
+ if (typeof part.text === "string") {
382149
+ breakdown.text += estimateTokenCountSync([part], 0, this.charsPerToken);
382150
+ } else if (part.inlineData?.mimeType?.startsWith("image/") || part.fileData?.mimeType?.startsWith("image/")) {
382151
+ breakdown.media += estimateTokenCountSync([part], 0, this.charsPerToken);
382152
+ } else if (part.functionCall || part.functionResponse) {
382153
+ breakdown.tool += estimateTokenCountSync([part], 0, this.charsPerToken);
382154
+ } else {
382155
+ breakdown.overhead += estimateTokenCountSync([part], 0, this.charsPerToken);
382156
+ }
382157
+ }
382158
+ }
382159
+ return breakdown;
382160
+ }
382161
+ /**
382162
+ * For the static calculator, Raw Base Units are exactly the same as the final tokens,
382163
+ * because there is no dynamic learned weight (the multiplier is effectively 1.0).
382164
+ */
382165
+ getRawBaseUnits(nodes) {
382166
+ return this.calculateConcreteListTokens(nodes);
382167
+ }
382168
+ getRawBaseUnitsForContent(content) {
382169
+ return this.calculateContentTokens(content);
382170
+ }
382171
+ calculateTokensAndBaseUnits(nodes) {
382172
+ const baseUnits = this.calculateConcreteListTokens(nodes);
382173
+ return { tokens: baseUnits, baseUnits };
382174
+ }
382175
+ calculateContentTokensAndBaseUnits(content) {
382176
+ const baseUnits = this.calculateContentTokens(content);
382177
+ return { tokens: baseUnits, baseUnits };
382178
+ }
382179
+ /**
382180
+ * Fast calculation for a flat array of ConcreteNodes (The Nodes).
382181
+ * It relies entirely on the O(1) sidecar token cache.
382182
+ */
382183
+ calculateConcreteListTokens(nodes) {
382184
+ let tokens = 0;
382185
+ const seenIds = /* @__PURE__ */ new Set();
382186
+ const seenTurnIds = /* @__PURE__ */ new Set();
382187
+ for (const node of nodes) {
382188
+ if (!seenIds.has(node.id)) {
382189
+ seenIds.add(node.id);
382190
+ tokens += this.getTokenCost(node);
382191
+ if (node.turnId) {
382192
+ if (!seenTurnIds.has(node.turnId)) {
382193
+ seenTurnIds.add(node.turnId);
382194
+ tokens += MSG_OVERHEAD_TOKENS;
382195
+ }
382196
+ }
382197
+ }
382198
+ }
382199
+ return tokens;
382200
+ }
382201
+ /**
382202
+ * Calculates the token cost for a single Gemini Content object.
382203
+ */
382204
+ calculateContentTokens(content) {
382205
+ return this.estimateTokensForParts(content.parts || []) + MSG_OVERHEAD_TOKENS;
382206
+ }
382207
+ /**
382208
+ * Slower, precise estimation for a Gemini Content/Part graph.
382209
+ * Deeply inspects the nested structure and uses the base tokenization math.
382210
+ */
382211
+ partTokenCache = /* @__PURE__ */ new WeakMap();
382212
+ estimateTokensForParts(parts2) {
382213
+ let total = 0;
382214
+ for (const part of parts2) {
382215
+ if (part !== null && typeof part === "object") {
382216
+ let cost = this.partTokenCache.get(part);
382217
+ if (cost === void 0) {
382218
+ cost = estimateTokenCountSync([part], 0, this.charsPerToken);
382219
+ this.partTokenCache.set(part, cost);
382220
+ }
382221
+ total += cost;
382222
+ } else {
382223
+ total += estimateTokenCountSync([part], 0, this.charsPerToken);
382224
+ }
382225
+ }
382226
+ return total;
382227
+ }
382228
+ };
382229
+ }
382230
+ });
382231
+
382232
+ // packages/core/dist/src/context/utils/adaptiveTokenCalculator.js
382233
+ var AdaptiveTokenCalculator;
382234
+ var init_adaptiveTokenCalculator = __esm({
382235
+ "packages/core/dist/src/context/utils/adaptiveTokenCalculator.js"() {
382236
+ "use strict";
382237
+ init_contextTokenCalculator();
382238
+ init_debugLogger();
382239
+ AdaptiveTokenCalculator = class {
382240
+ learnedWeight = 1;
382241
+ baseCalculator;
382242
+ constructor(charsPerToken, registry2, eventBus) {
382243
+ this.baseCalculator = new StaticTokenCalculator(charsPerToken, registry2);
382244
+ eventBus.onTokenGroundTruth((event) => {
382245
+ this.handleGroundTruth(event.actualTokens, event.promptBaseUnits);
382246
+ });
382247
+ }
382248
+ handleGroundTruth(actualTokens, promptBaseUnits) {
382249
+ if (promptBaseUnits <= 0)
382250
+ return;
382251
+ const targetWeight = actualTokens / promptBaseUnits;
382252
+ const oldWeight = this.learnedWeight;
382253
+ const learningRate = 0.2;
382254
+ const newWeight = oldWeight * (1 - learningRate) + targetWeight * learningRate;
382255
+ this.learnedWeight = Math.max(0.5, Math.min(newWeight, 2));
382256
+ debugLogger.log(`[AdaptiveTokenCalculator] Learned weight updated to ${this.learnedWeight.toFixed(3)} (API Tokens: ${actualTokens}, Base Units: ${promptBaseUnits}, Target Ratio: ${targetWeight.toFixed(3)})`);
382257
+ }
382258
+ /**
382259
+ * Retrieves the current learned weight multiplier.
382260
+ */
382261
+ getLearnedWeight() {
382262
+ return this.learnedWeight;
382263
+ }
382264
+ /**
382265
+ * Returns the exact, unweighted Base Heuristic Units for the graph.
382266
+ * This is used exactly once per interaction to capture the baseline sent to the API.
382267
+ */
382268
+ getRawBaseUnits(nodes) {
382269
+ return this.baseCalculator.calculateConcreteListTokens(nodes);
382270
+ }
382271
+ /**
382272
+ * Returns the exact, unweighted Base Heuristic Units for a raw content chunk.
382273
+ */
382274
+ getRawBaseUnitsForContent(content) {
382275
+ return this.baseCalculator.calculateContentTokens(content);
382276
+ }
382277
+ calculateTokensAndBaseUnits(nodes) {
382278
+ const baseUnits = this.baseCalculator.calculateConcreteListTokens(nodes);
382279
+ return {
382280
+ tokens: Math.round(baseUnits * this.learnedWeight),
382281
+ baseUnits
382282
+ };
382283
+ }
382284
+ calculateContentTokensAndBaseUnits(content) {
382285
+ const baseUnits = this.baseCalculator.calculateContentTokens(content);
382286
+ return {
382287
+ tokens: Math.round(baseUnits * this.learnedWeight),
382288
+ baseUnits
382289
+ };
382290
+ }
382291
+ // --- Delegation and Weighting ---
382292
+ garbageCollectCache(liveNodeIds) {
382293
+ this.baseCalculator.garbageCollectCache(liveNodeIds);
382294
+ }
382295
+ cacheNodeTokens(node) {
382296
+ return this.baseCalculator.cacheNodeTokens(node);
382297
+ }
382298
+ calculateTokenBreakdown(nodes) {
382299
+ const raw = this.baseCalculator.calculateTokenBreakdown(nodes);
382300
+ return {
382301
+ text: Math.round(raw.text * this.learnedWeight),
382302
+ media: Math.round(raw.media * this.learnedWeight),
382303
+ tool: Math.round(raw.tool * this.learnedWeight),
382304
+ overhead: Math.round(raw.overhead * this.learnedWeight),
382305
+ total: Math.round(raw.total * this.learnedWeight)
382306
+ };
382307
+ }
382308
+ estimateTokensForParts(parts2) {
382309
+ const baseUnits = this.baseCalculator.estimateTokensForParts(parts2);
382310
+ return Math.round(baseUnits * this.learnedWeight);
382311
+ }
382312
+ getTokenCost(node) {
382313
+ const baseUnits = this.baseCalculator.getTokenCost(node);
382314
+ return Math.round(baseUnits * this.learnedWeight);
382315
+ }
382316
+ calculateConcreteListTokens(nodes) {
382317
+ const baseUnits = this.baseCalculator.calculateConcreteListTokens(nodes);
382318
+ return Math.round(baseUnits * this.learnedWeight);
382319
+ }
382320
+ calculateContentTokens(content) {
382321
+ const baseUnits = this.baseCalculator.calculateContentTokens(content);
382322
+ return Math.round(baseUnits * this.learnedWeight);
382323
+ }
382324
+ estimateTokensForString(text) {
382325
+ const baseUnits = this.baseCalculator.estimateTokensForString(text);
382326
+ return Math.round(baseUnits * this.learnedWeight);
382327
+ }
382328
+ tokensToChars(tokens) {
382329
+ return this.baseCalculator.tokensToChars(tokens / this.learnedWeight);
382330
+ }
382331
+ };
382332
+ }
382333
+ });
382334
+
382335
+ // packages/core/dist/src/context/graph/behaviorRegistry.js
382336
+ var NodeBehaviorRegistry;
382337
+ var init_behaviorRegistry = __esm({
382338
+ "packages/core/dist/src/context/graph/behaviorRegistry.js"() {
382339
+ "use strict";
382340
+ NodeBehaviorRegistry = class {
382341
+ behaviors = /* @__PURE__ */ new Map();
382342
+ register(behavior) {
382343
+ this.behaviors.set(behavior.type, behavior);
382344
+ }
382345
+ get(type2) {
382346
+ const behavior = this.behaviors.get(type2);
382347
+ if (!behavior) {
382348
+ throw new Error(`Unregistered Node type: ${type2}`);
382349
+ }
382350
+ return behavior;
382351
+ }
382352
+ };
382353
+ }
382354
+ });
382355
+
382356
+ // packages/core/dist/src/context/graph/builtinBehaviors.js
382357
+ function registerBuiltInBehaviors(registry2) {
382358
+ registry2.register(UserPromptBehavior);
382359
+ registry2.register(AgentThoughtBehavior);
382360
+ registry2.register(ToolExecutionBehavior);
382361
+ registry2.register(MaskedToolBehavior);
382362
+ registry2.register(AgentYieldBehavior);
382363
+ registry2.register(SystemEventBehavior);
382364
+ registry2.register(SnapshotBehavior);
382365
+ registry2.register(RollingSummaryBehavior);
382366
+ }
382367
+ var UserPromptBehavior, AgentThoughtBehavior, ToolExecutionBehavior, MaskedToolBehavior, AgentYieldBehavior, SystemEventBehavior, SnapshotBehavior, RollingSummaryBehavior;
382368
+ var init_builtinBehaviors = __esm({
382369
+ "packages/core/dist/src/context/graph/builtinBehaviors.js"() {
382370
+ "use strict";
382371
+ init_types15();
382372
+ UserPromptBehavior = {
382373
+ type: NodeType.USER_PROMPT,
382374
+ getEstimatableParts(node) {
382375
+ return [node.payload];
382376
+ }
382377
+ };
382378
+ AgentThoughtBehavior = {
382379
+ type: NodeType.AGENT_THOUGHT,
382380
+ getEstimatableParts(node) {
382381
+ return [node.payload];
382382
+ }
382383
+ };
382384
+ ToolExecutionBehavior = {
382385
+ type: NodeType.TOOL_EXECUTION,
382386
+ getEstimatableParts(node) {
382387
+ return [node.payload];
382388
+ }
382389
+ };
382390
+ MaskedToolBehavior = {
382391
+ type: NodeType.MASKED_TOOL,
382392
+ getEstimatableParts(node) {
382393
+ return [node.payload];
382394
+ }
382395
+ };
382396
+ AgentYieldBehavior = {
382397
+ type: NodeType.AGENT_YIELD,
382398
+ getEstimatableParts() {
382399
+ return [];
382400
+ }
382401
+ };
382402
+ SystemEventBehavior = {
382403
+ type: NodeType.SYSTEM_EVENT,
382404
+ getEstimatableParts(node) {
382405
+ return [node.payload];
382406
+ }
382407
+ };
382408
+ SnapshotBehavior = {
382409
+ type: NodeType.SNAPSHOT,
382410
+ getEstimatableParts(node) {
382411
+ return [node.payload];
382412
+ }
382413
+ };
382414
+ RollingSummaryBehavior = {
382415
+ type: NodeType.ROLLING_SUMMARY,
382416
+ getEstimatableParts(node) {
382417
+ return [node.payload];
382418
+ }
382419
+ };
382420
+ }
382421
+ });
382422
+
381482
382423
  // packages/core/dist/src/context/initializer.js
381483
382424
  async function initializeContextManager(config3, chat, lastPromptId) {
381484
382425
  const isV1Enabled = config3.getContextManagementConfig().enabled;
@@ -381528,9 +382469,15 @@ async function initializeContextManager(config3, chat, lastPromptId) {
381528
382469
  sessionId: lastPromptId
381529
382470
  });
381530
382471
  const eventBus = new ContextEventBus();
381531
- const env = new ContextEnvironmentImpl(() => config3.getBaseLlmClient(), config3.getSessionId(), lastPromptId, logDir, projectTempDir, tracer, 4, eventBus);
382472
+ const charsPerToken = 3;
382473
+ const behaviorRegistry = new NodeBehaviorRegistry();
382474
+ registerBuiltInBehaviors(behaviorRegistry);
382475
+ const calculator = new AdaptiveTokenCalculator(charsPerToken, behaviorRegistry, eventBus);
382476
+ const env = new ContextEnvironmentImpl(() => config3.getBaseLlmClient(), config3.getSessionId(), lastPromptId, logDir, projectTempDir, tracer, charsPerToken, eventBus, calculator, behaviorRegistry, {
382477
+ calibrateTokenCalculation: !!process.env["GEMINI_CONTEXT_CALIBRATE_TOKEN_CALCULATIONS"]
382478
+ });
381532
382479
  const orchestrator = new PipelineOrchestrator(sidecarProfile.buildPipelines(env), sidecarProfile.buildAsyncPipelines(env), env, eventBus, tracer);
381533
- return new ContextManager(sidecarProfile, env, tracer, orchestrator, chat.agentHistory, async () => {
382480
+ return new ContextManager(sidecarProfile, env, tracer, orchestrator, chat.agentHistory, calculator, async () => {
381534
382481
  const parts2 = await getEnvironmentContext(config3);
381535
382482
  return { role: "user", parts: parts2 };
381536
382483
  });
@@ -381554,6 +382501,9 @@ var init_initializer = __esm({
381554
382501
  init_stateSnapshotAsyncProcessor();
381555
382502
  init_rollingSummaryProcessor();
381556
382503
  init_environmentContext();
382504
+ init_adaptiveTokenCalculator();
382505
+ init_behaviorRegistry();
382506
+ init_builtinBehaviors();
381557
382507
  }
381558
382508
  });
381559
382509
 
@@ -381953,10 +382903,12 @@ var init_client4 = __esm({
381953
382903
  return turn;
381954
382904
  }
381955
382905
  const modelForLimitCheck = this._getActiveModelForCurrentTurn();
382906
+ let currentBaseUnits = 0;
381956
382907
  if (this.config.getContextManagementConfig().enabled) {
381957
382908
  if (this.contextManager) {
381958
382909
  const pendingRequest = createUserContent(request);
381959
- const { history: newHistory, didApplyManagement } = await this.contextManager.renderHistory(pendingRequest);
382910
+ const { history: newHistory, didApplyManagement, baseUnits } = await this.contextManager.renderHistory(pendingRequest, void 0, signal);
382911
+ currentBaseUnits = baseUnits;
381960
382912
  if (didApplyManagement) {
381961
382913
  this.getChat().setHistory(newHistory, { silent: true });
381962
382914
  }
@@ -382056,6 +383008,15 @@ var init_client4 = __esm({
382056
383008
  break;
382057
383009
  }
382058
383010
  yield event;
383011
+ if (event.type === GeminiEventType.Finished && this.contextManager) {
383012
+ const usageMetadata = event.value.usageMetadata;
383013
+ if (usageMetadata && usageMetadata.promptTokenCount !== void 0) {
383014
+ this.contextManager.getEnvironment().eventBus.emitTokenGroundTruth({
383015
+ actualTokens: usageMetadata.promptTokenCount,
383016
+ promptBaseUnits: currentBaseUnits
383017
+ });
383018
+ }
383019
+ }
382059
383020
  this.updateTelemetryTokenCount();
382060
383021
  if (event.type === GeminiEventType.Error) {
382061
383022
  isError = true;
@@ -382576,7 +383537,7 @@ var init_tool_executor = __esm({
382576
383537
  completedToolCall = await this.createSuccessResult(call, toolResult);
382577
383538
  } else {
382578
383539
  const displayText = typeof toolResult.returnDisplay === "string" ? toolResult.returnDisplay : void 0;
382579
- completedToolCall = this.createErrorResult(call, new Error(toolResult.error.message), toolResult.error.type, displayText, toolResult.tailToolCallRequest);
383540
+ completedToolCall = this.createErrorResult(call, new Error(toolResult.error.message), toolResult.error.type, displayText, toolResult.tailToolCallRequest, toolResult.display);
382580
383541
  }
382581
383542
  } catch (executionError) {
382582
383543
  spanMetadata.error = executionError;
@@ -382674,6 +383635,7 @@ var init_tool_executor = __esm({
382674
383635
  response: {
382675
383636
  callId: call.request.callId,
382676
383637
  responseParts,
383638
+ display: toolResult?.display,
382677
383639
  resultDisplay: toolResult?.returnDisplay,
382678
383640
  error: void 0,
382679
383641
  errorType: void 0,
@@ -382696,6 +383658,7 @@ var init_tool_executor = __esm({
382696
383658
  const successResponse = {
382697
383659
  callId,
382698
383660
  responseParts: response,
383661
+ display: toolResult.display,
382699
383662
  resultDisplay: toolResult.returnDisplay,
382700
383663
  error: void 0,
382701
383664
  errorType: void 0,
@@ -382720,8 +383683,8 @@ var init_tool_executor = __esm({
382720
383683
  tailToolCallRequest: toolResult.tailToolCallRequest
382721
383684
  };
382722
383685
  }
382723
- createErrorResult(call, error2, errorType, returnDisplay, tailToolCallRequest) {
382724
- const response = this.createErrorResponse(call.request, error2, errorType, returnDisplay);
383686
+ createErrorResult(call, error2, errorType, returnDisplay, tailToolCallRequest, display) {
383687
+ const response = this.createErrorResponse(call.request, error2, errorType, returnDisplay, display);
382725
383688
  const startTime = "startTime" in call ? call.startTime : void 0;
382726
383689
  return {
382727
383690
  status: CoreToolCallStatus.Error,
@@ -382735,11 +383698,12 @@ var init_tool_executor = __esm({
382735
383698
  tailToolCallRequest
382736
383699
  };
382737
383700
  }
382738
- createErrorResponse(request, error2, errorType, returnDisplay) {
383701
+ createErrorResponse(request, error2, errorType, returnDisplay, display) {
382739
383702
  const displayText = returnDisplay ?? error2.message;
382740
383703
  return {
382741
383704
  callId: request.callId,
382742
383705
  error: error2,
383706
+ display,
382743
383707
  responseParts: [
382744
383708
  {
382745
383709
  functionResponse: {
@@ -382833,6 +383797,7 @@ var init_scheduler = __esm({
382833
383797
  init_trace3();
382834
383798
  init_loggers();
382835
383799
  init_types7();
383800
+ init_tool_display_utils();
382836
383801
  init_types3();
382837
383802
  init_toolCallContext();
382838
383803
  init_events();
@@ -383044,6 +384009,16 @@ var init_scheduler = __esm({
383044
384009
  }, () => {
383045
384010
  try {
383046
384011
  const invocation = tool.build(request.args);
384012
+ if (!request.display) {
384013
+ request.display = populateToolDisplay({
384014
+ name: tool.name,
384015
+ invocation,
384016
+ displayName: tool.displayName
384017
+ });
384018
+ if (!request.display.description) {
384019
+ request.display.description = tool.description;
384020
+ }
384021
+ }
383047
384022
  return {
383048
384023
  status: CoreToolCallStatus.Validating,
383049
384024
  request,
@@ -384066,6 +385041,7 @@ var init_local_executor = __esm({
384066
385041
  init_errors2();
384067
385042
  init_utils6();
384068
385043
  init_models();
385044
+ init_mnemonist();
384069
385045
  init_thoughtUtils();
384070
385046
  init_debugLogger();
384071
385047
  init_registry();
@@ -384089,6 +385065,7 @@ var init_local_executor = __esm({
384089
385065
  compressionService;
384090
385066
  parentCallId;
384091
385067
  hasFailedCompressionAttempt = false;
385068
+ cache;
384092
385069
  get executionContext() {
384093
385070
  return {
384094
385071
  config: this.context.config,
@@ -384206,6 +385183,7 @@ var init_local_executor = __esm({
384206
385183
  this.onActivity = onActivity;
384207
385184
  this.compressionService = new ChatCompressionService();
384208
385185
  this.parentCallId = parentCallId;
385186
+ this.cache = new import_lru_cache.default(10);
384209
385187
  this.agentId = Math.random().toString(36).slice(2, 8);
384210
385188
  }
384211
385189
  /**
@@ -384406,7 +385384,14 @@ var init_local_executor = __esm({
384406
385384
  try {
384407
385385
  const initialHints = this.context.config.injectionService.getInjectionsAfter(startIndex, "user_steering");
384408
385386
  const formattedInitialHints = formatUserHintsForModel(initialHints);
384409
- const environmentMemory = this.context.config.isJitContextEnabled?.() ? this.context.config.getSessionMemory() : this.context.config.getEnvironmentMemory();
385387
+ let environmentMemory;
385388
+ if (this.context.config.isJitContextEnabled?.()) {
385389
+ environmentMemory = this.definition.includeExtensionContext === false ? this.context.config.getSessionMemory({
385390
+ includeExtensionContext: false
385391
+ }) : this.context.config.getSessionMemory();
385392
+ } else {
385393
+ environmentMemory = this.context.config.getEnvironmentMemory();
385394
+ }
384410
385395
  const initialParts = [];
384411
385396
  if (environmentMemory) {
384412
385397
  initialParts.push({ text: environmentMemory });
@@ -384609,22 +385594,26 @@ var init_local_executor = __esm({
384609
385594
  const requestedModel = resolvedConfig.model;
384610
385595
  let modelToUse;
384611
385596
  if (isAutoModel(requestedModel)) {
384612
- try {
384613
- const routingContext = {
384614
- history: chat.getHistory(
384615
- /*curated=*/
384616
- true
384617
- ),
384618
- request: message.parts || [],
384619
- signal,
384620
- requestedModel
384621
- };
384622
- const router = this.context.config.getModelRouterService();
384623
- const decision = await router.route(routingContext);
384624
- modelToUse = decision.model;
384625
- } catch (error2) {
384626
- debugLogger.warn(`Error during model routing: ${error2}`);
384627
- modelToUse = DEFAULT_GEMINI_MODEL;
385597
+ modelToUse = this.cache.get("modelToUse");
385598
+ if (!modelToUse) {
385599
+ try {
385600
+ const routingContext = {
385601
+ history: chat.getHistory(
385602
+ /*curated=*/
385603
+ true
385604
+ ),
385605
+ request: message.parts || [],
385606
+ signal,
385607
+ requestedModel
385608
+ };
385609
+ const router = this.context.config.getModelRouterService();
385610
+ const decision = await router.route(routingContext);
385611
+ modelToUse = decision.model;
385612
+ } catch (error2) {
385613
+ debugLogger.warn(`Error during model routing: ${error2}`);
385614
+ modelToUse = DEFAULT_GEMINI_MODEL;
385615
+ }
385616
+ this.cache.set("modelToUse", modelToUse);
384628
385617
  }
384629
385618
  } else {
384630
385619
  modelToUse = requestedModel;
@@ -384833,12 +385822,14 @@ var init_local_executor = __esm({
384833
385822
  const part = syncResults.get(callId);
384834
385823
  if (part) {
384835
385824
  toolResponseParts.push(part);
385825
+ continue;
384836
385826
  }
384837
- }
384838
- if (functionCalls.length > 0 && toolResponseParts.length === 0 && !taskCompleted) {
384839
- toolResponseParts.push({
384840
- text: "All tool calls failed or were unauthorized. Please analyze the errors and try an alternative approach."
384841
- });
385827
+ const isAborted2 = signal.aborted;
385828
+ const isTaskComplete = functionCall.name === COMPLETE_TASK_TOOL_NAME && taskCompleted;
385829
+ if (isAborted2 || isTaskComplete) {
385830
+ continue;
385831
+ }
385832
+ throw new Error(`[LocalAgentExecutor] Critical System Failure: Tool execution result was lost/dropped by the scheduler for callId ${callId} (${functionCall.name}). This indicates an internal race condition or scheduler bug.`);
384842
385833
  }
384843
385834
  return {
384844
385835
  nextMessage: { role: "user", parts: toolResponseParts },
@@ -385164,7 +386155,7 @@ var init_local_invocation = __esm({
385164
386155
  isSubagentProgress: true,
385165
386156
  agentName: this.definition.name,
385166
386157
  recentActivity: [],
385167
- state: "running"
386158
+ state: SubagentState.RUNNING
385168
386159
  };
385169
386160
  updateOutput(initialProgress);
385170
386161
  }
@@ -385176,14 +386167,14 @@ var init_local_invocation = __esm({
385176
386167
  case "THOUGHT_CHUNK": {
385177
386168
  const text = String(activity.data["text"]);
385178
386169
  const lastItem = recentActivity[recentActivity.length - 1];
385179
- if (lastItem && lastItem.type === "thought" && lastItem.status === "running") {
386170
+ if (lastItem && lastItem.type === "thought" && lastItem.status === SubagentState.RUNNING) {
385180
386171
  lastItem.content = sanitizeThoughtContent(text);
385181
386172
  } else {
385182
386173
  recentActivity.push({
385183
386174
  id: randomUUID18(),
385184
386175
  type: "thought",
385185
386176
  content: sanitizeThoughtContent(text),
385186
- status: "running"
386177
+ status: SubagentState.RUNNING
385187
386178
  });
385188
386179
  }
385189
386180
  updated = true;
@@ -385205,7 +386196,7 @@ var init_local_invocation = __esm({
385205
386196
  displayName,
385206
386197
  description,
385207
386198
  args: args2,
385208
- status: "running"
386199
+ status: SubagentState.RUNNING
385209
386200
  });
385210
386201
  updated = true;
385211
386202
  const latestTool = recentActivity[recentActivity.length - 1];
@@ -385219,8 +386210,8 @@ var init_local_invocation = __esm({
385219
386210
  const data = activity.data["data"];
385220
386211
  const isError = isToolActivityError(data);
385221
386212
  for (let i3 = recentActivity.length - 1; i3 >= 0; i3--) {
385222
- if (recentActivity[i3].type === "tool_call" && recentActivity[i3].content === name3 && recentActivity[i3].status === "running") {
385223
- recentActivity[i3].status = isError ? "error" : "completed";
386213
+ if (recentActivity[i3].type === "tool_call" && recentActivity[i3].content === name3 && recentActivity[i3].status === SubagentState.RUNNING) {
386214
+ recentActivity[i3].status = isError ? SubagentState.ERROR : SubagentState.COMPLETED;
385224
386215
  updated = true;
385225
386216
  this.publishActivity(recentActivity[i3]);
385226
386217
  break;
@@ -385237,16 +386228,16 @@ var init_local_invocation = __esm({
385237
386228
  const toolName = activity.data["name"] ? String(activity.data["name"]) : void 0;
385238
386229
  if (toolName && (isCancellation || isRejection)) {
385239
386230
  for (let i3 = recentActivity.length - 1; i3 >= 0; i3--) {
385240
- if (recentActivity[i3].type === "tool_call" && recentActivity[i3].content === toolName && recentActivity[i3].status === "running") {
385241
- recentActivity[i3].status = "cancelled";
386231
+ if (recentActivity[i3].type === "tool_call" && recentActivity[i3].content === toolName && recentActivity[i3].status === SubagentState.RUNNING) {
386232
+ recentActivity[i3].status = SubagentState.CANCELLED;
385242
386233
  updated = true;
385243
386234
  break;
385244
386235
  }
385245
386236
  }
385246
386237
  } else if (toolName) {
385247
386238
  for (let i3 = recentActivity.length - 1; i3 >= 0; i3--) {
385248
- if (recentActivity[i3].type === "tool_call" && recentActivity[i3].content === toolName && recentActivity[i3].status === "running") {
385249
- recentActivity[i3].status = "error";
386239
+ if (recentActivity[i3].type === "tool_call" && recentActivity[i3].content === toolName && recentActivity[i3].status === SubagentState.RUNNING) {
386240
+ recentActivity[i3].status = SubagentState.ERROR;
385250
386241
  updated = true;
385251
386242
  break;
385252
386243
  }
@@ -385256,7 +386247,7 @@ var init_local_invocation = __esm({
385256
386247
  id: randomUUID18(),
385257
386248
  type: "thought",
385258
386249
  content: isCancellation || isRejection ? sanitizedError : `Error: ${sanitizedError}`,
385259
- status: isCancellation || isRejection ? "cancelled" : "error"
386250
+ status: isCancellation || isRejection ? SubagentState.CANCELLED : SubagentState.ERROR
385260
386251
  });
385261
386252
  updated = true;
385262
386253
  break;
@@ -385270,7 +386261,7 @@ var init_local_invocation = __esm({
385270
386261
  agentName: this.definition.name,
385271
386262
  recentActivity: [...recentActivity],
385272
386263
  // Copy to avoid mutation issues
385273
- state: "running"
386264
+ state: SubagentState.RUNNING
385274
386265
  };
385275
386266
  updateOutput(progress2);
385276
386267
  }
@@ -385282,7 +386273,7 @@ var init_local_invocation = __esm({
385282
386273
  isSubagentProgress: true,
385283
386274
  agentName: this.definition.name,
385284
386275
  recentActivity: [...recentActivity],
385285
- state: "cancelled"
386276
+ state: SubagentState.CANCELLED
385286
386277
  };
385287
386278
  if (updateOutput) {
385288
386279
  updateOutput(progress2);
@@ -385295,7 +386286,7 @@ var init_local_invocation = __esm({
385295
386286
  isSubagentProgress: true,
385296
386287
  agentName: this.definition.name,
385297
386288
  recentActivity: [...recentActivity],
385298
- state: "completed",
386289
+ state: SubagentState.COMPLETED,
385299
386290
  result: output.result,
385300
386291
  terminateReason: output.terminate_reason
385301
386292
  };
@@ -385316,18 +386307,18 @@ ${output.result}`;
385316
386307
  debugLogger.error(`Subagent '${this.definition.name}' failed:`, error2);
385317
386308
  const isAbort = error2 instanceof Error && error2.name === "AbortError" || errorMessage.includes("Aborted");
385318
386309
  for (const item of recentActivity) {
385319
- if (item.status === "running") {
385320
- item.status = isAbort ? "cancelled" : "error";
386310
+ if (item.status === SubagentState.RUNNING) {
386311
+ item.status = isAbort ? SubagentState.CANCELLED : SubagentState.ERROR;
385321
386312
  }
385322
386313
  }
385323
386314
  if (!isAbort) {
385324
386315
  const lastActivity = recentActivity[recentActivity.length - 1];
385325
- if (!lastActivity || lastActivity.status !== "error") {
386316
+ if (!lastActivity || lastActivity.status !== SubagentState.ERROR) {
385326
386317
  recentActivity.push({
385327
386318
  id: randomUUID18(),
385328
386319
  type: "thought",
385329
386320
  content: `Error: ${errorMessage}`,
385330
- status: "error"
386321
+ status: SubagentState.ERROR
385331
386322
  });
385332
386323
  }
385333
386324
  }
@@ -385335,7 +386326,7 @@ ${output.result}`;
385335
386326
  isSubagentProgress: true,
385336
386327
  agentName: this.definition.name,
385337
386328
  recentActivity: [...recentActivity],
385338
- state: isAbort ? "cancelled" : "error"
386329
+ state: isAbort ? SubagentState.CANCELLED : SubagentState.ERROR
385339
386330
  };
385340
386331
  if (updateOutput) {
385341
386332
  updateOutput(progress);
@@ -385452,6 +386443,7 @@ var AUTH_REQUIRED_MSG, A2AResultReassembler;
385452
386443
  var init_a2aUtils = __esm({
385453
386444
  "packages/core/dist/src/agents/a2aUtils.js"() {
385454
386445
  "use strict";
386446
+ init_types14();
385455
386447
  AUTH_REQUIRED_MSG = `[Authorization Required] The agent has indicated it requires authorization to proceed. Please follow the agent's instructions.`;
385456
386448
  A2AResultReassembler = class {
385457
386449
  messageLog = [];
@@ -385547,7 +386539,7 @@ var init_a2aUtils = __esm({
385547
386539
  id: "auth-required",
385548
386540
  type: "thought",
385549
386541
  content: AUTH_REQUIRED_MSG,
385550
- status: "running"
386542
+ status: SubagentState.RUNNING
385551
386543
  });
385552
386544
  }
385553
386545
  this.messageLog.forEach((msg, index) => {
@@ -385555,7 +386547,7 @@ var init_a2aUtils = __esm({
385555
386547
  id: `msg-${index}`,
385556
386548
  type: "thought",
385557
386549
  content: msg.trim(),
385558
- status: "completed"
386550
+ status: SubagentState.COMPLETED
385559
386551
  });
385560
386552
  });
385561
386553
  if (items.length === 0 && !isAuthRequired) {
@@ -385563,7 +386555,7 @@ var init_a2aUtils = __esm({
385563
386555
  id: "pending",
385564
386556
  type: "thought",
385565
386557
  content: "Working...",
385566
- status: "running"
386558
+ status: SubagentState.RUNNING
385567
386559
  });
385568
386560
  }
385569
386561
  return items;
@@ -385670,13 +386662,13 @@ var init_remote_invocation = __esm({
385670
386662
  updateOutput({
385671
386663
  isSubagentProgress: true,
385672
386664
  agentName,
385673
- state: "running",
386665
+ state: SubagentState.RUNNING,
385674
386666
  recentActivity: [
385675
386667
  {
385676
386668
  id: "pending",
385677
386669
  type: "thought",
385678
386670
  content: "Working...",
385679
- status: "running"
386671
+ status: SubagentState.RUNNING
385680
386672
  }
385681
386673
  ]
385682
386674
  });
@@ -385707,7 +386699,7 @@ var init_remote_invocation = __esm({
385707
386699
  updateOutput({
385708
386700
  isSubagentProgress: true,
385709
386701
  agentName,
385710
- state: "running",
386702
+ state: SubagentState.RUNNING,
385711
386703
  recentActivity: reassembler.toActivityItems(),
385712
386704
  result: reassembler.toString()
385713
386705
  });
@@ -385727,7 +386719,7 @@ ${JSON.stringify(finalResponse, null, 2)}`);
385727
386719
  const finalProgress = {
385728
386720
  isSubagentProgress: true,
385729
386721
  agentName,
385730
- state: "completed",
386722
+ state: SubagentState.COMPLETED,
385731
386723
  result: finalOutput,
385732
386724
  recentActivity: reassembler.toActivityItems()
385733
386725
  };
@@ -385747,7 +386739,7 @@ ${errorMessage}` : errorMessage;
385747
386739
  const errorProgress = {
385748
386740
  isSubagentProgress: true,
385749
386741
  agentName,
385750
- state: "error",
386742
+ state: SubagentState.ERROR,
385751
386743
  result: fullDisplay,
385752
386744
  recentActivity: reassembler.toActivityItems()
385753
386745
  };
@@ -387352,7 +388344,7 @@ var init_browserAgentInvocation = __esm({
387352
388344
  isSubagentProgress: true,
387353
388345
  agentName: this.agentName,
387354
388346
  recentActivity: [],
387355
- state: "running"
388347
+ state: SubagentState.RUNNING
387356
388348
  };
387357
388349
  updateOutput(initialProgress);
387358
388350
  }
@@ -387362,7 +388354,7 @@ var init_browserAgentInvocation = __esm({
387362
388354
  id: randomUUID19(),
387363
388355
  type: "thought",
387364
388356
  content: sanitizedMsg,
387365
- status: "completed"
388357
+ status: SubagentState.COMPLETED
387366
388358
  });
387367
388359
  if (recentActivity.length > MAX_RECENT_ACTIVITY) {
387368
388360
  recentActivity = recentActivity.slice(-MAX_RECENT_ACTIVITY);
@@ -387371,7 +388363,7 @@ var init_browserAgentInvocation = __esm({
387371
388363
  isSubagentProgress: true,
387372
388364
  agentName: this.agentName,
387373
388365
  recentActivity: [...recentActivity],
387374
- state: "running"
388366
+ state: SubagentState.RUNNING
387375
388367
  });
387376
388368
  } : void 0;
387377
388369
  const result2 = await createBrowserAgentDefinition(this.config, this.messageBus, printOutput);
@@ -387387,14 +388379,14 @@ var init_browserAgentInvocation = __esm({
387387
388379
  case "THOUGHT_CHUNK": {
387388
388380
  const text = String(activity.data["text"]);
387389
388381
  const lastItem = recentActivity[recentActivity.length - 1];
387390
- if (lastItem && lastItem.type === "thought" && lastItem.status === "running") {
388382
+ if (lastItem && lastItem.type === "thought" && lastItem.status === SubagentState.RUNNING) {
387391
388383
  lastItem.content = sanitizeThoughtContent(text);
387392
388384
  } else {
387393
388385
  recentActivity.push({
387394
388386
  id: randomUUID19(),
387395
388387
  type: "thought",
387396
388388
  content: sanitizeThoughtContent(text),
387397
- status: "running"
388389
+ status: SubagentState.RUNNING
387398
388390
  });
387399
388391
  }
387400
388392
  updated = true;
@@ -387413,7 +388405,7 @@ var init_browserAgentInvocation = __esm({
387413
388405
  displayName,
387414
388406
  description,
387415
388407
  args: args2,
387416
- status: "running"
388408
+ status: SubagentState.RUNNING
387417
388409
  });
387418
388410
  updated = true;
387419
388411
  break;
@@ -387423,8 +388415,8 @@ var init_browserAgentInvocation = __esm({
387423
388415
  const data = activity.data["data"];
387424
388416
  const isError = isToolActivityError(data);
387425
388417
  for (let i3 = recentActivity.length - 1; i3 >= 0; i3--) {
387426
- if (recentActivity[i3].type === "tool_call" && callId != null && recentActivity[i3].id === callId && recentActivity[i3].status === "running") {
387427
- recentActivity[i3].status = isError ? "error" : "completed";
388418
+ if (recentActivity[i3].type === "tool_call" && callId != null && recentActivity[i3].id === callId && recentActivity[i3].status === SubagentState.RUNNING) {
388419
+ recentActivity[i3].status = isError ? SubagentState.ERROR : SubagentState.COMPLETED;
387428
388420
  updated = true;
387429
388421
  break;
387430
388422
  }
@@ -387435,10 +388427,10 @@ var init_browserAgentInvocation = __esm({
387435
388427
  const error2 = String(activity.data["error"]);
387436
388428
  const isCancellation = error2 === "Request cancelled.";
387437
388429
  const callId = activity.data["callId"] ? String(activity.data["callId"]) : void 0;
387438
- const newStatus = isCancellation ? "cancelled" : "error";
388430
+ const newStatus = isCancellation ? SubagentState.CANCELLED : SubagentState.ERROR;
387439
388431
  if (callId) {
387440
388432
  for (let i3 = recentActivity.length - 1; i3 >= 0; i3--) {
387441
- if (recentActivity[i3].type === "tool_call" && recentActivity[i3].id === callId && recentActivity[i3].status === "running") {
388433
+ if (recentActivity[i3].type === "tool_call" && recentActivity[i3].id === callId && recentActivity[i3].status === SubagentState.RUNNING) {
387442
388434
  recentActivity[i3].status = newStatus;
387443
388435
  updated = true;
387444
388436
  break;
@@ -387446,7 +388438,7 @@ var init_browserAgentInvocation = __esm({
387446
388438
  }
387447
388439
  } else {
387448
388440
  for (const item of recentActivity) {
387449
- if (item.type === "tool_call" && item.status === "running") {
388441
+ if (item.type === "tool_call" && item.status === SubagentState.RUNNING) {
387450
388442
  item.status = newStatus;
387451
388443
  updated = true;
387452
388444
  }
@@ -387473,7 +388465,7 @@ var init_browserAgentInvocation = __esm({
387473
388465
  isSubagentProgress: true,
387474
388466
  agentName: this.agentName,
387475
388467
  recentActivity: [...recentActivity],
387476
- state: "running"
388468
+ state: SubagentState.RUNNING
387477
388469
  };
387478
388470
  updateOutput(progress2);
387479
388471
  }
@@ -387492,11 +388484,11 @@ Result:
387492
388484
  ${output.result}`;
387493
388485
  let progressState;
387494
388486
  if (output.terminate_reason === AgentTerminateMode.ABORTED) {
387495
- progressState = "cancelled";
388487
+ progressState = SubagentState.CANCELLED;
387496
388488
  } else if (output.terminate_reason === AgentTerminateMode.GOAL) {
387497
- progressState = "completed";
388489
+ progressState = SubagentState.COMPLETED;
387498
388490
  } else {
387499
- progressState = "error";
388491
+ progressState = SubagentState.ERROR;
387500
388492
  }
387501
388493
  const progress = {
387502
388494
  isSubagentProgress: true,
@@ -387518,15 +388510,15 @@ ${output.result}`;
387518
388510
  const isAbort = error2 instanceof Error && error2.name === "AbortError" || rawErrorMessage.includes("Aborted");
387519
388511
  const errorMessage = sanitizeErrorMessage(rawErrorMessage);
387520
388512
  for (const item of recentActivity) {
387521
- if (item.status === "running") {
387522
- item.status = isAbort ? "cancelled" : "error";
388513
+ if (item.status === SubagentState.RUNNING) {
388514
+ item.status = isAbort ? SubagentState.CANCELLED : SubagentState.ERROR;
387523
388515
  }
387524
388516
  }
387525
388517
  const progress = {
387526
388518
  isSubagentProgress: true,
387527
388519
  agentName: this.agentName,
387528
388520
  recentActivity: [...recentActivity],
387529
- state: isAbort ? "cancelled" : "error"
388521
+ state: isAbort ? SubagentState.CANCELLED : SubagentState.ERROR
387530
388522
  };
387531
388523
  if (updateOutput) {
387532
388524
  updateOutput(progress);
@@ -392847,6 +393839,7 @@ var init_gitService = __esm({
392847
393839
  init_shell_utils();
392848
393840
  init_esm18();
392849
393841
  init_debugLogger();
393842
+ init_environmentSanitization();
392850
393843
  SHADOW_REPO_AUTHOR_NAME = "Gemini CLI";
392851
393844
  SHADOW_REPO_AUTHOR_EMAIL = "gemini-cli@google.com";
392852
393845
  GitService = class _GitService {
@@ -392883,9 +393876,15 @@ var init_gitService = __esm({
392883
393876
  const gitConfigPath = path75.join(repoDir, ".gitconfig");
392884
393877
  const systemConfigPath = path75.join(repoDir, ".gitconfig_system_empty");
392885
393878
  return {
393879
+ ...sanitizeEnvironment(process.env, getSecureSanitizationConfig({
393880
+ enableEnvironmentVariableRedaction: true
393881
+ })),
392886
393882
  // Prevent git from using the user's global git config.
392887
393883
  GIT_CONFIG_GLOBAL: gitConfigPath,
392888
393884
  GIT_CONFIG_SYSTEM: systemConfigPath,
393885
+ // Ensure we don't inherit isolation-breaking variables from the user environment.
393886
+ GIT_DIR: void 0,
393887
+ GIT_WORK_TREE: void 0,
392889
393888
  // Explicitly provide identity to prevent "Author identity unknown" errors
392890
393889
  // inside sandboxed environments like Docker where the gitconfig might not
392891
393890
  // be picked up properly.
@@ -392940,9 +393939,9 @@ var init_gitService = __esm({
392940
393939
  get shadowGitRepository() {
392941
393940
  const repoDir = this.getHistoryDir();
392942
393941
  return simpleGit(this.projectRoot).env({
393942
+ ...this.getShadowRepoEnv(repoDir),
392943
393943
  GIT_DIR: path75.join(repoDir, ".git"),
392944
- GIT_WORK_TREE: this.projectRoot,
392945
- ...this.getShadowRepoEnv(repoDir)
393944
+ GIT_WORK_TREE: this.projectRoot
392946
393945
  });
392947
393946
  }
392948
393947
  async getCurrentCommitHash() {
@@ -393847,18 +394846,22 @@ var ModelAvailabilityService;
393847
394846
  var init_modelAvailabilityService = __esm({
393848
394847
  "packages/core/dist/src/availability/modelAvailabilityService.js"() {
393849
394848
  "use strict";
394849
+ init_modelUtils();
393850
394850
  ModelAvailabilityService = class {
393851
394851
  health = /* @__PURE__ */ new Map();
393852
- markTerminal(model, reason) {
394852
+ markTerminal(modelId, reason) {
394853
+ const model = normalizeModelId(modelId);
393853
394854
  this.setState(model, {
393854
394855
  status: "terminal",
393855
394856
  reason
393856
394857
  });
393857
394858
  }
393858
- markHealthy(model) {
394859
+ markHealthy(modelId) {
394860
+ const model = normalizeModelId(modelId);
393859
394861
  this.clearState(model);
393860
394862
  }
393861
- markRetryOncePerTurn(model, attempts = 1) {
394863
+ markRetryOncePerTurn(modelId, attempts = 1) {
394864
+ const model = normalizeModelId(modelId);
393862
394865
  const currentState = this.health.get(model);
393863
394866
  if (currentState?.status === "terminal") {
393864
394867
  return;
@@ -393874,13 +394877,15 @@ var init_modelAvailabilityService = __esm({
393874
394877
  attempts
393875
394878
  });
393876
394879
  }
393877
- consumeStickyAttempt(model) {
394880
+ consumeStickyAttempt(modelId) {
394881
+ const model = normalizeModelId(modelId);
393878
394882
  const state = this.health.get(model);
393879
394883
  if (state?.status === "sticky_retry") {
393880
394884
  this.setState(model, { ...state, consumed: true });
393881
394885
  }
393882
394886
  }
393883
- snapshot(model) {
394887
+ snapshot(modelId) {
394888
+ const model = normalizeModelId(modelId);
393884
394889
  const state = this.health.get(model);
393885
394890
  if (!state) {
393886
394891
  return { available: true };
@@ -393893,9 +394898,10 @@ var init_modelAvailabilityService = __esm({
393893
394898
  }
393894
394899
  return { available: true };
393895
394900
  }
393896
- selectFirstAvailable(models) {
394901
+ selectFirstAvailable(modelIds) {
393897
394902
  const skipped = [];
393898
- for (const model of models) {
394903
+ for (const modelId of modelIds) {
394904
+ const model = normalizeModelId(modelId);
393899
394905
  const snapshot = this.snapshot(model);
393900
394906
  if (snapshot.available) {
393901
394907
  const state = this.health.get(model);
@@ -394073,7 +395079,13 @@ ${formattedHistory}
394073
395079
  const routerResponse = ClassifierResponseSchema.parse(jsonResponse);
394074
395080
  const reasoning = routerResponse.reasoning;
394075
395081
  const latencyMs = Date.now() - startTime;
394076
- const selectedModel = resolveClassifierModel(context2.requestedModel ?? config3.getModel(), routerResponse.model_choice);
395082
+ const [useGemini3_1, useGemini3_1FlashLite, useCustomToolModel, hasAccessToPreview] = await Promise.all([
395083
+ config3.getGemini31Launched(),
395084
+ config3.getGemini31FlashLiteLaunched(),
395085
+ config3.getUseCustomToolModel(),
395086
+ config3.getHasAccessToPreviewModel?.() ?? true
395087
+ ]);
395088
+ const selectedModel = resolveClassifierModel(context2.requestedModel ?? config3.getModel(), routerResponse.model_choice, useGemini3_1, useGemini3_1FlashLite, useCustomToolModel, hasAccessToPreview, config3);
394077
395089
  return {
394078
395090
  model: selectedModel,
394079
395091
  metadata: {
@@ -394125,6 +395137,7 @@ var init_classifierStrategy = __esm({
394125
395137
  init_node();
394126
395138
  init_messageInspectors();
394127
395139
  init_debugLogger();
395140
+ init_modelUtils();
394128
395141
  init_types7();
394129
395142
  HISTORY_TURNS_FOR_CONTEXT2 = 4;
394130
395143
  HISTORY_SEARCH_WINDOW2 = 20;
@@ -394251,7 +395264,13 @@ Respond *only* in JSON format according to the following schema. Do not include
394251
395264
  config3.getGemini31FlashLiteLaunched(),
394252
395265
  config3.getUseCustomToolModel()
394253
395266
  ]);
394254
- const selectedModel = resolveClassifierModel(model, routerResponse.model_choice, useGemini3_1, useGemini3_1FlashLite, useCustomToolModel, config3.getHasAccessToPreviewModel?.() ?? true, config3);
395267
+ const selectedModel = normalizeModelId(resolveClassifierModel(normalizeModelId(model), routerResponse.model_choice, useGemini3_1, useGemini3_1FlashLite, useCustomToolModel, config3.getHasAccessToPreviewModel?.() ?? true, config3));
395268
+ const service = config3.getModelAvailabilityService();
395269
+ const snapshot = service.snapshot(selectedModel);
395270
+ if (!snapshot.available) {
395271
+ debugLogger.warn(`[Routing] Classifier selected unavailable model ${selectedModel} (${snapshot.reason}). Bypassing.`);
395272
+ return null;
395273
+ }
394255
395274
  return {
394256
395275
  model: selectedModel,
394257
395276
  metadata: {
@@ -394278,7 +395297,9 @@ var init_numericalClassifierStrategy = __esm({
394278
395297
  init_promptIdContext();
394279
395298
  init_models();
394280
395299
  init_node();
395300
+ init_messageInspectors();
394281
395301
  init_debugLogger();
395302
+ init_modelUtils();
394282
395303
  init_types7();
394283
395304
  HISTORY_TURNS_FOR_CONTEXT3 = 8;
394284
395305
  FLASH_MODEL3 = "flash";
@@ -394361,7 +395382,15 @@ Model: {"complexity_reasoning": "High-level architecture and strategic planning.
394361
395382
  return null;
394362
395383
  }
394363
395384
  const promptId = getPromptIdWithFallback("classifier-router");
394364
- const finalHistory = context2.history.slice(-HISTORY_TURNS_FOR_CONTEXT3);
395385
+ const candidateSlice = context2.history.slice(-HISTORY_TURNS_FOR_CONTEXT3);
395386
+ let firstTextIndex = -1;
395387
+ for (let i3 = 0; i3 < candidateSlice.length; i3++) {
395388
+ if (!isFunctionCall(candidateSlice[i3]) && !isFunctionResponse(candidateSlice[i3])) {
395389
+ firstTextIndex = i3;
395390
+ break;
395391
+ }
395392
+ }
395393
+ const finalHistory = firstTextIndex === -1 ? [] : candidateSlice.slice(firstTextIndex);
394365
395394
  const requestParts = Array.isArray(context2.request) ? context2.request : [context2.request];
394366
395395
  const sanitizedRequest = requestParts.map((part) => {
394367
395396
  if (typeof part === "string") {
@@ -394389,7 +395418,13 @@ Model: {"complexity_reasoning": "High-level architecture and strategic planning.
394389
395418
  config3.getGemini31FlashLiteLaunched(),
394390
395419
  config3.getUseCustomToolModel()
394391
395420
  ]);
394392
- const selectedModel = resolveClassifierModel(model, modelAlias, useGemini3_1, useGemini3_1FlashLite, useCustomToolModel, config3.getHasAccessToPreviewModel?.() ?? true, config3);
395421
+ const selectedModel = normalizeModelId(resolveClassifierModel(normalizeModelId(model), modelAlias, useGemini3_1, useGemini3_1FlashLite, useCustomToolModel, config3.getHasAccessToPreviewModel?.() ?? true, config3));
395422
+ const service = config3.getModelAvailabilityService();
395423
+ const snapshot = service.snapshot(selectedModel);
395424
+ if (!snapshot.available) {
395425
+ debugLogger.warn(`[Routing] Numerical classifier selected unavailable model ${selectedModel} (${snapshot.reason}). Bypassing.`);
395426
+ return null;
395427
+ }
394393
395428
  const latencyMs = Date.now() - startTime;
394394
395429
  return {
394395
395430
  model: selectedModel,
@@ -394562,12 +395597,14 @@ var init_approvalModeStrategy = __esm({
394562
395597
  const startTime = Date.now();
394563
395598
  const approvalMode = config3.getApprovalMode();
394564
395599
  const approvedPlanPath = config3.getApprovedPlanPath();
394565
- const [useGemini3_1, useCustomToolModel] = await Promise.all([
395600
+ const [useGemini3_1, useGemini3_1FlashLite, useCustomToolModel, hasAccessToPreview] = await Promise.all([
394566
395601
  config3.getGemini31Launched(),
394567
- config3.getUseCustomToolModel()
395602
+ config3.getGemini31FlashLiteLaunched(),
395603
+ config3.getUseCustomToolModel(),
395604
+ config3.getHasAccessToPreviewModel()
394568
395605
  ]);
394569
395606
  if (approvalMode === ApprovalMode.PLAN) {
394570
- const proModel = resolveClassifierModel(model, GEMINI_MODEL_ALIAS_PRO, useGemini3_1, useCustomToolModel);
395607
+ const proModel = resolveClassifierModel(model, GEMINI_MODEL_ALIAS_PRO, useGemini3_1, useGemini3_1FlashLite, useCustomToolModel, hasAccessToPreview, config3);
394571
395608
  return {
394572
395609
  model: proModel,
394573
395610
  metadata: {
@@ -394577,7 +395614,7 @@ var init_approvalModeStrategy = __esm({
394577
395614
  }
394578
395615
  };
394579
395616
  } else if (approvedPlanPath) {
394580
- const flashModel = resolveClassifierModel(model, GEMINI_MODEL_ALIAS_FLASH, useGemini3_1, useCustomToolModel);
395617
+ const flashModel = resolveClassifierModel(model, GEMINI_MODEL_ALIAS_FLASH, useGemini3_1, useGemini3_1FlashLite, useCustomToolModel, hasAccessToPreview, config3);
394581
395618
  return {
394582
395619
  model: flashModel,
394583
395620
  metadata: {
@@ -394910,6 +395947,19 @@ var init_defaultModelConfigs = __esm({
394910
395947
  extends: "gemini-3-flash-base",
394911
395948
  modelConfig: {}
394912
395949
  },
395950
+ "context-snapshotter": {
395951
+ extends: "gemini-3-flash-base",
395952
+ modelConfig: {
395953
+ generateContentConfig: {
395954
+ thinkingConfig: {
395955
+ thinkingLevel: ThinkingLevel.HIGH
395956
+ },
395957
+ temperature: 1,
395958
+ topP: 0.95,
395959
+ topK: 64
395960
+ }
395961
+ }
395962
+ },
394913
395963
  "chat-compression-3-pro": {
394914
395964
  modelConfig: {
394915
395965
  model: "gemini-3-pro-preview"
@@ -395726,7 +396776,7 @@ async function findProjectRoot2(startDir, boundaryMarkers = [".git"]) {
395726
396776
  if (boundaryMarkers.length === 0) {
395727
396777
  return null;
395728
396778
  }
395729
- let currentDir = normalizePath(startDir);
396779
+ let currentDir = toAbsolutePath(startDir);
395730
396780
  while (true) {
395731
396781
  for (const marker of boundaryMarkers) {
395732
396782
  if (path77.isAbsolute(marker) || marker.includes("..")) {
@@ -395750,7 +396800,7 @@ async function findProjectRoot2(startDir, boundaryMarkers = [".git"]) {
395750
396800
  }
395751
396801
  }
395752
396802
  }
395753
- const parentDir = normalizePath(path77.dirname(currentDir));
396803
+ const parentDir = path77.dirname(currentDir);
395754
396804
  if (parentDir === currentDir) {
395755
396805
  return null;
395756
396806
  }
@@ -395791,9 +396841,11 @@ async function getGeminiMdFilePathsInternalForEachDir(dir, userHomePath, fileSer
395791
396841
  const projectPaths = /* @__PURE__ */ new Set();
395792
396842
  const geminiMdFilenames = getAllGeminiMdFilenames();
395793
396843
  for (const geminiMdFilename of geminiMdFilenames) {
395794
- const resolvedHome = normalizePath(userHomePath);
395795
- const globalGeminiDir = normalizePath(path77.join(resolvedHome, GEMINI_DIR));
395796
- const globalMemoryPath = normalizePath(path77.join(globalGeminiDir, geminiMdFilename));
396844
+ const resolvedHome = toAbsolutePath(userHomePath);
396845
+ const globalGeminiDir = toAbsolutePath(path77.join(resolvedHome, GEMINI_DIR));
396846
+ const globalMemoryPath = toAbsolutePath(path77.join(globalGeminiDir, geminiMdFilename));
396847
+ const globalMemoryKey = normalizePath(globalMemoryPath);
396848
+ const globalGeminiDirKey = normalizePath(globalGeminiDir);
395797
396849
  try {
395798
396850
  await fs72.access(globalMemoryPath, fsSync4.constants.R_OK);
395799
396851
  globalPaths.add(globalMemoryPath);
@@ -395801,29 +396853,29 @@ async function getGeminiMdFilePathsInternalForEachDir(dir, userHomePath, fileSer
395801
396853
  } catch {
395802
396854
  }
395803
396855
  if (dir && folderTrust) {
395804
- const resolvedCwd = normalizePath(dir);
396856
+ const resolvedCwd = toAbsolutePath(dir);
395805
396857
  debugLogger.debug("[DEBUG] [MemoryDiscovery] Searching for", geminiMdFilename, "starting from CWD:", resolvedCwd);
395806
396858
  const projectRoot = await findProjectRoot2(resolvedCwd, boundaryMarkers);
395807
396859
  debugLogger.debug("[DEBUG] [MemoryDiscovery] Determined project root:", projectRoot ?? "None");
395808
396860
  const upwardPaths = [];
395809
396861
  let currentDir = resolvedCwd;
395810
- const ultimateStopDir = projectRoot ? normalizePath(path77.dirname(projectRoot)) : normalizePath(path77.dirname(resolvedHome));
395811
- while (currentDir && currentDir !== normalizePath(path77.dirname(currentDir))) {
395812
- if (currentDir === globalGeminiDir) {
396862
+ const ultimateStopDirKey = projectRoot ? normalizePath(path77.dirname(projectRoot)) : normalizePath(path77.dirname(resolvedHome));
396863
+ while (currentDir && currentDir !== path77.dirname(currentDir)) {
396864
+ if (normalizePath(currentDir) === globalGeminiDirKey) {
395813
396865
  break;
395814
396866
  }
395815
- const potentialPath = normalizePath(path77.join(currentDir, geminiMdFilename));
396867
+ const potentialPath = toAbsolutePath(path77.join(currentDir, geminiMdFilename));
395816
396868
  try {
395817
396869
  await fs72.access(potentialPath, fsSync4.constants.R_OK);
395818
- if (potentialPath !== globalMemoryPath) {
396870
+ if (normalizePath(potentialPath) !== globalMemoryKey) {
395819
396871
  upwardPaths.unshift(potentialPath);
395820
396872
  }
395821
396873
  } catch {
395822
396874
  }
395823
- if (currentDir === ultimateStopDir) {
396875
+ if (normalizePath(currentDir) === ultimateStopDirKey) {
395824
396876
  break;
395825
396877
  }
395826
- currentDir = normalizePath(path77.dirname(currentDir));
396878
+ currentDir = path77.dirname(currentDir);
395827
396879
  }
395828
396880
  upwardPaths.forEach((p2) => projectPaths.add(p2));
395829
396881
  const mergedOptions = {
@@ -395838,7 +396890,7 @@ async function getGeminiMdFilePathsInternalForEachDir(dir, userHomePath, fileSer
395838
396890
  });
395839
396891
  downwardPaths.sort();
395840
396892
  for (const dPath of downwardPaths) {
395841
- projectPaths.add(normalizePath(dPath));
396893
+ projectPaths.add(toAbsolutePath(dPath));
395842
396894
  }
395843
396895
  }
395844
396896
  }
@@ -395901,7 +396953,7 @@ async function getGlobalMemoryPaths() {
395901
396953
  const userHome = homedir();
395902
396954
  const geminiMdFilenames = getAllGeminiMdFilenames();
395903
396955
  const accessChecks = geminiMdFilenames.map(async (filename) => {
395904
- const globalPath = normalizePath(path77.join(userHome, GEMINI_DIR, filename));
396956
+ const globalPath = toAbsolutePath(path77.join(userHome, GEMINI_DIR, filename));
395905
396957
  try {
395906
396958
  await fs72.access(globalPath, fsSync4.constants.R_OK);
395907
396959
  debugLogger.debug("[DEBUG] [MemoryDiscovery] Found global memory file:", globalPath);
@@ -395913,7 +396965,7 @@ async function getGlobalMemoryPaths() {
395913
396965
  return (await Promise.all(accessChecks)).filter((p2) => p2 !== null);
395914
396966
  }
395915
396967
  async function getUserProjectMemoryPaths(projectMemoryDir) {
395916
- const preferredMemoryPath = normalizePath(path77.join(projectMemoryDir, PROJECT_MEMORY_INDEX_FILENAME));
396968
+ const preferredMemoryPath = toAbsolutePath(path77.join(projectMemoryDir, PROJECT_MEMORY_INDEX_FILENAME));
395917
396969
  try {
395918
396970
  await fs72.access(preferredMemoryPath, fsSync4.constants.R_OK);
395919
396971
  debugLogger.debug("[DEBUG] [MemoryDiscovery] Found user project memory index:", preferredMemoryPath);
@@ -395922,7 +396974,7 @@ async function getUserProjectMemoryPaths(projectMemoryDir) {
395922
396974
  }
395923
396975
  const geminiMdFilenames = getAllGeminiMdFilenames();
395924
396976
  const accessChecks = geminiMdFilenames.map(async (filename) => {
395925
- const legacyMemoryPath = normalizePath(path77.join(projectMemoryDir, filename));
396977
+ const legacyMemoryPath = toAbsolutePath(path77.join(projectMemoryDir, filename));
395926
396978
  try {
395927
396979
  await fs72.access(legacyMemoryPath, fsSync4.constants.R_OK);
395928
396980
  debugLogger.debug("[DEBUG] [MemoryDiscovery] Found legacy user project memory file:", legacyMemoryPath);
@@ -395934,21 +396986,29 @@ async function getUserProjectMemoryPaths(projectMemoryDir) {
395934
396986
  return (await Promise.all(accessChecks)).filter((p2) => p2 !== null);
395935
396987
  }
395936
396988
  function getExtensionMemoryPaths(extensionLoader) {
395937
- const extensionPaths = extensionLoader.getExtensions().filter((ext2) => ext2.isActive).flatMap((ext2) => ext2.contextFiles).map((p2) => normalizePath(p2));
395938
- return Array.from(new Set(extensionPaths)).sort();
396989
+ const extensionPaths = extensionLoader.getExtensions().filter((ext2) => ext2.isActive).flatMap((ext2) => ext2.contextFiles).map((p2) => toAbsolutePath(p2));
396990
+ const seenKeys = /* @__PURE__ */ new Set();
396991
+ const unique = [];
396992
+ for (const p2 of extensionPaths) {
396993
+ const key = normalizePath(p2);
396994
+ if (seenKeys.has(key))
396995
+ continue;
396996
+ seenKeys.add(key);
396997
+ unique.push(p2);
396998
+ }
396999
+ return unique.sort();
395939
397000
  }
395940
397001
  async function getEnvironmentMemoryPaths(trustedRoots, boundaryMarkers = [".git"]) {
395941
- const allPaths = /* @__PURE__ */ new Set();
395942
397002
  const traversalPromises = trustedRoots.map(async (root) => {
395943
- const resolvedRoot = normalizePath(root);
397003
+ const resolvedRoot = toAbsolutePath(root);
395944
397004
  const gitRoot = await findProjectRoot2(resolvedRoot, boundaryMarkers);
395945
- const ceiling = gitRoot ? normalizePath(gitRoot) : resolvedRoot;
397005
+ const ceiling = gitRoot ?? resolvedRoot;
395946
397006
  debugLogger.debug("[DEBUG] [MemoryDiscovery] Loading environment memory for trusted root:", resolvedRoot, "(Stopping at", gitRoot ? `git root: ${ceiling})` : `trusted root: ${ceiling} \u2014 no git root found)`);
395947
397007
  return findUpwardGeminiFiles(resolvedRoot, ceiling);
395948
397008
  });
395949
397009
  const pathArrays = await Promise.all(traversalPromises);
395950
- pathArrays.flat().forEach((p2) => allPaths.add(p2));
395951
- return Array.from(allPaths).sort();
397010
+ const { paths: unique } = await deduplicatePathsByFileIdentity(pathArrays.flat());
397011
+ return unique.sort();
395952
397012
  }
395953
397013
  function categorizeAndConcatenate(paths, contentsMap) {
395954
397014
  const getConcatenated = (pList) => concatenateInstructions(pList.map((p2) => contentsMap.get(p2)).filter((c2) => !!c2));
@@ -395961,17 +397021,17 @@ function categorizeAndConcatenate(paths, contentsMap) {
395961
397021
  }
395962
397022
  async function findUpwardGeminiFiles(startDir, stopDir) {
395963
397023
  const upwardPaths = [];
395964
- let currentDir = normalizePath(startDir);
395965
- const resolvedStopDir = normalizePath(stopDir);
397024
+ let currentDir = toAbsolutePath(startDir);
397025
+ const resolvedStopDirKey = normalizePath(stopDir);
395966
397026
  const geminiMdFilenames = getAllGeminiMdFilenames();
395967
- const globalGeminiDir = normalizePath(path77.join(homedir(), GEMINI_DIR));
395968
- debugLogger.debug("[DEBUG] [MemoryDiscovery] Starting upward search from", currentDir, "stopping at", resolvedStopDir);
397027
+ const globalGeminiDirKey = normalizePath(path77.join(homedir(), GEMINI_DIR));
397028
+ debugLogger.debug("[DEBUG] [MemoryDiscovery] Starting upward search from", currentDir, "stopping at", stopDir);
395969
397029
  while (true) {
395970
- if (currentDir === globalGeminiDir) {
397030
+ if (normalizePath(currentDir) === globalGeminiDirKey) {
395971
397031
  break;
395972
397032
  }
395973
397033
  const accessChecks = geminiMdFilenames.map(async (filename) => {
395974
- const potentialPath = normalizePath(path77.join(currentDir, filename));
397034
+ const potentialPath = toAbsolutePath(path77.join(currentDir, filename));
395975
397035
  try {
395976
397036
  await fs72.access(potentialPath, fsSync4.constants.R_OK);
395977
397037
  return potentialPath;
@@ -395981,8 +397041,9 @@ async function findUpwardGeminiFiles(startDir, stopDir) {
395981
397041
  });
395982
397042
  const foundPathsInDir = (await Promise.all(accessChecks)).filter((p2) => p2 !== null);
395983
397043
  upwardPaths.unshift(...foundPathsInDir);
395984
- const parentDir = normalizePath(path77.dirname(currentDir));
395985
- if (currentDir === resolvedStopDir || currentDir === parentDir) {
397044
+ const parentDir = path77.dirname(currentDir);
397045
+ const currentKey = normalizePath(currentDir);
397046
+ if (currentKey === resolvedStopDirKey || currentDir === parentDir) {
395986
397047
  break;
395987
397048
  }
395988
397049
  currentDir = parentDir;
@@ -396049,13 +397110,16 @@ async function refreshServerHierarchicalMemory(config3) {
396049
397110
  return result2;
396050
397111
  }
396051
397112
  async function loadJitSubdirectoryMemory(targetPath, trustedRoots, alreadyLoadedPaths, alreadyLoadedIdentities, boundaryMarkers = [".git"]) {
396052
- const resolvedTarget = normalizePath(targetPath);
397113
+ const resolvedTarget = toAbsolutePath(targetPath);
396053
397114
  let bestRoot = null;
397115
+ let bestRootKeyLength = -1;
396054
397116
  for (const root of trustedRoots) {
396055
397117
  if (isSubpath(root, targetPath)) {
396056
- const resolvedRoot = normalizePath(root);
396057
- if (!bestRoot || resolvedRoot.length > bestRoot.length) {
397118
+ const resolvedRoot = toAbsolutePath(root);
397119
+ const rootKeyLength = normalizePath(resolvedRoot).length;
397120
+ if (rootKeyLength > bestRootKeyLength) {
396058
397121
  bestRoot = resolvedRoot;
397122
+ bestRootKeyLength = rootKeyLength;
396059
397123
  }
396060
397124
  }
396061
397125
  }
@@ -396064,16 +397128,16 @@ async function loadJitSubdirectoryMemory(targetPath, trustedRoots, alreadyLoaded
396064
397128
  return { files: [], fileIdentities: [] };
396065
397129
  }
396066
397130
  const gitRoot = await findProjectRoot2(bestRoot, boundaryMarkers);
396067
- const resolvedCeiling = gitRoot ? normalizePath(gitRoot) : bestRoot;
397131
+ const resolvedCeiling = gitRoot ?? bestRoot;
396068
397132
  debugLogger.debug("[DEBUG] [MemoryDiscovery] Loading JIT memory for", resolvedTarget, `(Trusted root: ${bestRoot}, Ceiling: ${resolvedCeiling}${gitRoot ? " [git root]" : " [trusted root, no git]"})`);
396069
397133
  let startDir = resolvedTarget;
396070
397134
  try {
396071
397135
  const stat5 = await fs72.stat(resolvedTarget);
396072
397136
  if (stat5.isFile()) {
396073
- startDir = normalizePath(path77.dirname(resolvedTarget));
397137
+ startDir = path77.dirname(resolvedTarget);
396074
397138
  }
396075
397139
  } catch {
396076
- startDir = normalizePath(path77.dirname(resolvedTarget));
397140
+ startDir = path77.dirname(resolvedTarget);
396077
397141
  }
396078
397142
  const potentialPaths = await findUpwardGeminiFiles(startDir, resolvedCeiling);
396079
397143
  if (potentialPaths.length === 0) {
@@ -398368,7 +399432,7 @@ var init_hookEventHandler = __esm({
398368
399432
  const hookType = this.getHookTypeFromResult(result2);
398369
399433
  const hookCallEvent = new HookCallEvent(eventName, hookType, hookName, { ...input }, result2.duration, result2.success, result2.output ? { ...result2.output } : void 0, result2.exitCode, result2.stdout, result2.stderr, result2.error?.message);
398370
399434
  logHookCall(this.context.config, hookCallEvent);
398371
- if (result2.output?.systemMessage && result2.outputFormat === "json") {
399435
+ if (result2.output?.systemMessage) {
398372
399436
  coreEvents.emitHookSystemMessage({
398373
399437
  hookName,
398374
399438
  eventName,
@@ -402408,21 +403472,29 @@ async function connectToMcpServer(clientVersion, mcpServerName, mcpServerConfig,
402408
403472
  }
402409
403473
  }
402410
403474
  function createUrlTransport(mcpServerName, mcpServerConfig, transportOptions) {
403475
+ const baseFetch = transportOptions.fetch ?? globalThis.fetch;
403476
+ const httpOptions = {
403477
+ ...transportOptions,
403478
+ fetch: async (url5, init2) => {
403479
+ const res = await baseFetch(url5, init2);
403480
+ return init2?.method === "GET" && res.status === 404 ? new Response(null, { status: 405, statusText: "Method Not Allowed" }) : res;
403481
+ }
403482
+ };
402411
403483
  if (mcpServerConfig.httpUrl) {
402412
403484
  if (mcpServerConfig.url) {
402413
403485
  debugLogger.warn(`MCP server '${mcpServerName}': Both 'httpUrl' and 'url' are configured. Using deprecated 'httpUrl'. Please migrate to 'url' with 'type: "http"'.`);
402414
403486
  }
402415
- return new StreamableHTTPClientTransport(new URL(mcpServerConfig.httpUrl), transportOptions);
403487
+ return new StreamableHTTPClientTransport(new URL(mcpServerConfig.httpUrl), httpOptions);
402416
403488
  }
402417
403489
  if (mcpServerConfig.url && mcpServerConfig.type) {
402418
403490
  if (mcpServerConfig.type === "http") {
402419
- return new StreamableHTTPClientTransport(new URL(mcpServerConfig.url), transportOptions);
403491
+ return new StreamableHTTPClientTransport(new URL(mcpServerConfig.url), httpOptions);
402420
403492
  } else if (mcpServerConfig.type === "sse") {
402421
403493
  return new SSEClientTransport(new URL(mcpServerConfig.url), transportOptions);
402422
403494
  }
402423
403495
  }
402424
403496
  if (mcpServerConfig.url) {
402425
- return new StreamableHTTPClientTransport(new URL(mcpServerConfig.url), transportOptions);
403497
+ return new StreamableHTTPClientTransport(new URL(mcpServerConfig.url), httpOptions);
402426
403498
  }
402427
403499
  throw new Error(`No URL configured for MCP server '${mcpServerName}'`);
402428
403500
  }
@@ -423026,7 +424098,15 @@ var init_config4 = __esm({
423026
424098
  this.workspaceContext.addDirectory(dir);
423027
424099
  }
423028
424100
  if (this.planEnabled) {
423029
- const plansDir = this.storage.getPlansDir();
424101
+ let plansDir;
424102
+ try {
424103
+ plansDir = this.storage.getPlansDir();
424104
+ } catch (error2) {
424105
+ const errorMessage = error2 instanceof Error ? error2.message : String(error2);
424106
+ coreEvents.emitFeedback("warning", "Invalid custom plans directory: " + errorMessage + ". Falling back to default project temp directory.", error2);
424107
+ this.storage.setCustomPlansDir(void 0);
424108
+ plansDir = this.storage.getPlansDir();
424109
+ }
423030
424110
  try {
423031
424111
  await fs80.promises.access(plansDir);
423032
424112
  this.workspaceContext.addDirectory(plansDir);
@@ -423746,12 +424826,13 @@ var init_config4 = __esm({
423746
424826
  * user message when JIT is enabled. Returns empty string when JIT is
423747
424827
  * disabled (Tier 2 memory is already in the system instruction).
423748
424828
  */
423749
- getSessionMemory() {
424829
+ getSessionMemory(options) {
423750
424830
  if (!this.experimentalJitContext || !this.memoryContextManager) {
423751
424831
  return "";
423752
424832
  }
423753
424833
  const sections = [];
423754
- const extension = this.memoryContextManager.getExtensionMemory();
424834
+ const includeExtensionContext = options?.includeExtensionContext ?? true;
424835
+ const extension = includeExtensionContext ? this.memoryContextManager.getExtensionMemory() : "";
423755
424836
  const project = this.memoryContextManager.getEnvironmentMemory();
423756
424837
  if (extension?.trim()) {
423757
424838
  sections.push(`<extension_context>
@@ -424166,16 +425247,32 @@ ${sections.join("\n")}
424166
425247
  setIdeMode(value) {
424167
425248
  this.ideMode = value;
424168
425249
  }
424169
- isScopedMemoryInboxPatchPathAllowed(absolutePath, resolvedPath, inboxRoot) {
425250
+ isScopedMemoryInboxPatchPathAllowed(absolutePath, resolvedPath, inboxRoot, checkType = "write") {
424170
425251
  if (!hasScopedMemoryInboxAccess()) {
424171
425252
  return false;
424172
425253
  }
424173
425254
  const normalizedPath = path86.resolve(absolutePath);
425255
+ const resolvedMemoryRoot = resolveToRealPath(this.storage.getProjectMemoryTempDir());
425256
+ if (checkType === "read") {
425257
+ const resolvedInboxRoot = resolveToRealPath(inboxRoot);
425258
+ const normalizedInboxRoot = path86.resolve(inboxRoot);
425259
+ if (resolvedPath === resolvedInboxRoot || normalizedPath === normalizedInboxRoot) {
425260
+ return isSubpath(resolvedMemoryRoot, resolvedPath);
425261
+ }
425262
+ for (const kind of ["private", "global"]) {
425263
+ const kindRoot = path86.join(inboxRoot, kind);
425264
+ const resolvedKindRoot = resolveToRealPath(kindRoot);
425265
+ const normalizedKindRoot = path86.resolve(kindRoot);
425266
+ if (resolvedPath === resolvedKindRoot || normalizedPath === normalizedKindRoot || isSubpath(resolvedKindRoot, resolvedPath) || isSubpath(normalizedKindRoot, normalizedPath)) {
425267
+ return isSubpath(resolvedMemoryRoot, resolvedPath);
425268
+ }
425269
+ }
425270
+ return false;
425271
+ }
424174
425272
  const isCanonicalPatchPath = ["private", "global"].some((kind) => normalizedPath === path86.resolve(inboxRoot, kind, "extraction.patch"));
424175
425273
  if (!isCanonicalPatchPath) {
424176
425274
  return false;
424177
425275
  }
424178
- const resolvedMemoryRoot = resolveToRealPath(this.storage.getProjectMemoryTempDir());
424179
425276
  return isSubpath(resolvedMemoryRoot, resolvedPath);
424180
425277
  }
424181
425278
  isScopedAutoMemoryExtractionWritePathAllowed(absolutePath, resolvedPath) {
@@ -424205,7 +425302,9 @@ ${sections.join("\n")}
424205
425302
  * the auto-memory extraction agent and the `/memory inbox` review flow. The
424206
425303
  * main agent is denied access to it even though it falls inside the project
424207
425304
  * temp dir; the extraction agent receives a narrow execution-scoped exception
424208
- * for `.inbox/{private,global}/extraction.patch`.
425305
+ * for *writes* to `.inbox/{private,global}/extraction.patch`. Scoped *read*
425306
+ * access to the wider `.inbox/{private,global}/` subtree is granted in
425307
+ * `validatePathAccess` so the extractor can enumerate prior patches.
424209
425308
  *
424210
425309
  * @param absolutePath The absolute path to check.
424211
425310
  * @returns true if the path is allowed, false otherwise.
@@ -424257,6 +425356,12 @@ ${sections.join("\n")}
424257
425356
  if (this.getWorkspaceContext().isPathReadable(absolutePath)) {
424258
425357
  return null;
424259
425358
  }
425359
+ if (hasScopedMemoryInboxAccess()) {
425360
+ const inboxRoot = path86.join(this.storage.getProjectMemoryTempDir(), ".inbox");
425361
+ if (this.isScopedMemoryInboxPatchPathAllowed(absolutePath, resolveToRealPath(absolutePath), inboxRoot, "read")) {
425362
+ return null;
425363
+ }
425364
+ }
424260
425365
  }
424261
425366
  if (this.isPathAllowed(absolutePath)) {
424262
425367
  return null;
@@ -424583,10 +425688,10 @@ ${sections.join("\n")}
424583
425688
  return this.gemmaModelRouter;
424584
425689
  }
424585
425690
  getAgentSessionNoninteractiveEnabled() {
424586
- return this.agentSessionNoninteractiveEnabled;
425691
+ return process15.env["GEMINI_CLI_EXP_AGENT"] === "true" || this.agentSessionNoninteractiveEnabled;
424587
425692
  }
424588
425693
  getAgentSessionInteractiveEnabled() {
424589
- return this.agentSessionInteractiveEnabled;
425694
+ return process15.env["GEMINI_CLI_EXP_AGENT"] === "true" || this.agentSessionInteractiveEnabled;
424590
425695
  }
424591
425696
  /**
424592
425697
  * Get override settings for a specific agent.
@@ -425331,13 +426436,13 @@ var require_implementation2 = __commonJS({
425331
426436
  var isObject5 = object3 !== null && typeof object3 === "object";
425332
426437
  var isFunction = toStr.call(object3) === "[object Function]";
425333
426438
  var isArguments = isArgs(object3);
425334
- var isString = isObject5 && toStr.call(object3) === "[object String]";
426439
+ var isString2 = isObject5 && toStr.call(object3) === "[object String]";
425335
426440
  var theKeys = [];
425336
426441
  if (!isObject5 && !isFunction && !isArguments) {
425337
426442
  throw new TypeError("Object.keys called on a non-object");
425338
426443
  }
425339
426444
  var skipProto = hasProtoEnumBug && isFunction;
425340
- if (isString && object3.length > 0 && !has.call(object3, 0)) {
426445
+ if (isString2 && object3.length > 0 && !has.call(object3, 0)) {
425341
426446
  for (var i3 = 0; i3 < object3.length; ++i3) {
425342
426447
  theKeys.push(String(i3));
425343
426448
  }
@@ -425964,6 +427069,7 @@ var init_memoryPatchUtils = __esm({
425964
427069
  "packages/core/dist/src/services/memoryPatchUtils.js"() {
425965
427070
  "use strict";
425966
427071
  init_storage();
427072
+ init_memoryTool();
425967
427073
  init_errors2();
425968
427074
  init_debugLogger();
425969
427075
  init_paths();
@@ -426104,10 +427210,10 @@ var init_memory2 = __esm({
426104
427210
  init_storage();
426105
427211
  init_memory();
426106
427212
  init_skillLoader();
426107
- init_memoryTool();
426108
427213
  init_memoryPatchUtils();
426109
427214
  init_memoryService();
426110
427215
  init_memoryDiscovery();
427216
+ init_memoryPatchUtils();
426111
427217
  }
426112
427218
  });
426113
427219
 
@@ -428993,13 +430099,7 @@ var init_agent_session = __esm({
428993
430099
  var init_content_utils = __esm({
428994
430100
  "packages/core/dist/src/agent/content-utils.js"() {
428995
430101
  "use strict";
428996
- }
428997
- });
428998
-
428999
- // packages/core/dist/src/agent/tool-display-utils.js
429000
- var init_tool_display_utils = __esm({
429001
- "packages/core/dist/src/agent/tool-display-utils.js"() {
429002
- "use strict";
430102
+ init_debugLogger();
429003
430103
  }
429004
430104
  });
429005
430105
 
@@ -429552,12 +430652,13 @@ var init_src2 = __esm({
429552
430652
  init_storage();
429553
430653
  init_hooks();
429554
430654
  init_types13();
429555
- init_types14();
429556
430655
  init_stdio();
429557
430656
  init_terminal();
429558
430657
  init_worktreeService();
429559
430658
  init_responseFormatter();
429560
430659
  init_types19();
430660
+ init_snapshotGenerator();
430661
+ init_types15();
429561
430662
  init_profiles2();
429562
430663
  init_profiles();
429563
430664
  init_trust();
@@ -430190,10 +431291,10 @@ var JsonRpcTransportHandler = class {
430190
431291
  }
430191
431292
  if ("id" in rpcRequest) {
430192
431293
  const id = rpcRequest.id;
430193
- const isString = typeof id === "string";
431294
+ const isString2 = typeof id === "string";
430194
431295
  const isInteger3 = typeof id === "number" && Number.isInteger(id);
430195
431296
  const isNull2 = id === null;
430196
- if (!isString && !isInteger3 && !isNull2) {
431297
+ if (!isString2 && !isInteger3 && !isNull2) {
430197
431298
  return false;
430198
431299
  }
430199
431300
  }