@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
|
@@ -16,6 +16,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
16
16
|
* Copyright 2026 Google LLC
|
|
17
17
|
* SPDX-License-Identifier: Apache-2.0
|
|
18
18
|
*/
|
|
19
|
+
import { toSnakeCaseName } from "../../../utils/case_utils.js";
|
|
19
20
|
import { experimental } from "../../../utils/experimental.js";
|
|
20
21
|
import { OperationParser } from "./operation_parser.js";
|
|
21
22
|
const VALID_SCHEMA_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -47,9 +48,13 @@ __decorateClass([
|
|
|
47
48
|
OpenApiSpecParser = __decorateClass([
|
|
48
49
|
experimental
|
|
49
50
|
], OpenApiSpecParser);
|
|
51
|
+
function deepCopy(value) {
|
|
52
|
+
return JSON.parse(JSON.stringify(value));
|
|
53
|
+
}
|
|
54
|
+
__name(deepCopy, "deepCopy");
|
|
50
55
|
function resolveReferences(spec) {
|
|
51
56
|
const resolvedCache = /* @__PURE__ */ new Map();
|
|
52
|
-
const specCopy =
|
|
57
|
+
const specCopy = deepCopy(spec);
|
|
53
58
|
const recursiveResolve = /* @__PURE__ */ __name((obj, currentDoc, seenRefs = /* @__PURE__ */ new Set()) => {
|
|
54
59
|
if (typeof obj !== "object" || obj === null) {
|
|
55
60
|
return obj;
|
|
@@ -67,13 +72,13 @@ function resolveReferences(spec) {
|
|
|
67
72
|
}
|
|
68
73
|
seenRefs.add(refString);
|
|
69
74
|
if (resolvedCache.has(refString)) {
|
|
70
|
-
return resolvedCache.get(refString);
|
|
75
|
+
return deepCopy(resolvedCache.get(refString));
|
|
71
76
|
}
|
|
72
77
|
let resolvedValue = resolveRef(refString, currentDoc);
|
|
73
78
|
if (resolvedValue !== void 0) {
|
|
74
79
|
resolvedValue = recursiveResolve(resolvedValue, currentDoc, seenRefs);
|
|
75
80
|
resolvedCache.set(refString, resolvedValue);
|
|
76
|
-
return resolvedValue;
|
|
81
|
+
return deepCopy(resolvedValue);
|
|
77
82
|
} else {
|
|
78
83
|
return obj;
|
|
79
84
|
}
|
|
@@ -104,7 +109,6 @@ function resolveRef(refString, currentDoc) {
|
|
|
104
109
|
}
|
|
105
110
|
__name(resolveRef, "resolveRef");
|
|
106
111
|
function sanitizeSchemaTypes(openapiSpec) {
|
|
107
|
-
const specCopy = JSON.parse(JSON.stringify(openapiSpec));
|
|
108
112
|
const sanitizeTypeField = /* @__PURE__ */ __name((schemaDict) => {
|
|
109
113
|
if (!("type" in schemaDict)) return;
|
|
110
114
|
const typeValue = schemaDict["type"];
|
|
@@ -150,7 +154,7 @@ function sanitizeSchemaTypes(openapiSpec) {
|
|
|
150
154
|
}
|
|
151
155
|
return objRecord;
|
|
152
156
|
}, "sanitizeRecursive");
|
|
153
|
-
return sanitizeRecursive(
|
|
157
|
+
return sanitizeRecursive(openapiSpec, false);
|
|
154
158
|
}
|
|
155
159
|
__name(sanitizeSchemaTypes, "sanitizeSchemaTypes");
|
|
156
160
|
function resolveServerUrl(server) {
|
|
@@ -198,7 +202,7 @@ function collectOperations(spec, options = {}) {
|
|
|
198
202
|
const opParams = operation.parameters || [];
|
|
199
203
|
operation.parameters = [...opParams, ...pathParams];
|
|
200
204
|
if (!operation.operationId) {
|
|
201
|
-
operation.operationId = `${
|
|
205
|
+
operation.operationId = toSnakeCaseName(`${path}_${method}`);
|
|
202
206
|
}
|
|
203
207
|
const parser = new OperationParser(operation, {
|
|
204
208
|
preservePropertyNames
|
|
@@ -215,6 +219,7 @@ function collectOperations(spec, options = {}) {
|
|
|
215
219
|
endpoint: { baseUrl, path, method },
|
|
216
220
|
operation,
|
|
217
221
|
parameters: parser.getParameters(),
|
|
222
|
+
returnValue: parser.getReturnValue(),
|
|
218
223
|
authScheme
|
|
219
224
|
});
|
|
220
225
|
}
|
|
@@ -16,23 +16,48 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
16
16
|
* Copyright 2026 Google LLC
|
|
17
17
|
* SPDX-License-Identifier: Apache-2.0
|
|
18
18
|
*/
|
|
19
|
+
import {
|
|
20
|
+
renameReservedKeywords,
|
|
21
|
+
toSnakeCaseName
|
|
22
|
+
} from "../../../utils/case_utils.js";
|
|
19
23
|
import { experimental } from "../../../utils/experimental.js";
|
|
24
|
+
import {
|
|
25
|
+
generateParamDoc,
|
|
26
|
+
generateReturnDoc,
|
|
27
|
+
getTypeHint
|
|
28
|
+
} from "../common/common.js";
|
|
20
29
|
let OperationParser = class {
|
|
30
|
+
/**
|
|
31
|
+
* @param operation The operation to parse. A string is parsed as JSON, and a
|
|
32
|
+
* plain object is used as given.
|
|
33
|
+
* @param options.preservePropertyNames Keeps the original parameter and
|
|
34
|
+
* function names instead of converting them to snake_case.
|
|
35
|
+
* @param options.shouldParse Whether to parse the operation during
|
|
36
|
+
* construction. Defaults to `true`.
|
|
37
|
+
*/
|
|
21
38
|
constructor(operation, options = {}) {
|
|
22
|
-
this.operation = operation;
|
|
23
39
|
this.params = [];
|
|
24
|
-
var _a;
|
|
40
|
+
var _a, _b;
|
|
41
|
+
this.operation = typeof operation === "string" ? JSON.parse(operation) : operation;
|
|
25
42
|
this.preservePropertyNames = (_a = options.preservePropertyNames) != null ? _a : false;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
43
|
+
if ((_b = options.shouldParse) != null ? _b : true) {
|
|
44
|
+
this.processOperationParameters();
|
|
45
|
+
this.processRequestBody();
|
|
46
|
+
this.returnValue = this.processReturnValue();
|
|
47
|
+
this.dedupeParamNames();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
static load(operation, params, returnValue) {
|
|
51
|
+
const parser = new this(operation, { shouldParse: false });
|
|
52
|
+
parser.params = params;
|
|
53
|
+
parser.returnValue = returnValue;
|
|
54
|
+
return parser;
|
|
30
55
|
}
|
|
31
56
|
getParamName(originalName) {
|
|
32
57
|
if (this.preservePropertyNames) {
|
|
33
58
|
return originalName;
|
|
34
59
|
}
|
|
35
|
-
return
|
|
60
|
+
return renameReservedKeywords(toSnakeCaseName(originalName));
|
|
36
61
|
}
|
|
37
62
|
processOperationParameters() {
|
|
38
63
|
const parameters = this.operation.parameters || [];
|
|
@@ -54,6 +79,7 @@ let OperationParser = class {
|
|
|
54
79
|
}
|
|
55
80
|
}
|
|
56
81
|
processRequestBody() {
|
|
82
|
+
var _a;
|
|
57
83
|
const requestBody = this.operation.requestBody;
|
|
58
84
|
if (!requestBody || "$ref" in requestBody) {
|
|
59
85
|
return;
|
|
@@ -64,9 +90,9 @@ let OperationParser = class {
|
|
|
64
90
|
return;
|
|
65
91
|
}
|
|
66
92
|
const mediaTypeObject = content[firstMimeType];
|
|
67
|
-
const schema = mediaTypeObject.schema;
|
|
93
|
+
const schema = (_a = mediaTypeObject.schema) != null ? _a : {};
|
|
68
94
|
const description = requestBody.description || "";
|
|
69
|
-
if (
|
|
95
|
+
if (!("$ref" in schema)) {
|
|
70
96
|
if (schema.type === "object") {
|
|
71
97
|
const properties = schema.properties || {};
|
|
72
98
|
if (Object.keys(properties).length > 0) {
|
|
@@ -121,16 +147,16 @@ let OperationParser = class {
|
|
|
121
147
|
if (min20x) {
|
|
122
148
|
const response = responses[min20x];
|
|
123
149
|
if (!("$ref" in response) && response.content) {
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
const schema = response.content[firstMimeType].schema;
|
|
150
|
+
for (const mediaType of Object.values(response.content)) {
|
|
151
|
+
const schema = mediaType.schema;
|
|
127
152
|
if (schema && !("$ref" in schema)) {
|
|
128
153
|
returnSchema = schema;
|
|
154
|
+
break;
|
|
129
155
|
}
|
|
130
156
|
}
|
|
131
157
|
}
|
|
132
158
|
}
|
|
133
|
-
|
|
159
|
+
return {
|
|
134
160
|
originalName: "",
|
|
135
161
|
paramLocation: "",
|
|
136
162
|
paramSchema: returnSchema,
|
|
@@ -178,6 +204,32 @@ let OperationParser = class {
|
|
|
178
204
|
getDescription() {
|
|
179
205
|
return this.operation.description || this.operation.summary || "";
|
|
180
206
|
}
|
|
207
|
+
getAuthSchemeName() {
|
|
208
|
+
var _a, _b;
|
|
209
|
+
const security = (_a = this.operation.security) != null ? _a : [];
|
|
210
|
+
return security.length > 0 ? (_b = Object.keys(security[0])[0]) != null ? _b : "" : "";
|
|
211
|
+
}
|
|
212
|
+
getReturnValue() {
|
|
213
|
+
return this.returnValue;
|
|
214
|
+
}
|
|
215
|
+
getReturnTypeHint() {
|
|
216
|
+
var _a;
|
|
217
|
+
return getTypeHint((_a = this.returnValue) == null ? void 0 : _a.paramSchema);
|
|
218
|
+
}
|
|
219
|
+
getPydocString() {
|
|
220
|
+
var _a;
|
|
221
|
+
const description = this.operation.summary || this.operation.description || "";
|
|
222
|
+
const argLines = this.params.map((param) => ` ${generateParamDoc(param)}`).join("\n");
|
|
223
|
+
const returnDoc = generateReturnDoc((_a = this.operation.responses) != null ? _a : {});
|
|
224
|
+
const returnBlock = returnDoc ? `
|
|
225
|
+
|
|
226
|
+
${returnDoc}` : "";
|
|
227
|
+
return `"""${description}
|
|
228
|
+
|
|
229
|
+
Args:
|
|
230
|
+
${argLines}${returnBlock}
|
|
231
|
+
"""`;
|
|
232
|
+
}
|
|
181
233
|
};
|
|
182
234
|
__name(OperationParser, "OperationParser");
|
|
183
235
|
__decorateClass([
|
|
@@ -192,6 +244,21 @@ __decorateClass([
|
|
|
192
244
|
__decorateClass([
|
|
193
245
|
experimental
|
|
194
246
|
], OperationParser.prototype, "getDescription", 1);
|
|
247
|
+
__decorateClass([
|
|
248
|
+
experimental
|
|
249
|
+
], OperationParser.prototype, "getAuthSchemeName", 1);
|
|
250
|
+
__decorateClass([
|
|
251
|
+
experimental
|
|
252
|
+
], OperationParser.prototype, "getReturnValue", 1);
|
|
253
|
+
__decorateClass([
|
|
254
|
+
experimental
|
|
255
|
+
], OperationParser.prototype, "getReturnTypeHint", 1);
|
|
256
|
+
__decorateClass([
|
|
257
|
+
experimental
|
|
258
|
+
], OperationParser.prototype, "getPydocString", 1);
|
|
259
|
+
__decorateClass([
|
|
260
|
+
experimental
|
|
261
|
+
], OperationParser, "load", 1);
|
|
195
262
|
OperationParser = __decorateClass([
|
|
196
263
|
experimental
|
|
197
264
|
], OperationParser);
|
|
@@ -16,71 +16,183 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
16
16
|
* Copyright 2026 Google LLC
|
|
17
17
|
* SPDX-License-Identifier: Apache-2.0
|
|
18
18
|
*/
|
|
19
|
+
import { cloneDeep } from "lodash-es";
|
|
20
|
+
import {
|
|
21
|
+
isAuthCredential
|
|
22
|
+
} from "../../../auth/auth_credential.js";
|
|
19
23
|
import { experimental } from "../../../utils/experimental.js";
|
|
24
|
+
import { stableHash } from "../../../utils/hash_utils.js";
|
|
25
|
+
import { logger } from "../../../utils/logger.js";
|
|
20
26
|
import { AutoAuthCredentialExchanger } from "../auth/credential_exchangers/auto_auth_credential_exchanger.js";
|
|
27
|
+
import { AuthCredentialMissingError } from "../auth/credential_exchangers/base_auth_credential_exchanger.js";
|
|
28
|
+
const DEFAULT_CREDENTIAL_KEY = "default_openapi_key";
|
|
21
29
|
const _ToolContextCredentialStore = class _ToolContextCredentialStore {
|
|
22
30
|
constructor(context) {
|
|
23
31
|
this.context = context;
|
|
24
32
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Returns the state key that holds the credential exchanged for this scheme
|
|
35
|
+
* and credential pair.
|
|
36
|
+
*
|
|
37
|
+
* Both operands are hashed into the key, so two tools configured with
|
|
38
|
+
* different schemes, or with different credentials under one scheme, never
|
|
39
|
+
* share a slot.
|
|
40
|
+
*
|
|
41
|
+
* The key deliberately carries no `temp:` prefix. Session state is a copy and
|
|
42
|
+
* only the delta is persisted, and `temp:` is cleared at the end of a run,
|
|
43
|
+
* while an exchanged token has to stay readable across runs.
|
|
44
|
+
*/
|
|
45
|
+
getCredentialKey(authScheme, authCredential) {
|
|
46
|
+
const schemeName = authScheme ? `${authScheme.type}_${stableHash(authScheme)}` : "";
|
|
47
|
+
const credentialName = authCredential ? `${authCredential.authType}_${stableHash(authCredential)}` : "";
|
|
48
|
+
return `${schemeName}_${credentialName}_existing_exchanged_credential`;
|
|
28
49
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Returns the credential stored for this scheme and credential pair, or
|
|
52
|
+
* `undefined` when there is none.
|
|
53
|
+
*
|
|
54
|
+
* @throws Error if the state entry under the key is not an
|
|
55
|
+
* {@link AuthCredential}, which means something else wrote to the key.
|
|
56
|
+
*/
|
|
57
|
+
getCredential(authScheme, authCredential) {
|
|
58
|
+
const key = this.getCredentialKey(authScheme, authCredential);
|
|
59
|
+
const stored = this.context.state.get(key);
|
|
60
|
+
if (stored === void 0 || stored === null) {
|
|
61
|
+
return void 0;
|
|
62
|
+
}
|
|
63
|
+
if (!isAuthCredential(stored)) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
`State entry '${key}' is not an AuthCredential. Another writer has taken this key.`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
return stored;
|
|
32
69
|
}
|
|
33
70
|
storeCredential(key, credential) {
|
|
34
|
-
this.context.state.set(key, credential);
|
|
71
|
+
this.context.state.set(key, JSON.parse(JSON.stringify(credential)));
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Makes the credential under `key` unreadable again.
|
|
75
|
+
*
|
|
76
|
+
* adk-python deletes the state entry. `State` has no delete, so this writes
|
|
77
|
+
* `undefined`, which `State.get` returns for a missing key as well, and
|
|
78
|
+
* {@link getCredential} therefore misses exactly as a delete would make it.
|
|
79
|
+
*/
|
|
80
|
+
removeCredential(key) {
|
|
81
|
+
this.context.state.set(key, void 0);
|
|
35
82
|
}
|
|
36
83
|
};
|
|
37
84
|
__name(_ToolContextCredentialStore, "ToolContextCredentialStore");
|
|
38
85
|
let ToolContextCredentialStore = _ToolContextCredentialStore;
|
|
39
86
|
let ToolAuthHandler = class {
|
|
40
|
-
constructor(context, authScheme, authCredential,
|
|
87
|
+
constructor(context, authScheme, authCredential, options = {}) {
|
|
41
88
|
this.context = context;
|
|
42
|
-
|
|
43
|
-
this.
|
|
44
|
-
this.
|
|
89
|
+
var _a;
|
|
90
|
+
this.authScheme = authScheme ? cloneDeep(authScheme) : void 0;
|
|
91
|
+
this.authCredential = authCredential ? cloneDeep(authCredential) : void 0;
|
|
92
|
+
this.credentialKey = options.credentialKey;
|
|
93
|
+
this.credentialExchanger = options.credentialExchanger;
|
|
94
|
+
this.credentialStore = (_a = options.credentialStore) != null ? _a : new ToolContextCredentialStore(context);
|
|
45
95
|
}
|
|
46
96
|
static fromToolContext(context, authScheme, authCredential, options = {}) {
|
|
47
|
-
return new ToolAuthHandler(
|
|
48
|
-
context,
|
|
49
|
-
authScheme,
|
|
50
|
-
authCredential,
|
|
51
|
-
options.credentialKey
|
|
52
|
-
);
|
|
97
|
+
return new ToolAuthHandler(context, authScheme, authCredential, options);
|
|
53
98
|
}
|
|
54
99
|
async prepareAuthCredentials() {
|
|
55
100
|
if (!this.authScheme) {
|
|
56
101
|
return { state: "done" };
|
|
57
102
|
}
|
|
58
|
-
const
|
|
59
|
-
|
|
103
|
+
const existingCredential = this.credentialStore.getCredential(
|
|
104
|
+
this.authScheme,
|
|
105
|
+
this.authCredential
|
|
106
|
+
);
|
|
60
107
|
if (existingCredential) {
|
|
61
|
-
return {
|
|
108
|
+
return {
|
|
109
|
+
state: "done",
|
|
110
|
+
authScheme: this.authScheme,
|
|
111
|
+
authCredential: existingCredential
|
|
112
|
+
};
|
|
62
113
|
}
|
|
63
114
|
const authConfig = {
|
|
64
115
|
authScheme: this.authScheme,
|
|
65
116
|
rawAuthCredential: this.authCredential,
|
|
66
|
-
credentialKey: this.credentialKey ||
|
|
117
|
+
credentialKey: this.credentialKey || DEFAULT_CREDENTIAL_KEY
|
|
67
118
|
};
|
|
68
119
|
const authResponseCredential = this.context.getAuthResponse(authConfig);
|
|
69
120
|
const credential = authResponseCredential != null ? authResponseCredential : this.authCredential;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
121
|
+
const exchanged = credential ? await this.tryExchange(credential) : void 0;
|
|
122
|
+
if (!exchanged) {
|
|
123
|
+
this.requestCredential(authConfig);
|
|
124
|
+
return {
|
|
125
|
+
state: "pending",
|
|
126
|
+
authScheme: this.authScheme,
|
|
127
|
+
authCredential: this.authCredential
|
|
128
|
+
};
|
|
73
129
|
}
|
|
74
|
-
|
|
75
|
-
|
|
130
|
+
if (authResponseCredential || exchanged.wasExchanged) {
|
|
131
|
+
const key = this.credentialStore.getCredentialKey(
|
|
132
|
+
this.authScheme,
|
|
133
|
+
this.authCredential
|
|
134
|
+
);
|
|
135
|
+
this.credentialStore.storeCredential(key, exchanged.credential);
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
state: "done",
|
|
76
139
|
authScheme: this.authScheme,
|
|
77
|
-
authCredential: credential
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
140
|
+
authCredential: exchanged.credential
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Exchanges `credential`, or returns `undefined` when the exchange failed.
|
|
145
|
+
*
|
|
146
|
+
* An exchange failure is transient far more often than it is fatal, so it
|
|
147
|
+
* becomes a `pending` result the client can resume from rather than an
|
|
148
|
+
* exception that fails the whole tool call.
|
|
149
|
+
*/
|
|
150
|
+
async tryExchange(credential) {
|
|
151
|
+
var _a;
|
|
152
|
+
const exchanger = (_a = this.credentialExchanger) != null ? _a : new AutoAuthCredentialExchanger();
|
|
153
|
+
try {
|
|
154
|
+
return await exchanger.exchange({
|
|
155
|
+
authScheme: this.authScheme,
|
|
156
|
+
authCredential: credential
|
|
157
|
+
});
|
|
158
|
+
} catch (e) {
|
|
159
|
+
logger.error(
|
|
160
|
+
`Failed to exchange credential: ${e instanceof Error ? e.message : e}`
|
|
161
|
+
);
|
|
162
|
+
return void 0;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Asks the client for a credential, after checking that an interactive
|
|
167
|
+
* scheme has the OAuth2 client configuration it cannot proceed without.
|
|
168
|
+
*
|
|
169
|
+
* @throws Error if an `oauth2` or `openIdConnect` scheme has no OAuth2
|
|
170
|
+
* credential.
|
|
171
|
+
* @throws AuthCredentialMissingError if that credential omits `clientId` or
|
|
172
|
+
* `clientSecret`.
|
|
173
|
+
*/
|
|
174
|
+
requestCredential(authConfig) {
|
|
175
|
+
var _a, _b;
|
|
176
|
+
const schemeType = (_a = this.authScheme) == null ? void 0 : _a.type;
|
|
177
|
+
if (schemeType === "oauth2" || schemeType === "openIdConnect") {
|
|
178
|
+
const oauth2 = (_b = this.authCredential) == null ? void 0 : _b.oauth2;
|
|
179
|
+
if (!oauth2) {
|
|
180
|
+
throw new Error(
|
|
181
|
+
`authCredential is empty for scheme ${schemeType}. Please create AuthCredential using OAuth2Auth.`
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
if (!oauth2.clientId) {
|
|
185
|
+
throw new AuthCredentialMissingError(
|
|
186
|
+
"OAuth2 credentials clientId is missing."
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
if (!oauth2.clientSecret) {
|
|
190
|
+
throw new AuthCredentialMissingError(
|
|
191
|
+
"OAuth2 credentials clientSecret is missing."
|
|
192
|
+
);
|
|
193
|
+
}
|
|
82
194
|
}
|
|
83
|
-
|
|
195
|
+
this.context.requestCredential(authConfig);
|
|
84
196
|
}
|
|
85
197
|
};
|
|
86
198
|
__name(ToolAuthHandler, "ToolAuthHandler");
|
|
@@ -94,5 +206,6 @@ ToolAuthHandler = __decorateClass([
|
|
|
94
206
|
experimental
|
|
95
207
|
], ToolAuthHandler);
|
|
96
208
|
export {
|
|
97
|
-
ToolAuthHandler
|
|
209
|
+
ToolAuthHandler,
|
|
210
|
+
ToolContextCredentialStore
|
|
98
211
|
};
|
|
@@ -18,6 +18,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
18
18
|
*/
|
|
19
19
|
import yaml from "js-yaml";
|
|
20
20
|
import { experimental } from "../../utils/experimental.js";
|
|
21
|
+
import { logger } from "../../utils/logger.js";
|
|
21
22
|
import { BaseToolset } from "../base_toolset.js";
|
|
22
23
|
import { OpenApiSpecParser } from "./openapi_spec_parser/openapi_spec_parser.js";
|
|
23
24
|
import { createRestApiTool } from "./rest_api_tool.js";
|
|
@@ -29,8 +30,10 @@ let OpenAPIToolset = class extends BaseToolset {
|
|
|
29
30
|
if (!spec && options.specStr) {
|
|
30
31
|
if (options.specType === "yaml" || !options.specType && options.specStr.trim().startsWith("---")) {
|
|
31
32
|
spec = yaml.load(options.specStr);
|
|
32
|
-
} else {
|
|
33
|
+
} else if (options.specType === "json" || !options.specType) {
|
|
33
34
|
spec = JSON.parse(options.specStr);
|
|
35
|
+
} else {
|
|
36
|
+
throw new Error(`Unsupported spec type: ${options.specType}`);
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
if (!spec) {
|
|
@@ -51,7 +54,9 @@ let OpenAPIToolset = class extends BaseToolset {
|
|
|
51
54
|
description: op.description,
|
|
52
55
|
endpoint: op.endpoint,
|
|
53
56
|
operation: op.operation,
|
|
54
|
-
authScheme: op.authScheme
|
|
57
|
+
authScheme: op.authScheme,
|
|
58
|
+
parameters: op.parameters,
|
|
59
|
+
authCredential: op.authCredential
|
|
55
60
|
},
|
|
56
61
|
{
|
|
57
62
|
preservePropertyNames: options.preservePropertyNames,
|
|
@@ -60,6 +65,7 @@ let OpenAPIToolset = class extends BaseToolset {
|
|
|
60
65
|
}
|
|
61
66
|
);
|
|
62
67
|
this.tools.push(tool);
|
|
68
|
+
logger.info(`Parsed tool: ${tool.name}`);
|
|
63
69
|
}
|
|
64
70
|
if (options.authScheme || options.authCredential) {
|
|
65
71
|
for (const tool of this.tools) {
|
|
@@ -80,6 +86,9 @@ let OpenAPIToolset = class extends BaseToolset {
|
|
|
80
86
|
return true;
|
|
81
87
|
});
|
|
82
88
|
}
|
|
89
|
+
getTool(toolName) {
|
|
90
|
+
return this.tools.find((tool) => tool.name === toolName);
|
|
91
|
+
}
|
|
83
92
|
async close() {
|
|
84
93
|
return Promise.resolve();
|
|
85
94
|
}
|
|
@@ -88,6 +97,9 @@ __name(OpenAPIToolset, "OpenAPIToolset");
|
|
|
88
97
|
__decorateClass([
|
|
89
98
|
experimental
|
|
90
99
|
], OpenAPIToolset.prototype, "getTools", 1);
|
|
100
|
+
__decorateClass([
|
|
101
|
+
experimental
|
|
102
|
+
], OpenAPIToolset.prototype, "getTool", 1);
|
|
91
103
|
__decorateClass([
|
|
92
104
|
experimental
|
|
93
105
|
], OpenAPIToolset.prototype, "close", 1);
|