@google/adk 1.4.0 → 1.5.0

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