@google/adk 1.5.0 → 1.6.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 (129) hide show
  1. package/dist/cjs/a2a/a2a_remote_agent.js +12 -2
  2. package/dist/cjs/a2a/agent_to_a2a.js +0 -1
  3. package/dist/cjs/a2a/auth.js +65 -0
  4. package/dist/cjs/a2a/event_converter_utils.js +40 -15
  5. package/dist/cjs/agents/functions.js +20 -7
  6. package/dist/cjs/agents/llm_agent.js +2 -1
  7. package/dist/cjs/agents/processors/basic_llm_request_processor.js +3 -2
  8. package/dist/cjs/agents/processors/content_request_processor.js +2 -21
  9. package/dist/cjs/agents/processors/instructions_llm_request_processor.js +3 -1
  10. package/dist/cjs/artifacts/in_memory_artifact_service.js +10 -9
  11. package/dist/cjs/auth/credential_service/in_memory_credential_service.js +14 -3
  12. package/dist/cjs/code_executors/unsafe_local_code_executor.js +23 -12
  13. package/dist/cjs/common.js +6 -0
  14. package/dist/cjs/context/agent_controlled_context_compactor.js +2 -11
  15. package/dist/cjs/context/compaction_utils.js +14 -2
  16. package/dist/cjs/context/token_based_context_compactor.js +2 -20
  17. package/dist/cjs/index.js +3 -0
  18. package/dist/cjs/memory/in_memory_memory_service.js +13 -2
  19. package/dist/cjs/memory/vertex_ai_memory_bank_service.js +3 -0
  20. package/dist/cjs/plugins/base_plugin.js +4 -2
  21. package/dist/cjs/runner/runner.js +18 -11
  22. package/dist/cjs/sessions/base_session_service.js +8 -3
  23. package/dist/cjs/sessions/in_memory_session_service.js +8 -8
  24. package/dist/cjs/sessions/vertex_ai_session_service.js +22 -10
  25. package/dist/cjs/skills/loader.js +40 -6
  26. package/dist/cjs/tools/get_user_choice_tool.js +53 -0
  27. package/dist/cjs/tools/mcp/mcp_session_manager.js +35 -21
  28. package/dist/cjs/tools/request_input_tool.js +54 -0
  29. package/dist/cjs/utils/crypto_shim.js +43 -0
  30. package/dist/cjs/utils/env_aware_utils.js +15 -13
  31. package/dist/cjs/utils/error_utils.js +120 -0
  32. package/dist/cjs/utils/file_utils.js +5 -2
  33. package/dist/cjs/utils/output_schema_utils.js +43 -0
  34. package/dist/cjs/utils/vertex_ai_utils.js +3 -0
  35. package/dist/cjs/version.js +1 -1
  36. package/dist/esm/a2a/a2a_remote_agent.js +12 -2
  37. package/dist/esm/a2a/agent_to_a2a.js +0 -1
  38. package/dist/esm/a2a/auth.js +37 -0
  39. package/dist/esm/a2a/event_converter_utils.js +40 -15
  40. package/dist/esm/agents/functions.js +20 -7
  41. package/dist/esm/agents/llm_agent.js +2 -1
  42. package/dist/esm/agents/processors/basic_llm_request_processor.js +3 -2
  43. package/dist/esm/agents/processors/content_request_processor.js +2 -21
  44. package/dist/esm/agents/processors/instructions_llm_request_processor.js +3 -1
  45. package/dist/esm/artifacts/in_memory_artifact_service.js +10 -9
  46. package/dist/esm/auth/credential_service/in_memory_credential_service.js +14 -3
  47. package/dist/esm/code_executors/unsafe_local_code_executor.js +22 -11
  48. package/dist/esm/common.js +4 -0
  49. package/dist/esm/context/agent_controlled_context_compactor.js +2 -11
  50. package/dist/esm/context/compaction_utils.js +12 -1
  51. package/dist/esm/context/token_based_context_compactor.js +6 -21
  52. package/dist/esm/index.js +2 -0
  53. package/dist/esm/memory/in_memory_memory_service.js +13 -2
  54. package/dist/esm/memory/vertex_ai_memory_bank_service.js +7 -1
  55. package/dist/esm/plugins/base_plugin.js +4 -2
  56. package/dist/esm/runner/runner.js +18 -11
  57. package/dist/esm/sessions/base_session_service.js +8 -3
  58. package/dist/esm/sessions/in_memory_session_service.js +8 -8
  59. package/dist/esm/sessions/vertex_ai_session_service.js +26 -11
  60. package/dist/esm/skills/loader.js +40 -6
  61. package/dist/esm/tools/get_user_choice_tool.js +25 -0
  62. package/dist/esm/tools/mcp/mcp_session_manager.js +35 -21
  63. package/dist/esm/tools/request_input_tool.js +26 -0
  64. package/dist/esm/utils/crypto_shim.js +15 -0
  65. package/dist/esm/utils/env_aware_utils.js +15 -13
  66. package/dist/esm/utils/error_utils.js +92 -0
  67. package/dist/esm/utils/file_utils.js +5 -2
  68. package/dist/esm/utils/output_schema_utils.js +15 -0
  69. package/dist/esm/utils/vertex_ai_utils.js +2 -0
  70. package/dist/esm/version.js +1 -1
  71. package/dist/types/a2a/auth.d.ts +30 -0
  72. package/dist/types/a2a/event_converter_utils.d.ts +4 -1
  73. package/dist/types/auth/credential_service/in_memory_credential_service.d.ts +11 -0
  74. package/dist/types/code_executors/unsafe_local_code_executor.d.ts +5 -1
  75. package/dist/types/common.d.ts +2 -0
  76. package/dist/types/context/agent_controlled_context_compactor.d.ts +0 -1
  77. package/dist/types/context/compaction_utils.d.ts +8 -0
  78. package/dist/types/context/token_based_context_compactor.d.ts +0 -1
  79. package/dist/types/index.d.ts +2 -1
  80. package/dist/types/memory/in_memory_memory_service.d.ts +11 -0
  81. package/dist/types/plugins/base_plugin.d.ts +4 -2
  82. package/dist/types/sessions/base_session_service.d.ts +8 -0
  83. package/dist/types/sessions/in_memory_session_service.d.ts +9 -0
  84. package/dist/types/sessions/vertex_ai_session_service.d.ts +19 -1
  85. package/dist/types/skills/loader.d.ts +5 -0
  86. package/dist/types/tools/get_user_choice_tool.d.ts +14 -0
  87. package/dist/types/tools/request_input_tool.d.ts +15 -0
  88. package/dist/types/utils/crypto_shim.d.ts +16 -0
  89. package/dist/types/utils/env_aware_utils.d.ts +23 -0
  90. package/dist/types/utils/error_utils.d.ts +18 -0
  91. package/dist/types/utils/output_schema_utils.d.ts +18 -0
  92. package/dist/types/utils/vertex_ai_utils.d.ts +1 -0
  93. package/dist/types/version.d.ts +1 -1
  94. package/dist/web/a2a/a2a_remote_agent.js +12 -2
  95. package/dist/web/a2a/agent_to_a2a.js +0 -1
  96. package/dist/web/a2a/auth.js +37 -0
  97. package/dist/web/a2a/event_converter_utils.js +40 -15
  98. package/dist/web/agents/functions.js +20 -7
  99. package/dist/web/agents/llm_agent.js +2 -1
  100. package/dist/web/agents/processors/basic_llm_request_processor.js +3 -2
  101. package/dist/web/agents/processors/content_request_processor.js +2 -21
  102. package/dist/web/agents/processors/instructions_llm_request_processor.js +3 -1
  103. package/dist/web/artifacts/in_memory_artifact_service.js +10 -9
  104. package/dist/web/auth/credential_service/in_memory_credential_service.js +14 -3
  105. package/dist/web/code_executors/unsafe_local_code_executor.js +22 -11
  106. package/dist/web/common.js +4 -0
  107. package/dist/web/context/agent_controlled_context_compactor.js +2 -11
  108. package/dist/web/context/compaction_utils.js +12 -1
  109. package/dist/web/context/token_based_context_compactor.js +6 -21
  110. package/dist/web/index.js +2 -0
  111. package/dist/web/memory/in_memory_memory_service.js +13 -2
  112. package/dist/web/memory/vertex_ai_memory_bank_service.js +7 -1
  113. package/dist/web/plugins/base_plugin.js +4 -2
  114. package/dist/web/runner/runner.js +17 -11
  115. package/dist/web/sessions/base_session_service.js +8 -3
  116. package/dist/web/sessions/in_memory_session_service.js +8 -8
  117. package/dist/web/sessions/vertex_ai_session_service.js +24 -11
  118. package/dist/web/skills/loader.js +40 -6
  119. package/dist/web/tools/get_user_choice_tool.js +25 -0
  120. package/dist/web/tools/mcp/mcp_session_manager.js +35 -21
  121. package/dist/web/tools/request_input_tool.js +26 -0
  122. package/dist/web/utils/crypto_shim.js +15 -0
  123. package/dist/web/utils/env_aware_utils.js +15 -13
  124. package/dist/web/utils/error_utils.js +92 -0
  125. package/dist/web/utils/file_utils.js +5 -2
  126. package/dist/web/utils/output_schema_utils.js +15 -0
  127. package/dist/web/utils/vertex_ai_utils.js +2 -0
  128. package/dist/web/version.js +1 -1
  129. package/package.json +1 -1
@@ -130,7 +130,12 @@ class RemoteA2AAgent extends import_base_agent.BaseAgent {
130
130
  await callback(context, chunk);
131
131
  }
132
132
  }
133
- const adkEvent = (0, import_event_converter_utils.toAdkEvent)(chunk, context.invocationId, this.name);
133
+ const adkEvent = (0, import_event_converter_utils.toAdkEvent)(
134
+ chunk,
135
+ context.invocationId,
136
+ this.name,
137
+ context.branch
138
+ );
134
139
  if (!adkEvent) {
135
140
  continue;
136
141
  }
@@ -151,7 +156,12 @@ class RemoteA2AAgent extends import_base_agent.BaseAgent {
151
156
  await callback(context, result);
152
157
  }
153
158
  }
154
- const adkEvent = (0, import_event_converter_utils.toAdkEvent)(result, context.invocationId, this.name);
159
+ const adkEvent = (0, import_event_converter_utils.toAdkEvent)(
160
+ result,
161
+ context.invocationId,
162
+ this.name,
163
+ context.branch
164
+ );
155
165
  if (adkEvent) {
156
166
  processor.updateCustomMetadata(adkEvent, result);
157
167
  yield adkEvent;
@@ -102,7 +102,6 @@ async function toA2a(agent, options = {}) {
102
102
  );
103
103
  const app = (_d = options.app) != null ? _d : (0, import_express2.default)();
104
104
  if (!options.app) {
105
- app.use(import_express2.default.urlencoded({ limit: "50mb", extended: true }));
106
105
  app.use(import_express2.default.json({ limit: "50mb" }));
107
106
  }
108
107
  app.use(
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ "use strict";
8
+ var __defProp = Object.defineProperty;
9
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
10
+ var __getOwnPropNames = Object.getOwnPropertyNames;
11
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
12
+ var __export = (target, all) => {
13
+ for (var name in all)
14
+ __defProp(target, name, { get: all[name], enumerable: true });
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") {
18
+ for (let key of __getOwnPropNames(from))
19
+ if (!__hasOwnProp.call(to, key) && key !== except)
20
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
21
+ }
22
+ return to;
23
+ };
24
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
25
+ var auth_exports = {};
26
+ __export(auth_exports, {
27
+ bearerTokenUserBuilder: () => bearerTokenUserBuilder
28
+ });
29
+ module.exports = __toCommonJS(auth_exports);
30
+ var import_node_crypto = require("node:crypto");
31
+ /**
32
+ * @license
33
+ * Copyright 2026 Google LLC
34
+ * SPDX-License-Identifier: Apache-2.0
35
+ */
36
+ const AUTHENTICATED_USER_NAME = "a2a-bearer-token";
37
+ const BEARER_SCHEME_PREFIX = "bearer ";
38
+ function timingSafeEqualStrings(a, b) {
39
+ const left = Buffer.from(a, "utf8");
40
+ const right = Buffer.from(b, "utf8");
41
+ return left.length === right.length && (0, import_node_crypto.timingSafeEqual)(left, right);
42
+ }
43
+ function bearerTokenUserBuilder(token) {
44
+ const expected = token.trim();
45
+ if (!expected) {
46
+ throw new Error(
47
+ "bearerTokenUserBuilder: an empty A2A bearer token is not a valid authenticator. Supply a real shared secret, or configure no token at all to run the A2A surface unauthenticated."
48
+ );
49
+ }
50
+ return async (req) => {
51
+ var _a;
52
+ const header = (_a = req.headers.authorization) != null ? _a : "";
53
+ const credential = header.toLowerCase().startsWith(BEARER_SCHEME_PREFIX) ? header.slice(BEARER_SCHEME_PREFIX.length) : "";
54
+ if (!timingSafeEqualStrings(credential, expected)) {
55
+ throw new Error(
56
+ "A2A request rejected: missing or invalid `Authorization: Bearer` credential."
57
+ );
58
+ }
59
+ return { isAuthenticated: true, userName: AUTHENTICATED_USER_NAME };
60
+ };
61
+ }
62
+ // Annotate the CommonJS export names for ESM import in node:
63
+ 0 && (module.exports = {
64
+ bearerTokenUserBuilder
65
+ });
@@ -54,34 +54,35 @@ function toA2AMessage(event, {
54
54
  metadata: (0, import_metadata_converter_utils.getA2AEventMetadata)(event, { appName, userId, sessionId })
55
55
  };
56
56
  }
57
- function toAdkEvent(event, invocationId, agentName) {
57
+ function toAdkEvent(event, invocationId, agentName, branch) {
58
58
  if ((0, import_a2a_event.isMessage)(event)) {
59
- return messageToAdkEvent(event, invocationId, agentName);
59
+ return messageToAdkEvent(event, invocationId, agentName, branch);
60
60
  }
61
61
  if ((0, import_a2a_event.isTask)(event)) {
62
- return taskToAdkEvent(event, invocationId, agentName);
62
+ return taskToAdkEvent(event, invocationId, agentName, branch);
63
63
  }
64
64
  if ((0, import_a2a_event.isTaskArtifactUpdateEvent)(event)) {
65
- return artifactUpdateToAdkEvent(event, invocationId, agentName);
65
+ return artifactUpdateToAdkEvent(event, invocationId, agentName, branch);
66
66
  }
67
67
  if ((0, import_a2a_event.isTaskStatusUpdateEvent)(event)) {
68
- return event.final ? finalTaskStatusUpdateToAdkEvent(event, invocationId, agentName) : taskStatusUpdateToAdkEvent(event, invocationId, agentName);
68
+ return event.final ? finalTaskStatusUpdateToAdkEvent(event, invocationId, agentName, branch) : taskStatusUpdateToAdkEvent(event, invocationId, agentName, branch);
69
69
  }
70
70
  return void 0;
71
71
  }
72
- function messageToAdkEvent(msg, invocationId, agentName) {
72
+ function messageToAdkEvent(msg, invocationId, agentName, branch) {
73
73
  const parts = (0, import_part_converter_utils.toGenAIParts)(msg.parts);
74
74
  const content = parts.length === 0 ? void 0 : msg.role === import_a2a_event.MessageRole.USER ? (0, import_genai.createUserContent)(parts) : (0, import_genai.createModelContent)(parts);
75
75
  return {
76
76
  ...createAdkEventFromMetadata(msg),
77
77
  invocationId,
78
78
  author: msg.role === import_a2a_event.MessageRole.USER ? import_a2a_event.MessageRole.USER : agentName,
79
+ branch,
79
80
  content,
80
81
  turnComplete: true,
81
82
  partial: false
82
83
  };
83
84
  }
84
- function artifactUpdateToAdkEvent(a2aEvent, invocationId, agentName) {
85
+ function artifactUpdateToAdkEvent(a2aEvent, invocationId, agentName, branch) {
85
86
  var _a;
86
87
  const partsToConvert = ((_a = a2aEvent.artifact) == null ? void 0 : _a.parts) || [];
87
88
  if (partsToConvert.length === 0) {
@@ -92,12 +93,13 @@ function artifactUpdateToAdkEvent(a2aEvent, invocationId, agentName) {
92
93
  ...createAdkEventFromMetadata(a2aEvent),
93
94
  invocationId,
94
95
  author: agentName,
96
+ branch,
95
97
  content: (0, import_genai.createModelContent)((0, import_part_converter_utils.toGenAIParts)(partsToConvert)),
96
98
  longRunningToolIds: getLongRunningToolIDs(partsToConvert),
97
99
  partial
98
100
  };
99
101
  }
100
- function finalTaskStatusUpdateToAdkEvent(a2aEvent, invocationId, agentName) {
102
+ function finalTaskStatusUpdateToAdkEvent(a2aEvent, invocationId, agentName, branch) {
101
103
  var _a;
102
104
  const partsToConvert = ((_a = a2aEvent.status.message) == null ? void 0 : _a.parts) || [];
103
105
  if (partsToConvert.length === 0) {
@@ -110,13 +112,14 @@ function finalTaskStatusUpdateToAdkEvent(a2aEvent, invocationId, agentName) {
110
112
  ...createAdkEventFromMetadata(a2aEvent),
111
113
  invocationId,
112
114
  author: agentName,
115
+ branch,
113
116
  errorMessage: isFailedTask ? (0, import_a2a_event.getFailedTaskStatusUpdateEventError)(a2aEvent) : void 0,
114
117
  content: hasContent ? (0, import_genai.createModelContent)(parts) : void 0,
115
118
  longRunningToolIds: getLongRunningToolIDs(partsToConvert),
116
119
  turnComplete: true
117
120
  };
118
121
  }
119
- function taskStatusUpdateToAdkEvent(a2aEvent, invocationId, agentName) {
122
+ function taskStatusUpdateToAdkEvent(a2aEvent, invocationId, agentName, branch) {
120
123
  const msg = a2aEvent.status.message;
121
124
  if (!msg) {
122
125
  return void 0;
@@ -129,12 +132,13 @@ function taskStatusUpdateToAdkEvent(a2aEvent, invocationId, agentName) {
129
132
  ...createAdkEventFromMetadata(a2aEvent),
130
133
  invocationId,
131
134
  author: agentName,
135
+ branch,
132
136
  content: (0, import_genai.createModelContent)(parts),
133
137
  turnComplete: false,
134
138
  partial: true
135
139
  };
136
140
  }
137
- function taskToAdkEvent(a2aTask, invocationId, agentName) {
141
+ function taskToAdkEvent(a2aTask, invocationId, agentName, branch) {
138
142
  var _a, _b;
139
143
  const parts = [];
140
144
  const longRunningToolIds = [];
@@ -162,16 +166,26 @@ function taskToAdkEvent(a2aTask, invocationId, agentName) {
162
166
  ...createAdkEventFromMetadata(a2aTask),
163
167
  invocationId,
164
168
  author: agentName,
169
+ branch,
165
170
  content: isFailed ? void 0 : (0, import_genai.createModelContent)(parts),
166
171
  errorMessage: isFailed ? (0, import_a2a_event.getFailedTaskStatusUpdateEventError)(a2aTask) : void 0,
167
172
  longRunningToolIds,
168
173
  turnComplete: isTerminal
169
174
  };
170
175
  }
176
+ const PEER_SETTABLE_ACTION_FIELDS = /* @__PURE__ */ new Set(["escalate"]);
171
177
  function createAdkEventFromMetadata(a2aEvent) {
172
178
  const metadata = a2aEvent.metadata || {};
173
179
  return (0, import_event.createEvent)({
174
- branch: metadata[import_metadata_converter_utils.A2AMetadataKeys.BRANCH],
180
+ // `branch` is intentionally NOT restored from peer metadata here (unlike
181
+ // the other fields below): it is the mechanism getContents() (see
182
+ // content_processor_utils.ts) uses to keep sibling sub-agent branches'
183
+ // conversation contexts isolated from each other. A remote A2A peer that
184
+ // controls its own outgoing metadata could otherwise forge `adk_branch`
185
+ // (set it to a shared ancestor branch, or omit it) to leak its content
186
+ // into an unrelated sibling agent's LLM context. Every caller of the
187
+ // `*ToAdkEvent` functions in this file force-sets `branch` from its own
188
+ // local `InvocationContext` instead, the same way `author` is handled.
175
189
  author: metadata[import_metadata_converter_utils.A2AMetadataKeys.AUTHOR],
176
190
  partial: metadata[import_metadata_converter_utils.A2AMetadataKeys.PARTIAL],
177
191
  errorCode: metadata[import_metadata_converter_utils.A2AMetadataKeys.ERROR_CODE],
@@ -180,10 +194,21 @@ function createAdkEventFromMetadata(a2aEvent) {
180
194
  groundingMetadata: metadata[import_metadata_converter_utils.A2AMetadataKeys.GROUNDING_METADATA],
181
195
  usageMetadata: metadata[import_metadata_converter_utils.A2AMetadataKeys.USAGE_METADATA],
182
196
  customMetadata: metadata[import_metadata_converter_utils.A2AMetadataKeys.CUSTOM_METADATA],
183
- actions: (0, import_event_actions.createEventActions)({
184
- escalate: !!metadata[import_metadata_converter_utils.A2AMetadataKeys.ESCALATE],
185
- transferToAgent: metadata[import_metadata_converter_utils.A2AMetadataKeys.TRANSFER_TO_AGENT]
186
- })
197
+ // Only fields in PEER_SETTABLE_ACTION_FIELDS may be restored from
198
+ // metadata a remote A2A peer controls. Every other action field either
199
+ // mutates the caller's own session or drives the caller's own control
200
+ // flow (e.g. `transferToAgent`, see llm_agent.ts), so it must never be
201
+ // rebuilt from peer-supplied data. Filtering through an allowlist here
202
+ // (rather than just omitting the unsafe field) means a future action
203
+ // field is unsafe-by-default: adding it to `candidateActions` alone
204
+ // does nothing until it's also added to the allowlist.
205
+ actions: (0, import_event_actions.createEventActions)(
206
+ Object.fromEntries(
207
+ Object.entries({
208
+ escalate: !!metadata[import_metadata_converter_utils.A2AMetadataKeys.ESCALATE]
209
+ }).filter(([key]) => PEER_SETTABLE_ACTION_FIELDS.has(key))
210
+ )
211
+ )
187
212
  });
188
213
  }
189
214
  function getLongRunningToolIDs(parts) {
@@ -212,6 +212,18 @@ async function handleFunctionCallsAsync({
212
212
  toolConfirmationDict
213
213
  });
214
214
  }
215
+ function normalizeCallbackResponse(response) {
216
+ if (response == null) {
217
+ return void 0;
218
+ }
219
+ if (typeof response !== "object") {
220
+ return { result: response };
221
+ }
222
+ if (Array.isArray(response)) {
223
+ return { results: response };
224
+ }
225
+ return response;
226
+ }
215
227
  async function handleFunctionCallList({
216
228
  invocationContext,
217
229
  functionCalls,
@@ -258,6 +270,7 @@ async function handleFunctionCallList({
258
270
  }
259
271
  }
260
272
  }
273
+ functionResponse = normalizeCallbackResponse(functionResponse);
261
274
  if (functionResponse == null) {
262
275
  try {
263
276
  functionResponse = await callToolAsync(tool, functionArgs, toolContext);
@@ -269,8 +282,8 @@ async function handleFunctionCallList({
269
282
  toolContext,
270
283
  error: e
271
284
  });
272
- if (onToolErrorResponse) {
273
- functionResponse = onToolErrorResponse;
285
+ if (onToolErrorResponse != null) {
286
+ functionResponse = normalizeCallbackResponse(onToolErrorResponse);
274
287
  } else {
275
288
  functionResponseError = e.message;
276
289
  }
@@ -299,17 +312,17 @@ async function handleFunctionCallList({
299
312
  }
300
313
  }
301
314
  if (alteredFunctionResponse != null) {
302
- functionResponse = alteredFunctionResponse;
315
+ functionResponse = normalizeCallbackResponse(alteredFunctionResponse);
303
316
  }
304
- if (tool.isLongRunning && !functionResponse) {
317
+ if (tool.isLongRunning && functionResponse == null) {
305
318
  continue;
306
319
  }
307
320
  if (functionResponseError) {
308
321
  functionResponse = { error: functionResponseError };
309
- } else if (typeof functionResponse !== "object" || functionResponse == null) {
322
+ } else if (functionResponse == null) {
310
323
  functionResponse = { result: functionResponse };
311
- } else if (Array.isArray(functionResponse)) {
312
- functionResponse = { results: functionResponse };
324
+ } else {
325
+ functionResponse = normalizeCallbackResponse(functionResponse);
313
326
  }
314
327
  const functionResponseEvent = (0, import_event.createEvent)({
315
328
  invocationId: invocationContext.invocationId,
@@ -35,6 +35,7 @@ var import_base_llm = require("../models/base_llm.js");
35
35
  var import_registry = require("../models/registry.js");
36
36
  var import_base_tool = require("../tools/base_tool.js");
37
37
  var import_logger = require("../utils/logger.js");
38
+ var import_output_schema_utils = require("../utils/output_schema_utils.js");
38
39
  var import_context = require("./context.js");
39
40
  var import_tracing = require("../telemetry/tracing.js");
40
41
  var import_simple_zod_to_json = require("../utils/simple_zod_to_json.js");
@@ -404,7 +405,7 @@ class LlmAgent extends (_b = import_base_agent.BaseAgent, _a = LLM_AGENT_SIGNATU
404
405
  }
405
406
  }
406
407
  const allTools = [...this.tools];
407
- if (this.outputSchema && allTools.length > 0) {
408
+ if (this.outputSchema && allTools.length > 0 && !(0, import_output_schema_utils.canUseOutputSchemaWithTools)(this.canonicalModel.model)) {
408
409
  const setModelResponseTool = new import_function_tool.FunctionTool({
409
410
  name: "set_model_response",
410
411
  description: "Call this tool to submit your final response conforming to the output schema. Use this tool only when you have collected all the information and are ready to return the final answer.",
@@ -29,6 +29,7 @@ __export(basic_llm_request_processor_exports, {
29
29
  });
30
30
  module.exports = __toCommonJS(basic_llm_request_processor_exports);
31
31
  var import_llm_request = require("../../models/llm_request.js");
32
+ var import_output_schema_utils = require("../../utils/output_schema_utils.js");
32
33
  var import_llm_agent = require("../llm_agent.js");
33
34
  var import_base_llm_processor = require("./base_llm_processor.js");
34
35
  /**
@@ -46,14 +47,14 @@ class BasicLlmRequestProcessor extends import_base_llm_processor.BaseLlmRequestP
46
47
  */
47
48
  // eslint-disable-next-line require-yield
48
49
  async *runAsync(invocationContext, llmRequest) {
49
- var _a;
50
+ var _a, _b;
50
51
  const agent = invocationContext.agent;
51
52
  if (!(0, import_llm_agent.isLlmAgent)(agent)) {
52
53
  return;
53
54
  }
54
55
  llmRequest.model = agent.canonicalModel.model;
55
56
  llmRequest.config = { ...(_a = agent.generateContentConfig) != null ? _a : {} };
56
- if (agent.outputSchema && (!agent.tools || agent.tools.length === 0)) {
57
+ if (agent.outputSchema && (!((_b = agent.tools) == null ? void 0 : _b.length) || (0, import_output_schema_utils.canUseOutputSchemaWithTools)(agent.canonicalModel.model))) {
57
58
  (0, import_llm_request.setOutputSchema)(llmRequest, agent.outputSchema);
58
59
  }
59
60
  if (invocationContext.runConfig) {
@@ -28,7 +28,7 @@ __export(content_request_processor_exports, {
28
28
  ContentRequestProcessor: () => ContentRequestProcessor
29
29
  });
30
30
  module.exports = __toCommonJS(content_request_processor_exports);
31
- var import_compacted_event = require("../../events/compacted_event.js");
31
+ var import_compaction_utils = require("../../context/compaction_utils.js");
32
32
  var import_llm_agent = require("../llm_agent.js");
33
33
  var import_content_processor_utils = require("./content_processor_utils.js");
34
34
  /**
@@ -50,26 +50,7 @@ class ContentRequestProcessor {
50
50
  if (!agent || !(0, import_llm_agent.isLlmAgent)(agent)) {
51
51
  return;
52
52
  }
53
- let events = invocationContext.session.events;
54
- const compactedEvents = events.filter(import_compacted_event.isCompactedEvent);
55
- const latestCompactedEvent = compactedEvents.length > 0 ? compactedEvents.reduce(
56
- (latest, current) => current.endTime > latest.endTime ? current : latest
57
- ) : void 0;
58
- if (latestCompactedEvent) {
59
- const remainingEvents = events.filter((event) => {
60
- if (event === latestCompactedEvent) {
61
- return false;
62
- }
63
- if ((0, import_compacted_event.isCompactedEvent)(event)) {
64
- return false;
65
- }
66
- if (event.timestamp <= latestCompactedEvent.endTime) {
67
- return false;
68
- }
69
- return true;
70
- });
71
- events = [latestCompactedEvent, ...remainingEvents];
72
- }
53
+ const events = (0, import_compaction_utils.getActiveEvents)(invocationContext.session.events);
73
54
  if (agent.includeContents === "default") {
74
55
  llmRequest.contents = (0, import_content_processor_utils.getContents)(
75
56
  events,
@@ -29,6 +29,7 @@ __export(instructions_llm_request_processor_exports, {
29
29
  });
30
30
  module.exports = __toCommonJS(instructions_llm_request_processor_exports);
31
31
  var import_llm_request = require("../../models/llm_request.js");
32
+ var import_output_schema_utils = require("../../utils/output_schema_utils.js");
32
33
  var import_instructions = require("../instructions.js");
33
34
  var import_llm_agent = require("../llm_agent.js");
34
35
  var import_readonly_context = require("../readonly_context.js");
@@ -44,6 +45,7 @@ class InstructionsLlmRequestProcessor extends import_base_llm_processor.BaseLlmR
44
45
  */
45
46
  // eslint-disable-next-line require-yield
46
47
  async *runAsync(invocationContext, llmRequest) {
48
+ var _a;
47
49
  const agent = invocationContext.agent;
48
50
  if (!(0, import_llm_agent.isLlmAgent)(agent)) {
49
51
  return;
@@ -75,7 +77,7 @@ class InstructionsLlmRequestProcessor extends import_base_llm_processor.BaseLlmR
75
77
  }
76
78
  (0, import_llm_request.appendInstructions)(llmRequest, [instructionWithState]);
77
79
  }
78
- if (agent.outputSchema && agent.tools && agent.tools.length > 0) {
80
+ if (agent.outputSchema && ((_a = agent.tools) == null ? void 0 : _a.length) && !(0, import_output_schema_utils.canUseOutputSchemaWithTools)(agent.canonicalModel.model)) {
79
81
  (0, import_llm_request.appendInstructions)(llmRequest, [
80
82
  'To output the final result, you must call the "set_model_response" function with the appropriate values. Do not output anything else.'
81
83
  ]);
@@ -98,16 +98,14 @@ class InMemoryArtifactService {
98
98
  userId,
99
99
  sessionId
100
100
  }) {
101
- const sessionPrefix = `${appName}/${userId}/${sessionId}/`;
102
- const usernamespacePrefix = `${appName}/${userId}/user/`;
101
+ const sessionPrefix = artifactPrefix("session", appName, userId, sessionId);
102
+ const userPrefix = artifactPrefix("user", appName, userId);
103
103
  const filenames = [];
104
104
  for (const path in this.artifacts) {
105
105
  if (path.startsWith(sessionPrefix)) {
106
- const filename = path.replace(sessionPrefix, "");
107
- filenames.push(filename);
108
- } else if (path.startsWith(usernamespacePrefix)) {
109
- const filename = path.replace(usernamespacePrefix, "");
110
- filenames.push(filename);
106
+ filenames.push(decodeURIComponent(path.slice(sessionPrefix.length)));
107
+ } else if (path.startsWith(userPrefix)) {
108
+ filenames.push(decodeURIComponent(path.slice(userPrefix.length)));
111
109
  }
112
110
  }
113
111
  return Promise.resolve(filenames.sort());
@@ -178,9 +176,12 @@ class InMemoryArtifactService {
178
176
  }
179
177
  function artifactPath(appName, userId, sessionId, filename) {
180
178
  if (fileHasUserNamespace(filename)) {
181
- return `${appName}/${userId}/user/${filename}`;
179
+ return `${artifactPrefix("user", appName, userId)}${encodeURIComponent(filename)}`;
182
180
  }
183
- return `${appName}/${userId}/${sessionId}/${filename}`;
181
+ return `${artifactPrefix("session", appName, userId, sessionId)}${encodeURIComponent(filename)}`;
182
+ }
183
+ function artifactPrefix(scope, ...parts) {
184
+ return `${[scope, ...parts].map(encodeURIComponent).join("/")}/`;
184
185
  }
185
186
  function fileHasUserNamespace(filename) {
186
187
  return filename.startsWith("user:");
@@ -34,7 +34,18 @@ module.exports = __toCommonJS(in_memory_credential_service_exports);
34
34
  */
35
35
  class InMemoryCredentialService {
36
36
  constructor() {
37
- this.credentials = {};
37
+ /**
38
+ * A map from app name to a map from user ID to a map from credential key to
39
+ * credential.
40
+ *
41
+ * `appName`, `userId` and `credentialKey` are all attacker-influenced, so
42
+ * every level is created with `Object.create(null)`. On an ordinary `{}`
43
+ * literal a key of `__proto__` resolves to the inherited `__proto__`
44
+ * accessor rather than creating an own property, so nested assignment
45
+ * pollutes every object in the process, and a lookup of an inherited key
46
+ * such as `toString` returns a function instead of `undefined`.
47
+ */
48
+ this.credentials = /* @__PURE__ */ Object.create(null);
38
49
  }
39
50
  loadCredential(authConfig, toolContext) {
40
51
  const credentialBucket = this.getBucketForCurrentContext(toolContext);
@@ -49,10 +60,10 @@ class InMemoryCredentialService {
49
60
  getBucketForCurrentContext(toolContext) {
50
61
  const { appName, userId } = toolContext.invocationContext.session;
51
62
  if (!this.credentials[appName]) {
52
- this.credentials[appName] = {};
63
+ this.credentials[appName] = /* @__PURE__ */ Object.create(null);
53
64
  }
54
65
  if (!this.credentials[appName][userId]) {
55
- this.credentials[appName][userId] = {};
66
+ this.credentials[appName][userId] = /* @__PURE__ */ Object.create(null);
56
67
  }
57
68
  return this.credentials[appName][userId];
58
69
  }
@@ -37,7 +37,7 @@ __export(unsafe_local_code_executor_exports, {
37
37
  UnsafeLocalCodeExecutor: () => UnsafeLocalCodeExecutor
38
38
  });
39
39
  module.exports = __toCommonJS(unsafe_local_code_executor_exports);
40
- var import_child_process = require("child_process");
40
+ var import_node_child_process = require("node:child_process");
41
41
  var fs = __toESM(require("node:fs/promises"), 1);
42
42
  var os = __toESM(require("node:os"), 1);
43
43
  var path = __toESM(require("node:path"), 1);
@@ -52,13 +52,21 @@ var import_code_execution_utils = require("./code_execution_utils.js");
52
52
  * SPDX-License-Identifier: Apache-2.0
53
53
  */
54
54
  const IS_WINDOWS = os.platform() === "win32";
55
+ const POWERSHELL_BASE_ARGS = [
56
+ "-NoLogo",
57
+ "-NoProfile",
58
+ "-ExecutionPolicy",
59
+ "Bypass",
60
+ "-File"
61
+ ];
62
+ const CMD_BASE_ARGS = ["/D", "/c"];
63
+ function isPowerShellCommand(commandPath) {
64
+ return /^(powershell|pwsh)(\.exe)?$/i.test(path.win32.basename(commandPath));
65
+ }
55
66
  async function createTempScriptFile(code, language, shellCommandPath) {
56
- const tempDir = path.join(
57
- os.tmpdir(),
58
- "adk_js_unsafe_code_executor",
59
- Date.now().toString() + "_" + Math.random().toString(36).slice(2)
67
+ const tempDir = await fs.mkdtemp(
68
+ path.join(os.tmpdir(), "adk_js_unsafe_code_executor_")
60
69
  );
61
- await fs.mkdir(tempDir, { recursive: true });
62
70
  const ext = getExtensionForLanguage(language, shellCommandPath) || ".js";
63
71
  const filePath = path.join(tempDir, `script${ext}`);
64
72
  await fs.writeFile(filePath, code);
@@ -78,6 +86,9 @@ function getExtensionForLanguage(language, shellCommandPath) {
78
86
  return ".bat";
79
87
  }
80
88
  if (language === import_code_execution_utils.CodeExecutionLanguage.SHELL) {
89
+ if (shellCommandPath && isPowerShellCommand(shellCommandPath)) {
90
+ return ".ps1";
91
+ }
81
92
  if (IS_WINDOWS) {
82
93
  if (shellCommandPath && shellCommandPath.toLowerCase().includes("cmd")) {
83
94
  return ".bat";
@@ -136,17 +147,17 @@ class UnsafeLocalCodeExecutor extends import_base_code_executor.BaseCodeExecutor
136
147
  command = this.pythonCommandPath;
137
148
  } else if (language === import_code_execution_utils.CodeExecutionLanguage.SHELL) {
138
149
  command = this.shellCommandPath;
139
- if (this.shellCommandPath.toLowerCase().includes("powershell")) {
140
- args = ["-NoLogo", "-ExecutionPolicy", "Bypass", "-File", filePath];
150
+ if (isPowerShellCommand(this.shellCommandPath)) {
151
+ args = [...POWERSHELL_BASE_ARGS, filePath];
141
152
  } else if (this.shellCommandPath.toLowerCase().includes("cmd")) {
142
- args = ["/c", filePath];
153
+ args = [...CMD_BASE_ARGS, filePath];
143
154
  }
144
155
  } else if (language === import_code_execution_utils.CodeExecutionLanguage.POWERSHELL) {
145
156
  command = IS_WINDOWS ? "powershell" : "pwsh";
146
- args = ["-NoLogo", "-ExecutionPolicy", "Bypass", "-File", filePath];
157
+ args = [...POWERSHELL_BASE_ARGS, filePath];
147
158
  } else if (language === import_code_execution_utils.CodeExecutionLanguage.WINDOWS_CMD) {
148
159
  command = "cmd.exe";
149
- args = ["/c", filePath];
160
+ args = [...CMD_BASE_ARGS, filePath];
150
161
  }
151
162
  if (params.codeExecutionInput.args) {
152
163
  if (Array.isArray(params.codeExecutionInput.args)) {
@@ -158,7 +169,7 @@ class UnsafeLocalCodeExecutor extends import_base_code_executor.BaseCodeExecutor
158
169
  }
159
170
  }
160
171
  const executionResult = await new Promise((resolve) => {
161
- const child = (0, import_child_process.spawn)(command, args, {
172
+ const child = (0, import_node_child_process.spawn)(command, args, {
162
173
  timeout: this.timeoutSeconds * 1e3,
163
174
  killSignal: "SIGKILL",
164
175
  cwd: tempDir
@@ -150,6 +150,7 @@ __export(common_exports, {
150
150
  getFunctionCalls: () => import_event.getFunctionCalls,
151
151
  getFunctionResponses: () => import_event.getFunctionResponses,
152
152
  getLogger: () => import_logger.getLogger,
153
+ getUserChoiceTool: () => import_get_user_choice_tool.getUserChoiceTool,
153
154
  hasThoughts: () => import_event.hasThoughts,
154
155
  hasTrailingCodeExecutionResult: () => import_event.hasTrailingCodeExecutionResult,
155
156
  isAgentTool: () => import_agent_tool.isAgentTool,
@@ -177,6 +178,7 @@ __export(common_exports, {
177
178
  loadWebPage: () => import_load_web_page.loadWebPage,
178
179
  populateClientFunctionCallId: () => import_event.populateClientFunctionCallId,
179
180
  pruneThoughts: () => import_event.pruneThoughts,
181
+ requestInputTool: () => import_request_input_tool.requestInputTool,
180
182
  runWithClientLabel: () => import_client_labels.runWithClientLabel,
181
183
  setLogLevel: () => import_logger.setLogLevel,
182
184
  setLogger: () => import_logger.setLogger,
@@ -258,6 +260,7 @@ var import_enterprise_web_search_tool = require("./tools/enterprise_web_search_t
258
260
  var import_example_tool = require("./tools/example_tool.js");
259
261
  var import_exit_loop_tool = require("./tools/exit_loop_tool.js");
260
262
  var import_function_tool = require("./tools/function_tool.js");
263
+ var import_get_user_choice_tool = require("./tools/get_user_choice_tool.js");
261
264
  var import_google_maps_grounding_tool = require("./tools/google_maps_grounding_tool.js");
262
265
  var import_google_search_tool = require("./tools/google_search_tool.js");
263
266
  var import_load_artifacts_tool = require("./tools/load_artifacts_tool.js");
@@ -265,6 +268,7 @@ var import_load_memory_tool = require("./tools/load_memory_tool.js");
265
268
  var import_load_web_page = require("./tools/load_web_page.js");
266
269
  var import_long_running_tool = require("./tools/long_running_tool.js");
267
270
  var import_preload_memory_tool = require("./tools/preload_memory_tool.js");
271
+ var import_request_input_tool = require("./tools/request_input_tool.js");
268
272
  var import_tool_confirmation = require("./tools/tool_confirmation.js");
269
273
  var import_url_context_tool = require("./tools/url_context_tool.js");
270
274
  var import_vertex_ai_search_tool = require("./tools/vertex_ai_search_tool.js");
@@ -431,6 +435,7 @@ __reExport(common_exports, require("./tools/base_tool.js"), module.exports);
431
435
  getFunctionCalls,
432
436
  getFunctionResponses,
433
437
  getLogger,
438
+ getUserChoiceTool,
434
439
  hasThoughts,
435
440
  hasTrailingCodeExecutionResult,
436
441
  isAgentTool,
@@ -458,6 +463,7 @@ __reExport(common_exports, require("./tools/base_tool.js"), module.exports);
458
463
  loadWebPage,
459
464
  populateClientFunctionCallId,
460
465
  pruneThoughts,
466
+ requestInputTool,
461
467
  runWithClientLabel,
462
468
  setLogLevel,
463
469
  setLogger,
@@ -27,9 +27,9 @@ __export(agent_controlled_context_compactor_exports, {
27
27
  AgentControlledContextCompactor: () => AgentControlledContextCompactor
28
28
  });
29
29
  module.exports = __toCommonJS(agent_controlled_context_compactor_exports);
30
- var import_compacted_event = require("../events/compacted_event.js");
31
30
  var import_event = require("../events/event.js");
32
31
  var import_base_plugin = require("../plugins/base_plugin.js");
32
+ var import_compaction_utils = require("./compaction_utils.js");
33
33
  /**
34
34
  * @license
35
35
  * Copyright 2026 Google LLC
@@ -45,7 +45,7 @@ class AgentControlledContextCompactor {
45
45
  }
46
46
  async compact(invocationContext) {
47
47
  const events = invocationContext.session.events;
48
- const activeEvents = this.getActiveEvents(events);
48
+ const activeEvents = (0, import_compaction_utils.getActiveEvents)(events);
49
49
  const consolidateToolCallIndex = activeEvents.reduce(
50
50
  (acc, e, idx) => {
51
51
  var _a, _b;
@@ -93,15 +93,6 @@ class AgentControlledContextCompactor {
93
93
  delete invocationContext.session.state["temp:consolidate_context"];
94
94
  delete invocationContext.session.state["temp:consolidate_context_detail"];
95
95
  }
96
- getActiveEvents(events) {
97
- const latest = events.filter(import_compacted_event.isCompactedEvent).pop();
98
- return latest ? [
99
- latest,
100
- ...events.filter(
101
- (e) => !(0, import_compacted_event.isCompactedEvent)(e) && e.timestamp > latest.endTime
102
- )
103
- ] : events;
104
- }
105
96
  }
106
97
  // Annotate the CommonJS export names for ESM import in node:
107
98
  0 && (module.exports = {