@google/adk 0.2.4 → 0.3.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.
- package/dist/cjs/agents/base_agent.js +52 -24
- package/dist/cjs/agents/callback_context.js +4 -1
- package/dist/cjs/agents/content_processor_utils.js +15 -7
- package/dist/cjs/agents/functions.js +79 -29
- package/dist/cjs/agents/invocation_context.js +3 -1
- package/dist/cjs/agents/llm_agent.js +188 -108
- package/dist/cjs/agents/loop_agent.js +18 -6
- package/dist/cjs/agents/parallel_agent.js +20 -7
- package/dist/cjs/agents/readonly_context.js +4 -1
- package/dist/cjs/agents/sequential_agent.js +34 -12
- package/dist/cjs/artifacts/gcs_artifact_service.js +28 -20
- package/dist/cjs/artifacts/in_memory_artifact_service.js +18 -4
- package/dist/cjs/auth/auth_handler.js +3 -1
- package/dist/cjs/code_executors/base_code_executor.js +14 -2
- package/dist/cjs/code_executors/built_in_code_executor.js +21 -5
- package/dist/cjs/code_executors/code_executor_context.js +5 -5
- package/dist/cjs/common.js +45 -0
- package/dist/cjs/events/event.js +1 -3
- package/dist/cjs/examples/base_example_provider.js +18 -2
- package/dist/cjs/examples/example_util.js +1 -1
- package/dist/cjs/index.js +19 -19
- package/dist/cjs/index.js.map +4 -4
- package/dist/cjs/memory/in_memory_memory_service.js +3 -1
- package/dist/cjs/models/base_llm.js +8 -4
- package/dist/cjs/models/gemini_llm_connection.js +1 -0
- package/dist/cjs/models/google_llm.js +3 -3
- package/dist/cjs/plugins/base_plugin.js +71 -49
- package/dist/cjs/plugins/logging_plugin.js +50 -13
- package/dist/cjs/plugins/plugin_manager.js +56 -24
- package/dist/cjs/plugins/security_plugin.js +5 -2
- package/dist/cjs/runner/runner.js +126 -101
- package/dist/cjs/sessions/in_memory_session_service.js +38 -14
- package/dist/cjs/telemetry/google_cloud.js +7 -9
- package/dist/cjs/telemetry/setup.js +15 -7
- package/dist/cjs/telemetry/tracing.js +37 -15
- package/dist/cjs/tools/agent_tool.js +26 -13
- package/dist/cjs/tools/base_tool.js +19 -7
- package/dist/cjs/tools/forwarding_artifact_service.js +1 -1
- package/dist/cjs/tools/function_tool.js +15 -7
- package/dist/cjs/tools/google_search_tool.js +8 -4
- package/dist/cjs/tools/mcp/mcp_session_manager.js +16 -10
- package/dist/cjs/tools/mcp/mcp_tool.js +1 -3
- package/dist/cjs/tools/mcp/mcp_toolset.js +1 -1
- package/dist/cjs/tools/tool_context.js +4 -9
- package/dist/cjs/utils/env_aware_utils.js +1 -1
- package/dist/cjs/utils/gemini_schema_util.js +10 -4
- package/dist/cjs/utils/logger.js +47 -3
- package/dist/cjs/utils/simple_zod_to_json.js +100 -141
- package/dist/cjs/utils/variant_utils.js +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/agents/base_agent.js +57 -25
- package/dist/esm/agents/callback_context.js +4 -1
- package/dist/esm/agents/content_processor_utils.js +25 -9
- package/dist/esm/agents/functions.js +83 -29
- package/dist/esm/agents/invocation_context.js +3 -1
- package/dist/esm/agents/llm_agent.js +228 -116
- package/dist/esm/agents/loop_agent.js +16 -5
- package/dist/esm/agents/parallel_agent.js +18 -6
- package/dist/esm/agents/readonly_context.js +4 -1
- package/dist/esm/agents/sequential_agent.js +33 -12
- package/dist/esm/artifacts/gcs_artifact_service.js +28 -20
- package/dist/esm/artifacts/in_memory_artifact_service.js +18 -4
- package/dist/esm/auth/auth_handler.js +3 -1
- package/dist/esm/code_executors/base_code_executor.js +12 -1
- package/dist/esm/code_executors/built_in_code_executor.js +19 -4
- package/dist/esm/code_executors/code_executor_context.js +5 -5
- package/dist/esm/common.js +56 -11
- package/dist/esm/events/event.js +1 -3
- package/dist/esm/examples/base_example_provider.js +16 -1
- package/dist/esm/examples/example_util.js +4 -2
- package/dist/esm/index.js +19 -19
- package/dist/esm/index.js.map +4 -4
- package/dist/esm/memory/in_memory_memory_service.js +3 -1
- package/dist/esm/models/base_llm.js +8 -4
- package/dist/esm/models/gemini_llm_connection.js +1 -0
- package/dist/esm/models/google_llm.js +8 -4
- package/dist/esm/plugins/base_plugin.js +71 -49
- package/dist/esm/plugins/logging_plugin.js +55 -14
- package/dist/esm/plugins/plugin_manager.js +56 -24
- package/dist/esm/plugins/security_plugin.js +5 -2
- package/dist/esm/runner/runner.js +139 -105
- package/dist/esm/sessions/in_memory_session_service.js +41 -15
- package/dist/esm/telemetry/google_cloud.js +7 -9
- package/dist/esm/telemetry/setup.js +23 -9
- package/dist/esm/telemetry/tracing.js +37 -15
- package/dist/esm/tools/agent_tool.js +25 -13
- package/dist/esm/tools/base_tool.js +17 -6
- package/dist/esm/tools/forwarding_artifact_service.js +1 -1
- package/dist/esm/tools/function_tool.js +13 -8
- package/dist/esm/tools/google_search_tool.js +6 -3
- package/dist/esm/tools/long_running_tool.js +3 -1
- package/dist/esm/tools/mcp/mcp_session_manager.js +22 -12
- package/dist/esm/tools/mcp/mcp_tool.js +1 -3
- package/dist/esm/tools/mcp/mcp_toolset.js +1 -1
- package/dist/esm/tools/tool_context.js +4 -9
- package/dist/esm/utils/env_aware_utils.js +1 -1
- package/dist/esm/utils/gemini_schema_util.js +10 -4
- package/dist/esm/utils/logger.js +43 -2
- package/dist/esm/utils/simple_zod_to_json.js +102 -141
- package/dist/esm/utils/variant_utils.js +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/types/agents/base_agent.d.ts +16 -4
- package/dist/types/agents/callback_context.d.ts +1 -1
- package/dist/types/agents/invocation_context.d.ts +4 -2
- package/dist/types/agents/llm_agent.d.ts +43 -31
- package/dist/types/agents/loop_agent.d.ts +17 -1
- package/dist/types/agents/parallel_agent.d.ts +17 -1
- package/dist/types/agents/sequential_agent.d.ts +17 -1
- package/dist/types/artifacts/in_memory_artifact_service.d.ts +3 -3
- package/dist/types/auth/auth_schemes.d.ts +5 -2
- package/dist/types/code_executors/base_code_executor.d.ts +14 -0
- package/dist/types/code_executors/built_in_code_executor.d.ts +20 -1
- package/dist/types/code_executors/code_executor_context.d.ts +2 -4
- package/dist/types/common.d.ts +40 -15
- package/dist/types/examples/base_example_provider.d.ts +16 -0
- package/dist/types/index.d.ts +3 -3
- package/dist/types/models/base_llm_connection.d.ts +1 -1
- package/dist/types/models/llm_response.d.ts +1 -1
- package/dist/types/plugins/base_plugin.d.ts +50 -40
- package/dist/types/plugins/logging_plugin.d.ts +12 -12
- package/dist/types/plugins/plugin_manager.d.ts +12 -12
- package/dist/types/plugins/security_plugin.d.ts +1 -1
- package/dist/types/runner/runner.d.ts +18 -10
- package/dist/types/sessions/in_memory_session_service.d.ts +5 -5
- package/dist/types/telemetry/setup.d.ts +1 -1
- package/dist/types/telemetry/tracing.d.ts +7 -6
- package/dist/types/tools/agent_tool.d.ts +15 -1
- package/dist/types/tools/base_tool.d.ts +15 -1
- package/dist/types/tools/base_toolset.d.ts +2 -1
- package/dist/types/tools/forwarding_artifact_service.d.ts +2 -2
- package/dist/types/tools/function_tool.d.ts +18 -4
- package/dist/types/tools/google_search_tool.d.ts +5 -6
- package/dist/types/tools/mcp/mcp_session_manager.d.ts +10 -3
- package/dist/types/tools/mcp/mcp_toolset.d.ts +1 -2
- package/dist/types/tools/tool_context.d.ts +1 -1
- package/dist/types/utils/gemini_schema_util.d.ts +4 -12
- package/dist/types/utils/logger.d.ts +11 -10
- package/dist/types/utils/simple_zod_to_json.d.ts +5 -4
- package/dist/types/version.d.ts +1 -1
- package/dist/web/agents/base_agent.js +103 -36
- package/dist/web/agents/callback_context.js +4 -1
- package/dist/web/agents/content_processor_utils.js +25 -9
- package/dist/web/agents/functions.js +83 -29
- package/dist/web/agents/invocation_context.js +3 -1
- package/dist/web/agents/llm_agent.js +282 -137
- package/dist/web/agents/loop_agent.js +16 -5
- package/dist/web/agents/parallel_agent.js +18 -6
- package/dist/web/agents/readonly_context.js +4 -1
- package/dist/web/agents/sequential_agent.js +33 -12
- package/dist/web/artifacts/gcs_artifact_service.js +25 -17
- package/dist/web/artifacts/in_memory_artifact_service.js +18 -4
- package/dist/web/auth/auth_handler.js +3 -1
- package/dist/web/code_executors/base_code_executor.js +12 -1
- package/dist/web/code_executors/built_in_code_executor.js +19 -4
- package/dist/web/code_executors/code_executor_context.js +5 -5
- package/dist/web/common.js +56 -11
- package/dist/web/events/event.js +1 -3
- package/dist/web/examples/base_example_provider.js +16 -1
- package/dist/web/examples/example_util.js +4 -2
- package/dist/web/index.js +1 -1
- package/dist/web/index.js.map +4 -4
- package/dist/web/memory/in_memory_memory_service.js +3 -1
- package/dist/web/models/base_llm.js +8 -4
- package/dist/web/models/gemini_llm_connection.js +1 -0
- package/dist/web/models/google_llm.js +8 -4
- package/dist/web/plugins/base_plugin.js +71 -49
- package/dist/web/plugins/logging_plugin.js +55 -14
- package/dist/web/plugins/plugin_manager.js +56 -24
- package/dist/web/plugins/security_plugin.js +5 -2
- package/dist/web/runner/runner.js +186 -119
- package/dist/web/sessions/in_memory_session_service.js +41 -15
- package/dist/web/telemetry/google_cloud.js +7 -9
- package/dist/web/telemetry/setup.js +23 -9
- package/dist/web/telemetry/tracing.js +37 -15
- package/dist/web/tools/agent_tool.js +25 -13
- package/dist/web/tools/base_tool.js +17 -6
- package/dist/web/tools/forwarding_artifact_service.js +1 -1
- package/dist/web/tools/function_tool.js +13 -8
- package/dist/web/tools/google_search_tool.js +6 -3
- package/dist/web/tools/long_running_tool.js +3 -1
- package/dist/web/tools/mcp/mcp_session_manager.js +22 -12
- package/dist/web/tools/mcp/mcp_tool.js +1 -3
- package/dist/web/tools/mcp/mcp_toolset.js +1 -1
- package/dist/web/tools/tool_context.js +4 -9
- package/dist/web/utils/env_aware_utils.js +1 -1
- package/dist/web/utils/gemini_schema_util.js +10 -4
- package/dist/web/utils/logger.js +43 -2
- package/dist/web/utils/simple_zod_to_json.js +102 -155
- package/dist/web/utils/variant_utils.js +1 -1
- package/dist/web/version.js +1 -1
- package/package.json +5 -3
|
@@ -24,7 +24,8 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
24
24
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
25
25
|
var base_tool_exports = {};
|
|
26
26
|
__export(base_tool_exports, {
|
|
27
|
-
BaseTool: () => BaseTool
|
|
27
|
+
BaseTool: () => BaseTool,
|
|
28
|
+
isBaseTool: () => isBaseTool
|
|
28
29
|
});
|
|
29
30
|
module.exports = __toCommonJS(base_tool_exports);
|
|
30
31
|
var import_variant_utils = require("../utils/variant_utils.js");
|
|
@@ -33,6 +34,12 @@ var import_variant_utils = require("../utils/variant_utils.js");
|
|
|
33
34
|
* Copyright 2025 Google LLC
|
|
34
35
|
* SPDX-License-Identifier: Apache-2.0
|
|
35
36
|
*/
|
|
37
|
+
var _a;
|
|
38
|
+
const BASE_TOOL_SIGNATURE_SYMBOL = Symbol.for("google.adk.baseTool");
|
|
39
|
+
function isBaseTool(obj) {
|
|
40
|
+
return typeof obj === "object" && obj !== null && BASE_TOOL_SIGNATURE_SYMBOL in obj && obj[BASE_TOOL_SIGNATURE_SYMBOL] === true;
|
|
41
|
+
}
|
|
42
|
+
_a = BASE_TOOL_SIGNATURE_SYMBOL;
|
|
36
43
|
class BaseTool {
|
|
37
44
|
/**
|
|
38
45
|
* Base constructor for a tool.
|
|
@@ -40,10 +47,12 @@ class BaseTool {
|
|
|
40
47
|
* @param params The parameters for `BaseTool`.
|
|
41
48
|
*/
|
|
42
49
|
constructor(params) {
|
|
43
|
-
|
|
50
|
+
/** A unique symbol to identify ADK base tool class. */
|
|
51
|
+
this[_a] = true;
|
|
52
|
+
var _a2;
|
|
44
53
|
this.name = params.name;
|
|
45
54
|
this.description = params.description;
|
|
46
|
-
this.isLongRunning = (
|
|
55
|
+
this.isLongRunning = (_a2 = params.isLongRunning) != null ? _a2 : false;
|
|
47
56
|
}
|
|
48
57
|
/**
|
|
49
58
|
* Gets the OpenAPI specification of this tool in the form of a
|
|
@@ -70,7 +79,7 @@ class BaseTool {
|
|
|
70
79
|
*
|
|
71
80
|
* @param request The request to process the LLM request.
|
|
72
81
|
*/
|
|
73
|
-
async processLlmRequest({
|
|
82
|
+
async processLlmRequest({ llmRequest }) {
|
|
74
83
|
const functionDeclaration = this._getDeclaration();
|
|
75
84
|
if (!functionDeclaration) {
|
|
76
85
|
return;
|
|
@@ -98,10 +107,13 @@ class BaseTool {
|
|
|
98
107
|
}
|
|
99
108
|
}
|
|
100
109
|
function findToolWithFunctionDeclarations(llmRequest) {
|
|
101
|
-
var
|
|
102
|
-
return (((
|
|
110
|
+
var _a2;
|
|
111
|
+
return (((_a2 = llmRequest.config) == null ? void 0 : _a2.tools) || []).find(
|
|
112
|
+
(tool) => "functionDeclarations" in tool
|
|
113
|
+
);
|
|
103
114
|
}
|
|
104
115
|
// Annotate the CommonJS export names for ESM import in node:
|
|
105
116
|
0 && (module.exports = {
|
|
106
|
-
BaseTool
|
|
117
|
+
BaseTool,
|
|
118
|
+
isBaseTool
|
|
107
119
|
});
|
|
@@ -45,7 +45,7 @@ class ForwardingArtifactService {
|
|
|
45
45
|
async loadArtifact(request) {
|
|
46
46
|
return this.toolContext.loadArtifact(request.filename, request.version);
|
|
47
47
|
}
|
|
48
|
-
async listArtifactKeys(
|
|
48
|
+
async listArtifactKeys() {
|
|
49
49
|
return this.toolContext.listArtifacts();
|
|
50
50
|
}
|
|
51
51
|
async deleteArtifact(request) {
|
|
@@ -24,11 +24,11 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
24
24
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
25
25
|
var function_tool_exports = {};
|
|
26
26
|
__export(function_tool_exports, {
|
|
27
|
-
FunctionTool: () => FunctionTool
|
|
27
|
+
FunctionTool: () => FunctionTool,
|
|
28
|
+
isFunctionTool: () => isFunctionTool
|
|
28
29
|
});
|
|
29
30
|
module.exports = __toCommonJS(function_tool_exports);
|
|
30
31
|
var import_genai = require("@google/genai");
|
|
31
|
-
var import_zod = require("zod");
|
|
32
32
|
var import_simple_zod_to_json = require("../utils/simple_zod_to_json.js");
|
|
33
33
|
var import_base_tool = require("./base_tool.js");
|
|
34
34
|
/**
|
|
@@ -36,6 +36,7 @@ var import_base_tool = require("./base_tool.js");
|
|
|
36
36
|
* Copyright 2025 Google LLC
|
|
37
37
|
* SPDX-License-Identifier: Apache-2.0
|
|
38
38
|
*/
|
|
39
|
+
var _a, _b;
|
|
39
40
|
function toSchema(parameters) {
|
|
40
41
|
if (parameters === void 0) {
|
|
41
42
|
return { type: import_genai.Type.OBJECT, properties: {} };
|
|
@@ -45,14 +46,18 @@ function toSchema(parameters) {
|
|
|
45
46
|
}
|
|
46
47
|
return parameters;
|
|
47
48
|
}
|
|
48
|
-
|
|
49
|
+
const FUNCTION_TOOL_SIGNATURE_SYMBOL = Symbol.for("google.adk.functionTool");
|
|
50
|
+
function isFunctionTool(obj) {
|
|
51
|
+
return typeof obj === "object" && obj !== null && FUNCTION_TOOL_SIGNATURE_SYMBOL in obj && obj[FUNCTION_TOOL_SIGNATURE_SYMBOL] === true;
|
|
52
|
+
}
|
|
53
|
+
class FunctionTool extends (_b = import_base_tool.BaseTool, _a = FUNCTION_TOOL_SIGNATURE_SYMBOL, _b) {
|
|
49
54
|
/**
|
|
50
55
|
* The constructor acts as the user-friendly factory.
|
|
51
56
|
* @param options The configuration for the tool.
|
|
52
57
|
*/
|
|
53
58
|
constructor(options) {
|
|
54
|
-
var
|
|
55
|
-
const name = (
|
|
59
|
+
var _a2;
|
|
60
|
+
const name = (_a2 = options.name) != null ? _a2 : options.execute.name;
|
|
56
61
|
if (!name) {
|
|
57
62
|
throw new Error(
|
|
58
63
|
"Tool name cannot be empty. Either name the `execute` function or provide a `name`."
|
|
@@ -63,6 +68,8 @@ class FunctionTool extends import_base_tool.BaseTool {
|
|
|
63
68
|
description: options.description,
|
|
64
69
|
isLongRunning: options.isLongRunning
|
|
65
70
|
});
|
|
71
|
+
/** A unique symbol to identify ADK function tool class. */
|
|
72
|
+
this[_a] = true;
|
|
66
73
|
this.execute = options.execute;
|
|
67
74
|
this.parameters = options.parameters;
|
|
68
75
|
}
|
|
@@ -82,7 +89,7 @@ class FunctionTool extends import_base_tool.BaseTool {
|
|
|
82
89
|
async runAsync(req) {
|
|
83
90
|
try {
|
|
84
91
|
let validatedArgs = req.args;
|
|
85
|
-
if (this.parameters
|
|
92
|
+
if ((0, import_simple_zod_to_json.isZodObject)(this.parameters)) {
|
|
86
93
|
validatedArgs = this.parameters.parse(req.args);
|
|
87
94
|
}
|
|
88
95
|
return await this.execute(
|
|
@@ -97,5 +104,6 @@ class FunctionTool extends import_base_tool.BaseTool {
|
|
|
97
104
|
}
|
|
98
105
|
// Annotate the CommonJS export names for ESM import in node:
|
|
99
106
|
0 && (module.exports = {
|
|
100
|
-
FunctionTool
|
|
107
|
+
FunctionTool,
|
|
108
|
+
isFunctionTool
|
|
101
109
|
});
|
|
@@ -24,7 +24,8 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
24
24
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
25
25
|
var google_search_tool_exports = {};
|
|
26
26
|
__export(google_search_tool_exports, {
|
|
27
|
-
GOOGLE_SEARCH: () => GOOGLE_SEARCH
|
|
27
|
+
GOOGLE_SEARCH: () => GOOGLE_SEARCH,
|
|
28
|
+
GoogleSearchTool: () => GoogleSearchTool
|
|
28
29
|
});
|
|
29
30
|
module.exports = __toCommonJS(google_search_tool_exports);
|
|
30
31
|
var import_model_name = require("../utils/model_name.js");
|
|
@@ -38,10 +39,12 @@ class GoogleSearchTool extends import_base_tool.BaseTool {
|
|
|
38
39
|
constructor() {
|
|
39
40
|
super({ name: "google_search", description: "Google Search Tool" });
|
|
40
41
|
}
|
|
41
|
-
runAsync(
|
|
42
|
+
runAsync() {
|
|
42
43
|
return Promise.resolve();
|
|
43
44
|
}
|
|
44
|
-
async processLlmRequest({
|
|
45
|
+
async processLlmRequest({
|
|
46
|
+
llmRequest
|
|
47
|
+
}) {
|
|
45
48
|
if (!llmRequest.model) {
|
|
46
49
|
return;
|
|
47
50
|
}
|
|
@@ -72,5 +75,6 @@ class GoogleSearchTool extends import_base_tool.BaseTool {
|
|
|
72
75
|
const GOOGLE_SEARCH = new GoogleSearchTool();
|
|
73
76
|
// Annotate the CommonJS export names for ESM import in node:
|
|
74
77
|
0 && (module.exports = {
|
|
75
|
-
GOOGLE_SEARCH
|
|
78
|
+
GOOGLE_SEARCH,
|
|
79
|
+
GoogleSearchTool
|
|
76
80
|
});
|
|
@@ -40,6 +40,7 @@ class MCPSessionManager {
|
|
|
40
40
|
this.connectionParams = connectionParams;
|
|
41
41
|
}
|
|
42
42
|
async createSession() {
|
|
43
|
+
var _a;
|
|
43
44
|
const client = new import_client.Client({ name: "MCPClient", version: "1.0.0" });
|
|
44
45
|
switch (this.connectionParams.type) {
|
|
45
46
|
case "StdioConnectionParams":
|
|
@@ -47,20 +48,25 @@ class MCPSessionManager {
|
|
|
47
48
|
new import_stdio.StdioClientTransport(this.connectionParams.serverParams)
|
|
48
49
|
);
|
|
49
50
|
break;
|
|
50
|
-
case "StreamableHTTPConnectionParams":
|
|
51
|
-
const
|
|
52
|
-
|
|
51
|
+
case "StreamableHTTPConnectionParams": {
|
|
52
|
+
const options = (_a = this.connectionParams.transportOptions) != null ? _a : {};
|
|
53
|
+
if (!options.requestInit && this.connectionParams.header !== void 0) {
|
|
54
|
+
options.requestInit = {
|
|
53
55
|
headers: this.connectionParams.header
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
await client.connect(
|
|
57
|
-
new
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
await client.connect(
|
|
59
|
+
new import_streamableHttp.StreamableHTTPClientTransport(
|
|
60
|
+
new URL(this.connectionParams.url),
|
|
61
|
+
options
|
|
62
|
+
)
|
|
63
|
+
);
|
|
60
64
|
break;
|
|
61
|
-
|
|
65
|
+
}
|
|
66
|
+
default: {
|
|
62
67
|
const _exhaustiveCheck = this.connectionParams;
|
|
63
68
|
break;
|
|
69
|
+
}
|
|
64
70
|
}
|
|
65
71
|
return client;
|
|
66
72
|
}
|
|
@@ -41,8 +41,7 @@ class MCPTool extends import_base_tool.BaseTool {
|
|
|
41
41
|
this.mcpSessionManager = mcpSessionManager;
|
|
42
42
|
}
|
|
43
43
|
_getDeclaration() {
|
|
44
|
-
|
|
45
|
-
declaration = {
|
|
44
|
+
return {
|
|
46
45
|
name: this.mcpTool.name,
|
|
47
46
|
description: this.mcpTool.description,
|
|
48
47
|
parameters: (0, import_gemini_schema_util.toGeminiSchema)(this.mcpTool.inputSchema),
|
|
@@ -50,7 +49,6 @@ class MCPTool extends import_base_tool.BaseTool {
|
|
|
50
49
|
// https://modelcontextprotocol.io/specification/2025-06-18/server/tools#tool-result
|
|
51
50
|
response: (0, import_gemini_schema_util.toGeminiSchema)(this.mcpTool.outputSchema)
|
|
52
51
|
};
|
|
53
|
-
return declaration;
|
|
54
52
|
}
|
|
55
53
|
async runAsync(request) {
|
|
56
54
|
const session = await this.mcpSessionManager.createSession();
|
|
@@ -41,7 +41,7 @@ class MCPToolset extends import_base_toolset.BaseToolset {
|
|
|
41
41
|
super(toolFilter);
|
|
42
42
|
this.mcpSessionManager = new import_mcp_session_manager.MCPSessionManager(connectionParams);
|
|
43
43
|
}
|
|
44
|
-
async getTools(
|
|
44
|
+
async getTools() {
|
|
45
45
|
const session = await this.mcpSessionManager.createSession();
|
|
46
46
|
const listResult = await session.listTools();
|
|
47
47
|
import_logger.logger.debug(`number of tools: ${listResult.tools.length}`);
|
|
@@ -47,15 +47,10 @@ class ToolContext extends import_callback_context.CallbackContext {
|
|
|
47
47
|
* @param params.toolConfirmation The tool confirmation of the current tool
|
|
48
48
|
* call.
|
|
49
49
|
*/
|
|
50
|
-
constructor({
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
toolConfirmation
|
|
55
|
-
}) {
|
|
56
|
-
super({ invocationContext, eventActions });
|
|
57
|
-
this.functionCallId = functionCallId;
|
|
58
|
-
this.toolConfirmation = toolConfirmation;
|
|
50
|
+
constructor(params) {
|
|
51
|
+
super(params);
|
|
52
|
+
this.functionCallId = params.functionCallId;
|
|
53
|
+
this.toolConfirmation = params.toolConfirmation;
|
|
59
54
|
}
|
|
60
55
|
get actions() {
|
|
61
56
|
return this.eventActions;
|
|
@@ -34,12 +34,13 @@ var import_zod = require("zod");
|
|
|
34
34
|
* Copyright 2025 Google LLC
|
|
35
35
|
* SPDX-License-Identifier: Apache-2.0
|
|
36
36
|
*/
|
|
37
|
-
const
|
|
37
|
+
const MCPToolSchemaObject = import_zod.z.object({
|
|
38
38
|
type: import_zod.z.literal("object"),
|
|
39
|
-
properties: import_zod.z.record(import_zod.z.unknown()).optional(),
|
|
39
|
+
properties: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional(),
|
|
40
40
|
required: import_zod.z.string().array().optional()
|
|
41
41
|
});
|
|
42
42
|
function toGeminiType(mcpType) {
|
|
43
|
+
if (!mcpType) return import_genai.Type.TYPE_UNSPECIFIED;
|
|
43
44
|
switch (mcpType.toLowerCase()) {
|
|
44
45
|
case "text":
|
|
45
46
|
case "string":
|
|
@@ -80,12 +81,17 @@ function toGeminiSchema(mcpSchema) {
|
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
const geminiType = toGeminiType(mcp.type);
|
|
83
|
-
const geminiSchema = {
|
|
84
|
+
const geminiSchema = {
|
|
85
|
+
type: geminiType,
|
|
86
|
+
description: mcp.description
|
|
87
|
+
};
|
|
84
88
|
if (geminiType === import_genai.Type.OBJECT) {
|
|
85
89
|
geminiSchema.properties = {};
|
|
86
90
|
if (mcp.properties) {
|
|
87
91
|
for (const name in mcp.properties) {
|
|
88
|
-
geminiSchema.properties[name] = recursiveConvert(
|
|
92
|
+
geminiSchema.properties[name] = recursiveConvert(
|
|
93
|
+
mcp.properties[name]
|
|
94
|
+
);
|
|
89
95
|
}
|
|
90
96
|
}
|
|
91
97
|
geminiSchema.required = mcp.required;
|
package/dist/cjs/utils/logger.js
CHANGED
|
@@ -25,8 +25,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
25
25
|
var logger_exports = {};
|
|
26
26
|
__export(logger_exports, {
|
|
27
27
|
LogLevel: () => LogLevel,
|
|
28
|
+
getLogger: () => getLogger,
|
|
28
29
|
logger: () => logger,
|
|
29
|
-
|
|
30
|
+
resetLogger: () => resetLogger,
|
|
31
|
+
setLogLevel: () => setLogLevel,
|
|
32
|
+
setLogger: () => setLogger
|
|
30
33
|
});
|
|
31
34
|
module.exports = __toCommonJS(logger_exports);
|
|
32
35
|
/**
|
|
@@ -92,6 +95,18 @@ class SimpleLogger {
|
|
|
92
95
|
console.error(getColoredPrefix(3 /* ERROR */), ...args);
|
|
93
96
|
}
|
|
94
97
|
}
|
|
98
|
+
class NoOpLogger {
|
|
99
|
+
log(_level, ..._args) {
|
|
100
|
+
}
|
|
101
|
+
debug(..._args) {
|
|
102
|
+
}
|
|
103
|
+
info(..._args) {
|
|
104
|
+
}
|
|
105
|
+
warn(..._args) {
|
|
106
|
+
}
|
|
107
|
+
error(..._args) {
|
|
108
|
+
}
|
|
109
|
+
}
|
|
95
110
|
const LOG_LEVEL_STR = {
|
|
96
111
|
[0 /* DEBUG */]: "DEBUG",
|
|
97
112
|
[1 /* INFO */]: "INFO",
|
|
@@ -112,10 +127,39 @@ const RESET_COLOR = "\x1B[0m";
|
|
|
112
127
|
function getColoredPrefix(level) {
|
|
113
128
|
return `${CONSOLE_COLOR_MAP[level]}[ADK ${LOG_LEVEL_STR[level]}]:${RESET_COLOR}`;
|
|
114
129
|
}
|
|
115
|
-
|
|
130
|
+
let currentLogger = new SimpleLogger();
|
|
131
|
+
function setLogger(customLogger) {
|
|
132
|
+
currentLogger = customLogger != null ? customLogger : new NoOpLogger();
|
|
133
|
+
}
|
|
134
|
+
function getLogger() {
|
|
135
|
+
return currentLogger;
|
|
136
|
+
}
|
|
137
|
+
function resetLogger() {
|
|
138
|
+
currentLogger = new SimpleLogger();
|
|
139
|
+
}
|
|
140
|
+
const logger = {
|
|
141
|
+
log(level, ...args) {
|
|
142
|
+
currentLogger.log(level, ...args);
|
|
143
|
+
},
|
|
144
|
+
debug(...args) {
|
|
145
|
+
currentLogger.debug(...args);
|
|
146
|
+
},
|
|
147
|
+
info(...args) {
|
|
148
|
+
currentLogger.info(...args);
|
|
149
|
+
},
|
|
150
|
+
warn(...args) {
|
|
151
|
+
currentLogger.warn(...args);
|
|
152
|
+
},
|
|
153
|
+
error(...args) {
|
|
154
|
+
currentLogger.error(...args);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
116
157
|
// Annotate the CommonJS export names for ESM import in node:
|
|
117
158
|
0 && (module.exports = {
|
|
118
159
|
LogLevel,
|
|
160
|
+
getLogger,
|
|
119
161
|
logger,
|
|
120
|
-
|
|
162
|
+
resetLogger,
|
|
163
|
+
setLogLevel,
|
|
164
|
+
setLogger
|
|
121
165
|
});
|
|
@@ -29,160 +29,119 @@ __export(simple_zod_to_json_exports, {
|
|
|
29
29
|
});
|
|
30
30
|
module.exports = __toCommonJS(simple_zod_to_json_exports);
|
|
31
31
|
var import_genai = require("@google/genai");
|
|
32
|
-
var
|
|
32
|
+
var import_zod_to_json_schema = require("zod-to-json-schema");
|
|
33
|
+
var import_v4 = require("zod/v4");
|
|
33
34
|
/**
|
|
34
35
|
* @license
|
|
35
36
|
* Copyright 2025 Google LLC
|
|
36
37
|
* SPDX-License-Identifier: Apache-2.0
|
|
37
38
|
*/
|
|
38
|
-
function
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
function isZodSchema(obj) {
|
|
40
|
+
return obj !== null && typeof obj === "object" && "parse" in obj && typeof obj.parse === "function" && "safeParse" in obj && typeof obj.safeParse === "function";
|
|
41
|
+
}
|
|
42
|
+
function isZodV3Schema(obj) {
|
|
43
|
+
return isZodSchema(obj) && !("_zod" in obj);
|
|
44
|
+
}
|
|
45
|
+
function isZodV4Schema(obj) {
|
|
46
|
+
return isZodSchema(obj) && "_zod" in obj;
|
|
41
47
|
}
|
|
42
|
-
function
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
function getZodTypeName(schema) {
|
|
49
|
+
var _a, _b;
|
|
50
|
+
const schemaAny = schema;
|
|
51
|
+
if ((_a = schemaAny._def) == null ? void 0 : _a.typeName) {
|
|
52
|
+
return schemaAny._def.typeName;
|
|
46
53
|
}
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const returnResult = (result2) => {
|
|
51
|
-
if (result2.description === void 0) {
|
|
52
|
-
delete result2.description;
|
|
53
|
-
}
|
|
54
|
-
return result2;
|
|
55
|
-
};
|
|
56
|
-
switch (def.typeName) {
|
|
57
|
-
case import_zod.z.ZodFirstPartyTypeKind.ZodString:
|
|
58
|
-
result.type = import_genai.Type.STRING;
|
|
59
|
-
for (const check of def.checks || []) {
|
|
60
|
-
if (check.kind === "min")
|
|
61
|
-
result.minLength = check.value.toString();
|
|
62
|
-
else if (check.kind === "max")
|
|
63
|
-
result.maxLength = check.value.toString();
|
|
64
|
-
else if (check.kind === "email")
|
|
65
|
-
result.format = "email";
|
|
66
|
-
else if (check.kind === "uuid")
|
|
67
|
-
result.format = "uuid";
|
|
68
|
-
else if (check.kind === "url")
|
|
69
|
-
result.format = "uri";
|
|
70
|
-
else if (check.kind === "regex")
|
|
71
|
-
result.pattern = check.regex.source;
|
|
72
|
-
}
|
|
73
|
-
return returnResult(result);
|
|
74
|
-
case import_zod.z.ZodFirstPartyTypeKind.ZodNumber:
|
|
75
|
-
result.type = import_genai.Type.NUMBER;
|
|
76
|
-
for (const check of def.checks || []) {
|
|
77
|
-
if (check.kind === "min")
|
|
78
|
-
result.minimum = check.value;
|
|
79
|
-
else if (check.kind === "max")
|
|
80
|
-
result.maximum = check.value;
|
|
81
|
-
else if (check.kind === "int")
|
|
82
|
-
result.type = import_genai.Type.INTEGER;
|
|
83
|
-
}
|
|
84
|
-
return returnResult(result);
|
|
85
|
-
case import_zod.z.ZodFirstPartyTypeKind.ZodBoolean:
|
|
86
|
-
result.type = import_genai.Type.BOOLEAN;
|
|
87
|
-
return returnResult(result);
|
|
88
|
-
case import_zod.z.ZodFirstPartyTypeKind.ZodArray:
|
|
89
|
-
result.type = import_genai.Type.ARRAY;
|
|
90
|
-
result.items = parseZodType(def.type);
|
|
91
|
-
if (def.minLength) result.minItems = def.minLength.value.toString();
|
|
92
|
-
if (def.maxLength) result.maxItems = def.maxLength.value.toString();
|
|
93
|
-
return returnResult(result);
|
|
94
|
-
case import_zod.z.ZodFirstPartyTypeKind.ZodObject: {
|
|
95
|
-
const nestedSchema = zodObjectToSchema(zodType);
|
|
96
|
-
return nestedSchema;
|
|
97
|
-
}
|
|
98
|
-
case import_zod.z.ZodFirstPartyTypeKind.ZodLiteral:
|
|
99
|
-
const literalType = typeof def.value;
|
|
100
|
-
result.enum = [def.value.toString()];
|
|
101
|
-
if (literalType === "string") {
|
|
102
|
-
result.type = import_genai.Type.STRING;
|
|
103
|
-
} else if (literalType === "number") {
|
|
104
|
-
result.type = import_genai.Type.NUMBER;
|
|
105
|
-
} else if (literalType === "boolean") {
|
|
106
|
-
result.type = import_genai.Type.BOOLEAN;
|
|
107
|
-
} else if (def.value === null) {
|
|
108
|
-
result.type = import_genai.Type.NULL;
|
|
109
|
-
} else {
|
|
110
|
-
throw new Error(`Unsupported ZodLiteral value type: ${literalType}`);
|
|
111
|
-
}
|
|
112
|
-
return returnResult(result);
|
|
113
|
-
case import_zod.z.ZodFirstPartyTypeKind.ZodEnum:
|
|
114
|
-
result.type = import_genai.Type.STRING;
|
|
115
|
-
result.enum = def.values;
|
|
116
|
-
return returnResult(result);
|
|
117
|
-
case import_zod.z.ZodFirstPartyTypeKind.ZodNativeEnum:
|
|
118
|
-
result.type = import_genai.Type.STRING;
|
|
119
|
-
result.enum = Object.values(def.values);
|
|
120
|
-
return returnResult(result);
|
|
121
|
-
case import_zod.z.ZodFirstPartyTypeKind.ZodUnion:
|
|
122
|
-
result.anyOf = def.options.map(parseZodType);
|
|
123
|
-
return returnResult(result);
|
|
124
|
-
case import_zod.z.ZodFirstPartyTypeKind.ZodOptional:
|
|
125
|
-
return parseZodType(def.innerType);
|
|
126
|
-
case import_zod.z.ZodFirstPartyTypeKind.ZodNullable:
|
|
127
|
-
const nullableInner = parseZodType(def.innerType);
|
|
128
|
-
return nullableInner ? returnResult({
|
|
129
|
-
anyOf: [nullableInner, { type: import_genai.Type.NULL }],
|
|
130
|
-
...description && { description }
|
|
131
|
-
}) : returnResult({ type: import_genai.Type.NULL, ...description && { description } });
|
|
132
|
-
case import_zod.z.ZodFirstPartyTypeKind.ZodDefault:
|
|
133
|
-
const defaultInner = parseZodType(def.innerType);
|
|
134
|
-
if (defaultInner) defaultInner.default = def.defaultValue();
|
|
135
|
-
return defaultInner;
|
|
136
|
-
case import_zod.z.ZodFirstPartyTypeKind.ZodBranded:
|
|
137
|
-
return parseZodType(def.type);
|
|
138
|
-
case import_zod.z.ZodFirstPartyTypeKind.ZodReadonly:
|
|
139
|
-
return parseZodType(def.innerType);
|
|
140
|
-
case import_zod.z.ZodFirstPartyTypeKind.ZodNull:
|
|
141
|
-
result.type = import_genai.Type.NULL;
|
|
142
|
-
return returnResult(result);
|
|
143
|
-
case import_zod.z.ZodFirstPartyTypeKind.ZodAny:
|
|
144
|
-
case import_zod.z.ZodFirstPartyTypeKind.ZodUnknown:
|
|
145
|
-
return returnResult({ ...description && { description } });
|
|
146
|
-
default:
|
|
147
|
-
throw new Error(`Unsupported Zod type: ${def.typeName}`);
|
|
54
|
+
const zod4Type = (_b = schemaAny._def) == null ? void 0 : _b.type;
|
|
55
|
+
if (typeof zod4Type === "string" && zod4Type) {
|
|
56
|
+
return "Zod" + zod4Type.charAt(0).toUpperCase() + zod4Type.slice(1);
|
|
148
57
|
}
|
|
58
|
+
return void 0;
|
|
59
|
+
}
|
|
60
|
+
function isZodObject(obj) {
|
|
61
|
+
return isZodSchema(obj) && getZodTypeName(obj) === "ZodObject";
|
|
149
62
|
}
|
|
150
63
|
function zodObjectToSchema(schema) {
|
|
151
|
-
if (schema
|
|
152
|
-
throw new Error("Expected a
|
|
64
|
+
if (!isZodObject(schema)) {
|
|
65
|
+
throw new Error("Expected a Zod Object");
|
|
153
66
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
67
|
+
if (isZodV4Schema(schema)) {
|
|
68
|
+
return (0, import_v4.toJSONSchema)(schema, {
|
|
69
|
+
target: "openapi-3.0",
|
|
70
|
+
io: "input",
|
|
71
|
+
override: (ctx) => {
|
|
72
|
+
var _a;
|
|
73
|
+
const { jsonSchema } = ctx;
|
|
74
|
+
if (jsonSchema.additionalProperties !== void 0) {
|
|
75
|
+
delete jsonSchema.additionalProperties;
|
|
76
|
+
}
|
|
77
|
+
if (jsonSchema.readOnly !== void 0) {
|
|
78
|
+
delete jsonSchema.readOnly;
|
|
79
|
+
}
|
|
80
|
+
if (jsonSchema.maxItems !== void 0) {
|
|
81
|
+
jsonSchema.maxItems = jsonSchema.maxItems.toString();
|
|
82
|
+
}
|
|
83
|
+
if (jsonSchema.format === "email" || jsonSchema.format === "uuid") {
|
|
84
|
+
delete jsonSchema.pattern;
|
|
85
|
+
}
|
|
86
|
+
if (jsonSchema.minItems !== void 0) {
|
|
87
|
+
jsonSchema.minItems = jsonSchema.minItems.toString();
|
|
88
|
+
}
|
|
89
|
+
if (jsonSchema.minLength !== void 0) {
|
|
90
|
+
jsonSchema.minLength = jsonSchema.minLength.toString();
|
|
91
|
+
}
|
|
92
|
+
if (jsonSchema.maxLength !== void 0) {
|
|
93
|
+
jsonSchema.maxLength = jsonSchema.maxLength.toString();
|
|
94
|
+
}
|
|
95
|
+
if (((_a = jsonSchema.enum) == null ? void 0 : _a.length) === 1 && jsonSchema.enum[0] === null) {
|
|
96
|
+
jsonSchema.type = import_genai.Type.NULL;
|
|
97
|
+
delete jsonSchema.enum;
|
|
98
|
+
}
|
|
99
|
+
if (jsonSchema.type !== void 0) {
|
|
100
|
+
jsonSchema.type = jsonSchema.type.toUpperCase();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
});
|
|
172
104
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
105
|
+
if (isZodV3Schema(schema)) {
|
|
106
|
+
return (0, import_zod_to_json_schema.zodToJsonSchema)(schema, {
|
|
107
|
+
target: "openApi3",
|
|
108
|
+
emailStrategy: "format:email",
|
|
109
|
+
postProcess: (jsonSchema) => {
|
|
110
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
111
|
+
if (!jsonSchema) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (jsonSchema.additionalProperties !== void 0) {
|
|
115
|
+
delete jsonSchema.additionalProperties;
|
|
116
|
+
}
|
|
117
|
+
if (jsonSchema.maxItems !== void 0) {
|
|
118
|
+
jsonSchema.maxItems = (_a = jsonSchema.maxItems) == null ? void 0 : _a.toString();
|
|
119
|
+
}
|
|
120
|
+
if (jsonSchema.minItems !== void 0) {
|
|
121
|
+
jsonSchema.minItems = (_b = jsonSchema.minItems) == null ? void 0 : _b.toString();
|
|
122
|
+
}
|
|
123
|
+
if (jsonSchema.minLength !== void 0) {
|
|
124
|
+
jsonSchema.minLength = (_c = jsonSchema.minLength) == null ? void 0 : _c.toString();
|
|
125
|
+
}
|
|
126
|
+
if (jsonSchema.maxLength !== void 0) {
|
|
127
|
+
jsonSchema.maxLength = (_d = jsonSchema.maxLength) == null ? void 0 : _d.toString();
|
|
128
|
+
}
|
|
129
|
+
if (((_e = jsonSchema.enum) == null ? void 0 : _e.length) === 1 && jsonSchema.enum[0] === "null") {
|
|
130
|
+
jsonSchema.type = import_genai.Type.NULL;
|
|
131
|
+
delete jsonSchema.enum;
|
|
132
|
+
}
|
|
133
|
+
if (jsonSchema.type === "integer" && jsonSchema.format !== "int64") {
|
|
134
|
+
(_f = jsonSchema.minimum) != null ? _f : jsonSchema.minimum = Number.MIN_SAFE_INTEGER;
|
|
135
|
+
(_g = jsonSchema.maximum) != null ? _g : jsonSchema.maximum = Number.MAX_SAFE_INTEGER;
|
|
136
|
+
}
|
|
137
|
+
if (jsonSchema.type !== void 0) {
|
|
138
|
+
jsonSchema.type = jsonSchema.type.toUpperCase();
|
|
139
|
+
}
|
|
140
|
+
return jsonSchema;
|
|
141
|
+
}
|
|
142
|
+
});
|
|
179
143
|
}
|
|
180
|
-
|
|
181
|
-
type: import_genai.Type.OBJECT,
|
|
182
|
-
properties,
|
|
183
|
-
required: required.length > 0 ? required : [],
|
|
184
|
-
...schema._def.description ? { description: schema._def.description } : {}
|
|
185
|
-
};
|
|
144
|
+
throw new Error("Unsupported Zod schema version.");
|
|
186
145
|
}
|
|
187
146
|
// Annotate the CommonJS export names for ESM import in node:
|
|
188
147
|
0 && (module.exports = {
|
|
@@ -46,7 +46,7 @@ function getBooleanEnvVar(envVar) {
|
|
|
46
46
|
return false;
|
|
47
47
|
}
|
|
48
48
|
const envVarValue = (process.env[envVar] || "").toLowerCase();
|
|
49
|
-
return ["true", "1"].includes(
|
|
49
|
+
return ["true", "1"].includes(envVarValue);
|
|
50
50
|
}
|
|
51
51
|
// Annotate the CommonJS export names for ESM import in node:
|
|
52
52
|
0 && (module.exports = {
|
package/dist/cjs/version.js
CHANGED
|
@@ -32,7 +32,7 @@ module.exports = __toCommonJS(version_exports);
|
|
|
32
32
|
* Copyright 2025 Google LLC
|
|
33
33
|
* SPDX-License-Identifier: Apache-2.0
|
|
34
34
|
*/
|
|
35
|
-
const version = "0.
|
|
35
|
+
const version = "0.3.0";
|
|
36
36
|
// Annotate the CommonJS export names for ESM import in node:
|
|
37
37
|
0 && (module.exports = {
|
|
38
38
|
version
|