@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
@@ -32,6 +32,7 @@ __export(env_aware_utils_exports, {
32
32
  randomUUID: () => randomUUID
33
33
  });
34
34
  module.exports = __toCommonJS(env_aware_utils_exports);
35
+ var import_node_crypto = require("node:crypto");
35
36
  /**
36
37
  * @license
37
38
  * Copyright 2025 Google LLC
@@ -40,24 +41,25 @@ module.exports = __toCommonJS(env_aware_utils_exports);
40
41
  function isBrowser() {
41
42
  return typeof window !== "undefined";
42
43
  }
43
- const UUID_MASK = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
44
44
  function randomUUID() {
45
- var _a;
45
+ var _a, _b;
46
46
  if ((_a = globalThis.crypto) == null ? void 0 : _a.randomUUID) {
47
47
  return globalThis.crypto.randomUUID();
48
48
  }
49
- let uuid = "";
50
- for (let i = 0; i < UUID_MASK.length; i++) {
51
- const randomValue = Math.random() * 16 | 0;
52
- if (UUID_MASK[i] === "x") {
53
- uuid += randomValue.toString(16);
54
- } else if (UUID_MASK[i] === "y") {
55
- uuid += (randomValue & 3 | 8).toString(16);
56
- } else {
57
- uuid += UUID_MASK[i];
58
- }
49
+ if ((_b = globalThis.crypto) == null ? void 0 : _b.getRandomValues) {
50
+ const bytes = globalThis.crypto.getRandomValues(new Uint8Array(16));
51
+ bytes[6] = bytes[6] & 15 | 64;
52
+ bytes[8] = bytes[8] & 63 | 128;
53
+ const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0"));
54
+ return [
55
+ hex.slice(0, 4),
56
+ hex.slice(4, 6),
57
+ hex.slice(6, 8),
58
+ hex.slice(8, 10),
59
+ hex.slice(10, 16)
60
+ ].map((group) => group.join("")).join("-");
59
61
  }
60
- return uuid;
62
+ return (0, import_node_crypto.randomUUID)();
61
63
  }
62
64
  function base64Encode(data) {
63
65
  if (isBrowser()) {
@@ -0,0 +1,120 @@
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 error_utils_exports = {};
26
+ __export(error_utils_exports, {
27
+ formatError: () => formatError
28
+ });
29
+ module.exports = __toCommonJS(error_utils_exports);
30
+ /**
31
+ * @license
32
+ * Copyright 2026 Google LLC
33
+ * SPDX-License-Identifier: Apache-2.0
34
+ */
35
+ const MAX_RESPONSE_BODY_LENGTH = 1e3;
36
+ const TRUNCATION_MARKER = "... [truncated]";
37
+ const UNKNOWN_ERROR = "Unknown error";
38
+ const MIN_HTTP_STATUS = 100;
39
+ const MAX_HTTP_STATUS = 599;
40
+ function asRecord(value) {
41
+ return value !== null && typeof value === "object" ? value : void 0;
42
+ }
43
+ function firstString(...values) {
44
+ for (const value of values) {
45
+ if (typeof value === "string") {
46
+ return value;
47
+ }
48
+ }
49
+ return void 0;
50
+ }
51
+ function truncateBody(body) {
52
+ return body.length > MAX_RESPONSE_BODY_LENGTH ? body.slice(0, MAX_RESPONSE_BODY_LENGTH) + TRUNCATION_MARKER : body;
53
+ }
54
+ function baseMessage(err) {
55
+ if (err instanceof Error) {
56
+ return err.message;
57
+ }
58
+ if (typeof err === "string") {
59
+ return err;
60
+ }
61
+ return String(err);
62
+ }
63
+ function extractHttpDetails(err) {
64
+ var _a, _b;
65
+ const record = asRecord(err);
66
+ if (record === void 0) {
67
+ return void 0;
68
+ }
69
+ const response = asRecord(record["response"]);
70
+ const rawStatus = (_b = (_a = record["status"]) != null ? _a : record["code"]) != null ? _b : response == null ? void 0 : response["status"];
71
+ const status = typeof rawStatus === "number" && rawStatus >= MIN_HTTP_STATUS && rawStatus <= MAX_HTTP_STATUS ? rawStatus : void 0;
72
+ const statusText = firstString(
73
+ record["statusText"],
74
+ response == null ? void 0 : response["statusText"]
75
+ );
76
+ const body = firstString(
77
+ response == null ? void 0 : response["data"],
78
+ response == null ? void 0 : response["body"],
79
+ response == null ? void 0 : response["text"]
80
+ );
81
+ if (status === void 0 && body === void 0) {
82
+ return void 0;
83
+ }
84
+ const head = status === void 0 ? "HTTP error" : `HTTP ${status}${statusText === void 0 ? "" : ` ${statusText}`}`;
85
+ return body === void 0 ? head : `${head}: ${truncateBody(body)}`;
86
+ }
87
+ function formatErrorRecursive(err, seen) {
88
+ var _a;
89
+ if (err === null || err === void 0) {
90
+ return UNKNOWN_ERROR;
91
+ }
92
+ if (typeof err === "object") {
93
+ if (seen.has(err)) {
94
+ return baseMessage(err);
95
+ }
96
+ seen.add(err);
97
+ }
98
+ if (err instanceof AggregateError && err.errors.length > 0) {
99
+ return err.errors.map((sub) => formatErrorRecursive(sub, seen)).join(" | ");
100
+ }
101
+ const http = extractHttpDetails(err);
102
+ const base = baseMessage(err);
103
+ const cause = (_a = asRecord(err)) == null ? void 0 : _a["cause"];
104
+ const causeMessage = cause !== void 0 ? formatErrorRecursive(cause, seen) : void 0;
105
+ let message = base.length > 0 ? base : UNKNOWN_ERROR;
106
+ if (http !== void 0) {
107
+ message = `${message} (${http})`;
108
+ }
109
+ if (causeMessage !== void 0 && http === void 0 && !message.includes(causeMessage)) {
110
+ message = `${message}: ${causeMessage}`;
111
+ }
112
+ return message;
113
+ }
114
+ function formatError(err) {
115
+ return formatErrorRecursive(err, /* @__PURE__ */ new Set());
116
+ }
117
+ // Annotate the CommonJS export names for ESM import in node:
118
+ 0 && (module.exports = {
119
+ formatError
120
+ });
@@ -46,12 +46,15 @@ var path = __toESM(require("node:path"), 1);
46
46
  * Copyright 2026 Google LLC
47
47
  * SPDX-License-Identifier: Apache-2.0
48
48
  */
49
+ function isInsideDir(resolvedPath, resolvedBaseDir) {
50
+ return resolvedPath === resolvedBaseDir || resolvedPath.startsWith(resolvedBaseDir + path.sep);
51
+ }
49
52
  async function materializeFiles(files, dir = process.cwd()) {
50
53
  const resolvedBaseDir = path.resolve(dir);
51
54
  const createdFiles = [];
52
55
  for (const file of files) {
53
56
  const fullPath = path.resolve(dir, file.name);
54
- if (!fullPath.startsWith(resolvedBaseDir)) {
57
+ if (!isInsideDir(fullPath, resolvedBaseDir)) {
55
58
  throw new Error(
56
59
  `Path traversal detected: ${file.name} resolves outside of ${dir}`
57
60
  );
@@ -73,7 +76,7 @@ async function materializeFiles(files, dir = process.cwd()) {
73
76
  break;
74
77
  }
75
78
  }
76
- if (!finalPath.startsWith(resolvedBaseDir)) {
79
+ if (!isInsideDir(finalPath, resolvedBaseDir)) {
77
80
  throw new Error(
78
81
  `Path traversal detected: ${file.name} resolves outside of ${dir}`
79
82
  );
@@ -0,0 +1,43 @@
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 output_schema_utils_exports = {};
26
+ __export(output_schema_utils_exports, {
27
+ canUseOutputSchemaWithTools: () => canUseOutputSchemaWithTools
28
+ });
29
+ module.exports = __toCommonJS(output_schema_utils_exports);
30
+ var import_model_name = require("./model_name.js");
31
+ var import_variant_utils = require("./variant_utils.js");
32
+ /**
33
+ * @license
34
+ * Copyright 2026 Google LLC
35
+ * SPDX-License-Identifier: Apache-2.0
36
+ */
37
+ function canUseOutputSchemaWithTools(modelString) {
38
+ return (0, import_variant_utils.getGoogleLlmVariant)() === import_variant_utils.GoogleLLMVariant.VERTEX_AI && (0, import_model_name.isGemini2OrAbove)(modelString);
39
+ }
40
+ // Annotate the CommonJS export names for ESM import in node:
41
+ 0 && (module.exports = {
42
+ canUseOutputSchemaWithTools
43
+ });
@@ -24,6 +24,7 @@ var __copyProps = (to, from, except, desc) => {
24
24
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
25
25
  var vertex_ai_utils_exports = {};
26
26
  __export(vertex_ai_utils_exports, {
27
+ EXPRESS_MODE_UNSUPPORTED_MESSAGE: () => EXPRESS_MODE_UNSUPPORTED_MESSAGE,
27
28
  getExpressModeApiKey: () => getExpressModeApiKey
28
29
  });
29
30
  module.exports = __toCommonJS(vertex_ai_utils_exports);
@@ -33,6 +34,7 @@ var import_env_aware_utils = require("./env_aware_utils.js");
33
34
  * Copyright 2026 Google LLC
34
35
  * SPDX-License-Identifier: Apache-2.0
35
36
  */
37
+ const EXPRESS_MODE_UNSUPPORTED_MESSAGE = "Vertex AI Express Mode (expressModeApiKey / GOOGLE_API_KEY) is not supported: the @google-cloud/vertexai Agent Engine client cannot send an API key. Provide projectId and location (with Application Default Credentials), or inject a preconfigured client.";
36
38
  function getExpressModeApiKey(project, location, expressModeApiKey) {
37
39
  if ((project || location) && expressModeApiKey) {
38
40
  throw new Error(
@@ -46,5 +48,6 @@ function getExpressModeApiKey(project, location, expressModeApiKey) {
46
48
  }
47
49
  // Annotate the CommonJS export names for ESM import in node:
48
50
  0 && (module.exports = {
51
+ EXPRESS_MODE_UNSUPPORTED_MESSAGE,
49
52
  getExpressModeApiKey
50
53
  });
@@ -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.5.0";
35
+ const version = "1.6.0";
36
36
  // Annotate the CommonJS export names for ESM import in node:
37
37
  0 && (module.exports = {
38
38
  version
@@ -107,7 +107,12 @@ class RemoteA2AAgent extends BaseAgent {
107
107
  await callback(context, chunk);
108
108
  }
109
109
  }
110
- const adkEvent = toAdkEvent(chunk, context.invocationId, this.name);
110
+ const adkEvent = toAdkEvent(
111
+ chunk,
112
+ context.invocationId,
113
+ this.name,
114
+ context.branch
115
+ );
111
116
  if (!adkEvent) {
112
117
  continue;
113
118
  }
@@ -128,7 +133,12 @@ class RemoteA2AAgent extends BaseAgent {
128
133
  await callback(context, result);
129
134
  }
130
135
  }
131
- const adkEvent = toAdkEvent(result, context.invocationId, this.name);
136
+ const adkEvent = toAdkEvent(
137
+ result,
138
+ context.invocationId,
139
+ this.name,
140
+ context.branch
141
+ );
132
142
  if (adkEvent) {
133
143
  processor.updateCustomMetadata(adkEvent, result);
134
144
  yield adkEvent;
@@ -70,7 +70,6 @@ async function toA2a(agent, options = {}) {
70
70
  );
71
71
  const app = (_d = options.app) != null ? _d : express();
72
72
  if (!options.app) {
73
- app.use(express.urlencoded({ limit: "50mb", extended: true }));
74
73
  app.use(express.json({ limit: "50mb" }));
75
74
  }
76
75
  app.use(
@@ -0,0 +1,37 @@
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 { timingSafeEqual } from "node:crypto";
9
+ const AUTHENTICATED_USER_NAME = "a2a-bearer-token";
10
+ const BEARER_SCHEME_PREFIX = "bearer ";
11
+ function timingSafeEqualStrings(a, b) {
12
+ const left = Buffer.from(a, "utf8");
13
+ const right = Buffer.from(b, "utf8");
14
+ return left.length === right.length && timingSafeEqual(left, right);
15
+ }
16
+ function bearerTokenUserBuilder(token) {
17
+ const expected = token.trim();
18
+ if (!expected) {
19
+ throw new Error(
20
+ "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."
21
+ );
22
+ }
23
+ return async (req) => {
24
+ var _a;
25
+ const header = (_a = req.headers.authorization) != null ? _a : "";
26
+ const credential = header.toLowerCase().startsWith(BEARER_SCHEME_PREFIX) ? header.slice(BEARER_SCHEME_PREFIX.length) : "";
27
+ if (!timingSafeEqualStrings(credential, expected)) {
28
+ throw new Error(
29
+ "A2A request rejected: missing or invalid `Authorization: Bearer` credential."
30
+ );
31
+ }
32
+ return { isAuthenticated: true, userName: AUTHENTICATED_USER_NAME };
33
+ };
34
+ }
35
+ export {
36
+ bearerTokenUserBuilder
37
+ };
@@ -43,34 +43,35 @@ function toA2AMessage(event, {
43
43
  metadata: getA2AEventMetadata(event, { appName, userId, sessionId })
44
44
  };
45
45
  }
46
- function toAdkEvent(event, invocationId, agentName) {
46
+ function toAdkEvent(event, invocationId, agentName, branch) {
47
47
  if (isMessage(event)) {
48
- return messageToAdkEvent(event, invocationId, agentName);
48
+ return messageToAdkEvent(event, invocationId, agentName, branch);
49
49
  }
50
50
  if (isTask(event)) {
51
- return taskToAdkEvent(event, invocationId, agentName);
51
+ return taskToAdkEvent(event, invocationId, agentName, branch);
52
52
  }
53
53
  if (isTaskArtifactUpdateEvent(event)) {
54
- return artifactUpdateToAdkEvent(event, invocationId, agentName);
54
+ return artifactUpdateToAdkEvent(event, invocationId, agentName, branch);
55
55
  }
56
56
  if (isTaskStatusUpdateEvent(event)) {
57
- return event.final ? finalTaskStatusUpdateToAdkEvent(event, invocationId, agentName) : taskStatusUpdateToAdkEvent(event, invocationId, agentName);
57
+ return event.final ? finalTaskStatusUpdateToAdkEvent(event, invocationId, agentName, branch) : taskStatusUpdateToAdkEvent(event, invocationId, agentName, branch);
58
58
  }
59
59
  return void 0;
60
60
  }
61
- function messageToAdkEvent(msg, invocationId, agentName) {
61
+ function messageToAdkEvent(msg, invocationId, agentName, branch) {
62
62
  const parts = toGenAIParts(msg.parts);
63
63
  const content = parts.length === 0 ? void 0 : msg.role === MessageRole.USER ? createUserContent(parts) : createModelContent(parts);
64
64
  return {
65
65
  ...createAdkEventFromMetadata(msg),
66
66
  invocationId,
67
67
  author: msg.role === MessageRole.USER ? MessageRole.USER : agentName,
68
+ branch,
68
69
  content,
69
70
  turnComplete: true,
70
71
  partial: false
71
72
  };
72
73
  }
73
- function artifactUpdateToAdkEvent(a2aEvent, invocationId, agentName) {
74
+ function artifactUpdateToAdkEvent(a2aEvent, invocationId, agentName, branch) {
74
75
  var _a;
75
76
  const partsToConvert = ((_a = a2aEvent.artifact) == null ? void 0 : _a.parts) || [];
76
77
  if (partsToConvert.length === 0) {
@@ -81,12 +82,13 @@ function artifactUpdateToAdkEvent(a2aEvent, invocationId, agentName) {
81
82
  ...createAdkEventFromMetadata(a2aEvent),
82
83
  invocationId,
83
84
  author: agentName,
85
+ branch,
84
86
  content: createModelContent(toGenAIParts(partsToConvert)),
85
87
  longRunningToolIds: getLongRunningToolIDs(partsToConvert),
86
88
  partial
87
89
  };
88
90
  }
89
- function finalTaskStatusUpdateToAdkEvent(a2aEvent, invocationId, agentName) {
91
+ function finalTaskStatusUpdateToAdkEvent(a2aEvent, invocationId, agentName, branch) {
90
92
  var _a;
91
93
  const partsToConvert = ((_a = a2aEvent.status.message) == null ? void 0 : _a.parts) || [];
92
94
  if (partsToConvert.length === 0) {
@@ -99,13 +101,14 @@ function finalTaskStatusUpdateToAdkEvent(a2aEvent, invocationId, agentName) {
99
101
  ...createAdkEventFromMetadata(a2aEvent),
100
102
  invocationId,
101
103
  author: agentName,
104
+ branch,
102
105
  errorMessage: isFailedTask ? getFailedTaskStatusUpdateEventError(a2aEvent) : void 0,
103
106
  content: hasContent ? createModelContent(parts) : void 0,
104
107
  longRunningToolIds: getLongRunningToolIDs(partsToConvert),
105
108
  turnComplete: true
106
109
  };
107
110
  }
108
- function taskStatusUpdateToAdkEvent(a2aEvent, invocationId, agentName) {
111
+ function taskStatusUpdateToAdkEvent(a2aEvent, invocationId, agentName, branch) {
109
112
  const msg = a2aEvent.status.message;
110
113
  if (!msg) {
111
114
  return void 0;
@@ -118,12 +121,13 @@ function taskStatusUpdateToAdkEvent(a2aEvent, invocationId, agentName) {
118
121
  ...createAdkEventFromMetadata(a2aEvent),
119
122
  invocationId,
120
123
  author: agentName,
124
+ branch,
121
125
  content: createModelContent(parts),
122
126
  turnComplete: false,
123
127
  partial: true
124
128
  };
125
129
  }
126
- function taskToAdkEvent(a2aTask, invocationId, agentName) {
130
+ function taskToAdkEvent(a2aTask, invocationId, agentName, branch) {
127
131
  var _a, _b;
128
132
  const parts = [];
129
133
  const longRunningToolIds = [];
@@ -151,16 +155,26 @@ function taskToAdkEvent(a2aTask, invocationId, agentName) {
151
155
  ...createAdkEventFromMetadata(a2aTask),
152
156
  invocationId,
153
157
  author: agentName,
158
+ branch,
154
159
  content: isFailed ? void 0 : createModelContent(parts),
155
160
  errorMessage: isFailed ? getFailedTaskStatusUpdateEventError(a2aTask) : void 0,
156
161
  longRunningToolIds,
157
162
  turnComplete: isTerminal
158
163
  };
159
164
  }
165
+ const PEER_SETTABLE_ACTION_FIELDS = /* @__PURE__ */ new Set(["escalate"]);
160
166
  function createAdkEventFromMetadata(a2aEvent) {
161
167
  const metadata = a2aEvent.metadata || {};
162
168
  return createEvent({
163
- branch: metadata[A2AMetadataKeys.BRANCH],
169
+ // `branch` is intentionally NOT restored from peer metadata here (unlike
170
+ // the other fields below): it is the mechanism getContents() (see
171
+ // content_processor_utils.ts) uses to keep sibling sub-agent branches'
172
+ // conversation contexts isolated from each other. A remote A2A peer that
173
+ // controls its own outgoing metadata could otherwise forge `adk_branch`
174
+ // (set it to a shared ancestor branch, or omit it) to leak its content
175
+ // into an unrelated sibling agent's LLM context. Every caller of the
176
+ // `*ToAdkEvent` functions in this file force-sets `branch` from its own
177
+ // local `InvocationContext` instead, the same way `author` is handled.
164
178
  author: metadata[A2AMetadataKeys.AUTHOR],
165
179
  partial: metadata[A2AMetadataKeys.PARTIAL],
166
180
  errorCode: metadata[A2AMetadataKeys.ERROR_CODE],
@@ -169,10 +183,21 @@ function createAdkEventFromMetadata(a2aEvent) {
169
183
  groundingMetadata: metadata[A2AMetadataKeys.GROUNDING_METADATA],
170
184
  usageMetadata: metadata[A2AMetadataKeys.USAGE_METADATA],
171
185
  customMetadata: metadata[A2AMetadataKeys.CUSTOM_METADATA],
172
- actions: createEventActions({
173
- escalate: !!metadata[A2AMetadataKeys.ESCALATE],
174
- transferToAgent: metadata[A2AMetadataKeys.TRANSFER_TO_AGENT]
175
- })
186
+ // Only fields in PEER_SETTABLE_ACTION_FIELDS may be restored from
187
+ // metadata a remote A2A peer controls. Every other action field either
188
+ // mutates the caller's own session or drives the caller's own control
189
+ // flow (e.g. `transferToAgent`, see llm_agent.ts), so it must never be
190
+ // rebuilt from peer-supplied data. Filtering through an allowlist here
191
+ // (rather than just omitting the unsafe field) means a future action
192
+ // field is unsafe-by-default: adding it to `candidateActions` alone
193
+ // does nothing until it's also added to the allowlist.
194
+ actions: createEventActions(
195
+ Object.fromEntries(
196
+ Object.entries({
197
+ escalate: !!metadata[A2AMetadataKeys.ESCALATE]
198
+ }).filter(([key]) => PEER_SETTABLE_ACTION_FIELDS.has(key))
199
+ )
200
+ )
176
201
  });
177
202
  }
178
203
  function getLongRunningToolIDs(parts) {
@@ -185,6 +185,18 @@ async function handleFunctionCallsAsync({
185
185
  toolConfirmationDict
186
186
  });
187
187
  }
188
+ function normalizeCallbackResponse(response) {
189
+ if (response == null) {
190
+ return void 0;
191
+ }
192
+ if (typeof response !== "object") {
193
+ return { result: response };
194
+ }
195
+ if (Array.isArray(response)) {
196
+ return { results: response };
197
+ }
198
+ return response;
199
+ }
188
200
  async function handleFunctionCallList({
189
201
  invocationContext,
190
202
  functionCalls,
@@ -231,6 +243,7 @@ async function handleFunctionCallList({
231
243
  }
232
244
  }
233
245
  }
246
+ functionResponse = normalizeCallbackResponse(functionResponse);
234
247
  if (functionResponse == null) {
235
248
  try {
236
249
  functionResponse = await callToolAsync(tool, functionArgs, toolContext);
@@ -242,8 +255,8 @@ async function handleFunctionCallList({
242
255
  toolContext,
243
256
  error: e
244
257
  });
245
- if (onToolErrorResponse) {
246
- functionResponse = onToolErrorResponse;
258
+ if (onToolErrorResponse != null) {
259
+ functionResponse = normalizeCallbackResponse(onToolErrorResponse);
247
260
  } else {
248
261
  functionResponseError = e.message;
249
262
  }
@@ -272,17 +285,17 @@ async function handleFunctionCallList({
272
285
  }
273
286
  }
274
287
  if (alteredFunctionResponse != null) {
275
- functionResponse = alteredFunctionResponse;
288
+ functionResponse = normalizeCallbackResponse(alteredFunctionResponse);
276
289
  }
277
- if (tool.isLongRunning && !functionResponse) {
290
+ if (tool.isLongRunning && functionResponse == null) {
278
291
  continue;
279
292
  }
280
293
  if (functionResponseError) {
281
294
  functionResponse = { error: functionResponseError };
282
- } else if (typeof functionResponse !== "object" || functionResponse == null) {
295
+ } else if (functionResponse == null) {
283
296
  functionResponse = { result: functionResponse };
284
- } else if (Array.isArray(functionResponse)) {
285
- functionResponse = { results: functionResponse };
297
+ } else {
298
+ functionResponse = normalizeCallbackResponse(functionResponse);
286
299
  }
287
300
  const functionResponseEvent = createEvent({
288
301
  invocationId: invocationContext.invocationId,
@@ -20,6 +20,7 @@ import { isBaseLlm } from "../models/base_llm.js";
20
20
  import { LLMRegistry } from "../models/registry.js";
21
21
  import { isBaseTool } from "../tools/base_tool.js";
22
22
  import { logger } from "../utils/logger.js";
23
+ import { canUseOutputSchemaWithTools } from "../utils/output_schema_utils.js";
23
24
  import { Context } from "./context.js";
24
25
  import {
25
26
  runAsyncGeneratorWithOtelContext,
@@ -392,7 +393,7 @@ class LlmAgent extends (_b = BaseAgent, _a = LLM_AGENT_SIGNATURE_SYMBOL, _b) {
392
393
  }
393
394
  }
394
395
  const allTools = [...this.tools];
395
- if (this.outputSchema && allTools.length > 0) {
396
+ if (this.outputSchema && allTools.length > 0 && !canUseOutputSchemaWithTools(this.canonicalModel.model)) {
396
397
  const setModelResponseTool = new FunctionTool({
397
398
  name: "set_model_response",
398
399
  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.",
@@ -6,6 +6,7 @@ const require = topLevelCreateRequire(import.meta.url);
6
6
  * SPDX-License-Identifier: Apache-2.0
7
7
  */
8
8
  import { setOutputSchema } from "../../models/llm_request.js";
9
+ import { canUseOutputSchemaWithTools } from "../../utils/output_schema_utils.js";
9
10
  import { isLlmAgent } from "../llm_agent.js";
10
11
  import { BaseLlmRequestProcessor } from "./base_llm_processor.js";
11
12
  class BasicLlmRequestProcessor extends BaseLlmRequestProcessor {
@@ -18,14 +19,14 @@ class BasicLlmRequestProcessor extends BaseLlmRequestProcessor {
18
19
  */
19
20
  // eslint-disable-next-line require-yield
20
21
  async *runAsync(invocationContext, llmRequest) {
21
- var _a;
22
+ var _a, _b;
22
23
  const agent = invocationContext.agent;
23
24
  if (!isLlmAgent(agent)) {
24
25
  return;
25
26
  }
26
27
  llmRequest.model = agent.canonicalModel.model;
27
28
  llmRequest.config = { ...(_a = agent.generateContentConfig) != null ? _a : {} };
28
- if (agent.outputSchema && (!agent.tools || agent.tools.length === 0)) {
29
+ if (agent.outputSchema && (!((_b = agent.tools) == null ? void 0 : _b.length) || canUseOutputSchemaWithTools(agent.canonicalModel.model))) {
29
30
  setOutputSchema(llmRequest, agent.outputSchema);
30
31
  }
31
32
  if (invocationContext.runConfig) {
@@ -5,7 +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 { isCompactedEvent } from "../../events/compacted_event.js";
8
+ import { getActiveEvents } from "../../context/compaction_utils.js";
9
9
  import { isLlmAgent } from "../llm_agent.js";
10
10
  import {
11
11
  getContents,
@@ -25,26 +25,7 @@ class ContentRequestProcessor {
25
25
  if (!agent || !isLlmAgent(agent)) {
26
26
  return;
27
27
  }
28
- let events = invocationContext.session.events;
29
- const compactedEvents = events.filter(isCompactedEvent);
30
- const latestCompactedEvent = compactedEvents.length > 0 ? compactedEvents.reduce(
31
- (latest, current) => current.endTime > latest.endTime ? current : latest
32
- ) : void 0;
33
- if (latestCompactedEvent) {
34
- const remainingEvents = events.filter((event) => {
35
- if (event === latestCompactedEvent) {
36
- return false;
37
- }
38
- if (isCompactedEvent(event)) {
39
- return false;
40
- }
41
- if (event.timestamp <= latestCompactedEvent.endTime) {
42
- return false;
43
- }
44
- return true;
45
- });
46
- events = [latestCompactedEvent, ...remainingEvents];
47
- }
28
+ const events = getActiveEvents(invocationContext.session.events);
48
29
  if (agent.includeContents === "default") {
49
30
  llmRequest.contents = getContents(
50
31
  events,
@@ -6,6 +6,7 @@ const require = topLevelCreateRequire(import.meta.url);
6
6
  * SPDX-License-Identifier: Apache-2.0
7
7
  */
8
8
  import { appendInstructions } from "../../models/llm_request.js";
9
+ import { canUseOutputSchemaWithTools } from "../../utils/output_schema_utils.js";
9
10
  import { injectSessionState } from "../instructions.js";
10
11
  import { isLlmAgent } from "../llm_agent.js";
11
12
  import { ReadonlyContext } from "../readonly_context.js";
@@ -16,6 +17,7 @@ class InstructionsLlmRequestProcessor extends BaseLlmRequestProcessor {
16
17
  */
17
18
  // eslint-disable-next-line require-yield
18
19
  async *runAsync(invocationContext, llmRequest) {
20
+ var _a;
19
21
  const agent = invocationContext.agent;
20
22
  if (!isLlmAgent(agent)) {
21
23
  return;
@@ -47,7 +49,7 @@ class InstructionsLlmRequestProcessor extends BaseLlmRequestProcessor {
47
49
  }
48
50
  appendInstructions(llmRequest, [instructionWithState]);
49
51
  }
50
- if (agent.outputSchema && agent.tools && agent.tools.length > 0) {
52
+ if (agent.outputSchema && ((_a = agent.tools) == null ? void 0 : _a.length) && !canUseOutputSchemaWithTools(agent.canonicalModel.model)) {
51
53
  appendInstructions(llmRequest, [
52
54
  'To output the final result, you must call the "set_model_response" function with the appropriate values. Do not output anything else.'
53
55
  ]);