@google/adk 2.1.0 → 2.2.1
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.
- package/dist/cjs/a2a/agent_card.js +8 -0
- package/dist/cjs/a2a/agent_executor.js +8 -3
- package/dist/cjs/a2a/event_converter_utils.js +5 -1
- package/dist/cjs/a2a/metadata_converter_utils.js +2 -1
- package/dist/cjs/agents/llm_agent.js +15 -1
- package/dist/cjs/agents/processors/content_processor_utils.js +10 -2
- package/dist/cjs/agents/processors/nl_planning_processor.js +114 -0
- package/dist/cjs/artifacts/gcs_artifact_service.js +13 -7
- package/dist/cjs/auth/auth_credential.js +12 -2
- package/dist/cjs/code_executors/code_execution_utils.js +3 -3
- package/dist/cjs/common.js +63 -0
- package/dist/cjs/events/abort_events.js +135 -0
- package/dist/cjs/events/internal_metadata.js +131 -0
- package/dist/cjs/examples/example.js +92 -0
- package/dist/cjs/examples/example_util.js +28 -4
- package/dist/cjs/examples/index.js +39 -0
- package/dist/cjs/examples/vertex_ai_example_store.js +39 -0
- package/dist/cjs/index.js +46 -0
- package/dist/cjs/memory/vertex_ai_memory_bank_service.js +17 -5
- package/dist/cjs/models/base_llm.js +1 -6
- package/dist/cjs/models/chrome_prompt_llm.js +16 -2
- package/dist/cjs/models/chrome_prompt_utils.js +54 -2
- package/dist/cjs/models/gemini_continuation.js +232 -0
- package/dist/cjs/models/gemini_llm_connection.js +5 -4
- package/dist/cjs/planners/base_planner.js +56 -0
- package/dist/cjs/planners/built_in_planner.js +85 -0
- package/dist/cjs/planners/plan_re_act_planner.js +172 -0
- package/dist/cjs/plugins/base_plugin.js +46 -61
- package/dist/cjs/plugins/debug_logging_plugin.js +653 -0
- package/dist/cjs/plugins/plugin_manager.js +1 -1
- package/dist/cjs/plugins/tool_call_integrity_plugin.js +364 -0
- package/dist/cjs/runner/runner.js +17 -3
- package/dist/cjs/tools/example_tool.js +1 -1
- package/dist/cjs/tools/mcp/mcp_session_manager.js +14 -8
- package/dist/cjs/tools/openapi_tool/auth/auth_helpers.js +281 -2
- package/dist/cjs/tools/openapi_tool/auth/credential_exchangers/auto_auth_credential_exchanger.js +15 -1
- package/dist/cjs/tools/openapi_tool/auth/credential_exchangers/base_auth_credential_exchanger.js +70 -0
- package/dist/cjs/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.js +120 -0
- package/dist/cjs/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.js +10 -10
- package/dist/cjs/tools/openapi_tool/common/common.js +139 -0
- package/dist/cjs/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.js +11 -6
- package/dist/cjs/tools/openapi_tool/openapi_spec_parser/operation_parser.js +73 -13
- package/dist/cjs/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +146 -34
- package/dist/cjs/tools/openapi_tool/openapi_toolset.js +14 -2
- package/dist/cjs/tools/openapi_tool/rest_api_tool.js +90 -28
- package/dist/cjs/tools/skill/skill_toolset.js +2 -0
- package/dist/cjs/tools/tool_context.js +41 -0
- package/dist/cjs/tools/webmcp/index.js +37 -0
- package/dist/cjs/tools/webmcp/webmcp_tool.js +156 -0
- package/dist/cjs/tools/webmcp/webmcp_toolset.js +116 -0
- package/dist/cjs/tools/webmcp/webmcp_types.js +50 -0
- package/dist/cjs/utils/case_utils.js +52 -2
- package/dist/cjs/utils/client_labels.js +67 -0
- package/dist/cjs/utils/gemini_schema_util.js +103 -3
- package/dist/cjs/utils/hash_utils.js +73 -0
- package/dist/cjs/utils/live_connection_utils.js +10 -9
- package/dist/cjs/utils/model_name.js +17 -2
- package/dist/cjs/utils/simple_zod_to_json.js +5 -0
- package/dist/cjs/version.js +1 -1
- package/dist/esm/a2a/agent_card.js +8 -0
- package/dist/esm/a2a/agent_executor.js +8 -3
- package/dist/esm/a2a/event_converter_utils.js +5 -1
- package/dist/esm/a2a/metadata_converter_utils.js +2 -1
- package/dist/esm/agents/llm_agent.js +18 -1
- package/dist/esm/agents/processors/content_processor_utils.js +10 -2
- package/dist/esm/agents/processors/nl_planning_processor.js +87 -0
- package/dist/esm/artifacts/gcs_artifact_service.js +13 -7
- package/dist/esm/auth/auth_credential.js +11 -1
- package/dist/esm/code_executors/code_execution_utils.js +3 -3
- package/dist/esm/common.js +58 -2
- package/dist/esm/events/abort_events.js +110 -0
- package/dist/esm/events/internal_metadata.js +97 -0
- package/dist/esm/examples/example.js +85 -0
- package/dist/esm/examples/example_util.js +25 -3
- package/dist/esm/examples/index.js +11 -0
- package/dist/esm/examples/vertex_ai_example_store.js +11 -0
- package/dist/esm/index.js +51 -1
- package/dist/esm/memory/vertex_ai_memory_bank_service.js +17 -5
- package/dist/esm/models/base_llm.js +2 -7
- package/dist/esm/models/chrome_prompt_llm.js +20 -3
- package/dist/esm/models/chrome_prompt_utils.js +51 -2
- package/dist/esm/models/gemini_continuation.js +205 -0
- package/dist/esm/models/gemini_llm_connection.js +6 -5
- package/dist/esm/planners/base_planner.js +28 -0
- package/dist/esm/planners/built_in_planner.js +57 -0
- package/dist/esm/planners/plan_re_act_planner.js +145 -0
- package/dist/esm/plugins/base_plugin.js +46 -61
- package/dist/esm/plugins/debug_logging_plugin.js +615 -0
- package/dist/esm/plugins/plugin_manager.js +1 -1
- package/dist/esm/plugins/tool_call_integrity_plugin.js +339 -0
- package/dist/esm/runner/runner.js +20 -3
- package/dist/esm/tools/example_tool.js +1 -1
- package/dist/esm/tools/mcp/mcp_session_manager.js +14 -8
- package/dist/esm/tools/openapi_tool/auth/auth_helpers.js +272 -1
- package/dist/esm/tools/openapi_tool/auth/credential_exchangers/auto_auth_credential_exchanger.js +15 -1
- package/dist/esm/tools/openapi_tool/auth/credential_exchangers/base_auth_credential_exchanger.js +43 -0
- package/dist/esm/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.js +93 -0
- package/dist/esm/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.js +10 -12
- package/dist/esm/tools/openapi_tool/common/common.js +112 -0
- package/dist/esm/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.js +11 -6
- package/dist/esm/tools/openapi_tool/openapi_spec_parser/operation_parser.js +80 -13
- package/dist/esm/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.js +146 -33
- package/dist/esm/tools/openapi_tool/openapi_toolset.js +14 -2
- package/dist/esm/tools/openapi_tool/rest_api_tool.js +89 -28
- package/dist/esm/tools/skill/skill_toolset.js +2 -0
- package/dist/esm/tools/tool_context.js +15 -0
- package/dist/esm/tools/webmcp/index.js +10 -0
- package/dist/esm/tools/webmcp/webmcp_tool.js +131 -0
- package/dist/esm/tools/webmcp/webmcp_toolset.js +89 -0
- package/dist/esm/tools/webmcp/webmcp_types.js +22 -0
- package/dist/esm/utils/case_utils.js +49 -1
- package/dist/esm/utils/client_labels.js +65 -0
- package/dist/esm/utils/gemini_schema_util.js +102 -3
- package/dist/esm/utils/hash_utils.js +45 -0
- package/dist/esm/utils/live_connection_utils.js +11 -10
- package/dist/esm/utils/model_name.js +15 -2
- package/dist/esm/utils/simple_zod_to_json.js +5 -0
- package/dist/esm/version.js +1 -1
- package/dist/types/agents/llm_agent.d.ts +12 -1
- package/dist/types/agents/processors/nl_planning_processor.d.ts +30 -0
- package/dist/types/auth/auth_credential.d.ts +9 -0
- package/dist/types/common.d.ts +19 -4
- package/dist/types/events/abort_events.d.ts +43 -0
- package/dist/types/events/internal_metadata.d.ts +78 -0
- package/dist/types/examples/base_example_provider.d.ts +2 -2
- package/dist/types/examples/example.d.ts +75 -0
- package/dist/types/examples/example_util.d.ts +13 -2
- package/dist/types/examples/index.d.ts +18 -0
- package/dist/types/examples/vertex_ai_example_store.d.ts +7 -0
- package/dist/types/index.d.ts +12 -3
- package/dist/types/memory/memory_entry.d.ts +15 -0
- package/dist/types/memory/vertex_ai_memory_bank_service.d.ts +9 -0
- package/dist/types/models/chrome_prompt_utils.d.ts +29 -0
- package/dist/types/models/gemini_continuation.d.ts +59 -0
- package/dist/types/planners/base_planner.d.ts +50 -0
- package/dist/types/planners/built_in_planner.d.ts +53 -0
- package/dist/types/planners/plan_re_act_planner.d.ts +21 -0
- package/dist/types/plugins/base_plugin.d.ts +52 -52
- package/dist/types/plugins/debug_logging_plugin.d.ts +157 -0
- package/dist/types/plugins/tool_call_integrity_plugin.d.ts +116 -0
- package/dist/types/skills/skill_registry.d.ts +8 -0
- package/dist/types/tools/openapi_tool/auth/auth_helpers.d.ts +110 -1
- package/dist/types/tools/openapi_tool/auth/credential_exchangers/auto_auth_credential_exchanger.d.ts +32 -2
- package/dist/types/tools/openapi_tool/auth/credential_exchangers/base_auth_credential_exchanger.d.ts +35 -0
- package/dist/types/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.d.ts +54 -0
- package/dist/types/tools/openapi_tool/common/common.d.ts +60 -0
- package/dist/types/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.d.ts +7 -0
- package/dist/types/tools/openapi_tool/openapi_spec_parser/operation_parser.d.ts +56 -2
- package/dist/types/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.d.ts +73 -5
- package/dist/types/tools/openapi_tool/openapi_toolset.d.ts +11 -0
- package/dist/types/tools/openapi_tool/rest_api_tool.d.ts +42 -8
- package/dist/types/tools/tool_context.d.ts +19 -0
- package/dist/types/tools/webmcp/index.d.ts +12 -0
- package/dist/types/tools/webmcp/webmcp_tool.d.ts +47 -0
- package/dist/types/tools/webmcp/webmcp_toolset.d.ts +67 -0
- package/dist/types/tools/webmcp/webmcp_types.d.ts +69 -0
- package/dist/types/utils/case_utils.d.ts +36 -0
- package/dist/types/utils/client_labels.d.ts +33 -0
- package/dist/types/utils/gemini_schema_util.d.ts +13 -0
- package/dist/types/utils/hash_utils.d.ts +25 -0
- package/dist/types/utils/logger.d.ts +10 -2
- package/dist/types/utils/model_name.d.ts +30 -2
- package/dist/types/version.d.ts +1 -1
- package/dist/web/index_web.js +113 -80
- package/dist/web/index_web.js.map +4 -4
- package/package.json +8 -2
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import {createRequire as topLevelCreateRequire} from 'module';
|
|
2
|
+
const require = topLevelCreateRequire(import.meta.url);
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
5
|
+
/**
|
|
6
|
+
* @license
|
|
7
|
+
* Copyright 2026 Google LLC
|
|
8
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
9
|
+
*/
|
|
10
|
+
import { createEvent, getFunctionCalls } from "../events/event.js";
|
|
11
|
+
import {
|
|
12
|
+
INTERNAL_METADATA_PREFIX,
|
|
13
|
+
markRestored,
|
|
14
|
+
RESTORED_EVENT_KEY
|
|
15
|
+
} from "../events/internal_metadata.js";
|
|
16
|
+
import { logger } from "../utils/logger.js";
|
|
17
|
+
import { BasePlugin } from "./base_plugin.js";
|
|
18
|
+
const TOOL_CALL_HMAC_METADATA_KEY = `${INTERNAL_METADATA_PREFIX}fc_hmac`;
|
|
19
|
+
const STAMP_PREFIX = "v1:";
|
|
20
|
+
const _ToolCallIntegrityError = class _ToolCallIntegrityError extends Error {
|
|
21
|
+
constructor(message) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = "ToolCallIntegrityError";
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
__name(_ToolCallIntegrityError, "ToolCallIntegrityError");
|
|
27
|
+
let ToolCallIntegrityError = _ToolCallIntegrityError;
|
|
28
|
+
function jsonForm(value) {
|
|
29
|
+
const json = JSON.stringify(value);
|
|
30
|
+
return json === void 0 ? null : JSON.parse(json);
|
|
31
|
+
}
|
|
32
|
+
__name(jsonForm, "jsonForm");
|
|
33
|
+
function canonicalJson(value) {
|
|
34
|
+
if (Array.isArray(value)) {
|
|
35
|
+
return `[${value.map((item) => canonicalJson(item)).join(",")}]`;
|
|
36
|
+
}
|
|
37
|
+
if (value !== null && typeof value === "object") {
|
|
38
|
+
const object = value;
|
|
39
|
+
const entries = Object.keys(object).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(object[key])}`);
|
|
40
|
+
return `{${entries.join(",")}}`;
|
|
41
|
+
}
|
|
42
|
+
return JSON.stringify(value);
|
|
43
|
+
}
|
|
44
|
+
__name(canonicalJson, "canonicalJson");
|
|
45
|
+
function jsonArgs(args) {
|
|
46
|
+
const json = jsonForm(args != null ? args : {});
|
|
47
|
+
return json != null ? json : {};
|
|
48
|
+
}
|
|
49
|
+
__name(jsonArgs, "jsonArgs");
|
|
50
|
+
function canonicalPayload(session, event, functionCall) {
|
|
51
|
+
var _a, _b, _c, _d, _e;
|
|
52
|
+
return new TextEncoder().encode(
|
|
53
|
+
canonicalJson({
|
|
54
|
+
app_name: session.appName,
|
|
55
|
+
user_id: session.userId,
|
|
56
|
+
session_id: session.id,
|
|
57
|
+
invocation_id: (_a = event.invocationId) != null ? _a : null,
|
|
58
|
+
branch: (_b = event.branch) != null ? _b : null,
|
|
59
|
+
author: (_c = event.author) != null ? _c : null,
|
|
60
|
+
name: (_d = functionCall.name) != null ? _d : null,
|
|
61
|
+
id: (_e = functionCall.id) != null ? _e : null,
|
|
62
|
+
args: jsonArgs(functionCall.args)
|
|
63
|
+
})
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
__name(canonicalPayload, "canonicalPayload");
|
|
67
|
+
function isStampMap(value) {
|
|
68
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) && Object.values(value).every(
|
|
69
|
+
// eslint-disable-next-line no-control-regex
|
|
70
|
+
(stamp) => typeof stamp === "string" && /^[\x00-\x7f]*$/.test(stamp)
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
__name(isStampMap, "isStampMap");
|
|
74
|
+
function isRestored(event) {
|
|
75
|
+
var _a;
|
|
76
|
+
return Boolean((_a = event.customMetadata) == null ? void 0 : _a[RESTORED_EVENT_KEY]);
|
|
77
|
+
}
|
|
78
|
+
__name(isRestored, "isRestored");
|
|
79
|
+
function getStamps(event) {
|
|
80
|
+
var _a;
|
|
81
|
+
const stamps = (_a = event.customMetadata) == null ? void 0 : _a[TOOL_CALL_HMAC_METADATA_KEY];
|
|
82
|
+
if (stamps === void 0 || stamps === null) {
|
|
83
|
+
return {};
|
|
84
|
+
}
|
|
85
|
+
if (!isStampMap(stamps)) {
|
|
86
|
+
throw new ToolCallIntegrityError(
|
|
87
|
+
`Event '${event.id}' has a malformed integrity stamp.`
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
return stamps;
|
|
91
|
+
}
|
|
92
|
+
__name(getStamps, "getStamps");
|
|
93
|
+
function hasStamp(stamps, callId) {
|
|
94
|
+
return Object.hasOwn(stamps, callId);
|
|
95
|
+
}
|
|
96
|
+
__name(hasStamp, "hasStamp");
|
|
97
|
+
function toHex(bytes) {
|
|
98
|
+
return Array.from(
|
|
99
|
+
new Uint8Array(bytes),
|
|
100
|
+
(b) => b.toString(16).padStart(2, "0")
|
|
101
|
+
).join("");
|
|
102
|
+
}
|
|
103
|
+
__name(toHex, "toHex");
|
|
104
|
+
function fromHex(hex) {
|
|
105
|
+
if (!/^[0-9a-f]{64}$/.test(hex)) {
|
|
106
|
+
return void 0;
|
|
107
|
+
}
|
|
108
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
109
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
110
|
+
bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
111
|
+
}
|
|
112
|
+
return bytes;
|
|
113
|
+
}
|
|
114
|
+
__name(fromHex, "fromHex");
|
|
115
|
+
function getSubtleCrypto() {
|
|
116
|
+
var _a;
|
|
117
|
+
const subtle = (_a = globalThis.crypto) == null ? void 0 : _a.subtle;
|
|
118
|
+
if (!subtle) {
|
|
119
|
+
throw new Error(
|
|
120
|
+
"ToolCallIntegrityPlugin requires the Web Crypto API (globalThis.crypto.subtle), which is not available in this environment."
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
return subtle;
|
|
124
|
+
}
|
|
125
|
+
__name(getSubtleCrypto, "getSubtleCrypto");
|
|
126
|
+
const _ToolCallIntegrityPlugin = class _ToolCallIntegrityPlugin extends BasePlugin {
|
|
127
|
+
/**
|
|
128
|
+
* @throws {Error} If `secretKey` is empty or contains a key that is not
|
|
129
|
+
* non-empty bytes.
|
|
130
|
+
*/
|
|
131
|
+
constructor(options) {
|
|
132
|
+
var _a, _b;
|
|
133
|
+
super((_a = options.name) != null ? _a : "tool_call_integrity");
|
|
134
|
+
const secretKey = options.secretKey;
|
|
135
|
+
const rawKeys = secretKey instanceof Uint8Array ? [secretKey] : Array.isArray(secretKey) ? [...secretKey] : [];
|
|
136
|
+
if (rawKeys.length === 0 || !rawKeys.every((key) => key instanceof Uint8Array && key.length > 0)) {
|
|
137
|
+
throw new Error(
|
|
138
|
+
"secretKey must be non-empty bytes or a non-empty list of them."
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
this.keys = rawKeys.map((key) => new Uint8Array(key));
|
|
142
|
+
this.allowUnstampedCalls = (_b = options.allowUnstampedCalls) != null ? _b : false;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Returns a copy with internal metadata removed and marked as restored.
|
|
146
|
+
*
|
|
147
|
+
* Use it on events that your code copies into another session, so that the
|
|
148
|
+
* history passes the integrity check. The copy only keeps the history: its
|
|
149
|
+
* function calls are never executed.
|
|
150
|
+
*
|
|
151
|
+
* @param event The event to copy. It is not modified.
|
|
152
|
+
* @returns The marked copy, ready to append to the new session.
|
|
153
|
+
*/
|
|
154
|
+
static prepareRestoredEvent(event) {
|
|
155
|
+
return markRestored(createEvent(structuredClone(event)));
|
|
156
|
+
}
|
|
157
|
+
getCryptoKeys() {
|
|
158
|
+
if (!this.cryptoKeys) {
|
|
159
|
+
const subtle = getSubtleCrypto();
|
|
160
|
+
this.cryptoKeys = Promise.all(
|
|
161
|
+
this.keys.map(
|
|
162
|
+
(key) => subtle.importKey("raw", key, { name: "HMAC", hash: "SHA-256" }, false, [
|
|
163
|
+
"sign",
|
|
164
|
+
"verify"
|
|
165
|
+
])
|
|
166
|
+
)
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
return this.cryptoKeys;
|
|
170
|
+
}
|
|
171
|
+
async sign(payload) {
|
|
172
|
+
const [primary] = await this.getCryptoKeys();
|
|
173
|
+
const digest = await getSubtleCrypto().sign("HMAC", primary, payload);
|
|
174
|
+
return STAMP_PREFIX + toHex(digest);
|
|
175
|
+
}
|
|
176
|
+
/** `subtle.verify` compares in constant time. */
|
|
177
|
+
async verify(payload, stamp) {
|
|
178
|
+
if (!stamp.startsWith(STAMP_PREFIX)) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
const signature = fromHex(stamp.slice(STAMP_PREFIX.length));
|
|
182
|
+
if (!signature) {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
const subtle = getSubtleCrypto();
|
|
186
|
+
for (const key of await this.getCryptoKeys()) {
|
|
187
|
+
if (await subtle.verify("HMAC", key, signature, payload)) {
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
unstamped(name, callId) {
|
|
194
|
+
const message = `${name} call '${callId}' has no integrity stamp.`;
|
|
195
|
+
if (!this.allowUnstampedCalls) {
|
|
196
|
+
throw new ToolCallIntegrityError(message);
|
|
197
|
+
}
|
|
198
|
+
logger.warn(message);
|
|
199
|
+
}
|
|
200
|
+
async onEventCallback({
|
|
201
|
+
invocationContext,
|
|
202
|
+
event
|
|
203
|
+
}) {
|
|
204
|
+
var _a;
|
|
205
|
+
const session = invocationContext.session;
|
|
206
|
+
const calls = getFunctionCalls(event).filter((fc) => fc.id);
|
|
207
|
+
if (!event.partial) {
|
|
208
|
+
const seen = /* @__PURE__ */ new Set();
|
|
209
|
+
for (const fc of calls) {
|
|
210
|
+
if (seen.has(fc.id)) {
|
|
211
|
+
throw new ToolCallIntegrityError(
|
|
212
|
+
`Event '${event.id}' repeats function call ID '${fc.id}'.`
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
seen.add(fc.id);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
const stamps = {};
|
|
219
|
+
for (const fc of calls) {
|
|
220
|
+
stamps[fc.id] = await this.sign(canonicalPayload(session, event, fc));
|
|
221
|
+
}
|
|
222
|
+
if (Object.keys(stamps).length > 0) {
|
|
223
|
+
event.customMetadata = {
|
|
224
|
+
...(_a = event.customMetadata) != null ? _a : {},
|
|
225
|
+
[TOOL_CALL_HMAC_METADATA_KEY]: stamps
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
return void 0;
|
|
229
|
+
}
|
|
230
|
+
async beforeRunCallback({
|
|
231
|
+
invocationContext
|
|
232
|
+
}) {
|
|
233
|
+
const session = invocationContext.session;
|
|
234
|
+
for (const event of session.events) {
|
|
235
|
+
const calls = getFunctionCalls(event);
|
|
236
|
+
if (calls.length === 0 || isRestored(event)) {
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
const stamps = getStamps(event);
|
|
240
|
+
const verified = /* @__PURE__ */ new Set();
|
|
241
|
+
for (const fc of calls) {
|
|
242
|
+
if (!fc.id) {
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
if (!hasStamp(stamps, fc.id)) {
|
|
246
|
+
this.unstamped(fc.name, fc.id);
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
if (verified.has(fc.id)) {
|
|
250
|
+
throw new ToolCallIntegrityError(
|
|
251
|
+
`Event '${event.id}' has duplicate function call ID '${fc.id}'.`
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
const payload = canonicalPayload(session, event, fc);
|
|
255
|
+
if (!await this.verify(payload, stamps[fc.id])) {
|
|
256
|
+
throw new ToolCallIntegrityError(
|
|
257
|
+
`${fc.name} call '${fc.id}' does not match its integrity stamp.`
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
verified.add(fc.id);
|
|
261
|
+
}
|
|
262
|
+
const unmatched = Object.keys(stamps).filter((id) => !verified.has(id)).sort();
|
|
263
|
+
if (unmatched.length > 0) {
|
|
264
|
+
throw new ToolCallIntegrityError(
|
|
265
|
+
`Event '${event.id}' has integrity stamps with no matching call: ${JSON.stringify(unmatched)}.`
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return void 0;
|
|
270
|
+
}
|
|
271
|
+
async beforeToolCallback({
|
|
272
|
+
tool,
|
|
273
|
+
toolArgs,
|
|
274
|
+
toolContext
|
|
275
|
+
}) {
|
|
276
|
+
const callId = toolContext.functionCallId;
|
|
277
|
+
if (!callId) {
|
|
278
|
+
throw new ToolCallIntegrityError(
|
|
279
|
+
`${tool.name} call has no ID, so its integrity cannot be checked.`
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
const session = toolContext.invocationContext.session;
|
|
283
|
+
const stored = [];
|
|
284
|
+
let restored = false;
|
|
285
|
+
for (const event of session.events) {
|
|
286
|
+
for (const fc of getFunctionCalls(event)) {
|
|
287
|
+
if (fc.id !== callId) {
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
if (isRestored(event)) {
|
|
291
|
+
restored = true;
|
|
292
|
+
} else {
|
|
293
|
+
stored.push([event, fc]);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
if (stored.length === 0) {
|
|
298
|
+
if (restored) {
|
|
299
|
+
throw new ToolCallIntegrityError(
|
|
300
|
+
`${tool.name} call '${callId}' comes from restored history and cannot be executed.`
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
this.unstamped(tool.name, callId);
|
|
304
|
+
return void 0;
|
|
305
|
+
}
|
|
306
|
+
const trusted = [];
|
|
307
|
+
for (const [event, fc] of stored) {
|
|
308
|
+
const stamps = getStamps(event);
|
|
309
|
+
if (!hasStamp(stamps, callId)) {
|
|
310
|
+
this.unstamped(tool.name, callId);
|
|
311
|
+
} else if (!await this.verify(
|
|
312
|
+
canonicalPayload(session, event, fc),
|
|
313
|
+
stamps[callId]
|
|
314
|
+
)) {
|
|
315
|
+
throw new ToolCallIntegrityError(
|
|
316
|
+
`${tool.name} call '${callId}' does not match its integrity stamp.`
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
trusted.push(fc);
|
|
320
|
+
}
|
|
321
|
+
const executed = canonicalJson(jsonArgs(toolArgs));
|
|
322
|
+
const matches = trusted.some(
|
|
323
|
+
(fc) => fc.name === tool.name && canonicalJson(jsonArgs(fc.args)) === executed
|
|
324
|
+
);
|
|
325
|
+
if (!matches) {
|
|
326
|
+
throw new ToolCallIntegrityError(
|
|
327
|
+
`${tool.name} call '${callId}' arguments do not match its stored call.`
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
return void 0;
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
__name(_ToolCallIntegrityPlugin, "ToolCallIntegrityPlugin");
|
|
334
|
+
let ToolCallIntegrityPlugin = _ToolCallIntegrityPlugin;
|
|
335
|
+
export {
|
|
336
|
+
TOOL_CALL_HMAC_METADATA_KEY,
|
|
337
|
+
ToolCallIntegrityError,
|
|
338
|
+
ToolCallIntegrityPlugin
|
|
339
|
+
};
|
|
@@ -33,6 +33,10 @@ import {
|
|
|
33
33
|
} from "../code_executors/built_in_code_executor.js";
|
|
34
34
|
import { createEvent } from "../events/event.js";
|
|
35
35
|
import { createEventActions } from "../events/event_actions.js";
|
|
36
|
+
import {
|
|
37
|
+
internalMetadata,
|
|
38
|
+
withoutInternalMetadata
|
|
39
|
+
} from "../events/internal_metadata.js";
|
|
36
40
|
import { PluginManager } from "../plugins/plugin_manager.js";
|
|
37
41
|
import {
|
|
38
42
|
runAsyncGeneratorWithOtelContext,
|
|
@@ -218,7 +222,8 @@ const _Runner = class _Runner {
|
|
|
218
222
|
author: "user",
|
|
219
223
|
actions: stateDelta ? createEventActions({ stateDelta }) : void 0,
|
|
220
224
|
content: newMessage,
|
|
221
|
-
|
|
225
|
+
// Callers cannot set ADK-internal keys.
|
|
226
|
+
customMetadata: withoutInternalMetadata(params.customMetadata)
|
|
222
227
|
})
|
|
223
228
|
});
|
|
224
229
|
if ((_e = params.abortSignal) == null ? void 0 : _e.aborted) {
|
|
@@ -262,7 +267,7 @@ const _Runner = class _Runner {
|
|
|
262
267
|
event
|
|
263
268
|
});
|
|
264
269
|
const outputEvent = modifiedEvent ? {
|
|
265
|
-
...modifiedEvent,
|
|
270
|
+
...withInternalMetadataOf(event, modifiedEvent),
|
|
266
271
|
id: event.id,
|
|
267
272
|
invocationId: event.invocationId,
|
|
268
273
|
timestamp: event.timestamp,
|
|
@@ -514,7 +519,7 @@ const _Runner = class _Runner {
|
|
|
514
519
|
if ((_d2 = params.abortSignal) == null ? void 0 : _d2.aborted) {
|
|
515
520
|
return;
|
|
516
521
|
}
|
|
517
|
-
const eventToProcess = modifiedEvent
|
|
522
|
+
const eventToProcess = modifiedEvent ? withInternalMetadataOf(event, modifiedEvent) : event;
|
|
518
523
|
if (!eventToProcess.partial && !isLiveModelMediaEventWithInlineData(eventToProcess)) {
|
|
519
524
|
await this.sessionService.appendEvent({
|
|
520
525
|
session,
|
|
@@ -533,6 +538,18 @@ const _Runner = class _Runner {
|
|
|
533
538
|
};
|
|
534
539
|
__name(_Runner, "Runner");
|
|
535
540
|
let Runner = _Runner;
|
|
541
|
+
function withInternalMetadataOf(original, replacement) {
|
|
542
|
+
var _a2;
|
|
543
|
+
const internal = internalMetadata(original.customMetadata);
|
|
544
|
+
if (Object.keys(internal).length === 0) {
|
|
545
|
+
return replacement;
|
|
546
|
+
}
|
|
547
|
+
return {
|
|
548
|
+
...replacement,
|
|
549
|
+
customMetadata: { ...(_a2 = replacement.customMetadata) != null ? _a2 : {}, ...internal }
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
__name(withInternalMetadataOf, "withInternalMetadataOf");
|
|
536
553
|
function isLiveModelMediaEventWithInlineData(event) {
|
|
537
554
|
var _a2;
|
|
538
555
|
const parts = (_a2 = event.content) == null ? void 0 : _a2.parts;
|
|
@@ -35,7 +35,7 @@ const _ExampleTool = class _ExampleTool extends BaseTool {
|
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
appendInstructions(llmRequest, [
|
|
38
|
-
buildExampleSi(this.examples, parts[0].text, llmRequest.model)
|
|
38
|
+
await buildExampleSi(this.examples, parts[0].text, llmRequest.model)
|
|
39
39
|
]);
|
|
40
40
|
}
|
|
41
41
|
};
|
|
@@ -28,6 +28,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
* Copyright 2025 Google LLC
|
|
29
29
|
* SPDX-License-Identifier: Apache-2.0
|
|
30
30
|
*/
|
|
31
|
+
import { mergeTrackingHeaders } from "../../utils/client_labels.js";
|
|
31
32
|
import { formatError } from "../../utils/error_utils.js";
|
|
32
33
|
import { logger } from "../../utils/logger.js";
|
|
33
34
|
import { loadOptionalPeer } from "../../utils/optional_peer.js";
|
|
@@ -39,13 +40,24 @@ function logTransportError(err) {
|
|
|
39
40
|
logger.error("MCP transport error: " + formatError(err));
|
|
40
41
|
}
|
|
41
42
|
__name(logTransportError, "logTransportError");
|
|
43
|
+
function buildTransportOptions(params) {
|
|
44
|
+
const { transportOptions, header } = params;
|
|
45
|
+
const callerHeaders = (transportOptions == null ? void 0 : transportOptions.requestInit) === void 0 ? header : transportOptions.requestInit.headers;
|
|
46
|
+
return {
|
|
47
|
+
...transportOptions,
|
|
48
|
+
requestInit: {
|
|
49
|
+
...transportOptions == null ? void 0 : transportOptions.requestInit,
|
|
50
|
+
headers: mergeTrackingHeaders(callerHeaders)
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
__name(buildTransportOptions, "buildTransportOptions");
|
|
42
55
|
const _MCPSessionManager = class _MCPSessionManager {
|
|
43
56
|
constructor(connectionParams) {
|
|
44
57
|
this.activeSessions = /* @__PURE__ */ new Set();
|
|
45
58
|
this.connectionParams = connectionParams;
|
|
46
59
|
}
|
|
47
60
|
async createSession() {
|
|
48
|
-
var _a;
|
|
49
61
|
const { Client } = await loadOptionalPeer(
|
|
50
62
|
MCP_SDK,
|
|
51
63
|
() => Promise.resolve().then(() => __toESM(require("@modelcontextprotocol/sdk/client/index.js"), 1))
|
|
@@ -66,19 +78,13 @@ const _MCPSessionManager = class _MCPSessionManager {
|
|
|
66
78
|
break;
|
|
67
79
|
}
|
|
68
80
|
case "StreamableHTTPConnectionParams": {
|
|
69
|
-
const options = (_a = this.connectionParams.transportOptions) != null ? _a : {};
|
|
70
|
-
if (!options.requestInit && this.connectionParams.header !== void 0) {
|
|
71
|
-
options.requestInit = {
|
|
72
|
-
headers: this.connectionParams.header
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
81
|
const { StreamableHTTPClientTransport } = await loadOptionalPeer(
|
|
76
82
|
MCP_SDK,
|
|
77
83
|
() => Promise.resolve().then(() => __toESM(require("@modelcontextprotocol/sdk/client/streamableHttp.js"), 1))
|
|
78
84
|
);
|
|
79
85
|
const transport = new StreamableHTTPClientTransport(
|
|
80
86
|
new URL(this.connectionParams.url),
|
|
81
|
-
|
|
87
|
+
buildTransportOptions(this.connectionParams)
|
|
82
88
|
);
|
|
83
89
|
transport.onerror = logTransportError;
|
|
84
90
|
await client.connect(transport);
|