@google/adk 1.4.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 (213) hide show
  1. package/dist/cjs/a2a/a2a_remote_agent.js +12 -2
  2. package/dist/cjs/a2a/agent_to_a2a.js +18 -3
  3. package/dist/cjs/a2a/auth.js +65 -0
  4. package/dist/cjs/a2a/event_converter_utils.js +47 -18
  5. package/dist/cjs/a2a/metadata_converter_utils.js +1 -1
  6. package/dist/cjs/agents/base_agent.js +39 -0
  7. package/dist/cjs/agents/functions.js +26 -28
  8. package/dist/cjs/agents/llm_agent.js +4 -2
  9. package/dist/cjs/agents/loop_agent.js +15 -3
  10. package/dist/cjs/agents/processors/basic_llm_request_processor.js +3 -2
  11. package/dist/cjs/agents/processors/content_processor_utils.js +2 -1
  12. package/dist/cjs/agents/processors/content_request_processor.js +2 -21
  13. package/dist/cjs/agents/processors/instructions_llm_request_processor.js +3 -1
  14. package/dist/cjs/agents/routed_agent.js +31 -0
  15. package/dist/cjs/agents/run_config.js +3 -2
  16. package/dist/cjs/artifacts/in_memory_artifact_service.js +17 -9
  17. package/dist/cjs/auth/credential_service/in_memory_credential_service.js +14 -3
  18. package/dist/cjs/code_executors/unsafe_local_code_executor.js +23 -12
  19. package/dist/cjs/common.js +35 -0
  20. package/dist/cjs/context/agent_controlled_context_compactor.js +2 -11
  21. package/dist/cjs/context/anchored_context_compactor.js +127 -0
  22. package/dist/cjs/context/compaction_utils.js +64 -0
  23. package/dist/cjs/context/token_based_context_compactor.js +13 -44
  24. package/dist/cjs/events/compacted_event.js +9 -3
  25. package/dist/cjs/events/event.js +28 -0
  26. package/dist/cjs/index.js +7 -0
  27. package/dist/cjs/integrations/agent_registry/agent_registry_mcp_toolset.js +9 -1
  28. package/dist/cjs/memory/in_memory_memory_service.js +13 -2
  29. package/dist/cjs/memory/vertex_ai_memory_bank_service.js +3 -0
  30. package/dist/cjs/plugins/base_plugin.js +4 -2
  31. package/dist/cjs/plugins/global_instruction_plugin.js +97 -0
  32. package/dist/cjs/runner/runner.js +69 -23
  33. package/dist/cjs/sessions/base_session_service.js +8 -3
  34. package/dist/cjs/sessions/in_memory_session_service.js +8 -8
  35. package/dist/cjs/sessions/vertex_ai_session_service.js +22 -10
  36. package/dist/cjs/skills/loader.js +40 -6
  37. package/dist/cjs/tools/enterprise_web_search_tool.js +81 -0
  38. package/dist/cjs/tools/example_tool.js +68 -0
  39. package/dist/cjs/tools/get_user_choice_tool.js +53 -0
  40. package/dist/cjs/tools/load_web_page.js +250 -0
  41. package/dist/cjs/tools/mcp/load_mcp_resource_tool.js +140 -0
  42. package/dist/cjs/tools/mcp/mcp_session_manager.js +35 -21
  43. package/dist/cjs/tools/mcp/mcp_toolset.js +63 -0
  44. package/dist/cjs/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +13 -10
  45. package/dist/cjs/tools/request_input_tool.js +54 -0
  46. package/dist/cjs/tools/skill/run_skill_inline_script_tool.js +54 -4
  47. package/dist/cjs/tools/skill/skill_toolset.js +4 -2
  48. package/dist/cjs/utils/branch_trie.js +41 -0
  49. package/dist/cjs/utils/crypto_shim.js +43 -0
  50. package/dist/cjs/utils/env_aware_utils.js +15 -13
  51. package/dist/cjs/utils/error_utils.js +120 -0
  52. package/dist/cjs/utils/file_utils.js +5 -2
  53. package/dist/cjs/utils/output_schema_utils.js +43 -0
  54. package/dist/cjs/utils/streaming_utils.js +5 -5
  55. package/dist/cjs/utils/vertex_ai_utils.js +3 -0
  56. package/dist/cjs/version.js +1 -1
  57. package/dist/esm/a2a/a2a_remote_agent.js +12 -2
  58. package/dist/esm/a2a/agent_to_a2a.js +18 -3
  59. package/dist/esm/a2a/auth.js +37 -0
  60. package/dist/esm/a2a/event_converter_utils.js +47 -18
  61. package/dist/esm/a2a/metadata_converter_utils.js +1 -1
  62. package/dist/esm/agents/base_agent.js +39 -0
  63. package/dist/esm/agents/functions.js +27 -24
  64. package/dist/esm/agents/llm_agent.js +6 -4
  65. package/dist/esm/agents/loop_agent.js +15 -3
  66. package/dist/esm/agents/processors/basic_llm_request_processor.js +3 -2
  67. package/dist/esm/agents/processors/content_processor_utils.js +2 -1
  68. package/dist/esm/agents/processors/content_request_processor.js +2 -21
  69. package/dist/esm/agents/processors/instructions_llm_request_processor.js +3 -1
  70. package/dist/esm/agents/routed_agent.js +31 -0
  71. package/dist/esm/agents/run_config.js +3 -2
  72. package/dist/esm/artifacts/in_memory_artifact_service.js +17 -9
  73. package/dist/esm/auth/credential_service/in_memory_credential_service.js +14 -3
  74. package/dist/esm/code_executors/unsafe_local_code_executor.js +22 -11
  75. package/dist/esm/common.js +29 -1
  76. package/dist/esm/context/agent_controlled_context_compactor.js +2 -11
  77. package/dist/esm/context/anchored_context_compactor.js +99 -0
  78. package/dist/esm/context/compaction_utils.js +38 -0
  79. package/dist/esm/context/token_based_context_compactor.js +16 -44
  80. package/dist/esm/events/compacted_event.js +7 -2
  81. package/dist/esm/events/event.js +24 -0
  82. package/dist/esm/index.js +8 -1
  83. package/dist/esm/integrations/agent_registry/agent_registry_mcp_toolset.js +9 -1
  84. package/dist/esm/memory/in_memory_memory_service.js +13 -2
  85. package/dist/esm/memory/vertex_ai_memory_bank_service.js +7 -1
  86. package/dist/esm/plugins/base_plugin.js +4 -2
  87. package/dist/esm/plugins/global_instruction_plugin.js +69 -0
  88. package/dist/esm/runner/runner.js +69 -23
  89. package/dist/esm/sessions/base_session_service.js +8 -3
  90. package/dist/esm/sessions/in_memory_session_service.js +8 -8
  91. package/dist/esm/sessions/vertex_ai_session_service.js +26 -11
  92. package/dist/esm/skills/loader.js +40 -6
  93. package/dist/esm/tools/enterprise_web_search_tool.js +55 -0
  94. package/dist/esm/tools/example_tool.js +42 -0
  95. package/dist/esm/tools/get_user_choice_tool.js +25 -0
  96. package/dist/esm/tools/load_web_page.js +221 -0
  97. package/dist/esm/tools/mcp/load_mcp_resource_tool.js +114 -0
  98. package/dist/esm/tools/mcp/mcp_session_manager.js +35 -21
  99. package/dist/esm/tools/mcp/mcp_toolset.js +63 -0
  100. package/dist/esm/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +13 -10
  101. package/dist/esm/tools/request_input_tool.js +26 -0
  102. package/dist/esm/tools/skill/run_skill_inline_script_tool.js +53 -4
  103. package/dist/esm/tools/skill/skill_toolset.js +4 -2
  104. package/dist/esm/utils/branch_trie.js +13 -0
  105. package/dist/esm/utils/crypto_shim.js +15 -0
  106. package/dist/esm/utils/env_aware_utils.js +15 -13
  107. package/dist/esm/utils/error_utils.js +92 -0
  108. package/dist/esm/utils/file_utils.js +5 -2
  109. package/dist/esm/utils/output_schema_utils.js +15 -0
  110. package/dist/esm/utils/streaming_utils.js +1 -1
  111. package/dist/esm/utils/vertex_ai_utils.js +2 -0
  112. package/dist/esm/version.js +1 -1
  113. package/dist/types/a2a/a2a_remote_agent.d.ts +5 -1
  114. package/dist/types/a2a/agent_to_a2a.d.ts +38 -0
  115. package/dist/types/a2a/auth.d.ts +30 -0
  116. package/dist/types/a2a/event_converter_utils.d.ts +4 -1
  117. package/dist/types/agents/base_agent.d.ts +29 -1
  118. package/dist/types/agents/functions.d.ts +1 -9
  119. package/dist/types/agents/llm_agent.d.ts +5 -1
  120. package/dist/types/agents/loop_agent.d.ts +2 -2
  121. package/dist/types/agents/routed_agent.d.ts +24 -1
  122. package/dist/types/agents/run_config.d.ts +1 -1
  123. package/dist/types/auth/credential_service/in_memory_credential_service.d.ts +11 -0
  124. package/dist/types/code_executors/unsafe_local_code_executor.d.ts +5 -1
  125. package/dist/types/common.d.ts +11 -2
  126. package/dist/types/context/agent_controlled_context_compactor.d.ts +0 -1
  127. package/dist/types/context/anchored_context_compactor.d.ts +35 -0
  128. package/dist/types/context/compaction_utils.d.ts +23 -0
  129. package/dist/types/context/token_based_context_compactor.d.ts +0 -1
  130. package/dist/types/events/compacted_event.d.ts +10 -0
  131. package/dist/types/events/event.d.ts +13 -0
  132. package/dist/types/index.d.ts +5 -3
  133. package/dist/types/memory/in_memory_memory_service.d.ts +11 -0
  134. package/dist/types/plugins/base_plugin.d.ts +4 -2
  135. package/dist/types/plugins/global_instruction_plugin.d.ts +38 -0
  136. package/dist/types/runner/runner.d.ts +1 -1
  137. package/dist/types/sessions/base_session_service.d.ts +8 -0
  138. package/dist/types/sessions/in_memory_session_service.d.ts +9 -0
  139. package/dist/types/sessions/vertex_ai_session_service.d.ts +19 -1
  140. package/dist/types/skills/loader.d.ts +5 -0
  141. package/dist/types/tools/enterprise_web_search_tool.d.ts +26 -0
  142. package/dist/types/tools/example_tool.d.ts +21 -0
  143. package/dist/types/tools/get_user_choice_tool.d.ts +14 -0
  144. package/dist/types/tools/load_web_page.d.ts +33 -0
  145. package/dist/types/tools/mcp/load_mcp_resource_tool.d.ts +26 -0
  146. package/dist/types/tools/mcp/mcp_toolset.d.ts +27 -0
  147. package/dist/types/tools/request_input_tool.d.ts +15 -0
  148. package/dist/types/tools/skill/run_skill_inline_script_tool.d.ts +25 -0
  149. package/dist/types/tools/skill/skill_toolset.d.ts +9 -0
  150. package/dist/types/utils/branch_trie.d.ts +14 -0
  151. package/dist/types/utils/crypto_shim.d.ts +16 -0
  152. package/dist/types/utils/env_aware_utils.d.ts +23 -0
  153. package/dist/types/utils/error_utils.d.ts +18 -0
  154. package/dist/types/utils/output_schema_utils.d.ts +18 -0
  155. package/dist/types/utils/vertex_ai_utils.d.ts +1 -0
  156. package/dist/types/version.d.ts +1 -1
  157. package/dist/web/a2a/a2a_remote_agent.js +12 -2
  158. package/dist/web/a2a/agent_to_a2a.js +18 -3
  159. package/dist/web/a2a/auth.js +37 -0
  160. package/dist/web/a2a/event_converter_utils.js +47 -18
  161. package/dist/web/a2a/metadata_converter_utils.js +1 -1
  162. package/dist/web/agents/base_agent.js +39 -0
  163. package/dist/web/agents/functions.js +27 -24
  164. package/dist/web/agents/llm_agent.js +6 -4
  165. package/dist/web/agents/loop_agent.js +27 -3
  166. package/dist/web/agents/processors/basic_llm_request_processor.js +3 -2
  167. package/dist/web/agents/processors/content_processor_utils.js +2 -1
  168. package/dist/web/agents/processors/content_request_processor.js +2 -21
  169. package/dist/web/agents/processors/instructions_llm_request_processor.js +3 -1
  170. package/dist/web/agents/routed_agent.js +31 -0
  171. package/dist/web/agents/run_config.js +8 -3
  172. package/dist/web/artifacts/in_memory_artifact_service.js +17 -9
  173. package/dist/web/auth/credential_service/in_memory_credential_service.js +14 -3
  174. package/dist/web/code_executors/unsafe_local_code_executor.js +22 -11
  175. package/dist/web/common.js +29 -1
  176. package/dist/web/context/agent_controlled_context_compactor.js +2 -11
  177. package/dist/web/context/anchored_context_compactor.js +117 -0
  178. package/dist/web/context/compaction_utils.js +38 -0
  179. package/dist/web/context/token_based_context_compactor.js +16 -44
  180. package/dist/web/events/compacted_event.js +7 -2
  181. package/dist/web/events/event.js +24 -0
  182. package/dist/web/index.js +8 -1
  183. package/dist/web/integrations/agent_registry/agent_registry_mcp_toolset.js +9 -1
  184. package/dist/web/memory/in_memory_memory_service.js +13 -2
  185. package/dist/web/memory/vertex_ai_memory_bank_service.js +7 -1
  186. package/dist/web/plugins/base_plugin.js +4 -2
  187. package/dist/web/plugins/global_instruction_plugin.js +67 -0
  188. package/dist/web/runner/runner.js +65 -22
  189. package/dist/web/sessions/base_session_service.js +8 -3
  190. package/dist/web/sessions/in_memory_session_service.js +8 -8
  191. package/dist/web/sessions/vertex_ai_session_service.js +24 -11
  192. package/dist/web/skills/loader.js +40 -6
  193. package/dist/web/tools/enterprise_web_search_tool.js +55 -0
  194. package/dist/web/tools/example_tool.js +42 -0
  195. package/dist/web/tools/get_user_choice_tool.js +25 -0
  196. package/dist/web/tools/load_web_page.js +221 -0
  197. package/dist/web/tools/mcp/load_mcp_resource_tool.js +107 -0
  198. package/dist/web/tools/mcp/mcp_session_manager.js +35 -21
  199. package/dist/web/tools/mcp/mcp_toolset.js +63 -0
  200. package/dist/web/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +13 -10
  201. package/dist/web/tools/request_input_tool.js +26 -0
  202. package/dist/web/tools/skill/run_skill_inline_script_tool.js +51 -4
  203. package/dist/web/tools/skill/skill_toolset.js +4 -2
  204. package/dist/web/utils/branch_trie.js +13 -0
  205. package/dist/web/utils/crypto_shim.js +15 -0
  206. package/dist/web/utils/env_aware_utils.js +15 -13
  207. package/dist/web/utils/error_utils.js +92 -0
  208. package/dist/web/utils/file_utils.js +5 -2
  209. package/dist/web/utils/output_schema_utils.js +15 -0
  210. package/dist/web/utils/streaming_utils.js +1 -1
  211. package/dist/web/utils/vertex_ai_utils.js +2 -0
  212. package/dist/web/version.js +1 -1
  213. package/package.json +1 -1
@@ -0,0 +1,221 @@
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 { lookup } from "node:dns/promises";
9
+ import { isIP } from "node:net";
10
+ import { z } from "zod";
11
+ import { FunctionTool } from "./function_tool.js";
12
+ const ALLOWED_SCHEMES = /* @__PURE__ */ new Set(["http:", "https:"]);
13
+ const DEFAULT_TIMEOUT_MS = 3e4;
14
+ const BLOCKED_IPV4_CIDRS = [
15
+ "0.0.0.0/8",
16
+ // "this host on this network"
17
+ "10.0.0.0/8",
18
+ // private
19
+ "100.64.0.0/10",
20
+ // shared address space / CGNAT
21
+ "127.0.0.0/8",
22
+ // loopback
23
+ "169.254.0.0/16",
24
+ // link-local (includes GCP metadata 169.254.169.254)
25
+ "172.16.0.0/12",
26
+ // private
27
+ "192.0.0.0/24",
28
+ // IETF protocol assignments
29
+ "192.0.2.0/24",
30
+ // TEST-NET-1 (documentation)
31
+ "192.88.99.0/24",
32
+ // 6to4 relay anycast (deprecated)
33
+ "192.168.0.0/16",
34
+ // private
35
+ "198.18.0.0/15",
36
+ // benchmarking
37
+ "198.51.100.0/24",
38
+ // TEST-NET-2 (documentation)
39
+ "203.0.113.0/24",
40
+ // TEST-NET-3 (documentation)
41
+ "224.0.0.0/4",
42
+ // multicast
43
+ "240.0.0.0/4"
44
+ // reserved / future use (includes 255.255.255.255)
45
+ ].map(parseIpv4Cidr);
46
+ const BLOCKED_IPV6_CIDRS = [
47
+ "::/128",
48
+ // unspecified
49
+ "::1/128",
50
+ // loopback
51
+ "64:ff9b:1::/48",
52
+ // local NAT64
53
+ "100::/64",
54
+ // discard-only
55
+ "2001:db8::/32",
56
+ // documentation
57
+ "fc00::/7",
58
+ // unique-local (ULA, private)
59
+ "fe80::/10",
60
+ // link-local
61
+ "ff00::/8"
62
+ // multicast
63
+ ].map(parseIpv6Cidr);
64
+ function failedToFetchMessage(url) {
65
+ return "Failed to fetch url: ".concat(url);
66
+ }
67
+ function isBlockedHostname(hostname) {
68
+ const normalized = hostname.replace(/\.+$/, "").toLowerCase();
69
+ return normalized === "localhost" || normalized.endsWith(".localhost");
70
+ }
71
+ function normalizeHost(hostname) {
72
+ return hostname.startsWith("[") ? hostname.slice(1, -1) : hostname;
73
+ }
74
+ function parseIpv4(address) {
75
+ const match = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(address);
76
+ if (!match) {
77
+ return null;
78
+ }
79
+ const octets = match.slice(1).map(Number);
80
+ if (octets.some((octet) => octet > 255)) {
81
+ return null;
82
+ }
83
+ return octets;
84
+ }
85
+ function parseIpv6(address) {
86
+ if (isIP(address) !== 6) {
87
+ return null;
88
+ }
89
+ const [head, tail] = address.split("::");
90
+ const highGroups = head ? expandHextets(head) : [];
91
+ const lowGroups = tail ? expandHextets(tail) : [];
92
+ const compressed = address.includes("::") ? new Array(8 - highGroups.length - lowGroups.length).fill(0) : [];
93
+ return [...highGroups, ...compressed, ...lowGroups];
94
+ }
95
+ function expandHextets(fragment) {
96
+ const hextets = [];
97
+ for (const group of fragment.split(":")) {
98
+ if (group.includes(".")) {
99
+ const octets = parseIpv4(group);
100
+ hextets.push(octets[0] << 8 | octets[1], octets[2] << 8 | octets[3]);
101
+ } else {
102
+ hextets.push(parseInt(group, 16));
103
+ }
104
+ }
105
+ return hextets;
106
+ }
107
+ function ipv4ToInt(octets) {
108
+ return (octets[0] << 24 | octets[1] << 16 | octets[2] << 8 | octets[3]) >>> 0;
109
+ }
110
+ function hextetsToBigInt(hextets) {
111
+ let value = /* @__PURE__ */ BigInt("0");
112
+ for (const hextet of hextets) {
113
+ value = value << /* @__PURE__ */ BigInt("16") | BigInt(hextet);
114
+ }
115
+ return value;
116
+ }
117
+ function parseIpv4Cidr(cidr) {
118
+ const [address, prefix] = cidr.split("/");
119
+ const mask = 4294967295 << 32 - Number(prefix) >>> 0;
120
+ return { base: (ipv4ToInt(parseIpv4(address)) & mask) >>> 0, mask };
121
+ }
122
+ function parseIpv6Cidr(cidr) {
123
+ const [address, prefix] = cidr.split("/");
124
+ return { base: hextetsToBigInt(parseIpv6(address)), prefix: Number(prefix) };
125
+ }
126
+ function isBlockedIpv4(octets) {
127
+ const value = ipv4ToInt(octets);
128
+ return BLOCKED_IPV4_CIDRS.some(
129
+ ({ base, mask }) => (value & mask) >>> 0 === base
130
+ );
131
+ }
132
+ function isBlockedIpv6(hextets) {
133
+ const value = hextetsToBigInt(hextets);
134
+ if (value >> /* @__PURE__ */ BigInt("32") === /* @__PURE__ */ BigInt("0xffff")) {
135
+ return isBlockedIpv4([
136
+ Number(value >> /* @__PURE__ */ BigInt("24") & /* @__PURE__ */ BigInt("0xff")),
137
+ Number(value >> /* @__PURE__ */ BigInt("16") & /* @__PURE__ */ BigInt("0xff")),
138
+ Number(value >> /* @__PURE__ */ BigInt("8") & /* @__PURE__ */ BigInt("0xff")),
139
+ Number(value & /* @__PURE__ */ BigInt("0xff"))
140
+ ]);
141
+ }
142
+ return BLOCKED_IPV6_CIDRS.some(
143
+ ({ base, prefix }) => value >> BigInt(128 - prefix) === base >> BigInt(128 - prefix)
144
+ );
145
+ }
146
+ function isBlockedAddress(address) {
147
+ const octets = parseIpv4(address);
148
+ if (octets) {
149
+ return isBlockedIpv4(octets);
150
+ }
151
+ const hextets = parseIpv6(address);
152
+ if (hextets) {
153
+ return isBlockedIpv6(hextets);
154
+ }
155
+ return true;
156
+ }
157
+ async function resolveHostAddresses(hostname) {
158
+ if (isIP(hostname) !== 0) {
159
+ return [hostname];
160
+ }
161
+ const records = await lookup(hostname, { all: true });
162
+ const addresses = [...new Set(records.map((record) => record.address))];
163
+ if (addresses.length === 0) {
164
+ throw new Error("Unable to resolve host: ".concat(hostname));
165
+ }
166
+ return addresses;
167
+ }
168
+ function assertUrlAllowed(url) {
169
+ const parsed = new URL(url);
170
+ if (!ALLOWED_SCHEMES.has(parsed.protocol)) {
171
+ throw new Error("Unsupported url scheme: ".concat(url));
172
+ }
173
+ if (isBlockedHostname(parsed.hostname)) {
174
+ throw new Error("Blocked host: ".concat(parsed.hostname));
175
+ }
176
+ return parsed;
177
+ }
178
+ async function validateResolvedAddresses(hostname) {
179
+ const addresses = await resolveHostAddresses(hostname);
180
+ if (addresses.some(isBlockedAddress)) {
181
+ throw new Error("Blocked host: ".concat(hostname));
182
+ }
183
+ }
184
+ function decodeHtmlEntities(text) {
185
+ return text.replace(/&nbsp;/g, " ").replace(/&#39;/g, "'").replace(/&#x27;/g, "'").replace(/&quot;/g, '"').replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&");
186
+ }
187
+ function htmlToText(html) {
188
+ const withoutCode = html.replace(/<script[\s\S]*?<\/script>/gi, " ").replace(/<style[\s\S]*?<\/style>/gi, " ").replace(/<!--[\s\S]*?-->/g, " ");
189
+ const text = decodeHtmlEntities(withoutCode.replace(/<[^>]+>/g, "\n"));
190
+ return text.split("\n").map((line) => line.trim()).filter((line) => line.split(/\s+/).filter(Boolean).length > 3).join("\n");
191
+ }
192
+ async function loadWebPage(url, options) {
193
+ var _a;
194
+ const timeoutMs = (_a = options == null ? void 0 : options.timeoutMs) != null ? _a : DEFAULT_TIMEOUT_MS;
195
+ try {
196
+ const parsed = assertUrlAllowed(url);
197
+ await validateResolvedAddresses(normalizeHost(parsed.hostname));
198
+ const response = await fetch(url, {
199
+ redirect: "manual",
200
+ signal: AbortSignal.timeout(timeoutMs)
201
+ });
202
+ if (response.status !== 200) {
203
+ return failedToFetchMessage(url);
204
+ }
205
+ return htmlToText(await response.text());
206
+ } catch (e) {
207
+ return failedToFetchMessage(url);
208
+ }
209
+ }
210
+ const LOAD_WEB_PAGE = new FunctionTool({
211
+ name: "load_web_page",
212
+ description: "Fetches the content at the given URL and returns the readable text extracted from the page.",
213
+ parameters: z.object({
214
+ url: z.string().describe("The URL to fetch and extract text from.")
215
+ }),
216
+ execute: ({ url }) => loadWebPage(url)
217
+ });
218
+ export {
219
+ LOAD_WEB_PAGE,
220
+ loadWebPage
221
+ };
@@ -0,0 +1,107 @@
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 { Type } from "@google/genai";
9
+ import { appendInstructions } from "../../models/llm_request.js";
10
+ import { logger } from "../../utils/logger.js";
11
+ import {
12
+ BaseTool
13
+ } from "../base_tool.js";
14
+ class LoadMcpResourceTool extends BaseTool {
15
+ constructor(mcpToolset) {
16
+ super({
17
+ name: "load_mcp_resource",
18
+ description: "Loads resources from the MCP server.\n\nNOTE: Call when you need access to resources."
19
+ });
20
+ this.mcpToolset = mcpToolset;
21
+ }
22
+ _getDeclaration() {
23
+ return {
24
+ name: this.name,
25
+ description: this.description,
26
+ parameters: {
27
+ type: Type.OBJECT,
28
+ properties: {
29
+ resource_names: {
30
+ type: Type.ARRAY,
31
+ items: {
32
+ type: Type.STRING
33
+ },
34
+ description: "The names of the MCP resources to load."
35
+ }
36
+ }
37
+ }
38
+ };
39
+ }
40
+ async runAsync({ args }) {
41
+ const resourceNames = args["resource_names"] || [];
42
+ return {
43
+ resource_names: resourceNames,
44
+ status: "resource contents temporarily inserted and removed. to access these resources, call load_mcp_resource tool again."
45
+ };
46
+ }
47
+ async processLlmRequest(request) {
48
+ await super.processLlmRequest(request);
49
+ await this.appendResourcesToLlmRequest(request.llmRequest);
50
+ }
51
+ async appendResourcesToLlmRequest(llmRequest) {
52
+ var _a, _b;
53
+ try {
54
+ const availableResourceNames = await this.mcpToolset.listResources();
55
+ if (availableResourceNames.length > 0) {
56
+ appendInstructions(llmRequest, [
57
+ "You have a list of MCP resources:\n".concat(JSON.stringify(
58
+ availableResourceNames
59
+ ), "\n\nWhen the user asks questions about any of the resources, you should call the\n`load_mcp_resource` function to load the resource. Always call load_mcp_resource\nbefore answering questions related to the resources.")
60
+ ]);
61
+ }
62
+ } catch (e) {
63
+ logger.warn("Failed to list MCP resources: ".concat(e));
64
+ }
65
+ const lastContent = llmRequest.contents.at(-1);
66
+ const functionResponse = (_b = (_a = lastContent == null ? void 0 : lastContent.parts) == null ? void 0 : _a[0]) == null ? void 0 : _b.functionResponse;
67
+ if (!functionResponse || functionResponse.name !== this.name) {
68
+ return;
69
+ }
70
+ const response = functionResponse.response || {};
71
+ const requestedResourceNames = response["resource_names"] || [];
72
+ for (const resourceName of requestedResourceNames) {
73
+ try {
74
+ const resourceContents = await this.mcpToolset.readResource(resourceName);
75
+ for (const content of resourceContents) {
76
+ llmRequest.contents.push({
77
+ role: "user",
78
+ parts: [
79
+ { text: "Resource ".concat(resourceName, " is:") },
80
+ this.mcpContentToPart(content, resourceName)
81
+ ]
82
+ });
83
+ }
84
+ } catch (e) {
85
+ logger.warn("Failed to read MCP resource '".concat(resourceName, "': ").concat(e));
86
+ }
87
+ }
88
+ }
89
+ mcpContentToPart(content, resourceName) {
90
+ var _a;
91
+ if ("text" in content) {
92
+ return { text: content.text };
93
+ }
94
+ if ("blob" in content) {
95
+ return {
96
+ inlineData: {
97
+ data: content.blob,
98
+ mimeType: (_a = content.mimeType) != null ? _a : "application/octet-stream"
99
+ }
100
+ };
101
+ }
102
+ return { text: "[Unknown content type for ".concat(resourceName, "]") };
103
+ }
104
+ }
105
+ export {
106
+ LoadMcpResourceTool
107
+ };
@@ -12,6 +12,11 @@ import {
12
12
  import {
13
13
  StreamableHTTPClientTransport
14
14
  } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
15
+ import { formatError } from "../../utils/error_utils.js";
16
+ import { logger } from "../../utils/logger.js";
17
+ function logTransportError(err) {
18
+ logger.error("MCP transport error: " + formatError(err));
19
+ }
15
20
  class MCPSessionManager {
16
21
  constructor(connectionParams) {
17
22
  this.activeSessions = /* @__PURE__ */ new Set();
@@ -20,31 +25,40 @@ class MCPSessionManager {
20
25
  async createSession() {
21
26
  var _a;
22
27
  const client = new Client({ name: "MCPClient", version: "1.0.0" });
23
- switch (this.connectionParams.type) {
24
- case "StdioConnectionParams":
25
- await client.connect(
26
- new StdioClientTransport(this.connectionParams.serverParams)
27
- );
28
- break;
29
- case "StreamableHTTPConnectionParams": {
30
- const options = (_a = this.connectionParams.transportOptions) != null ? _a : {};
31
- if (!options.requestInit && this.connectionParams.header !== void 0) {
32
- options.requestInit = {
33
- headers: this.connectionParams.header
34
- };
28
+ try {
29
+ switch (this.connectionParams.type) {
30
+ case "StdioConnectionParams": {
31
+ const transport = new StdioClientTransport(
32
+ this.connectionParams.serverParams
33
+ );
34
+ transport.onerror = logTransportError;
35
+ await client.connect(transport);
36
+ break;
35
37
  }
36
- await client.connect(
37
- new StreamableHTTPClientTransport(
38
+ case "StreamableHTTPConnectionParams": {
39
+ const options = (_a = this.connectionParams.transportOptions) != null ? _a : {};
40
+ if (!options.requestInit && this.connectionParams.header !== void 0) {
41
+ options.requestInit = {
42
+ headers: this.connectionParams.header
43
+ };
44
+ }
45
+ const transport = new StreamableHTTPClientTransport(
38
46
  new URL(this.connectionParams.url),
39
47
  options
40
- )
41
- );
42
- break;
43
- }
44
- default: {
45
- const _exhaustiveCheck = this.connectionParams;
46
- break;
48
+ );
49
+ transport.onerror = logTransportError;
50
+ await client.connect(transport);
51
+ break;
52
+ }
53
+ default: {
54
+ const _exhaustiveCheck = this.connectionParams;
55
+ break;
56
+ }
47
57
  }
58
+ } catch (err) {
59
+ throw new Error("Failed to create MCP session: " + formatError(err), {
60
+ cause: err
61
+ });
48
62
  }
49
63
  this.activeSessions.add(client);
50
64
  return client;
@@ -66,6 +66,69 @@ class MCPToolset extends BaseToolset {
66
66
  );
67
67
  return tools;
68
68
  }
69
+ /**
70
+ * Lists the names of the resources advertised by the MCP server.
71
+ *
72
+ * @return The resource names available on the server.
73
+ */
74
+ async listResources() {
75
+ const session = await this.mcpSessionManager.createSession();
76
+ try {
77
+ const result = await session.listResources();
78
+ return result.resources.map((resource) => resource.name);
79
+ } finally {
80
+ await this.mcpSessionManager.closeSession(session);
81
+ }
82
+ }
83
+ /**
84
+ * Returns metadata for the resource whose name matches `name`.
85
+ *
86
+ * @param name The advertised name of the resource.
87
+ * @return The matching MCP `Resource`.
88
+ * @throws If no resource with the given name is advertised by the server.
89
+ */
90
+ async getResourceInfo(name) {
91
+ const session = await this.mcpSessionManager.createSession();
92
+ let result;
93
+ try {
94
+ result = await session.listResources();
95
+ } finally {
96
+ await this.mcpSessionManager.closeSession(session);
97
+ }
98
+ const resource = result.resources.find(
99
+ (candidate) => candidate.name === name
100
+ );
101
+ if (!resource) {
102
+ throw new Error("Resource with name '".concat(name, "' not found."));
103
+ }
104
+ return resource;
105
+ }
106
+ /**
107
+ * Reads the contents of the named resource from the MCP server.
108
+ *
109
+ * The resource name is resolved to a URI via {@link getResourceInfo} before
110
+ * reading. Binary contents are returned base64-encoded, exactly as provided
111
+ * by the server (never decoded and re-encoded).
112
+ *
113
+ * @param name The advertised name of the resource to read.
114
+ * @return The resource contents (text and/or base64-encoded binary).
115
+ * @throws If the resource is unknown or has no URI.
116
+ */
117
+ async readResource(name) {
118
+ const resourceInfo = await this.getResourceInfo(name);
119
+ if (!resourceInfo.uri) {
120
+ throw new Error("Resource '".concat(name, "' has no URI."));
121
+ }
122
+ const session = await this.mcpSessionManager.createSession();
123
+ try {
124
+ const result = await session.readResource({
125
+ uri: resourceInfo.uri
126
+ });
127
+ return result.contents;
128
+ } finally {
129
+ await this.mcpSessionManager.closeSession(session);
130
+ }
131
+ }
69
132
  async close() {
70
133
  const sessions = this.mcpSessionManager.getActiveSessions();
71
134
  await Promise.allSettled(
@@ -62,19 +62,22 @@ let ToolAuthHandler = class {
62
62
  rawAuthCredential: this.authCredential,
63
63
  credentialKey: this.credentialKey || "default_openapi_key"
64
64
  };
65
- const credential = this.context.getAuthResponse(authConfig);
66
- if (credential) {
67
- const exchanger = new AutoAuthCredentialExchanger();
68
- const result = await exchanger.exchange({
69
- authScheme: this.authScheme,
70
- authCredential: credential
71
- });
65
+ const authResponseCredential = this.context.getAuthResponse(authConfig);
66
+ const credential = authResponseCredential != null ? authResponseCredential : this.authCredential;
67
+ if (!credential) {
68
+ this.context.requestCredential(authConfig);
69
+ return { state: "pending" };
70
+ }
71
+ const exchanger = new AutoAuthCredentialExchanger();
72
+ const result = await exchanger.exchange({
73
+ authScheme: this.authScheme,
74
+ authCredential: credential
75
+ });
76
+ if (authResponseCredential || result.wasExchanged) {
72
77
  const key = store.getCredentialKey(this.authScheme);
73
78
  store.storeCredential(key, result.credential);
74
- return { state: "done", authCredential: result.credential };
75
79
  }
76
- this.context.requestCredential(authConfig);
77
- return { state: "pending" };
80
+ return { state: "done", authCredential: result.credential };
78
81
  }
79
82
  };
80
83
  __decorateClass([
@@ -0,0 +1,26 @@
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 { z } from "zod";
9
+ import { LongRunningFunctionTool } from "./long_running_tool.js";
10
+ const requestInputTool = new LongRunningFunctionTool({
11
+ name: "adk_request_input",
12
+ description: "Presents a custom message to the user and awaits unstructured or structured input.",
13
+ parameters: z.object({
14
+ message: z.string().describe("The prompt for the user."),
15
+ responseSchema: z.record(z.string(), z.unknown()).optional().describe("Expected schema of the response.")
16
+ }),
17
+ execute: async (input, context) => {
18
+ if (context) {
19
+ context.actions.skipSummarization = true;
20
+ }
21
+ return null;
22
+ }
23
+ });
24
+ export {
25
+ requestInputTool
26
+ };
@@ -21,6 +21,15 @@ import { CodeExecutionLanguage } from "../../code_executors/code_execution_utils
21
21
  import { experimental } from "../../utils/experimental.js";
22
22
  import { materializeFiles } from "../../utils/file_utils.js";
23
23
  import { BaseTool } from "../base_tool.js";
24
+ var RunSkillInlineScriptErrorCode = /* @__PURE__ */ ((RunSkillInlineScriptErrorCode2) => {
25
+ RunSkillInlineScriptErrorCode2["MISSING_SCRIPT_CONTENT"] = "MISSING_SCRIPT_CONTENT";
26
+ RunSkillInlineScriptErrorCode2["MISSING_LANGUAGE"] = "MISSING_LANGUAGE";
27
+ RunSkillInlineScriptErrorCode2["NO_CODE_EXECUTOR"] = "NO_CODE_EXECUTOR";
28
+ RunSkillInlineScriptErrorCode2["EXECUTION_ERROR"] = "EXECUTION_ERROR";
29
+ RunSkillInlineScriptErrorCode2["CONFIRMATION_REJECTED"] = "CONFIRMATION_REJECTED";
30
+ return RunSkillInlineScriptErrorCode2;
31
+ })(RunSkillInlineScriptErrorCode || {});
32
+ const REQUIRE_CONFIRMATION_MESSAGE = "This tool call needs external confirmation before completion.";
24
33
  let RunSkillInlineScriptTool = class extends BaseTool {
25
34
  constructor(toolset) {
26
35
  super({
@@ -70,13 +79,13 @@ let RunSkillInlineScriptTool = class extends BaseTool {
70
79
  if (!inlineScriptContent) {
71
80
  return {
72
81
  error: "Script content is required.",
73
- errorCode: "MISSING_SCRIPT_CONTENT"
82
+ errorCode: "MISSING_SCRIPT_CONTENT" /* MISSING_SCRIPT_CONTENT */
74
83
  };
75
84
  }
76
85
  if (!language) {
77
86
  return {
78
87
  error: "Language is required.",
79
- errorCode: "MISSING_LANGUAGE"
88
+ errorCode: "MISSING_LANGUAGE" /* MISSING_LANGUAGE */
80
89
  };
81
90
  }
82
91
  let codeExecutor = (_a = this.toolset) == null ? void 0 : _a.codeExecutor;
@@ -89,9 +98,17 @@ let RunSkillInlineScriptTool = class extends BaseTool {
89
98
  if (!codeExecutor) {
90
99
  return {
91
100
  error: "No code executor configured.",
92
- errorCode: "NO_CODE_EXECUTOR"
101
+ errorCode: "NO_CODE_EXECUTOR" /* NO_CODE_EXECUTOR */
93
102
  };
94
103
  }
104
+ const confirmationResult = this.enforceConfirmation(
105
+ toolContext,
106
+ inlineScriptContent,
107
+ language
108
+ );
109
+ if (confirmationResult) {
110
+ return confirmationResult;
111
+ }
95
112
  try {
96
113
  const result = await codeExecutor.executeCode({
97
114
  invocationContext: toolContext.invocationContext,
@@ -107,14 +124,44 @@ let RunSkillInlineScriptTool = class extends BaseTool {
107
124
  } catch (e) {
108
125
  return {
109
126
  error: "Failed to execute inline script: ".concat(e.message),
110
- errorCode: "EXECUTION_ERROR"
127
+ errorCode: "EXECUTION_ERROR" /* EXECUTION_ERROR */
128
+ };
129
+ }
130
+ }
131
+ /**
132
+ * Enforces a human-in-the-loop confirmation gate before executing an inline
133
+ * script, using the repo's standard tool-confirmation mechanism.
134
+ *
135
+ * - When no confirmation has been provided yet, a confirmation is requested
136
+ * (surfacing the language and script that would run) and an intermediate
137
+ * result is returned so the tool call pauses until the client responds.
138
+ * - When a confirmation exists but was not confirmed, a rejection error is
139
+ * returned and execution is refused.
140
+ * - When the confirmation is confirmed, `undefined` is returned to allow the
141
+ * caller to proceed with execution.
142
+ */
143
+ enforceConfirmation(toolContext, scriptContent, language) {
144
+ const confirmation = toolContext.toolConfirmation;
145
+ if (!confirmation) {
146
+ toolContext.requestConfirmation({
147
+ hint: "Confirmation is required before executing an inline skill script. " + "The agent requested to run the following ".concat(language, " script in the ") + "code executor. Only approve if you trust its contents:\n\n" + scriptContent,
148
+ payload: { language, scriptContent }
149
+ });
150
+ return { partial: REQUIRE_CONFIRMATION_MESSAGE };
151
+ }
152
+ if (!confirmation.confirmed) {
153
+ return {
154
+ error: "Inline script execution was not confirmed and was rejected.",
155
+ errorCode: "CONFIRMATION_REJECTED" /* CONFIRMATION_REJECTED */
111
156
  };
112
157
  }
158
+ return void 0;
113
159
  }
114
160
  };
115
161
  RunSkillInlineScriptTool = __decorateClass([
116
162
  experimental
117
163
  ], RunSkillInlineScriptTool);
118
164
  export {
165
+ RunSkillInlineScriptErrorCode,
119
166
  RunSkillInlineScriptTool
120
167
  };
@@ -41,9 +41,11 @@ let SkillToolset = class extends BaseToolset {
41
41
  new ListSkillsTool(this),
42
42
  new LoadSkillTool(this),
43
43
  new LoadSkillResourceTool(this),
44
- new RunSkillScriptTool(this),
45
- new RunSkillInlineScriptTool(this)
44
+ new RunSkillScriptTool(this)
46
45
  ];
46
+ if (options.allowInlineScripts) {
47
+ this.tools.push(new RunSkillInlineScriptTool(this));
48
+ }
47
49
  if (this.registry) {
48
50
  this.tools.push(new SearchSkillsTool(this));
49
51
  }
@@ -0,0 +1,13 @@
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
+ function isSegmentPrefix(currentBranch, targetBranch) {
9
+ return !targetBranch || targetBranch === currentBranch || !!currentBranch && currentBranch.startsWith("".concat(targetBranch, "."));
10
+ }
11
+ export {
12
+ isSegmentPrefix
13
+ };
@@ -0,0 +1,15 @@
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
+ function randomUUID() {
9
+ throw new Error(
10
+ "randomUUID: no cryptographically secure source of randomness is available. Neither crypto.randomUUID() nor crypto.getRandomValues() is present in this environment."
11
+ );
12
+ }
13
+ export {
14
+ randomUUID
15
+ };