@google/gemini-cli-a2a-server 0.42.0-nightly.20260504.g37edd1d4d → 0.42.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.
@@ -114791,9 +114791,6 @@ var init_storage = __esm({
114791
114791
  static getUserAgentSkillsDir() {
114792
114792
  return path6.join(_Storage.getGlobalAgentsDir(), "skills");
114793
114793
  }
114794
- static getGlobalMemoryFilePath() {
114795
- return path6.join(_Storage.getGlobalGeminiDir(), "memory.md");
114796
- }
114797
114794
  static getUserPoliciesDir() {
114798
114795
  return path6.join(_Storage.getGlobalGeminiDir(), "policies");
114799
114796
  }
@@ -209441,8 +209438,8 @@ var GIT_COMMIT_INFO, CLI_VERSION;
209441
209438
  var init_git_commit = __esm({
209442
209439
  "packages/core/dist/src/generated/git-commit.js"() {
209443
209440
  "use strict";
209444
- GIT_COMMIT_INFO = "37edd1d4d";
209445
- CLI_VERSION = "0.42.0-nightly.20260504.g37edd1d4d";
209441
+ GIT_COMMIT_INFO = "0803007c8";
209442
+ CLI_VERSION = "0.42.0-preview.0";
209446
209443
  }
209447
209444
  });
209448
209445
 
@@ -283012,6 +283009,25 @@ function convertToFunctionResponse(toolName, callId, llmContent, model, config3)
283012
283009
  ];
283013
283010
  }
283014
283011
  }
283012
+ const filteredInlineDataParts = [];
283013
+ const unsupportedInlineDataParts = [];
283014
+ for (const part2 of inlineDataParts) {
283015
+ const mimeType = part2.inlineData?.mimeType;
283016
+ if (mimeType && (mimeType.startsWith("audio/") || mimeType.startsWith("video/"))) {
283017
+ unsupportedInlineDataParts.push(part2);
283018
+ } else {
283019
+ filteredInlineDataParts.push(part2);
283020
+ }
283021
+ }
283022
+ if (unsupportedInlineDataParts.length > 0) {
283023
+ const uniqueMimes = Array.from(new Set(unsupportedInlineDataParts.map((p2) => p2.inlineData?.mimeType ?? ""))).join(", ");
283024
+ const isReadFileTool2 = toolName === "read_file" || toolName === "read_many_files";
283025
+ if (isReadFileTool2) {
283026
+ textParts.unshift(`Binary content (${uniqueMimes}) read successfully. Content will be injected for analysis in the next sequence.`);
283027
+ } else {
283028
+ textParts.unshift(`[SYSTEM: Binary content (${uniqueMimes}) stripped from response due to protocol limitations.]`);
283029
+ }
283030
+ }
283015
283031
  const part = {
283016
283032
  functionResponse: {
283017
283033
  id: callId,
@@ -283019,17 +283035,25 @@ function convertToFunctionResponse(toolName, callId, llmContent, model, config3)
283019
283035
  response: textParts.length > 0 ? { output: textParts.join("\n") } : {}
283020
283036
  }
283021
283037
  };
283038
+ const isReadFileTool = toolName === "read_file" || toolName === "read_many_files";
283039
+ if (unsupportedInlineDataParts.length > 0 && isReadFileTool) {
283040
+ if (part.functionResponse) {
283041
+ Object.assign(part.functionResponse.response, {
283042
+ [BINARY_INJECTION_KEY]: unsupportedInlineDataParts
283043
+ });
283044
+ }
283045
+ }
283022
283046
  const isMultimodalFRSupported = supportsMultimodalFunctionResponse(model, config3);
283023
283047
  const siblingParts = [...fileDataParts];
283024
- if (inlineDataParts.length > 0) {
283048
+ if (filteredInlineDataParts.length > 0) {
283025
283049
  if (isMultimodalFRSupported) {
283026
- part.functionResponse.parts = inlineDataParts;
283050
+ Object.assign(part.functionResponse, { parts: filteredInlineDataParts });
283027
283051
  } else {
283028
- siblingParts.push(...inlineDataParts);
283052
+ siblingParts.push(...filteredInlineDataParts);
283029
283053
  }
283030
283054
  }
283031
- if (textParts.length === 0 && (inlineDataParts.length > 0 || fileDataParts.length > 0)) {
283032
- const totalBinaryItems = inlineDataParts.length + fileDataParts.length;
283055
+ if (textParts.length === 0 && (filteredInlineDataParts.length > 0 || fileDataParts.length > 0)) {
283056
+ const totalBinaryItems = filteredInlineDataParts.length + fileDataParts.length;
283033
283057
  part.functionResponse.response = {
283034
283058
  output: `Binary content provided (${totalBinaryItems} item(s)).`
283035
283059
  };
@@ -283047,12 +283071,14 @@ function getCitations(resp) {
283047
283071
  return citation.uri;
283048
283072
  });
283049
283073
  }
283074
+ var BINARY_INJECTION_KEY;
283050
283075
  var init_generateContentResponseUtilities = __esm({
283051
283076
  "packages/core/dist/src/utils/generateContentResponseUtilities.js"() {
283052
283077
  "use strict";
283053
283078
  init_partUtils();
283054
283079
  init_models();
283055
283080
  init_debugLogger();
283081
+ BINARY_INJECTION_KEY = "__binary_injection__";
283056
283082
  }
283057
283083
  });
283058
283084
 
@@ -329482,7 +329508,7 @@ function getVersion() {
329482
329508
  }
329483
329509
  versionPromise = (async () => {
329484
329510
  const pkgJson = await getPackageJson(__dirname4);
329485
- return "0.42.0-nightly.20260504.g37edd1d4d";
329511
+ return "0.42.0-preview.0";
329486
329512
  })();
329487
329513
  return versionPromise;
329488
329514
  }
@@ -331065,7 +331091,8 @@ var init_retry = __esm({
331065
331091
  // Generic protocol error (often SSL-related)
331066
331092
  "UND_ERR_HEADERS_TIMEOUT",
331067
331093
  "UND_ERR_BODY_TIMEOUT",
331068
- "UND_ERR_CONNECT_TIMEOUT"
331094
+ "UND_ERR_CONNECT_TIMEOUT",
331095
+ "ERR_STREAM_PREMATURE_CLOSE"
331069
331096
  ];
331070
331097
  RETRYABLE_SSL_ERROR_PATTERN = /^ERR_SSL_.*BAD_RECORD_MAC/i;
331071
331098
  FETCH_FAILED_MESSAGE = "fetch failed";
@@ -355878,7 +355905,7 @@ ${truncated}`;
355878
355905
  }
355879
355906
  };
355880
355907
  abortSignal.addEventListener("abort", abortHandler, { once: true });
355881
- child.on("exit", (code, signal) => {
355908
+ child.on("close", (code, signal) => {
355882
355909
  handleExit(code, signal);
355883
355910
  });
355884
355911
  return { pid: child.pid, result: result2 };
@@ -363448,7 +363475,29 @@ var init_ask_user = __esm({
363448
363475
  return null;
363449
363476
  }
363450
363477
  createInvocation(params, messageBus, toolName, toolDisplayName) {
363451
- return new AskUserInvocation(params, messageBus, toolName, toolDisplayName);
363478
+ const unescape4 = (str2) => str2.replace(/\\r\\n/g, "\n").replace(/\\n/g, "\n");
363479
+ const normalizedParams = {
363480
+ questions: params.questions.map((q2) => {
363481
+ const normalizedQ = {
363482
+ ...q2,
363483
+ type: q2.type,
363484
+ question: unescape4(q2.question)
363485
+ };
363486
+ if (q2.header)
363487
+ normalizedQ.header = unescape4(q2.header);
363488
+ if (q2.placeholder)
363489
+ normalizedQ.placeholder = unescape4(q2.placeholder);
363490
+ if (q2.options) {
363491
+ normalizedQ.options = q2.options.map((opt) => ({
363492
+ ...opt,
363493
+ label: unescape4(opt.label),
363494
+ description: opt.description?.trim() ? unescape4(opt.description.trim()) : ""
363495
+ }));
363496
+ }
363497
+ return normalizedQ;
363498
+ })
363499
+ };
363500
+ return new AskUserInvocation(normalizedParams, messageBus, toolName, toolDisplayName);
363452
363501
  }
363453
363502
  async validateBuildAndExecute(params, abortSignal) {
363454
363503
  const result2 = await super.validateBuildAndExecute(params, abortSignal);
@@ -364040,6 +364089,7 @@ var init_geminiChat = __esm({
364040
364089
  init_messageInspectors();
364041
364090
  init_historyHardening();
364042
364091
  init_geminiRequest();
364092
+ init_generateContentResponseUtilities();
364043
364093
  init_tokenCalculation();
364044
364094
  init_policyHelpers();
364045
364095
  init_events();
@@ -364144,7 +364194,7 @@ var init_geminiChat = __esm({
364144
364194
  streamDoneResolver = resolve24;
364145
364195
  });
364146
364196
  this.sendPromise = streamDonePromise;
364147
- const userContent = createUserContent(message);
364197
+ let userContent = createUserContent(message);
364148
364198
  const { model } = this.context.config.modelConfigService.getResolvedConfig(modelConfigKey);
364149
364199
  if (!isFunctionResponse(userContent)) {
364150
364200
  const userMessageParts = userContent.parts || [];
@@ -364164,6 +364214,24 @@ var init_geminiChat = __esm({
364164
364214
  displayContent: finalDisplayContent
364165
364215
  });
364166
364216
  }
364217
+ const binaryInjections = this.extractBinaryInjections(userContent.parts);
364218
+ if (binaryInjections) {
364219
+ this.agentHistory.push(userContent);
364220
+ this.agentHistory.push({
364221
+ role: "model",
364222
+ parts: [
364223
+ {
364224
+ text: "Binary content received. Proceeding with analysis.",
364225
+ thought: true,
364226
+ thoughtSignature: SYNTHETIC_THOUGHT_SIGNATURE2
364227
+ }
364228
+ ]
364229
+ });
364230
+ userContent = {
364231
+ role: "user",
364232
+ parts: binaryInjections
364233
+ };
364234
+ }
364167
364235
  this.agentHistory.push(userContent);
364168
364236
  const requestContents = this.getHistory(true);
364169
364237
  const streamWithRetries = async function* () {
@@ -364244,6 +364312,23 @@ var init_geminiChat = __esm({
364244
364312
  };
364245
364313
  return streamWithRetries.call(this);
364246
364314
  }
364315
+ extractBinaryInjections(parts2) {
364316
+ if (!parts2) {
364317
+ return void 0;
364318
+ }
364319
+ const binaryInjections = [];
364320
+ for (const part of parts2) {
364321
+ const response = part.functionResponse?.response;
364322
+ if (response && BINARY_INJECTION_KEY in response) {
364323
+ const binaryParts = response[BINARY_INJECTION_KEY];
364324
+ delete response[BINARY_INJECTION_KEY];
364325
+ if (Array.isArray(binaryParts)) {
364326
+ binaryInjections.push(...binaryParts);
364327
+ }
364328
+ }
364329
+ }
364330
+ return binaryInjections.length > 0 ? binaryInjections : void 0;
364331
+ }
364247
364332
  async makeApiCallAndProcessStream(modelConfigKey, requestContents, prompt_id, abortSignal, role) {
364248
364333
  const scrubbedContents = this.context.config.isContextManagementEnabled() ? scrubHistory([...requestContents]) : [...requestContents];
364249
364334
  const contentsForPreviewModel = this.ensureActiveLoopHasThoughtSignatures(scrubbedContents);
@@ -364391,7 +364476,7 @@ var init_geminiChat = __esm({
364391
364476
  */
364392
364477
  getHistory(curated = false) {
364393
364478
  const history = curated ? extractCuratedHistory2([...this.agentHistory.get()]) : this.agentHistory.get();
364394
- return [...history];
364479
+ return this.context.config.isContextManagementEnabled() ? scrubHistory([...history]) : [...history];
364395
364480
  }
364396
364481
  /**
364397
364482
  * Clears the chat history.
@@ -376436,6 +376521,7 @@ var init_registry = __esm({
376436
376521
  init_storage();
376437
376522
  init_events();
376438
376523
  init_types14();
376524
+ init_types14();
376439
376525
  init_agentLoader();
376440
376526
  init_codebase_investigator();
376441
376527
  init_cli_help_agent();
@@ -376480,12 +376566,45 @@ var init_registry = __esm({
376480
376566
  * Clears the current registry and re-scans for agents.
376481
376567
  */
376482
376568
  async reload() {
376569
+ const previousAgents = new Map(this.agents);
376570
+ const reloadErrors = [];
376483
376571
  this.config.getA2AClientManager()?.clearCache();
376484
376572
  await this.config.reloadAgents();
376485
- this.agents.clear();
376486
- this.allDefinitions.clear();
376487
- await this.loadAgents();
376573
+ await this.loadAgents(reloadErrors);
376574
+ const currentAgents = Array.from(this.agents.values());
376575
+ const newAgents = [];
376576
+ const updatedAgents = [];
376577
+ const deletedAgents = [];
376578
+ let localCount = 0;
376579
+ let remoteCount = 0;
376580
+ for (const agent of currentAgents) {
376581
+ if (agent.kind === "local") {
376582
+ localCount++;
376583
+ } else if (agent.kind === "remote") {
376584
+ remoteCount++;
376585
+ }
376586
+ const prev = previousAgents.get(agent.name);
376587
+ if (!prev) {
376588
+ newAgents.push(agent.name);
376589
+ } else if (agent.metadata?.hash !== prev.metadata?.hash) {
376590
+ updatedAgents.push(agent.name);
376591
+ }
376592
+ }
376593
+ for (const prevName of previousAgents.keys()) {
376594
+ if (!this.agents.has(prevName)) {
376595
+ deletedAgents.push(prevName);
376596
+ }
376597
+ }
376488
376598
  coreEvents.emitAgentsRefreshed();
376599
+ return {
376600
+ totalLoaded: currentAgents.length,
376601
+ localCount,
376602
+ remoteCount,
376603
+ newAgents,
376604
+ updatedAgents,
376605
+ deletedAgents,
376606
+ errors: reloadErrors
376607
+ };
376489
376608
  }
376490
376609
  /**
376491
376610
  * Acknowledges and registers a previously unacknowledged agent.
@@ -376505,7 +376624,7 @@ var init_registry = __esm({
376505
376624
  dispose() {
376506
376625
  coreEvents.off(CoreEvent.ModelChanged, this.onModelChanged);
376507
376626
  }
376508
- async loadAgents() {
376627
+ async loadAgents(errors) {
376509
376628
  this.agents.clear();
376510
376629
  this.allDefinitions.clear();
376511
376630
  this.loadBuiltInAgents();
@@ -376517,14 +376636,19 @@ var init_registry = __esm({
376517
376636
  const userAgents = await loadAgentsFromDirectory(userAgentsDir);
376518
376637
  for (const error2 of userAgents.errors) {
376519
376638
  debugLogger.warn(`[AgentRegistry] Error loading user agent: ${error2.message}`);
376520
- coreEvents.emitFeedback("error", `Agent loading error: ${error2.message}`);
376639
+ const msg = `Agent loading error: ${error2.message}`;
376640
+ errors?.push(msg);
376641
+ coreEvents.emitFeedback("error", msg);
376521
376642
  }
376522
376643
  await Promise.allSettled(userAgents.agents.map(async (agent) => {
376523
376644
  try {
376524
- await this.registerAgent(agent);
376645
+ this.ensureRemoteAgentHash(agent);
376646
+ await this.registerAgent(agent, errors);
376525
376647
  } catch (e3) {
376526
- debugLogger.warn(`[AgentRegistry] Error registering user agent "${agent.name}":`, e3);
376527
- coreEvents.emitFeedback("error", `Error registering user agent "${agent.name}": ${e3 instanceof Error ? e3.message : String(e3)}`);
376648
+ const msg = `Error registering user agent "${agent.name}": ${e3 instanceof Error ? e3.message : String(e3)}`;
376649
+ debugLogger.warn(`[AgentRegistry] ${msg}`, e3);
376650
+ errors?.push(msg);
376651
+ coreEvents.emitFeedback("error", msg);
376528
376652
  }
376529
376653
  }));
376530
376654
  const folderTrustEnabled = this.config.getFolderTrust();
@@ -376533,19 +376657,16 @@ var init_registry = __esm({
376533
376657
  const projectAgentsDir = this.config.storage.getProjectAgentsDir();
376534
376658
  const projectAgents = await loadAgentsFromDirectory(projectAgentsDir);
376535
376659
  for (const error2 of projectAgents.errors) {
376536
- coreEvents.emitFeedback("error", `Agent loading error: ${error2.message}`);
376660
+ const msg = `Agent loading error: ${error2.message}`;
376661
+ errors?.push(msg);
376662
+ coreEvents.emitFeedback("error", msg);
376537
376663
  }
376538
376664
  const ackService = this.config.getAcknowledgedAgentsService();
376539
376665
  const projectRoot = this.config.getProjectRoot();
376540
376666
  const unacknowledgedAgents = [];
376541
376667
  const agentsToRegister = [];
376542
376668
  for (const agent of projectAgents.agents) {
376543
- if (agent.kind === "remote") {
376544
- if (!agent.metadata) {
376545
- agent.metadata = {};
376546
- }
376547
- agent.metadata.hash = agent.agentCardUrl ?? (agent.agentCardJson ? crypto21.createHash("sha256").update(agent.agentCardJson).digest("hex") : void 0);
376548
- }
376669
+ this.ensureRemoteAgentHash(agent);
376549
376670
  if (!agent.metadata?.hash) {
376550
376671
  agentsToRegister.push(agent);
376551
376672
  continue;
@@ -376562,10 +376683,12 @@ var init_registry = __esm({
376562
376683
  }
376563
376684
  await Promise.allSettled(agentsToRegister.map(async (agent) => {
376564
376685
  try {
376565
- await this.registerAgent(agent);
376686
+ await this.registerAgent(agent, errors);
376566
376687
  } catch (e3) {
376567
- debugLogger.warn(`[AgentRegistry] Error registering project agent "${agent.name}":`, e3);
376568
- coreEvents.emitFeedback("error", `Error registering project agent "${agent.name}": ${e3 instanceof Error ? e3.message : String(e3)}`);
376688
+ const msg = `Error registering project agent "${agent.name}": ${e3 instanceof Error ? e3.message : String(e3)}`;
376689
+ debugLogger.warn(`[AgentRegistry] ${msg}`, e3);
376690
+ errors?.push(msg);
376691
+ coreEvents.emitFeedback("error", msg);
376569
376692
  }
376570
376693
  }));
376571
376694
  } else {
@@ -376575,10 +376698,12 @@ var init_registry = __esm({
376575
376698
  if (extension.isActive && extension.agents) {
376576
376699
  await Promise.allSettled(extension.agents.map(async (agent) => {
376577
376700
  try {
376578
- await this.registerAgent(agent);
376701
+ await this.registerAgent(agent, errors);
376579
376702
  } catch (e3) {
376580
- debugLogger.warn(`[AgentRegistry] Error registering extension agent "${agent.name}":`, e3);
376581
- coreEvents.emitFeedback("error", `Error registering extension agent "${agent.name}": ${e3 instanceof Error ? e3.message : String(e3)}`);
376703
+ const msg = `Error registering extension agent "${agent.name}": ${e3 instanceof Error ? e3.message : String(e3)}`;
376704
+ debugLogger.warn(`[AgentRegistry] ${msg}`, e3);
376705
+ errors?.push(msg);
376706
+ coreEvents.emitFeedback("error", msg);
376582
376707
  }
376583
376708
  }));
376584
376709
  }
@@ -376616,11 +376741,11 @@ var init_registry = __esm({
376616
376741
  * it will be overwritten, respecting the precedence established by the
376617
376742
  * initialization order.
376618
376743
  */
376619
- async registerAgent(definition) {
376744
+ async registerAgent(definition, errors) {
376620
376745
  if (definition.kind === "local") {
376621
376746
  this.registerLocalAgent(definition);
376622
376747
  } else if (definition.kind === "remote") {
376623
- await this.registerRemoteAgent(definition);
376748
+ await this.registerRemoteAgent(definition, errors);
376624
376749
  }
376625
376750
  }
376626
376751
  /**
@@ -376686,7 +376811,7 @@ var init_registry = __esm({
376686
376811
  * - Agent card fetch failures (404, 401/403, network errors)
376687
376812
  * - Missing authentication configuration
376688
376813
  */
376689
- async registerRemoteAgent(definition) {
376814
+ async registerRemoteAgent(definition, errors) {
376690
376815
  if (definition.kind !== "remote") {
376691
376816
  return;
376692
376817
  }
@@ -376762,11 +376887,14 @@ ${skillsList}`);
376762
376887
  this.agents.set(definition.name, definition);
376763
376888
  this.addAgentPolicy(definition);
376764
376889
  } catch (e3) {
376890
+ let msg;
376765
376891
  if (e3 instanceof A2AAgentError) {
376766
- coreEvents.emitFeedback("error", `[${definition.name}] ${e3.userMessage}`);
376892
+ msg = `[${definition.name}] ${e3.userMessage}`;
376767
376893
  } else {
376768
- coreEvents.emitFeedback("error", `[${definition.name}] Failed to load remote agent: ${e3 instanceof Error ? e3.message : String(e3)}`);
376894
+ msg = `[${definition.name}] Failed to load remote agent: ${e3 instanceof Error ? e3.message : String(e3)}`;
376769
376895
  }
376896
+ errors?.push(msg);
376897
+ coreEvents.emitFeedback("error", msg);
376770
376898
  debugLogger.warn(`[AgentRegistry] Error loading A2A agent "${definition.name}":`, e3);
376771
376899
  }
376772
376900
  }
@@ -376883,6 +377011,22 @@ ${skillsList}`);
376883
377011
  getDiscoveredDefinition(name3) {
376884
377012
  return this.allDefinitions.get(name3);
376885
377013
  }
377014
+ /**
377015
+ * Ensures that remote agents have a content-based hash for trust verification and change detection.
377016
+ */
377017
+ ensureRemoteAgentHash(agent) {
377018
+ if (agent.kind !== "remote") {
377019
+ return;
377020
+ }
377021
+ if (!agent.metadata) {
377022
+ agent.metadata = {};
377023
+ }
377024
+ if (agent.agentCardUrl) {
377025
+ agent.metadata.hash = agent.agentCardUrl;
377026
+ } else if (agent.agentCardJson) {
377027
+ agent.metadata.hash = crypto21.createHash("sha256").update(agent.agentCardJson).digest("hex");
377028
+ }
377029
+ }
376886
377030
  };
376887
377031
  }
376888
377032
  });
@@ -379485,9 +379629,9 @@ var init_snapshotGenerator = __esm({
379485
379629
  }
379486
379630
  async synthesizeSnapshot(nodes, systemInstruction) {
379487
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.
379488
- Your task is to synthesize these turns into a single, dense, factual snapshot that preserves all critical context, preferences, active tasks, and factual knowledge, but discards conversational filler, pleasantries, and redundant back-and-forth iterations.
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.
379489
379633
 
379490
- Output ONLY the raw factual snapshot, formatted compactly. Do not include markdown wrappers, prefixes like "Here is the snapshot", or conversational elements.`;
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.`;
379491
379635
  let userPromptText = "TRANSCRIPT TO SNAPSHOT:\n\n";
379492
379636
  for (const node of nodes) {
379493
379637
  const payload = node.payload;
@@ -379737,7 +379881,8 @@ var init_profiles = __esm({
379737
379881
  config: {
379738
379882
  budget: {
379739
379883
  retainedTokens: 65e3,
379740
- maxTokens: 15e4
379884
+ maxTokens: 15e4,
379885
+ coalescingThresholdTokens: 5e3
379741
379886
  }
379742
379887
  },
379743
379888
  buildPipelines: (env, config3) => (
@@ -379763,10 +379908,10 @@ var init_profiles = __esm({
379763
379908
  triggers: ["retained_exceeded"],
379764
379909
  processors: [
379765
379910
  createNodeDistillationProcessor("NodeDistillation", env, resolveProcessorOptions(config3, "NodeDistillation", {
379766
- nodeThresholdTokens: 1e3
379911
+ nodeThresholdTokens: 3e3
379767
379912
  })),
379768
379913
  createNodeTruncationProcessor("NodeTruncation", env, resolveProcessorOptions(config3, "NodeTruncation", {
379769
- maxTokensPerNode: 1200
379914
+ maxTokensPerNode: 4e3
379770
379915
  }))
379771
379916
  ]
379772
379917
  },
@@ -379857,6 +380002,10 @@ function getContextManagementConfigSchema(registry2) {
379857
380002
  maxTokens: {
379858
380003
  type: "number",
379859
380004
  description: "The absolute maximum token count allowed before synchronous truncation kicks in."
380005
+ },
380006
+ coalescingThresholdTokens: {
380007
+ type: "number",
380008
+ description: 'Only trigger background consolidation (snapshots) when at least this many tokens have aged out. Prevents "turn-by-turn" utility model churn.'
379860
380009
  }
379861
380010
  }
379862
380011
  },
@@ -381176,12 +381325,16 @@ var init_contextManager = __esm({
381176
381325
  }
381177
381326
  }
381178
381327
  if (agedOutNodes.size > 0) {
381179
- this.env.tokenCalculator.garbageCollectCache(new Set(this.buffer.nodes.map((n2) => n2.id)));
381180
- this.eventBus.emitConsolidationNeeded({
381181
- nodes: this.buffer.nodes,
381182
- targetDeficit: currentTokens - this.sidecar.config.budget.retainedTokens,
381183
- targetNodeIds: agedOutNodes
381184
- });
381328
+ const targetDeficit = currentTokens - this.sidecar.config.budget.retainedTokens;
381329
+ const threshold = this.sidecar.config.budget.coalescingThresholdTokens || 0;
381330
+ if (targetDeficit >= threshold) {
381331
+ this.env.tokenCalculator.garbageCollectCache(new Set(this.buffer.nodes.map((n2) => n2.id)));
381332
+ this.eventBus.emitConsolidationNeeded({
381333
+ nodes: this.buffer.nodes,
381334
+ targetDeficit,
381335
+ targetNodeIds: agedOutNodes
381336
+ });
381337
+ }
381185
381338
  }
381186
381339
  }
381187
381340
  }
@@ -383557,6 +383710,18 @@ function getWorkspaceContextOverride() {
383557
383710
  function runWithScopedWorkspaceContext(scopedContext, fn2) {
383558
383711
  return workspaceContextOverride.run(scopedContext, fn2);
383559
383712
  }
383713
+ function hasScopedMemoryInboxAccess() {
383714
+ return memoryInboxAccessOverride.getStore() === true;
383715
+ }
383716
+ function runWithScopedMemoryInboxAccess(fn2) {
383717
+ return memoryInboxAccessOverride.run(true, fn2);
383718
+ }
383719
+ function hasScopedAutoMemoryExtractionWriteAccess() {
383720
+ return autoMemoryExtractionWriteAccessOverride.getStore() === true;
383721
+ }
383722
+ function runWithScopedAutoMemoryExtractionWriteAccess(fn2) {
383723
+ return autoMemoryExtractionWriteAccessOverride.run(true, fn2);
383724
+ }
383560
383725
  function createScopedWorkspaceContext(parentContext, additionalDirectories) {
383561
383726
  if (additionalDirectories.length === 0) {
383562
383727
  return parentContext;
@@ -383575,12 +383740,14 @@ function createScopedWorkspaceContext(parentContext, additionalDirectories) {
383575
383740
  ...additionalDirectories
383576
383741
  ]);
383577
383742
  }
383578
- var workspaceContextOverride;
383743
+ var workspaceContextOverride, memoryInboxAccessOverride, autoMemoryExtractionWriteAccessOverride;
383579
383744
  var init_scoped_config = __esm({
383580
383745
  "packages/core/dist/src/config/scoped-config.js"() {
383581
383746
  "use strict";
383582
383747
  init_workspaceContext();
383583
383748
  workspaceContextOverride = new AsyncLocalStorage3();
383749
+ memoryInboxAccessOverride = new AsyncLocalStorage3();
383750
+ autoMemoryExtractionWriteAccessOverride = new AsyncLocalStorage3();
383584
383751
  }
383585
383752
  });
383586
383753
 
@@ -384182,12 +384349,19 @@ var init_local_executor = __esm({
384182
384349
  * @returns A promise that resolves to the agent's final output.
384183
384350
  */
384184
384351
  async run(inputs, signal) {
384185
- const dirs = this.definition.workspaceDirectories;
384186
- if (dirs && dirs.length > 0) {
384187
- const scopedCtx = createScopedWorkspaceContext(this.context.config.getWorkspaceContext(), dirs);
384188
- return runWithScopedWorkspaceContext(scopedCtx, () => this.runInternal(inputs, signal));
384352
+ const runWithWorkspaceScope = () => {
384353
+ const dirs = this.definition.workspaceDirectories;
384354
+ if (dirs && dirs.length > 0) {
384355
+ const scopedCtx = createScopedWorkspaceContext(this.context.config.getWorkspaceContext(), dirs);
384356
+ return runWithScopedWorkspaceContext(scopedCtx, () => this.runInternal(inputs, signal));
384357
+ }
384358
+ return this.runInternal(inputs, signal);
384359
+ };
384360
+ const runWithInboxScope = () => this.definition.memoryInboxAccess ? runWithScopedMemoryInboxAccess(runWithWorkspaceScope) : runWithWorkspaceScope();
384361
+ if (this.definition.autoMemoryExtractionWriteAccess) {
384362
+ return runWithScopedAutoMemoryExtractionWriteAccess(runWithInboxScope);
384189
384363
  }
384190
- return this.runInternal(inputs, signal);
384364
+ return runWithInboxScope();
384191
384365
  }
384192
384366
  async runInternal(inputs, signal) {
384193
384367
  const startTime = Date.now();
@@ -423993,6 +424167,28 @@ ${sections.join("\n")}
423993
424167
  setIdeMode(value) {
423994
424168
  this.ideMode = value;
423995
424169
  }
424170
+ isScopedMemoryInboxPatchPathAllowed(absolutePath, resolvedPath, inboxRoot) {
424171
+ if (!hasScopedMemoryInboxAccess()) {
424172
+ return false;
424173
+ }
424174
+ const normalizedPath = path86.resolve(absolutePath);
424175
+ const isCanonicalPatchPath = ["private", "global"].some((kind) => normalizedPath === path86.resolve(inboxRoot, kind, "extraction.patch"));
424176
+ if (!isCanonicalPatchPath) {
424177
+ return false;
424178
+ }
424179
+ const resolvedMemoryRoot = resolveToRealPath(this.storage.getProjectMemoryTempDir());
424180
+ return isSubpath(resolvedMemoryRoot, resolvedPath);
424181
+ }
424182
+ isScopedAutoMemoryExtractionWritePathAllowed(absolutePath, resolvedPath) {
424183
+ if (!hasScopedAutoMemoryExtractionWriteAccess()) {
424184
+ return false;
424185
+ }
424186
+ const resolvedSkillsMemoryDir = resolveToRealPath(this.storage.getProjectSkillsMemoryDir());
424187
+ if (isSubpath(resolvedSkillsMemoryDir, resolvedPath)) {
424188
+ return true;
424189
+ }
424190
+ return this.isScopedMemoryInboxPatchPathAllowed(absolutePath, resolvedPath, path86.join(this.storage.getProjectMemoryTempDir(), ".inbox"));
424191
+ }
423996
424192
  /**
423997
424193
  * Get the current FileSystemService
423998
424194
  */
@@ -424006,11 +424202,27 @@ ${sections.join("\n")}
424006
424202
  * file (the latter is the only file under `~/.gemini/` that is reachable —
424007
424203
  * settings, credentials, keybindings, etc. remain disallowed).
424008
424204
  *
424205
+ * One subtree is *carved back out*: `<projectMemoryDir>/.inbox/` is owned by
424206
+ * the auto-memory extraction agent and the `/memory inbox` review flow. The
424207
+ * main agent is denied access to it even though it falls inside the project
424208
+ * temp dir; the extraction agent receives a narrow execution-scoped exception
424209
+ * for `.inbox/{private,global}/extraction.patch`.
424210
+ *
424009
424211
  * @param absolutePath The absolute path to check.
424010
424212
  * @returns true if the path is allowed, false otherwise.
424011
424213
  */
424012
424214
  isPathAllowed(absolutePath) {
424013
424215
  const resolvedPath = resolveToRealPath(absolutePath);
424216
+ const inboxRoot = path86.join(this.storage.getProjectMemoryTempDir(), ".inbox");
424217
+ const resolvedInboxRoot = resolveToRealPath(inboxRoot);
424218
+ const normalizedPath = path86.resolve(absolutePath);
424219
+ const normalizedInboxRoot = path86.resolve(inboxRoot);
424220
+ if (resolvedPath === resolvedInboxRoot || isSubpath(resolvedInboxRoot, resolvedPath) || normalizedPath === normalizedInboxRoot || isSubpath(normalizedInboxRoot, normalizedPath)) {
424221
+ if (this.isScopedMemoryInboxPatchPathAllowed(absolutePath, resolvedPath, inboxRoot)) {
424222
+ return true;
424223
+ }
424224
+ return false;
424225
+ }
424014
424226
  const workspaceContext = this.getWorkspaceContext();
424015
424227
  if (workspaceContext.isPathWithinWorkspace(resolvedPath)) {
424016
424228
  return true;
@@ -424035,6 +424247,13 @@ ${sections.join("\n")}
424035
424247
  * @returns An error message string if the path is disallowed, null otherwise.
424036
424248
  */
424037
424249
  validatePathAccess(absolutePath, checkType = "write") {
424250
+ if (checkType === "write" && hasScopedAutoMemoryExtractionWriteAccess()) {
424251
+ const resolvedPath = resolveToRealPath(absolutePath);
424252
+ if (this.isScopedAutoMemoryExtractionWritePathAllowed(absolutePath, resolvedPath)) {
424253
+ return null;
424254
+ }
424255
+ return `Auto-memory extraction write denied: Attempted path "${absolutePath}" is outside the extraction write allowlist. Extraction may only write extracted skills under ${this.storage.getProjectSkillsMemoryDir()} and canonical inbox patches under ${path86.join(this.storage.getProjectMemoryTempDir(), ".inbox", "{private,global}", "extraction.patch")}.`;
424256
+ }
424038
424257
  if (checkType === "read") {
424039
424258
  if (this.getWorkspaceContext().isPathReadable(absolutePath)) {
424040
424259
  return null;
@@ -425761,7 +425980,7 @@ var init_skill_extraction_agent = __esm({
425761
425980
  init_tool_names();
425762
425981
  init_models();
425763
425982
  SkillExtractionSchema = external_exports.object({
425764
- response: external_exports.string().describe("A summary of the skills extracted or updated.")
425983
+ response: external_exports.string().describe("A summary of the memories or skills extracted or updated.")
425765
425984
  });
425766
425985
  }
425767
425986
  });
@@ -425775,7 +425994,7 @@ var init_sessionScratchpadUtils = __esm({
425775
425994
  });
425776
425995
 
425777
425996
  // packages/core/dist/src/services/memoryService.js
425778
- var LOCK_STALE_MS, MIN_IDLE_MS;
425997
+ var LOCK_STALE_MS, MIN_EXTRACTION_INTERVAL_MS, MIN_IDLE_MS;
425779
425998
  var init_memoryService = __esm({
425780
425999
  "packages/core/dist/src/services/memoryService.js"() {
425781
426000
  "use strict";
@@ -425799,6 +426018,7 @@ var init_memoryService = __esm({
425799
426018
  init_memoryPatchUtils();
425800
426019
  init_sessionScratchpadUtils();
425801
426020
  LOCK_STALE_MS = 35 * 60 * 1e3;
426021
+ MIN_EXTRACTION_INTERVAL_MS = 30 * 60 * 1e3;
425802
426022
  MIN_IDLE_MS = 3 * 60 * 60 * 1e3;
425803
426023
  }
425804
426024
  });
@@ -425885,6 +426105,7 @@ var init_memory2 = __esm({
425885
426105
  init_storage();
425886
426106
  init_memory();
425887
426107
  init_skillLoader();
426108
+ init_memoryTool();
425888
426109
  init_memoryPatchUtils();
425889
426110
  init_memoryService();
425890
426111
  init_memoryDiscovery();
@@ -446529,6 +446750,8 @@ var Task4 = class _Task {
446529
446750
  // For tool waiting logic
446530
446751
  pendingToolCalls = /* @__PURE__ */ new Map();
446531
446752
  //toolCallId --> status
446753
+ pendingOutcomes = /* @__PURE__ */ new Map();
446754
+ // toolCallId --> outcome
446532
446755
  toolsAlreadyConfirmed = /* @__PURE__ */ new Set();
446533
446756
  toolCompletionPromise;
446534
446757
  toolCompletionNotifier;
@@ -446766,7 +446989,7 @@ var Task4 = class _Task {
446766
446989
  this.scheduler.dispose();
446767
446990
  }
446768
446991
  handleEventDrivenToolCallsUpdate(event) {
446769
- if (event.type !== MessageBusType.TOOL_CALLS_UPDATE) {
446992
+ if (event.type !== MessageBusType.TOOL_CALLS_UPDATE || event.schedulerId !== this.id) {
446770
446993
  return;
446771
446994
  }
446772
446995
  const toolCalls = event.toolCalls;
@@ -446778,15 +447001,18 @@ var Task4 = class _Task {
446778
447001
  handleEventDrivenToolCall(tc) {
446779
447002
  const callId = tc.request.callId;
446780
447003
  if (this.processedToolCallIds.has(callId) || this.completedToolCalls.some((c2) => c2.request.callId === callId)) {
446781
- return;
447004
+ return false;
446782
447005
  }
446783
447006
  const previousStatus = this.pendingToolCalls.get(callId);
446784
- const hasChanged = previousStatus !== tc.status;
447007
+ const previousOutcome = this.pendingOutcomes.get(callId);
447008
+ const hasChanged = previousStatus !== tc.status || previousOutcome !== tc.outcome;
447009
+ this.pendingOutcomes.set(callId, tc.outcome);
446785
447010
  if (tc.status === "executing" && tc.liveOutput) {
446786
447011
  this._schedulerOutputUpdate(callId, tc.liveOutput);
446787
447012
  }
446788
447013
  if (tc.status === "success" || tc.status === "error" || tc.status === "cancelled") {
446789
447014
  this.toolsAlreadyConfirmed.delete(callId);
447015
+ this.pendingOutcomes.delete(callId);
446790
447016
  if (hasChanged) {
446791
447017
  logger.info(
446792
447018
  `[Task] Tool call ${callId} completed with status: ${tc.status}`
@@ -446819,6 +447045,7 @@ var Task4 = class _Task {
446819
447045
  );
446820
447046
  this.eventBus?.publish(statusUpdate);
446821
447047
  }
447048
+ return hasChanged;
446822
447049
  }
446823
447050
  checkInputRequiredState() {
446824
447051
  if (this.isYoloMatch) {
@@ -446827,9 +447054,9 @@ var Task4 = class _Task {
446827
447054
  let isAwaitingApproval = false;
446828
447055
  let isExecuting = false;
446829
447056
  for (const [callId, status2] of this.pendingToolCalls.entries()) {
446830
- if (status2 === "executing" || status2 === "scheduled") {
447057
+ if (status2 === CoreToolCallStatus.Executing || status2 === CoreToolCallStatus.Scheduled || status2 === CoreToolCallStatus.Validating || this.toolsAlreadyConfirmed.has(callId)) {
446831
447058
  isExecuting = true;
446832
- } else if (status2 === "awaiting_approval" && !this.toolsAlreadyConfirmed.has(callId)) {
447059
+ } else if (status2 === CoreToolCallStatus.AwaitingApproval) {
446833
447060
  isAwaitingApproval = true;
446834
447061
  }
446835
447062
  }
@@ -446866,8 +447093,12 @@ var Task4 = class _Task {
446866
447093
  "status",
446867
447094
  "confirmationDetails",
446868
447095
  "liveOutput",
446869
- "response"
447096
+ "response",
447097
+ "outcome"
446870
447098
  );
447099
+ if (serializableToolCall.status === CoreToolCallStatus.Validating) {
447100
+ serializableToolCall.status = CoreToolCallStatus.Scheduled;
447101
+ }
446871
447102
  if (tc.tool) {
446872
447103
  const toolFields = this._pickFields(
446873
447104
  tc.tool,