@google/adk 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/dist/cjs/a2a/agent_to_a2a.js +18 -2
  2. package/dist/cjs/a2a/event_converter_utils.js +8 -4
  3. package/dist/cjs/a2a/metadata_converter_utils.js +1 -1
  4. package/dist/cjs/agents/base_agent.js +39 -0
  5. package/dist/cjs/agents/functions.js +6 -21
  6. package/dist/cjs/agents/llm_agent.js +2 -1
  7. package/dist/cjs/agents/loop_agent.js +15 -3
  8. package/dist/cjs/agents/processors/content_processor_utils.js +2 -1
  9. package/dist/cjs/agents/routed_agent.js +31 -0
  10. package/dist/cjs/agents/run_config.js +3 -2
  11. package/dist/cjs/artifacts/in_memory_artifact_service.js +7 -0
  12. package/dist/cjs/common.js +29 -0
  13. package/dist/cjs/context/anchored_context_compactor.js +127 -0
  14. package/dist/cjs/context/compaction_utils.js +52 -0
  15. package/dist/cjs/context/token_based_context_compactor.js +11 -24
  16. package/dist/cjs/events/compacted_event.js +9 -3
  17. package/dist/cjs/events/event.js +28 -0
  18. package/dist/cjs/index.js +4 -0
  19. package/dist/cjs/integrations/agent_registry/agent_registry_mcp_toolset.js +9 -1
  20. package/dist/cjs/plugins/global_instruction_plugin.js +97 -0
  21. package/dist/cjs/runner/runner.js +51 -12
  22. package/dist/cjs/tools/enterprise_web_search_tool.js +81 -0
  23. package/dist/cjs/tools/example_tool.js +68 -0
  24. package/dist/cjs/tools/load_web_page.js +250 -0
  25. package/dist/cjs/tools/mcp/load_mcp_resource_tool.js +140 -0
  26. package/dist/cjs/tools/mcp/mcp_toolset.js +63 -0
  27. package/dist/cjs/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +13 -10
  28. package/dist/cjs/tools/skill/run_skill_inline_script_tool.js +54 -4
  29. package/dist/cjs/tools/skill/skill_toolset.js +4 -2
  30. package/dist/cjs/utils/branch_trie.js +41 -0
  31. package/dist/cjs/utils/streaming_utils.js +5 -5
  32. package/dist/cjs/version.js +1 -1
  33. package/dist/esm/a2a/agent_to_a2a.js +18 -2
  34. package/dist/esm/a2a/event_converter_utils.js +8 -4
  35. package/dist/esm/a2a/metadata_converter_utils.js +1 -1
  36. package/dist/esm/agents/base_agent.js +39 -0
  37. package/dist/esm/agents/functions.js +7 -17
  38. package/dist/esm/agents/llm_agent.js +4 -3
  39. package/dist/esm/agents/loop_agent.js +15 -3
  40. package/dist/esm/agents/processors/content_processor_utils.js +2 -1
  41. package/dist/esm/agents/routed_agent.js +31 -0
  42. package/dist/esm/agents/run_config.js +3 -2
  43. package/dist/esm/artifacts/in_memory_artifact_service.js +7 -0
  44. package/dist/esm/common.js +25 -1
  45. package/dist/esm/context/anchored_context_compactor.js +99 -0
  46. package/dist/esm/context/compaction_utils.js +27 -0
  47. package/dist/esm/context/token_based_context_compactor.js +11 -24
  48. package/dist/esm/events/compacted_event.js +7 -2
  49. package/dist/esm/events/event.js +24 -0
  50. package/dist/esm/index.js +6 -1
  51. package/dist/esm/integrations/agent_registry/agent_registry_mcp_toolset.js +9 -1
  52. package/dist/esm/plugins/global_instruction_plugin.js +69 -0
  53. package/dist/esm/runner/runner.js +51 -12
  54. package/dist/esm/tools/enterprise_web_search_tool.js +55 -0
  55. package/dist/esm/tools/example_tool.js +42 -0
  56. package/dist/esm/tools/load_web_page.js +221 -0
  57. package/dist/esm/tools/mcp/load_mcp_resource_tool.js +114 -0
  58. package/dist/esm/tools/mcp/mcp_toolset.js +63 -0
  59. package/dist/esm/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +13 -10
  60. package/dist/esm/tools/skill/run_skill_inline_script_tool.js +53 -4
  61. package/dist/esm/tools/skill/skill_toolset.js +4 -2
  62. package/dist/esm/utils/branch_trie.js +13 -0
  63. package/dist/esm/utils/streaming_utils.js +1 -1
  64. package/dist/esm/version.js +1 -1
  65. package/dist/types/a2a/a2a_remote_agent.d.ts +5 -1
  66. package/dist/types/a2a/agent_to_a2a.d.ts +38 -0
  67. package/dist/types/agents/base_agent.d.ts +29 -1
  68. package/dist/types/agents/functions.d.ts +1 -9
  69. package/dist/types/agents/llm_agent.d.ts +5 -1
  70. package/dist/types/agents/loop_agent.d.ts +2 -2
  71. package/dist/types/agents/routed_agent.d.ts +24 -1
  72. package/dist/types/agents/run_config.d.ts +1 -1
  73. package/dist/types/common.d.ts +9 -2
  74. package/dist/types/context/anchored_context_compactor.d.ts +35 -0
  75. package/dist/types/context/compaction_utils.d.ts +15 -0
  76. package/dist/types/events/compacted_event.d.ts +10 -0
  77. package/dist/types/events/event.d.ts +13 -0
  78. package/dist/types/index.d.ts +3 -2
  79. package/dist/types/plugins/global_instruction_plugin.d.ts +38 -0
  80. package/dist/types/runner/runner.d.ts +1 -1
  81. package/dist/types/tools/enterprise_web_search_tool.d.ts +26 -0
  82. package/dist/types/tools/example_tool.d.ts +21 -0
  83. package/dist/types/tools/load_web_page.d.ts +33 -0
  84. package/dist/types/tools/mcp/load_mcp_resource_tool.d.ts +26 -0
  85. package/dist/types/tools/mcp/mcp_toolset.d.ts +27 -0
  86. package/dist/types/tools/skill/run_skill_inline_script_tool.d.ts +25 -0
  87. package/dist/types/tools/skill/skill_toolset.d.ts +9 -0
  88. package/dist/types/utils/branch_trie.d.ts +14 -0
  89. package/dist/types/version.d.ts +1 -1
  90. package/dist/web/a2a/agent_to_a2a.js +18 -2
  91. package/dist/web/a2a/event_converter_utils.js +8 -4
  92. package/dist/web/a2a/metadata_converter_utils.js +1 -1
  93. package/dist/web/agents/base_agent.js +39 -0
  94. package/dist/web/agents/functions.js +7 -17
  95. package/dist/web/agents/llm_agent.js +4 -3
  96. package/dist/web/agents/loop_agent.js +27 -3
  97. package/dist/web/agents/processors/content_processor_utils.js +2 -1
  98. package/dist/web/agents/routed_agent.js +31 -0
  99. package/dist/web/agents/run_config.js +8 -3
  100. package/dist/web/artifacts/in_memory_artifact_service.js +7 -0
  101. package/dist/web/common.js +25 -1
  102. package/dist/web/context/anchored_context_compactor.js +117 -0
  103. package/dist/web/context/compaction_utils.js +27 -0
  104. package/dist/web/context/token_based_context_compactor.js +11 -24
  105. package/dist/web/events/compacted_event.js +7 -2
  106. package/dist/web/events/event.js +24 -0
  107. package/dist/web/index.js +6 -1
  108. package/dist/web/integrations/agent_registry/agent_registry_mcp_toolset.js +9 -1
  109. package/dist/web/plugins/global_instruction_plugin.js +67 -0
  110. package/dist/web/runner/runner.js +48 -11
  111. package/dist/web/tools/enterprise_web_search_tool.js +55 -0
  112. package/dist/web/tools/example_tool.js +42 -0
  113. package/dist/web/tools/load_web_page.js +221 -0
  114. package/dist/web/tools/mcp/load_mcp_resource_tool.js +107 -0
  115. package/dist/web/tools/mcp/mcp_toolset.js +63 -0
  116. package/dist/web/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +13 -10
  117. package/dist/web/tools/skill/run_skill_inline_script_tool.js +51 -4
  118. package/dist/web/tools/skill/skill_toolset.js +4 -2
  119. package/dist/web/utils/branch_trie.js +13 -0
  120. package/dist/web/utils/streaming_utils.js +1 -1
  121. package/dist/web/version.js +1 -1
  122. package/package.json +1 -1
@@ -30,7 +30,7 @@ __export(streaming_utils_exports, {
30
30
  module.exports = __toCommonJS(streaming_utils_exports);
31
31
  var import_genai = require("@google/genai");
32
32
  var import_jsonpath_plus = require("jsonpath-plus");
33
- var import_functions = require("../agents/functions.js");
33
+ var import_event = require("../events/event.js");
34
34
  var import_feature_registry = require("../features/feature_registry.js");
35
35
  var import_llm_response = require("../models/llm_response.js");
36
36
  /**
@@ -127,7 +127,7 @@ class ProgressiveStrategy {
127
127
  functionCall: {
128
128
  name: this.currentFcName,
129
129
  args: JSON.parse(JSON.stringify(this.currentFcArgs)),
130
- id: (_a = this.currentFcId) != null ? _a : (0, import_functions.generateClientFunctionCallId)()
130
+ id: (_a = this.currentFcId) != null ? _a : (0, import_event.generateClientFunctionCallId)()
131
131
  }
132
132
  };
133
133
  if (this.currentThoughtSignature) {
@@ -172,7 +172,7 @@ class ProgressiveStrategy {
172
172
  }
173
173
  if (fc.partialArgs || fc.willContinue) {
174
174
  if (!fc.id && !this.currentFcId) {
175
- fc.id = (0, import_functions.generateClientFunctionCallId)();
175
+ fc.id = (0, import_event.generateClientFunctionCallId)();
176
176
  }
177
177
  if (part.thoughtSignature && !this.currentThoughtSignature) {
178
178
  this.currentThoughtSignature = part.thoughtSignature;
@@ -181,7 +181,7 @@ class ProgressiveStrategy {
181
181
  } else {
182
182
  if (fc.name) {
183
183
  if (!fc.id) {
184
- fc.id = (0, import_functions.generateClientFunctionCallId)();
184
+ fc.id = (0, import_event.generateClientFunctionCallId)();
185
185
  }
186
186
  this.flushTextBufferToSequence();
187
187
  this.partsSequence.push(part);
@@ -243,7 +243,7 @@ class NonProgressiveStrategy {
243
243
  continue;
244
244
  }
245
245
  if (part.functionCall && !part.functionCall.id) {
246
- part.functionCall.id = (0, import_functions.generateClientFunctionCallId)();
246
+ part.functionCall.id = (0, import_event.generateClientFunctionCallId)();
247
247
  }
248
248
  nonTextParts.push(part);
249
249
  }
@@ -32,7 +32,7 @@ module.exports = __toCommonJS(version_exports);
32
32
  * Copyright 2025 Google LLC
33
33
  * SPDX-License-Identifier: Apache-2.0
34
34
  */
35
- const version = "1.4.0";
35
+ const version = "1.5.0";
36
36
  // Annotate the CommonJS export names for ESM import in node:
37
37
  0 && (module.exports = {
38
38
  version
@@ -16,10 +16,26 @@ import {
16
16
  import express from "express";
17
17
  import { StreamingMode } from "../agents/run_config.js";
18
18
  import { InMemorySessionService } from "../sessions/in_memory_session_service.js";
19
+ import { logger } from "../utils/logger.js";
19
20
  import { getA2AAgentCard, resolveAgentCard } from "./agent_card.js";
20
21
  import { A2AAgentExecutor } from "./agent_executor.js";
22
+ function resolveA2aUserBuilder(options) {
23
+ if (options.authentication) {
24
+ return options.authentication;
25
+ }
26
+ if (options.allowUnauthenticated === true) {
27
+ logger.warn(
28
+ "SECURITY WARNING: Mounting the A2A server WITHOUT authentication because `allowUnauthenticated: true` was set. The agent and all of its tools are exposed to any network-reachable caller, which can invoke them with arbitrary input and read the output. Do NOT use this outside of local, trusted development."
29
+ );
30
+ return UserBuilder.noAuthentication;
31
+ }
32
+ throw new Error(
33
+ "toA2a: refusing to mount the A2A server without authentication. The A2A surface lets any network-reachable caller invoke this agent and its tools with arbitrary input and read the output, so it must be authenticated. Provide `authentication` (a UserBuilder that validates the request, e.g. a bearer token or OIDC credential) or, only for local/trusted development, explicitly set `allowUnauthenticated: true`."
34
+ );
35
+ }
21
36
  async function toA2a(agent, options = {}) {
22
37
  var _a, _b, _c, _d;
38
+ const userBuilder = resolveA2aUserBuilder(options);
23
39
  const host = (_a = options.host) != null ? _a : "localhost";
24
40
  const port = (_b = options.port) != null ? _b : 8e3;
25
41
  const protocol = (_c = options.protocol) != null ? _c : "http";
@@ -65,14 +81,14 @@ async function toA2a(agent, options = {}) {
65
81
  `${basePath}/rest`,
66
82
  restHandler({
67
83
  requestHandler,
68
- userBuilder: UserBuilder.noAuthentication
84
+ userBuilder
69
85
  })
70
86
  );
71
87
  app.use(
72
88
  `${basePath}/jsonrpc`,
73
89
  jsonRpcHandler({
74
90
  requestHandler,
75
- userBuilder: UserBuilder.noAuthentication
91
+ userBuilder
76
92
  })
77
93
  );
78
94
  return app;
@@ -58,13 +58,14 @@ function toAdkEvent(event, invocationId, agentName) {
58
58
  }
59
59
  return void 0;
60
60
  }
61
- function messageToAdkEvent(msg, invocationId, agentName, parentEvent) {
61
+ function messageToAdkEvent(msg, invocationId, agentName) {
62
62
  const parts = toGenAIParts(msg.parts);
63
+ const content = parts.length === 0 ? void 0 : msg.role === MessageRole.USER ? createUserContent(parts) : createModelContent(parts);
63
64
  return {
64
- ...createAdkEventFromMetadata(parentEvent || msg),
65
+ ...createAdkEventFromMetadata(msg),
65
66
  invocationId,
66
67
  author: msg.role === MessageRole.USER ? MessageRole.USER : agentName,
67
- content: msg.role === MessageRole.USER ? createUserContent(parts) : createModelContent(parts),
68
+ content,
68
69
  turnComplete: true,
69
70
  partial: false
70
71
  };
@@ -110,6 +111,9 @@ function taskStatusUpdateToAdkEvent(a2aEvent, invocationId, agentName) {
110
111
  return void 0;
111
112
  }
112
113
  const parts = toGenAIParts(msg.parts);
114
+ if (parts.length === 0) {
115
+ return void 0;
116
+ }
113
117
  return {
114
118
  ...createAdkEventFromMetadata(a2aEvent),
115
119
  invocationId,
@@ -140,7 +144,7 @@ function taskToAdkEvent(a2aTask, invocationId, agentName) {
140
144
  }
141
145
  const isTerminal = isTerminalTaskStatusUpdateEvent(a2aTask) || isInputRequiredTaskStatusUpdateEvent(a2aTask);
142
146
  const isFailed = isFailedTaskStatusUpdateEvent(a2aTask);
143
- if (parts.length === 0 && !isTerminal) {
147
+ if (parts.length === 0 && !isFailed) {
144
148
  return void 0;
145
149
  }
146
150
  return {
@@ -56,7 +56,7 @@ function getA2AEventMetadata(adkEvent, {
56
56
  [A2AMetadataKeys.INVOCATION_ID]: adkEvent.invocationId,
57
57
  [A2AMetadataKeys.AUTHOR]: adkEvent.author,
58
58
  [A2AMetadataKeys.BRANCH]: adkEvent.branch,
59
- [A2AMetadataKeys.ERROR_CODE]: adkEvent.errorMessage,
59
+ [A2AMetadataKeys.ERROR_CODE]: adkEvent.errorCode,
60
60
  [A2AMetadataKeys.ERROR_MESSAGE]: adkEvent.errorMessage,
61
61
  [A2AMetadataKeys.CITATION_METADATA]: adkEvent.citationMetadata,
62
62
  [A2AMetadataKeys.GROUNDING_METADATA]: adkEvent.groundingMetadata,
@@ -26,6 +26,7 @@ class BaseAgent {
26
26
  * A unique symbol to identify ADK agent classes.
27
27
  */
28
28
  this[_a] = true;
29
+ this.config = { ...config };
29
30
  this.name = validateAgentName(config.name);
30
31
  this.description = config.description;
31
32
  this.parentAgent = config.parentAgent;
@@ -43,6 +44,44 @@ class BaseAgent {
43
44
  get rootAgent() {
44
45
  return getRootAgent(this);
45
46
  }
47
+ /**
48
+ * Creates a copy of this agent with the given config fields overridden.
49
+ *
50
+ * Mirrors adk-python's `BaseAgent.clone(update=...)`. The clone is a detached
51
+ * root: its `parentAgent` is always `undefined`. Sub-agents are recursively
52
+ * cloned (and re-parented to the clone) unless `subAgents` is overridden.
53
+ * Rebuilding via the concrete constructor re-derives all state, so a cloned
54
+ * `LlmAgent` gets a fresh `requestProcessors` array rather than sharing the
55
+ * original's. See google/adk-js#534.
56
+ *
57
+ * @param overrides Config fields to override on the clone. Overriding
58
+ * `parentAgent` is rejected, matching adk-python.
59
+ * @returns A new detached agent instance of the same concrete class.
60
+ */
61
+ clone(overrides) {
62
+ if (overrides && "parentAgent" in overrides) {
63
+ throw new Error(
64
+ "Cannot update `parentAgent` field in clone. Parent agent is set only when the parent agent is instantiated with the sub-agents."
65
+ );
66
+ }
67
+ const merged = { ...this.config, ...overrides };
68
+ merged.parentAgent = void 0;
69
+ const mergedRecord = merged;
70
+ for (const key of Object.keys(mergedRecord)) {
71
+ if (key === "subAgents" || overrides && key in overrides) {
72
+ continue;
73
+ }
74
+ const value = mergedRecord[key];
75
+ if (Array.isArray(value)) {
76
+ mergedRecord[key] = value.slice();
77
+ }
78
+ }
79
+ if (!overrides || !("subAgents" in overrides)) {
80
+ merged.subAgents = this.subAgents.map((subAgent) => subAgent.clone());
81
+ }
82
+ const ctor = this.constructor;
83
+ return new ctor(merged);
84
+ }
46
85
  /**
47
86
  * Entry method to run an agent via text-based conversation.
48
87
  *
@@ -9,11 +9,11 @@ import { createUserContent } from "@google/genai";
9
9
  import { isEmpty } from "lodash-es";
10
10
  import {
11
11
  createEvent,
12
+ generateClientFunctionCallId,
12
13
  getFunctionCalls,
13
14
  getFunctionResponses
14
15
  } from "../events/event.js";
15
16
  import { mergeEventActions } from "../events/event_actions.js";
16
- import { randomUUID } from "../utils/env_aware_utils.js";
17
17
  import { logger } from "../utils/logger.js";
18
18
  import { Context } from "./context.js";
19
19
  import {
@@ -21,7 +21,11 @@ import {
21
21
  tracer,
22
22
  traceToolCall
23
23
  } from "../telemetry/tracing.js";
24
- const AF_FUNCTION_CALL_ID_PREFIX = "adk-";
24
+ import {
25
+ AF_FUNCTION_CALL_ID_PREFIX,
26
+ generateClientFunctionCallId as generateClientFunctionCallId2,
27
+ populateClientFunctionCallId
28
+ } from "../events/event.js";
25
29
  const REQUEST_EUC_FUNCTION_CALL_NAME = "adk_request_credential";
26
30
  const REQUEST_CONFIRMATION_FUNCTION_CALL_NAME = "adk_request_confirmation";
27
31
  const functionsExportedForTestingOnly = {
@@ -29,20 +33,6 @@ const functionsExportedForTestingOnly = {
29
33
  generateAuthEvent,
30
34
  generateRequestConfirmationEvent
31
35
  };
32
- function generateClientFunctionCallId() {
33
- return `${AF_FUNCTION_CALL_ID_PREFIX}${randomUUID()}`;
34
- }
35
- function populateClientFunctionCallId(modelResponseEvent) {
36
- const functionCalls = getFunctionCalls(modelResponseEvent);
37
- if (!functionCalls) {
38
- return;
39
- }
40
- for (const functionCall of functionCalls) {
41
- if (!functionCall.id) {
42
- functionCall.id = generateClientFunctionCallId();
43
- }
44
- }
45
- }
46
36
  function getLongRunningFunctionCalls(functionCalls, toolsDict) {
47
37
  const longRunningToolIds = /* @__PURE__ */ new Set();
48
38
  for (const functionCall of functionCalls) {
@@ -420,7 +410,7 @@ export {
420
410
  findMatchingFunctionCall,
421
411
  functionsExportedForTestingOnly,
422
412
  generateAuthEvent,
423
- generateClientFunctionCallId,
413
+ generateClientFunctionCallId2 as generateClientFunctionCallId,
424
414
  generateRequestConfirmationEvent,
425
415
  getLongRunningFunctionCalls,
426
416
  handleFunctionCallList,
@@ -13,7 +13,8 @@ import {
13
13
  createNewEventId,
14
14
  getFunctionCalls,
15
15
  getFunctionResponses,
16
- isFinalResponse
16
+ isFinalResponse,
17
+ populateClientFunctionCallId
17
18
  } from "../events/event.js";
18
19
  import { isBaseLlm } from "../models/base_llm.js";
19
20
  import { LLMRegistry } from "../models/registry.js";
@@ -31,8 +32,7 @@ import {
31
32
  generateAuthEvent,
32
33
  generateRequestConfirmationEvent,
33
34
  getLongRunningFunctionCalls,
34
- handleFunctionCallsAsync,
35
- populateClientFunctionCallId
35
+ handleFunctionCallsAsync
36
36
  } from "./functions.js";
37
37
  import { AUTH_PREPROCESSOR } from "../auth/auth_preprocessor.js";
38
38
  import { AGENT_TRANSFER_LLM_REQUEST_PROCESSOR } from "./processors/agent_transfer_llm_request_processor.js";
@@ -183,6 +183,7 @@ class LlmAgent extends (_b = BaseAgent, _a = LLM_AGENT_SIGNATURE_SYMBOL, _b) {
183
183
  * This method is only for use by Agent Development Kit.
184
184
  * @param context The context to retrieve the session state.
185
185
  * @returns The resolved globalInstruction field.
186
+ * @deprecated Use GlobalInstructionPlugin instead.
186
187
  */
187
188
  async canonicalGlobalInstruction(context2) {
188
189
  if (typeof this.globalInstruction === "string") {
@@ -44,9 +44,21 @@ class LoopAgent extends (_b = BaseAgent, _a = LOOP_AGENT_SIGNATURE_SYMBOL, _b) {
44
44
  }
45
45
  return;
46
46
  }
47
- // eslint-disable-next-line require-yield
48
- async *runLiveImpl(_context) {
49
- throw new Error("This is not supported yet for LoopAgent.");
47
+ async *runLiveImpl(context) {
48
+ var _a2, _b2;
49
+ for (let iteration = 0; iteration < this.maxIterations; iteration++) {
50
+ for (const subAgent of this.subAgents) {
51
+ for await (const event of subAgent.runLive(context)) {
52
+ if ((_a2 = context.abortSignal) == null ? void 0 : _a2.aborted) {
53
+ return;
54
+ }
55
+ yield event;
56
+ if ((_b2 = event.actions) == null ? void 0 : _b2.escalate) {
57
+ return;
58
+ }
59
+ }
60
+ }
61
+ }
50
62
  }
51
63
  }
52
64
  export {
@@ -15,6 +15,7 @@ import {
15
15
  getFunctionCalls,
16
16
  getFunctionResponses
17
17
  } from "../../events/event.js";
18
+ import { isSegmentPrefix } from "../../utils/branch_trie.js";
18
19
  import {
19
20
  AF_FUNCTION_CALL_ID_PREFIX,
20
21
  REQUEST_CONFIRMATION_FUNCTION_CALL_NAME,
@@ -42,7 +43,7 @@ function getContents(events, agentName, currentBranch) {
42
43
  if (!((_a = event.content) == null ? void 0 : _a.role) || ((_c = (_b = event.content.parts) == null ? void 0 : _b[0]) == null ? void 0 : _c.text) === "") {
43
44
  continue;
44
45
  }
45
- if (currentBranch && event.branch && !currentBranch.startsWith(event.branch)) {
46
+ if (currentBranch && event.branch && !isSegmentPrefix(currentBranch, event.branch)) {
46
47
  continue;
47
48
  }
48
49
  if (isAuthEvent(event)) {
@@ -38,6 +38,29 @@ let RoutedAgent = class extends (_b = BaseAgent, _a = ROUTED_AGENT_SIGNATURE_SYM
38
38
  }
39
39
  this.router = config.router;
40
40
  }
41
+ /**
42
+ * Creates a detached copy of this routed agent.
43
+ *
44
+ * The inherited {@link BaseAgent.clone} only deep-clones `subAgents`, but a
45
+ * `RoutedAgent` derives its routing targets from `config.agents`. Rebuilding
46
+ * through the base clone alone would re-read the already-parented original
47
+ * agents and throw "already has a parent agent". This override deep-clones the
48
+ * routing targets (unless the caller overrides `agents`) so the rebuilt
49
+ * constructor re-parents fresh, detached copies. The array-vs-record shape
50
+ * and, for records, the keys are preserved so the router keeps selecting the
51
+ * same targets.
52
+ *
53
+ * @param overrides Config fields to override on the clone. Overriding
54
+ * `parentAgent` is rejected by the base implementation.
55
+ * @returns A new detached `RoutedAgent` of the same concrete class.
56
+ */
57
+ clone(overrides) {
58
+ const nextOverrides = { ...overrides };
59
+ if (!("agents" in nextOverrides)) {
60
+ nextOverrides.agents = cloneRoutingTargets(this.config.agents);
61
+ }
62
+ return super.clone(nextOverrides);
63
+ }
41
64
  /**
42
65
  * Runs the selected agent via text-based conversation.
43
66
  */
@@ -64,6 +87,14 @@ let RoutedAgent = class extends (_b = BaseAgent, _a = ROUTED_AGENT_SIGNATURE_SYM
64
87
  RoutedAgent = __decorateClass([
65
88
  experimental
66
89
  ], RoutedAgent);
90
+ function cloneRoutingTargets(agents) {
91
+ if (Array.isArray(agents)) {
92
+ return agents.map((agent) => agent.clone());
93
+ }
94
+ return Object.fromEntries(
95
+ Object.entries(agents).map(([key, agent]) => [key, agent.clone()])
96
+ );
97
+ }
67
98
  export {
68
99
  RoutedAgent,
69
100
  isRoutedAgent
@@ -13,14 +13,15 @@ var StreamingMode = /* @__PURE__ */ ((StreamingMode2) => {
13
13
  return StreamingMode2;
14
14
  })(StreamingMode || {});
15
15
  function createRunConfig(params = {}) {
16
+ var _a;
16
17
  return {
17
18
  saveInputBlobsAsArtifacts: false,
18
19
  supportCfc: false,
19
20
  enableAffectiveDialog: false,
20
21
  streamingMode: "none" /* NONE */,
21
- maxLlmCalls: validateMaxLlmCalls(params.maxLlmCalls || 500),
22
22
  pauseOnToolCalls: false,
23
- ...params
23
+ ...params,
24
+ maxLlmCalls: validateMaxLlmCalls((_a = params.maxLlmCalls) != null ? _a : 500)
24
25
  };
25
26
  }
26
27
  function validateMaxLlmCalls(value) {
@@ -5,6 +5,7 @@ const require = topLevelCreateRequire(import.meta.url);
5
5
  * Copyright 2025 Google LLC
6
6
  * SPDX-License-Identifier: Apache-2.0
7
7
  */
8
+ import { logger } from "../utils/logger.js";
8
9
  function isInMemoryConnectionString(uri) {
9
10
  return uri === "memory://";
10
11
  }
@@ -56,6 +57,12 @@ class InMemoryArtifactService {
56
57
  if (version === void 0) {
57
58
  version = versions.length - 1;
58
59
  }
60
+ if (!versions[version]) {
61
+ logger.warn(
62
+ `[InMemoryArtifactService] loadArtifact: Artifact ${filename} version ${version} not found`
63
+ );
64
+ return Promise.resolve(void 0);
65
+ }
59
66
  return Promise.resolve(versions[version].part);
60
67
  }
61
68
  listArtifactKeys({
@@ -56,17 +56,22 @@ import {
56
56
  FileContentEncoding
57
57
  } from "./code_executors/code_execution_utils.js";
58
58
  import { AgentControlledContextCompactor } from "./context/agent_controlled_context_compactor.js";
59
+ import { AnchoredContextCompactor } from "./context/anchored_context_compactor.js";
59
60
  import { LlmSummarizer } from "./context/summarizers/llm_summarizer.js";
60
61
  import { TokenBasedContextCompactor } from "./context/token_based_context_compactor.js";
61
62
  import { TrajectoryThoughtPruningCompactor } from "./context/trajectory_thought_pruning_compactor.js";
62
63
  import { TruncatingContextCompactor } from "./context/truncating_context_compactor.js";
63
- import { isCompactedEvent } from "./events/compacted_event.js";
64
+ import { isCompactedEvent, isScratchpadEvent } from "./events/compacted_event.js";
64
65
  import {
65
66
  createEvent,
67
+ generateClientFunctionCallId,
66
68
  getFunctionCalls,
67
69
  getFunctionResponses,
70
+ hasThoughts,
68
71
  hasTrailingCodeExecutionResult,
69
72
  isFinalResponse,
73
+ populateClientFunctionCallId,
74
+ pruneThoughts,
70
75
  stringifyContent
71
76
  } from "./events/event.js";
72
77
  import { createEventActions } from "./events/event_actions.js";
@@ -83,6 +88,7 @@ import { Gemini, geminiInitParams } from "./models/google_llm.js";
83
88
  import { LLMRegistry } from "./models/registry.js";
84
89
  import { RoutedLlm } from "./models/routed_llm.js";
85
90
  import { BasePlugin, ContextCompactionTrigger } from "./plugins/base_plugin.js";
91
+ import { GlobalInstructionPlugin } from "./plugins/global_instruction_plugin.js";
86
92
  import { LoggingPlugin } from "./plugins/logging_plugin.js";
87
93
  import { PluginManager } from "./plugins/plugin_manager.js";
88
94
  import {
@@ -108,6 +114,11 @@ import { AgentTool, isAgentTool } from "./tools/agent_tool.js";
108
114
  import { BaseTool, isBaseTool } from "./tools/base_tool.js";
109
115
  import { BaseToolset, isBaseToolset } from "./tools/base_toolset.js";
110
116
  import { ConsolidateContextTool } from "./tools/consolidate_context_tool.js";
117
+ import {
118
+ ENTERPRISE_WEB_SEARCH,
119
+ EnterpriseWebSearchTool
120
+ } from "./tools/enterprise_web_search_tool.js";
121
+ import { ExampleTool } from "./tools/example_tool.js";
111
122
  import { EXIT_LOOP, ExitLoopTool } from "./tools/exit_loop_tool.js";
112
123
  import { FunctionTool, isFunctionTool } from "./tools/function_tool.js";
113
124
  import {
@@ -120,6 +131,7 @@ import {
120
131
  LoadArtifactsTool
121
132
  } from "./tools/load_artifacts_tool.js";
122
133
  import { LOAD_MEMORY, LoadMemoryTool } from "./tools/load_memory_tool.js";
134
+ import { LOAD_WEB_PAGE, loadWebPage } from "./tools/load_web_page.js";
123
135
  import { LongRunningFunctionTool } from "./tools/long_running_tool.js";
124
136
  import {
125
137
  PRELOAD_MEMORY,
@@ -174,6 +186,7 @@ export {
174
186
  AgentControlledContextCompactor,
175
187
  AgentTool,
176
188
  AgentTransferLlmRequestProcessor,
189
+ AnchoredContextCompactor,
177
190
  ApigeeLlm,
178
191
  AuthCredentialTypes,
179
192
  AuthHandler,
@@ -199,8 +212,11 @@ export {
199
212
  ContextCompactorRequestProcessor,
200
213
  CredentialExchangeError,
201
214
  CredentialRefresherRegistry,
215
+ ENTERPRISE_WEB_SEARCH,
202
216
  EXIT_LOOP,
217
+ EnterpriseWebSearchTool,
203
218
  EventType,
219
+ ExampleTool,
204
220
  ExitLoopTool,
205
221
  FileContentEncoding,
206
222
  FunctionTool,
@@ -208,6 +224,7 @@ export {
208
224
  GOOGLE_MAPS_GROUNDING,
209
225
  GOOGLE_SEARCH,
210
226
  Gemini,
227
+ GlobalInstructionPlugin,
211
228
  GoogleLLMVariant,
212
229
  GoogleMapsGroundingTool,
213
230
  GoogleSearchTool,
@@ -223,6 +240,7 @@ export {
223
240
  LLMRegistry,
224
241
  LOAD_ARTIFACTS,
225
242
  LOAD_MEMORY,
243
+ LOAD_WEB_PAGE,
226
244
  ListSkillsTool,
227
245
  LiveRequestQueue,
228
246
  LlmAgent2 as LlmAgent,
@@ -281,11 +299,13 @@ export {
281
299
  findMatchingFunctionCall,
282
300
  functionsExportedForTestingOnly,
283
301
  geminiInitParams,
302
+ generateClientFunctionCallId,
284
303
  getAskUserConfirmationFunctionCalls,
285
304
  getClientLabels,
286
305
  getFunctionCalls,
287
306
  getFunctionResponses,
288
307
  getLogger,
308
+ hasThoughts,
289
309
  hasTrailingCodeExecutionResult,
290
310
  isAgentTool,
291
311
  isBaseAgent,
@@ -304,10 +324,14 @@ export {
304
324
  isRoutableLlmAgent,
305
325
  isRoutedAgent,
306
326
  isRunner,
327
+ isScratchpadEvent,
307
328
  isSequentialAgent,
308
329
  loadAllSkillsInDir,
309
330
  loadSkillFromDir,
310
331
  loadSkillFromZipBuffer,
332
+ loadWebPage,
333
+ populateClientFunctionCallId,
334
+ pruneThoughts,
311
335
  runWithClientLabel,
312
336
  setLogLevel,
313
337
  setLogger,
@@ -0,0 +1,99 @@
1
+ import {createRequire as topLevelCreateRequire} from 'module';
2
+ const require = topLevelCreateRequire(import.meta.url);
3
+ /**
4
+ * @license
5
+ * Copyright 2026 Google LLC
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+ import { isScratchpadEvent } from "../events/compacted_event.js";
9
+ import { getEventTokens } from "../events/event.js";
10
+ import { calculateRetainStartIndex } from "./compaction_utils.js";
11
+ class AnchoredContextCompactor {
12
+ constructor(options) {
13
+ this.tokenThreshold = options.tokenThreshold;
14
+ this.eventRetentionSize = options.eventRetentionSize;
15
+ this.summarizer = options.summarizer;
16
+ }
17
+ getActiveEvents(events) {
18
+ let latestScratchpad = void 0;
19
+ for (let i = events.length - 1; i >= 0; i--) {
20
+ const e = events[i];
21
+ if (isScratchpadEvent(e)) {
22
+ latestScratchpad = e;
23
+ break;
24
+ }
25
+ }
26
+ if (!latestScratchpad) {
27
+ return events;
28
+ }
29
+ const activeRawEvents = events.filter(
30
+ (e) => e.timestamp > latestScratchpad.endTime && !isScratchpadEvent(e)
31
+ );
32
+ return [latestScratchpad, ...activeRawEvents];
33
+ }
34
+ shouldCompact(invocationContext) {
35
+ const events = invocationContext.session.events;
36
+ const activeEvents = this.getActiveEvents(events);
37
+ const hasScratchpad = activeEvents.length > 0 && isScratchpadEvent(activeEvents[0]);
38
+ const rawEvents = hasScratchpad ? activeEvents.slice(1) : activeEvents;
39
+ if (rawEvents.length <= this.eventRetentionSize) {
40
+ return false;
41
+ }
42
+ const retainStartIndex = calculateRetainStartIndex(
43
+ rawEvents,
44
+ this.eventRetentionSize
45
+ );
46
+ if (retainStartIndex === 0) {
47
+ return false;
48
+ }
49
+ const totalTokens = activeEvents.reduce(
50
+ (sum, event) => sum + getEventTokens(event),
51
+ 0
52
+ );
53
+ return totalTokens > this.tokenThreshold;
54
+ }
55
+ async compact(invocationContext) {
56
+ const events = invocationContext.session.events;
57
+ const activeEvents = this.getActiveEvents(events);
58
+ const hasScratchpad = activeEvents.length > 0 && isScratchpadEvent(activeEvents[0]);
59
+ const rawEvents = hasScratchpad ? activeEvents.slice(1) : activeEvents;
60
+ if (rawEvents.length <= this.eventRetentionSize) {
61
+ return;
62
+ }
63
+ const retainStartIndex = calculateRetainStartIndex(
64
+ rawEvents,
65
+ this.eventRetentionSize
66
+ );
67
+ if (retainStartIndex === 0) {
68
+ return;
69
+ }
70
+ const rawEventsToCompact = rawEvents.slice(0, retainStartIndex);
71
+ let scratchpadEvent;
72
+ if (hasScratchpad) {
73
+ const existingScratchpad = activeEvents[0];
74
+ scratchpadEvent = await this.summarizer.summarize([
75
+ existingScratchpad,
76
+ ...rawEventsToCompact
77
+ ]);
78
+ } else {
79
+ scratchpadEvent = await this.summarizer.summarize(rawEventsToCompact);
80
+ }
81
+ const updatedScratchpad = {
82
+ ...scratchpadEvent,
83
+ isScratchpad: true,
84
+ author: "system"
85
+ };
86
+ const inactiveEvents = events.slice(0, events.indexOf(activeEvents[0]));
87
+ const retainedRawEvents = rawEvents.slice(retainStartIndex);
88
+ const newEventsList = [
89
+ ...inactiveEvents,
90
+ updatedScratchpad,
91
+ ...retainedRawEvents
92
+ ];
93
+ events.length = 0;
94
+ events.push(...newEventsList);
95
+ }
96
+ }
97
+ export {
98
+ AnchoredContextCompactor
99
+ };
@@ -0,0 +1,27 @@
1
+ import {createRequire as topLevelCreateRequire} from 'module';
2
+ const require = topLevelCreateRequire(import.meta.url);
3
+ /**
4
+ * @license
5
+ * Copyright 2026 Google LLC
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+ import {
9
+ getFunctionCalls,
10
+ getFunctionResponses
11
+ } from "../events/event.js";
12
+ function calculateRetainStartIndex(rawEvents, eventRetentionSize) {
13
+ let retainStartIndex = Math.max(0, rawEvents.length - eventRetentionSize);
14
+ while (retainStartIndex > 0) {
15
+ const eventToRetain = rawEvents[retainStartIndex];
16
+ const previousEvent = rawEvents[retainStartIndex - 1];
17
+ if (getFunctionResponses(eventToRetain).length > 0 && getFunctionCalls(previousEvent).length > 0) {
18
+ retainStartIndex--;
19
+ } else {
20
+ break;
21
+ }
22
+ }
23
+ return retainStartIndex;
24
+ }
25
+ export {
26
+ calculateRetainStartIndex
27
+ };