@iqai/adk 0.2.1 → 0.2.2
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/CHANGELOG.md +6 -0
- package/dist/index.d.mts +114 -113
- package/dist/index.d.ts +114 -113
- package/dist/index.js +1417 -1416
- package/dist/index.mjs +1373 -1372
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3879,7 +3879,6 @@ __export(tools_exports, {
|
|
|
3879
3879
|
McpAbi: () => McpAbi,
|
|
3880
3880
|
McpAtp: () => McpAtp,
|
|
3881
3881
|
McpBamm: () => McpBamm,
|
|
3882
|
-
McpClientService: () => McpClientService,
|
|
3883
3882
|
McpCoinGecko: () => McpCoinGecko,
|
|
3884
3883
|
McpDiscord: () => McpDiscord,
|
|
3885
3884
|
McpError: () => McpError,
|
|
@@ -3901,6 +3900,7 @@ __export(tools_exports, {
|
|
|
3901
3900
|
UserInteractionTool: () => UserInteractionTool,
|
|
3902
3901
|
adkToMcpToolType: () => adkToMcpToolType,
|
|
3903
3902
|
buildFunctionDeclaration: () => buildFunctionDeclaration,
|
|
3903
|
+
convertMcpToolToBaseTool: () => convertMcpToolToBaseTool,
|
|
3904
3904
|
createFunctionTool: () => createFunctionTool,
|
|
3905
3905
|
createSamplingHandler: () => createSamplingHandler,
|
|
3906
3906
|
createTool: () => createTool,
|
|
@@ -3909,954 +3909,957 @@ __export(tools_exports, {
|
|
|
3909
3909
|
mcpSchemaToParameters: () => mcpSchemaToParameters,
|
|
3910
3910
|
normalizeJsonSchema: () => normalizeJsonSchema
|
|
3911
3911
|
});
|
|
3912
|
+
init_base_tool();
|
|
3912
3913
|
|
|
3913
|
-
// src/tools/
|
|
3914
|
-
|
|
3915
|
-
var
|
|
3916
|
-
var
|
|
3917
|
-
var
|
|
3918
|
-
var _typesjs = require('@modelcontextprotocol/sdk/types.js');
|
|
3919
|
-
|
|
3920
|
-
// src/tools/mcp/sampling-handler.ts
|
|
3921
|
-
init_logger();
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
// src/tools/mcp/types.ts
|
|
3928
|
-
var McpErrorType = /* @__PURE__ */ ((McpErrorType2) => {
|
|
3929
|
-
McpErrorType2["CONNECTION_ERROR"] = "connection_error";
|
|
3930
|
-
McpErrorType2["TOOL_EXECUTION_ERROR"] = "tool_execution_error";
|
|
3931
|
-
McpErrorType2["RESOURCE_CLOSED_ERROR"] = "resource_closed_error";
|
|
3932
|
-
McpErrorType2["TIMEOUT_ERROR"] = "timeout_error";
|
|
3933
|
-
McpErrorType2["INVALID_SCHEMA_ERROR"] = "invalid_schema_error";
|
|
3934
|
-
McpErrorType2["SAMPLING_ERROR"] = "SAMPLING_ERROR";
|
|
3935
|
-
McpErrorType2["INVALID_REQUEST_ERROR"] = "INVALID_REQUEST_ERROR";
|
|
3936
|
-
return McpErrorType2;
|
|
3937
|
-
})(McpErrorType || {});
|
|
3938
|
-
var McpError = class extends Error {
|
|
3914
|
+
// src/tools/base/create-tool.ts
|
|
3915
|
+
init_base_tool();
|
|
3916
|
+
var _zod = require('zod'); var z = _interopRequireWildcard(_zod);
|
|
3917
|
+
var _zodtojsonschema = require('zod-to-json-schema');
|
|
3918
|
+
var CreatedTool = class extends BaseTool {
|
|
3939
3919
|
|
|
3940
3920
|
|
|
3941
|
-
constructor(message, type, originalError) {
|
|
3942
|
-
super(message);
|
|
3943
|
-
this.name = "McpError";
|
|
3944
|
-
this.type = type;
|
|
3945
|
-
this.originalError = originalError;
|
|
3946
|
-
}
|
|
3947
|
-
};
|
|
3948
|
-
|
|
3949
|
-
// src/tools/mcp/sampling-handler.ts
|
|
3950
|
-
var McpSamplingHandler = (_class13 = class {
|
|
3951
|
-
__init22() {this.logger = new Logger({ name: "McpSamplingHandler" })}
|
|
3952
3921
|
|
|
3953
|
-
constructor(
|
|
3954
|
-
|
|
3922
|
+
constructor(config) {
|
|
3923
|
+
super({
|
|
3924
|
+
name: config.name,
|
|
3925
|
+
description: config.description,
|
|
3926
|
+
isLongRunning: _nullishCoalesce(config.isLongRunning, () => ( false)),
|
|
3927
|
+
shouldRetryOnFailure: _nullishCoalesce(config.shouldRetryOnFailure, () => ( false)),
|
|
3928
|
+
maxRetryAttempts: _nullishCoalesce(config.maxRetryAttempts, () => ( 3))
|
|
3929
|
+
});
|
|
3930
|
+
this.func = config.fn;
|
|
3931
|
+
this.schema = _nullishCoalesce(config.schema, () => ( z.object({})));
|
|
3932
|
+
this.functionDeclaration = this.buildDeclaration();
|
|
3955
3933
|
}
|
|
3956
3934
|
/**
|
|
3957
|
-
*
|
|
3935
|
+
* Executes the tool function with validation
|
|
3958
3936
|
*/
|
|
3959
|
-
async
|
|
3937
|
+
async runAsync(args, context4) {
|
|
3960
3938
|
try {
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
);
|
|
3965
|
-
throw new McpError(
|
|
3966
|
-
`Invalid method: ${request.method}. This handler only processes sampling/createMessage requests.`,
|
|
3967
|
-
"INVALID_REQUEST_ERROR" /* INVALID_REQUEST_ERROR */
|
|
3968
|
-
);
|
|
3969
|
-
}
|
|
3970
|
-
const validationResult = _typesjs.CreateMessageRequestSchema.safeParse(request);
|
|
3971
|
-
if (!validationResult.success) {
|
|
3972
|
-
this.logger.error(
|
|
3973
|
-
"Invalid MCP sampling request:",
|
|
3974
|
-
validationResult.error
|
|
3975
|
-
);
|
|
3976
|
-
throw new McpError(
|
|
3977
|
-
`Invalid sampling request: ${validationResult.error.message}`,
|
|
3978
|
-
"INVALID_REQUEST_ERROR" /* INVALID_REQUEST_ERROR */
|
|
3979
|
-
);
|
|
3980
|
-
}
|
|
3981
|
-
const mcpParams = request.params;
|
|
3982
|
-
if (!mcpParams.messages || !Array.isArray(mcpParams.messages)) {
|
|
3983
|
-
throw new McpError(
|
|
3984
|
-
"Invalid sampling request: messages array is required",
|
|
3985
|
-
"INVALID_REQUEST_ERROR" /* INVALID_REQUEST_ERROR */
|
|
3986
|
-
);
|
|
3987
|
-
}
|
|
3988
|
-
if (!mcpParams.maxTokens || mcpParams.maxTokens <= 0) {
|
|
3989
|
-
throw new McpError(
|
|
3990
|
-
"Invalid sampling request: maxTokens must be a positive number",
|
|
3991
|
-
"INVALID_REQUEST_ERROR" /* INVALID_REQUEST_ERROR */
|
|
3992
|
-
);
|
|
3993
|
-
}
|
|
3994
|
-
this.logger.debug("Converting MCP request to ADK format");
|
|
3995
|
-
const adkContents = this.convertMcpMessagesToADK(
|
|
3996
|
-
mcpParams.messages,
|
|
3997
|
-
mcpParams.systemPrompt
|
|
3998
|
-
);
|
|
3999
|
-
const requestModel = mcpParams.model || "gemini-2.0-flash";
|
|
4000
|
-
const adkRequest = new LlmRequest({
|
|
4001
|
-
model: requestModel,
|
|
4002
|
-
contents: adkContents,
|
|
4003
|
-
config: {
|
|
4004
|
-
temperature: mcpParams.temperature,
|
|
4005
|
-
maxOutputTokens: mcpParams.maxTokens
|
|
4006
|
-
}
|
|
4007
|
-
});
|
|
4008
|
-
this.logger.debug("Calling ADK sampling handler");
|
|
4009
|
-
const adkResponse = await this.samplingHandler(adkRequest);
|
|
4010
|
-
this.logger.debug("Converting ADK response to MCP format");
|
|
4011
|
-
const mcpResponse = this.convertADKResponseToMcp(
|
|
4012
|
-
adkResponse,
|
|
4013
|
-
requestModel
|
|
4014
|
-
);
|
|
4015
|
-
const responseValidation = _typesjs.CreateMessageResultSchema.safeParse(mcpResponse);
|
|
4016
|
-
if (!responseValidation.success) {
|
|
4017
|
-
this.logger.error(
|
|
4018
|
-
"Invalid MCP response generated:",
|
|
4019
|
-
responseValidation.error
|
|
4020
|
-
);
|
|
4021
|
-
throw new McpError(
|
|
4022
|
-
`Invalid response generated: ${responseValidation.error.message}`,
|
|
4023
|
-
"SAMPLING_ERROR" /* SAMPLING_ERROR */
|
|
4024
|
-
);
|
|
4025
|
-
}
|
|
4026
|
-
return mcpResponse;
|
|
3939
|
+
const validatedArgs = this.schema.parse(args);
|
|
3940
|
+
const result = await Promise.resolve(this.func(validatedArgs, context4));
|
|
3941
|
+
return _nullishCoalesce(result, () => ( {}));
|
|
4027
3942
|
} catch (error) {
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
3943
|
+
if (error instanceof z.ZodError) {
|
|
3944
|
+
return {
|
|
3945
|
+
error: `Invalid arguments for ${this.name}: ${error.message}`
|
|
3946
|
+
};
|
|
4031
3947
|
}
|
|
4032
|
-
|
|
4033
|
-
`
|
|
4034
|
-
|
|
4035
|
-
error instanceof Error ? error : void 0
|
|
4036
|
-
);
|
|
3948
|
+
return {
|
|
3949
|
+
error: `Error executing ${this.name}: ${error instanceof Error ? error.message : String(error)}`
|
|
3950
|
+
};
|
|
4037
3951
|
}
|
|
4038
3952
|
}
|
|
4039
3953
|
/**
|
|
4040
|
-
*
|
|
3954
|
+
* Returns the function declaration for this tool
|
|
4041
3955
|
*/
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
if (systemPrompt) {
|
|
4045
|
-
contents.push({
|
|
4046
|
-
role: "user",
|
|
4047
|
-
// System messages are typically sent as user role in content
|
|
4048
|
-
parts: [{ text: systemPrompt }]
|
|
4049
|
-
});
|
|
4050
|
-
}
|
|
4051
|
-
const transformedMessages = mcpMessages.map(
|
|
4052
|
-
(mcpMessage) => this.convertSingleMcpMessageToADK(mcpMessage)
|
|
4053
|
-
);
|
|
4054
|
-
contents.push(...transformedMessages);
|
|
4055
|
-
return contents;
|
|
3956
|
+
getDeclaration() {
|
|
3957
|
+
return this.functionDeclaration;
|
|
4056
3958
|
}
|
|
4057
3959
|
/**
|
|
4058
|
-
*
|
|
3960
|
+
* Builds the function declaration from the Zod schema
|
|
4059
3961
|
*/
|
|
4060
|
-
|
|
4061
|
-
const
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
3962
|
+
buildDeclaration() {
|
|
3963
|
+
const rawParameters = _zodtojsonschema.zodToJsonSchema.call(void 0, this.schema, {
|
|
3964
|
+
target: "jsonSchema7",
|
|
3965
|
+
$refStrategy: "none"
|
|
3966
|
+
});
|
|
3967
|
+
const { $schema, ...parameters } = rawParameters;
|
|
3968
|
+
return {
|
|
3969
|
+
name: this.name,
|
|
3970
|
+
description: this.description,
|
|
3971
|
+
parameters
|
|
4066
3972
|
};
|
|
4067
|
-
this.logger.debug(
|
|
4068
|
-
`Converted MCP message - role: ${mcpMessage.role} -> ${adkRole}, content type: ${mcpMessage.content.type}`
|
|
4069
|
-
);
|
|
4070
|
-
return adkContent;
|
|
4071
3973
|
}
|
|
3974
|
+
};
|
|
3975
|
+
function createTool(config) {
|
|
3976
|
+
return new CreatedTool(config);
|
|
3977
|
+
}
|
|
3978
|
+
|
|
3979
|
+
// src/tools/common/agent-tool.ts
|
|
3980
|
+
init_logger();
|
|
3981
|
+
|
|
3982
|
+
|
|
3983
|
+
|
|
3984
|
+
// src/agents/invocation-context.ts
|
|
3985
|
+
var LlmCallsLimitExceededError = class extends Error {
|
|
3986
|
+
constructor(message) {
|
|
3987
|
+
super(message);
|
|
3988
|
+
this.name = "LlmCallsLimitExceededError";
|
|
3989
|
+
}
|
|
3990
|
+
};
|
|
3991
|
+
var InvocationCostManager = (_class13 = class {constructor() { _class13.prototype.__init22.call(this); }
|
|
4072
3992
|
/**
|
|
4073
|
-
*
|
|
3993
|
+
* A counter that keeps track of number of llm calls made.
|
|
4074
3994
|
*/
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
if (mcpContent.data && typeof mcpContent.data === "string") {
|
|
4086
|
-
const mimeType = mcpContent.mimeType || "image/jpeg";
|
|
4087
|
-
parts.push({
|
|
4088
|
-
inlineData: {
|
|
4089
|
-
data: mcpContent.data,
|
|
4090
|
-
mimeType
|
|
4091
|
-
}
|
|
4092
|
-
});
|
|
4093
|
-
}
|
|
4094
|
-
return parts.length > 0 ? parts : [{ text: "" }];
|
|
3995
|
+
__init22() {this._numberOfLlmCalls = 0}
|
|
3996
|
+
/**
|
|
3997
|
+
* Increments _numberOfLlmCalls and enforces the limit.
|
|
3998
|
+
*/
|
|
3999
|
+
incrementAndEnforceLlmCallsLimit(runConfig) {
|
|
4000
|
+
this._numberOfLlmCalls += 1;
|
|
4001
|
+
if (runConfig && runConfig.maxLlmCalls > 0 && this._numberOfLlmCalls > runConfig.maxLlmCalls) {
|
|
4002
|
+
throw new LlmCallsLimitExceededError(
|
|
4003
|
+
`Max number of llm calls limit of \`${runConfig.maxLlmCalls}\` exceeded`
|
|
4004
|
+
);
|
|
4095
4005
|
}
|
|
4096
|
-
this.logger.warn(`Unknown MCP content type: ${mcpContent.type}`);
|
|
4097
|
-
const fallbackText = typeof mcpContent.data === "string" ? mcpContent.data : "";
|
|
4098
|
-
return [{ text: fallbackText }];
|
|
4099
4006
|
}
|
|
4007
|
+
}, _class13);
|
|
4008
|
+
function newInvocationContextId() {
|
|
4009
|
+
return `e-${crypto.randomUUID()}`;
|
|
4010
|
+
}
|
|
4011
|
+
var InvocationContext = (_class14 = class _InvocationContext {
|
|
4012
|
+
|
|
4013
|
+
|
|
4014
|
+
|
|
4100
4015
|
/**
|
|
4101
|
-
*
|
|
4016
|
+
* The id of this invocation context. Readonly.
|
|
4102
4017
|
*/
|
|
4103
|
-
|
|
4104
|
-
let responseText = "";
|
|
4105
|
-
if (typeof adkResponse === "string") {
|
|
4106
|
-
responseText = adkResponse;
|
|
4107
|
-
} else {
|
|
4108
|
-
if (adkResponse.content) {
|
|
4109
|
-
if (typeof adkResponse.content === "string") {
|
|
4110
|
-
responseText = adkResponse.content;
|
|
4111
|
-
} else if (adkResponse.content.parts) {
|
|
4112
|
-
responseText = adkResponse.content.parts.map((part) => {
|
|
4113
|
-
return typeof part.text === "string" ? part.text : "";
|
|
4114
|
-
}).join("");
|
|
4115
|
-
}
|
|
4116
|
-
}
|
|
4117
|
-
}
|
|
4118
|
-
const mcpResponse = {
|
|
4119
|
-
model,
|
|
4120
|
-
// Use the model from the request
|
|
4121
|
-
role: "assistant",
|
|
4122
|
-
// ADK responses are always from assistant
|
|
4123
|
-
content: {
|
|
4124
|
-
type: "text",
|
|
4125
|
-
text: responseText
|
|
4126
|
-
}
|
|
4127
|
-
};
|
|
4128
|
-
this.logger.debug(`Received content: ${responseText}`);
|
|
4129
|
-
return mcpResponse;
|
|
4130
|
-
}
|
|
4018
|
+
|
|
4131
4019
|
/**
|
|
4132
|
-
*
|
|
4020
|
+
* The branch of the invocation context.
|
|
4021
|
+
*
|
|
4022
|
+
* The format is like agent_1.agent_2.agent_3, where agent_1 is the parent of
|
|
4023
|
+
* agent_2, and agent_2 is the parent of agent_3.
|
|
4024
|
+
*
|
|
4025
|
+
* Branch is used when multiple sub-agents shouldn't see their peer agents'
|
|
4026
|
+
* conversation history.
|
|
4133
4027
|
*/
|
|
4134
|
-
|
|
4135
|
-
this.samplingHandler = handler;
|
|
4136
|
-
this.logger.debug("ADK sampling handler updated");
|
|
4137
|
-
}
|
|
4138
|
-
}, _class13);
|
|
4139
|
-
function createSamplingHandler(handler) {
|
|
4140
|
-
return handler;
|
|
4141
|
-
}
|
|
4142
|
-
|
|
4143
|
-
// src/tools/mcp/utils.ts
|
|
4144
|
-
function withRetry(fn, instance, reinitMethod, maxRetries = 1) {
|
|
4145
|
-
return async (...args) => {
|
|
4146
|
-
let attempt = 0;
|
|
4147
|
-
while (attempt <= maxRetries) {
|
|
4148
|
-
try {
|
|
4149
|
-
return await fn.apply(instance, args);
|
|
4150
|
-
} catch (error) {
|
|
4151
|
-
const isClosedResourceError = error instanceof Error && (error.message.includes("closed") || error.message.includes("ECONNRESET") || error.message.includes("socket hang up"));
|
|
4152
|
-
if (!isClosedResourceError || attempt >= maxRetries) {
|
|
4153
|
-
throw error;
|
|
4154
|
-
}
|
|
4155
|
-
console.warn(
|
|
4156
|
-
`Resource closed, reinitializing (attempt ${attempt + 1}/${maxRetries + 1})...`
|
|
4157
|
-
);
|
|
4158
|
-
try {
|
|
4159
|
-
await reinitMethod(instance);
|
|
4160
|
-
} catch (reinitError) {
|
|
4161
|
-
console.error("Error reinitializing resources:", reinitError);
|
|
4162
|
-
throw new Error(`Failed to reinitialize resources: ${reinitError}`);
|
|
4163
|
-
}
|
|
4164
|
-
attempt++;
|
|
4165
|
-
}
|
|
4166
|
-
}
|
|
4167
|
-
throw new Error("Unexpected end of retry loop");
|
|
4168
|
-
};
|
|
4169
|
-
}
|
|
4170
|
-
|
|
4171
|
-
// src/tools/mcp/client.ts
|
|
4172
|
-
var McpClientService = (_class14 = class {
|
|
4173
|
-
|
|
4174
|
-
__init23() {this.client = null}
|
|
4175
|
-
__init24() {this.transport = null}
|
|
4176
|
-
__init25() {this.isClosing = false}
|
|
4177
|
-
__init26() {this.mcpSamplingHandler = null}
|
|
4178
|
-
__init27() {this.logger = new Logger({ name: "McpClientService" })}
|
|
4179
|
-
constructor(config) {;_class14.prototype.__init23.call(this);_class14.prototype.__init24.call(this);_class14.prototype.__init25.call(this);_class14.prototype.__init26.call(this);_class14.prototype.__init27.call(this);
|
|
4180
|
-
this.config = config;
|
|
4181
|
-
if (config.samplingHandler) {
|
|
4182
|
-
this.mcpSamplingHandler = new McpSamplingHandler(config.samplingHandler);
|
|
4183
|
-
}
|
|
4184
|
-
}
|
|
4028
|
+
|
|
4185
4029
|
/**
|
|
4186
|
-
*
|
|
4187
|
-
* Will create a new client if one doesn't exist yet.
|
|
4030
|
+
* The current agent of this invocation context. Readonly.
|
|
4188
4031
|
*/
|
|
4189
|
-
|
|
4190
|
-
if (this.isClosing) {
|
|
4191
|
-
throw new McpError(
|
|
4192
|
-
"Cannot initialize a client that is being closed",
|
|
4193
|
-
"resource_closed_error" /* RESOURCE_CLOSED_ERROR */
|
|
4194
|
-
);
|
|
4195
|
-
}
|
|
4196
|
-
if (this.client) {
|
|
4197
|
-
return this.client;
|
|
4198
|
-
}
|
|
4199
|
-
try {
|
|
4200
|
-
if (!this.transport) {
|
|
4201
|
-
this.transport = await this.createTransport();
|
|
4202
|
-
}
|
|
4203
|
-
const client = new (0, _indexjs.Client)(
|
|
4204
|
-
{
|
|
4205
|
-
name: this.config.name,
|
|
4206
|
-
version: "0.0.1"
|
|
4207
|
-
},
|
|
4208
|
-
{
|
|
4209
|
-
capabilities: {
|
|
4210
|
-
prompts: {},
|
|
4211
|
-
resources: {},
|
|
4212
|
-
tools: {},
|
|
4213
|
-
sampling: {}
|
|
4214
|
-
// Enable sampling capability
|
|
4215
|
-
}
|
|
4216
|
-
}
|
|
4217
|
-
);
|
|
4218
|
-
const connectPromise = client.connect(this.transport);
|
|
4219
|
-
if (this.config.timeout) {
|
|
4220
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
4221
|
-
setTimeout(() => {
|
|
4222
|
-
reject(
|
|
4223
|
-
new McpError(
|
|
4224
|
-
`MCP client connection timed out after ${this.config.timeout}ms`,
|
|
4225
|
-
"timeout_error" /* TIMEOUT_ERROR */
|
|
4226
|
-
)
|
|
4227
|
-
);
|
|
4228
|
-
}, this.config.timeout);
|
|
4229
|
-
});
|
|
4230
|
-
await Promise.race([connectPromise, timeoutPromise]);
|
|
4231
|
-
} else {
|
|
4232
|
-
await connectPromise;
|
|
4233
|
-
}
|
|
4234
|
-
await this.setupSamplingHandler(client);
|
|
4235
|
-
this.logger.debug("\u2705 MCP client connected successfully");
|
|
4236
|
-
this.client = client;
|
|
4237
|
-
return client;
|
|
4238
|
-
} catch (error) {
|
|
4239
|
-
await this.cleanupResources();
|
|
4240
|
-
if (!(error instanceof McpError)) {
|
|
4241
|
-
this.logger.error("Failed to initialize MCP client:", error);
|
|
4242
|
-
throw new McpError(
|
|
4243
|
-
`Failed to initialize MCP client: ${error instanceof Error ? error.message : String(error)}`,
|
|
4244
|
-
"connection_error" /* CONNECTION_ERROR */,
|
|
4245
|
-
error instanceof Error ? error : void 0
|
|
4246
|
-
);
|
|
4247
|
-
}
|
|
4248
|
-
throw error;
|
|
4249
|
-
}
|
|
4250
|
-
}
|
|
4032
|
+
|
|
4251
4033
|
/**
|
|
4252
|
-
*
|
|
4034
|
+
* The user content that started this invocation. Readonly.
|
|
4253
4035
|
*/
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4036
|
+
|
|
4037
|
+
/**
|
|
4038
|
+
* The current session of this invocation context. Readonly.
|
|
4039
|
+
*/
|
|
4040
|
+
|
|
4041
|
+
/**
|
|
4042
|
+
* Whether to end this invocation.
|
|
4043
|
+
*
|
|
4044
|
+
* Set to True in callbacks or tools to terminate this invocation.
|
|
4045
|
+
*/
|
|
4046
|
+
__init23() {this.endInvocation = false}
|
|
4047
|
+
/**
|
|
4048
|
+
* The queue to receive live requests.
|
|
4049
|
+
*/
|
|
4050
|
+
|
|
4051
|
+
/**
|
|
4052
|
+
* The running streaming tools of this invocation.
|
|
4053
|
+
*/
|
|
4054
|
+
|
|
4055
|
+
/**
|
|
4056
|
+
* Caches necessary, data audio or contents, that are needed by transcription.
|
|
4057
|
+
*/
|
|
4058
|
+
|
|
4059
|
+
/**
|
|
4060
|
+
* Configurations for live agents under this invocation.
|
|
4061
|
+
*/
|
|
4062
|
+
|
|
4063
|
+
/**
|
|
4064
|
+
* A container to keep track of different kinds of costs incurred as a part
|
|
4065
|
+
* of this invocation.
|
|
4066
|
+
*/
|
|
4067
|
+
__init24() {this._invocationCostManager = new InvocationCostManager()}
|
|
4068
|
+
/**
|
|
4069
|
+
* Constructor for InvocationContext
|
|
4070
|
+
*/
|
|
4071
|
+
constructor(options) {;_class14.prototype.__init23.call(this);_class14.prototype.__init24.call(this);
|
|
4072
|
+
this.artifactService = options.artifactService;
|
|
4073
|
+
this.sessionService = options.sessionService;
|
|
4074
|
+
this.memoryService = options.memoryService;
|
|
4075
|
+
this.invocationId = options.invocationId || newInvocationContextId();
|
|
4076
|
+
this.branch = options.branch;
|
|
4077
|
+
this.agent = options.agent;
|
|
4078
|
+
this.userContent = options.userContent;
|
|
4079
|
+
this.session = options.session;
|
|
4080
|
+
this.endInvocation = options.endInvocation || false;
|
|
4081
|
+
this.liveRequestQueue = options.liveRequestQueue;
|
|
4082
|
+
this.activeStreamingTools = options.activeStreamingTools;
|
|
4083
|
+
this.transcriptionCache = options.transcriptionCache;
|
|
4084
|
+
this.runConfig = options.runConfig;
|
|
4291
4085
|
}
|
|
4292
4086
|
/**
|
|
4293
|
-
*
|
|
4294
|
-
* Used by the retry mechanism.
|
|
4087
|
+
* App name from the session
|
|
4295
4088
|
*/
|
|
4296
|
-
|
|
4297
|
-
this.
|
|
4298
|
-
await this.cleanupResources();
|
|
4299
|
-
this.client = null;
|
|
4300
|
-
this.transport = null;
|
|
4301
|
-
await this.initialize();
|
|
4089
|
+
get appName() {
|
|
4090
|
+
return this.session.appName;
|
|
4302
4091
|
}
|
|
4303
4092
|
/**
|
|
4304
|
-
*
|
|
4305
|
-
* Similar to Python's AsyncExitStack.aclose() functionality.
|
|
4093
|
+
* User ID from the session
|
|
4306
4094
|
*/
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
this.isClosing = true;
|
|
4310
|
-
if (this.client) {
|
|
4311
|
-
try {
|
|
4312
|
-
if (typeof this.client.close === "function") {
|
|
4313
|
-
await this.client.close();
|
|
4314
|
-
}
|
|
4315
|
-
} catch (err) {
|
|
4316
|
-
}
|
|
4317
|
-
}
|
|
4318
|
-
if (this.transport && typeof this.transport.close === "function") {
|
|
4319
|
-
await this.transport.close();
|
|
4320
|
-
}
|
|
4321
|
-
this.logger.debug("\u{1F9F9} Cleaned up MCP client resources");
|
|
4322
|
-
} catch (error) {
|
|
4323
|
-
this.logger.error("Error cleaning up MCP resources:", error);
|
|
4324
|
-
} finally {
|
|
4325
|
-
this.client = null;
|
|
4326
|
-
this.transport = null;
|
|
4327
|
-
this.isClosing = false;
|
|
4328
|
-
}
|
|
4095
|
+
get userId() {
|
|
4096
|
+
return this.session.userId;
|
|
4329
4097
|
}
|
|
4330
4098
|
/**
|
|
4331
|
-
*
|
|
4099
|
+
* Tracks number of llm calls made.
|
|
4100
|
+
*
|
|
4101
|
+
* @throws {LlmCallsLimitExceededError} If number of llm calls made exceed the set threshold.
|
|
4332
4102
|
*/
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
const client = await this.initialize();
|
|
4338
|
-
return client.callTool({
|
|
4339
|
-
name,
|
|
4340
|
-
arguments: args
|
|
4341
|
-
});
|
|
4342
|
-
},
|
|
4343
|
-
this,
|
|
4344
|
-
async (instance) => await instance.reinitialize(),
|
|
4345
|
-
_optionalChain([this, 'access', _145 => _145.config, 'access', _146 => _146.retryOptions, 'optionalAccess', _147 => _147.maxRetries]) || 2
|
|
4346
|
-
);
|
|
4347
|
-
return await wrappedCall();
|
|
4348
|
-
} catch (error) {
|
|
4349
|
-
if (!(error instanceof McpError)) {
|
|
4350
|
-
throw new McpError(
|
|
4351
|
-
`Error calling tool "${name}": ${error instanceof Error ? error.message : String(error)}`,
|
|
4352
|
-
"tool_execution_error" /* TOOL_EXECUTION_ERROR */,
|
|
4353
|
-
error instanceof Error ? error : void 0
|
|
4354
|
-
);
|
|
4355
|
-
}
|
|
4356
|
-
throw error;
|
|
4357
|
-
}
|
|
4103
|
+
incrementLlmCallCount() {
|
|
4104
|
+
this._invocationCostManager.incrementAndEnforceLlmCallsLimit(
|
|
4105
|
+
this.runConfig
|
|
4106
|
+
);
|
|
4358
4107
|
}
|
|
4359
4108
|
/**
|
|
4360
|
-
*
|
|
4361
|
-
* Should be called when the service is no longer needed.
|
|
4362
|
-
* Similar to Python's close() method.
|
|
4109
|
+
* Creates a child invocation context for a sub-agent
|
|
4363
4110
|
*/
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4111
|
+
createChildContext(agent) {
|
|
4112
|
+
return new _InvocationContext({
|
|
4113
|
+
artifactService: this.artifactService,
|
|
4114
|
+
sessionService: this.sessionService,
|
|
4115
|
+
memoryService: this.memoryService,
|
|
4116
|
+
invocationId: this.invocationId,
|
|
4117
|
+
// Keep same invocation ID
|
|
4118
|
+
branch: this.branch ? `${this.branch}.${agent.name}` : agent.name,
|
|
4119
|
+
// Update branch
|
|
4120
|
+
agent,
|
|
4121
|
+
// Update to the new agent
|
|
4122
|
+
userContent: this.userContent,
|
|
4123
|
+
session: this.session,
|
|
4124
|
+
endInvocation: this.endInvocation,
|
|
4125
|
+
liveRequestQueue: this.liveRequestQueue,
|
|
4126
|
+
activeStreamingTools: this.activeStreamingTools,
|
|
4127
|
+
transcriptionCache: this.transcriptionCache,
|
|
4128
|
+
runConfig: this.runConfig
|
|
4129
|
+
});
|
|
4367
4130
|
}
|
|
4131
|
+
}, _class14);
|
|
4132
|
+
|
|
4133
|
+
// src/tools/common/agent-tool.ts
|
|
4134
|
+
init_base_tool();
|
|
4135
|
+
function isLlmAgent(agent) {
|
|
4136
|
+
return true;
|
|
4137
|
+
}
|
|
4138
|
+
var AgentTool = (_class15 = class extends BaseTool {
|
|
4368
4139
|
/**
|
|
4369
|
-
*
|
|
4140
|
+
* The agent used by this tool
|
|
4370
4141
|
*/
|
|
4371
|
-
|
|
4372
|
-
|
|
4142
|
+
|
|
4143
|
+
/**
|
|
4144
|
+
* The function declaration schema
|
|
4145
|
+
*/
|
|
4146
|
+
|
|
4147
|
+
/**
|
|
4148
|
+
* The key to store the tool output in the state
|
|
4149
|
+
*/
|
|
4150
|
+
|
|
4151
|
+
/**
|
|
4152
|
+
* Whether to skip summarization of the agent's response
|
|
4153
|
+
*/
|
|
4154
|
+
|
|
4155
|
+
__init25() {this.logger = new Logger({ name: "AgentTool" })}
|
|
4156
|
+
/**
|
|
4157
|
+
* Create a new agent tool
|
|
4158
|
+
*/
|
|
4159
|
+
constructor(config) {
|
|
4160
|
+
super({
|
|
4161
|
+
name: config.name,
|
|
4162
|
+
description: config.description || config.agent.description,
|
|
4163
|
+
isLongRunning: config.isLongRunning || false,
|
|
4164
|
+
shouldRetryOnFailure: config.shouldRetryOnFailure || false,
|
|
4165
|
+
maxRetryAttempts: config.maxRetryAttempts || 3
|
|
4166
|
+
});_class15.prototype.__init25.call(this);;
|
|
4167
|
+
this.agent = config.agent;
|
|
4168
|
+
this.functionDeclaration = config.functionDeclaration;
|
|
4169
|
+
this.outputKey = config.outputKey;
|
|
4170
|
+
this.skipSummarization = config.skipSummarization || false;
|
|
4373
4171
|
}
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
return;
|
|
4172
|
+
/**
|
|
4173
|
+
* Get the function declaration for the tool
|
|
4174
|
+
*/
|
|
4175
|
+
getDeclaration() {
|
|
4176
|
+
if (this.functionDeclaration) {
|
|
4177
|
+
return this.functionDeclaration;
|
|
4380
4178
|
}
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
this.logger.error("\u274C Error handling sampling request:", error);
|
|
4392
|
-
if (error instanceof McpError) {
|
|
4393
|
-
throw error;
|
|
4394
|
-
}
|
|
4395
|
-
throw new McpError(
|
|
4396
|
-
`Sampling request failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
4397
|
-
"SAMPLING_ERROR" /* SAMPLING_ERROR */,
|
|
4398
|
-
error instanceof Error ? error : void 0
|
|
4399
|
-
);
|
|
4179
|
+
const description = isLlmAgent(this.agent) ? typeof this.agent.instruction === "string" ? this.agent.instruction : this.description : this.description;
|
|
4180
|
+
return {
|
|
4181
|
+
name: this.name,
|
|
4182
|
+
description,
|
|
4183
|
+
parameters: {
|
|
4184
|
+
type: _genai.Type.OBJECT,
|
|
4185
|
+
properties: {
|
|
4186
|
+
input: {
|
|
4187
|
+
type: _genai.Type.STRING,
|
|
4188
|
+
description: "The input to provide to the agent"
|
|
4400
4189
|
}
|
|
4190
|
+
},
|
|
4191
|
+
required: ["input"]
|
|
4192
|
+
}
|
|
4193
|
+
};
|
|
4194
|
+
}
|
|
4195
|
+
/**
|
|
4196
|
+
* Execute the tool by running the agent with the provided input
|
|
4197
|
+
*/
|
|
4198
|
+
async runAsync(params, context4) {
|
|
4199
|
+
try {
|
|
4200
|
+
const input = params.input || Object.values(params)[0];
|
|
4201
|
+
if (!isLlmAgent(this.agent)) {
|
|
4202
|
+
throw new Error(
|
|
4203
|
+
`Agent ${this.name} does not support running as a tool`
|
|
4204
|
+
);
|
|
4205
|
+
}
|
|
4206
|
+
const parentInvocation = context4._invocationContext;
|
|
4207
|
+
const childInvocationContext = new InvocationContext({
|
|
4208
|
+
invocationId: _uuid.v4.call(void 0, ),
|
|
4209
|
+
agent: this.agent,
|
|
4210
|
+
session: parentInvocation.session,
|
|
4211
|
+
artifactService: parentInvocation.artifactService,
|
|
4212
|
+
sessionService: parentInvocation.sessionService,
|
|
4213
|
+
memoryService: parentInvocation.memoryService,
|
|
4214
|
+
runConfig: parentInvocation.runConfig,
|
|
4215
|
+
userContent: {
|
|
4216
|
+
role: "user",
|
|
4217
|
+
parts: [{ text: String(input) }]
|
|
4218
|
+
},
|
|
4219
|
+
branch: parentInvocation.branch ? `${parentInvocation.branch}.${this.agent.name}` : this.agent.name
|
|
4220
|
+
});
|
|
4221
|
+
let lastEvent = null;
|
|
4222
|
+
for await (const event of this.agent.runAsync(childInvocationContext)) {
|
|
4223
|
+
if (!event.partial) {
|
|
4224
|
+
await childInvocationContext.sessionService.appendEvent(
|
|
4225
|
+
childInvocationContext.session,
|
|
4226
|
+
event
|
|
4227
|
+
);
|
|
4401
4228
|
}
|
|
4402
|
-
|
|
4403
|
-
|
|
4229
|
+
if (event.content && event.author === this.agent.name) {
|
|
4230
|
+
lastEvent = event;
|
|
4231
|
+
}
|
|
4232
|
+
}
|
|
4233
|
+
if (!lastEvent || !lastEvent.content || !lastEvent.content.parts) {
|
|
4234
|
+
return "";
|
|
4235
|
+
}
|
|
4236
|
+
const mergedText = lastEvent.content.parts.filter((part) => part.text !== void 0 && part.text !== null).map((part) => part.text).join("\n");
|
|
4237
|
+
let toolResult;
|
|
4238
|
+
try {
|
|
4239
|
+
toolResult = JSON.parse(mergedText);
|
|
4240
|
+
} catch (e2) {
|
|
4241
|
+
toolResult = mergedText;
|
|
4242
|
+
}
|
|
4243
|
+
if (this.outputKey && _optionalChain([context4, 'optionalAccess', _145 => _145.state])) {
|
|
4244
|
+
context4.state[this.outputKey] = toolResult;
|
|
4245
|
+
}
|
|
4246
|
+
return toolResult;
|
|
4404
4247
|
} catch (error) {
|
|
4405
|
-
this.logger.error(
|
|
4406
|
-
|
|
4407
|
-
|
|
4248
|
+
this.logger.error(`Error executing agent tool ${this.name}:`, error);
|
|
4249
|
+
throw new Error(
|
|
4250
|
+
`Agent tool execution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
4408
4251
|
);
|
|
4409
4252
|
}
|
|
4410
4253
|
}
|
|
4254
|
+
}, _class15);
|
|
4255
|
+
|
|
4256
|
+
// src/tools/tool-context.ts
|
|
4257
|
+
var ToolContext = class extends CallbackContext {
|
|
4411
4258
|
/**
|
|
4412
|
-
*
|
|
4259
|
+
* The function call id of the current tool call. This id was
|
|
4260
|
+
* returned in the function call event from LLM to identify a function call.
|
|
4261
|
+
* If LLM didn't return this id, ADK will assign one to it. This id is used
|
|
4262
|
+
* to map function call response to the original function call.
|
|
4413
4263
|
*/
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4264
|
+
|
|
4265
|
+
/**
|
|
4266
|
+
* Constructor for ToolContext
|
|
4267
|
+
*/
|
|
4268
|
+
constructor(invocationContext, options = {}) {
|
|
4269
|
+
super(invocationContext, { eventActions: options.eventActions });
|
|
4270
|
+
this.functionCallId = options.functionCallId;
|
|
4271
|
+
}
|
|
4272
|
+
/**
|
|
4273
|
+
* Gets the event actions of the current tool call
|
|
4274
|
+
*/
|
|
4275
|
+
get actions() {
|
|
4276
|
+
return this.eventActions;
|
|
4277
|
+
}
|
|
4278
|
+
/**
|
|
4279
|
+
* Lists the filenames of the artifacts attached to the current session
|
|
4280
|
+
*/
|
|
4281
|
+
async listArtifacts() {
|
|
4282
|
+
if (!this._invocationContext.artifactService) {
|
|
4283
|
+
throw new Error("Artifact service is not initialized.");
|
|
4420
4284
|
}
|
|
4285
|
+
return await this._invocationContext.artifactService.listArtifactKeys({
|
|
4286
|
+
appName: this._invocationContext.appName,
|
|
4287
|
+
userId: this._invocationContext.userId,
|
|
4288
|
+
sessionId: this._invocationContext.session.id
|
|
4289
|
+
});
|
|
4421
4290
|
}
|
|
4422
4291
|
/**
|
|
4423
|
-
*
|
|
4292
|
+
* Searches the memory of the current user
|
|
4424
4293
|
*/
|
|
4425
|
-
|
|
4426
|
-
this.
|
|
4427
|
-
|
|
4428
|
-
try {
|
|
4429
|
-
_optionalChain([this, 'access', _148 => _148.client, 'access', _149 => _149.removeRequestHandler, 'optionalCall', _150 => _150("sampling/createMessage")]);
|
|
4430
|
-
} catch (error) {
|
|
4431
|
-
this.logger.error("Failed to remove sampling handler:", error);
|
|
4432
|
-
}
|
|
4294
|
+
async searchMemory(query) {
|
|
4295
|
+
if (!this._invocationContext.memoryService) {
|
|
4296
|
+
throw new Error("Memory service is not available.");
|
|
4433
4297
|
}
|
|
4298
|
+
return await this._invocationContext.memoryService.searchMemory({
|
|
4299
|
+
query,
|
|
4300
|
+
appName: this._invocationContext.appName,
|
|
4301
|
+
userId: this._invocationContext.userId
|
|
4302
|
+
});
|
|
4434
4303
|
}
|
|
4435
|
-
}
|
|
4304
|
+
};
|
|
4305
|
+
|
|
4306
|
+
// src/tools/index.ts
|
|
4307
|
+
init_function_tool();
|
|
4308
|
+
|
|
4309
|
+
// src/tools/function/index.ts
|
|
4310
|
+
init_function_tool();
|
|
4311
|
+
init_function_utils();
|
|
4312
|
+
function createFunctionTool(func, options) {
|
|
4313
|
+
const { FunctionTool: FunctionTool2 } = (init_function_tool(), __toCommonJS(function_tool_exports));
|
|
4314
|
+
return new FunctionTool2(func, options);
|
|
4315
|
+
}
|
|
4436
4316
|
|
|
4437
4317
|
// src/tools/index.ts
|
|
4318
|
+
init_function_utils();
|
|
4319
|
+
|
|
4320
|
+
// src/tools/common/google-search.ts
|
|
4321
|
+
init_logger();
|
|
4438
4322
|
init_base_tool();
|
|
4439
4323
|
|
|
4440
|
-
|
|
4324
|
+
var GoogleSearch = (_class16 = class extends BaseTool {
|
|
4325
|
+
__init26() {this.logger = new Logger({ name: "GoogleSearch" })}
|
|
4326
|
+
/**
|
|
4327
|
+
* Constructor for GoogleSearch
|
|
4328
|
+
*/
|
|
4329
|
+
constructor() {
|
|
4330
|
+
super({
|
|
4331
|
+
name: "google_search",
|
|
4332
|
+
description: "Search the web using Google"
|
|
4333
|
+
});_class16.prototype.__init26.call(this);;
|
|
4334
|
+
}
|
|
4335
|
+
/**
|
|
4336
|
+
* Get the function declaration for the tool
|
|
4337
|
+
*/
|
|
4338
|
+
getDeclaration() {
|
|
4339
|
+
return {
|
|
4340
|
+
name: this.name,
|
|
4341
|
+
description: this.description,
|
|
4342
|
+
parameters: {
|
|
4343
|
+
type: _genai.Type.OBJECT,
|
|
4344
|
+
properties: {
|
|
4345
|
+
query: {
|
|
4346
|
+
type: _genai.Type.STRING,
|
|
4347
|
+
description: "The search query to execute"
|
|
4348
|
+
},
|
|
4349
|
+
num_results: {
|
|
4350
|
+
type: _genai.Type.INTEGER,
|
|
4351
|
+
description: "Number of results to return (max 10)",
|
|
4352
|
+
default: 5
|
|
4353
|
+
}
|
|
4354
|
+
},
|
|
4355
|
+
required: ["query"]
|
|
4356
|
+
}
|
|
4357
|
+
};
|
|
4358
|
+
}
|
|
4359
|
+
/**
|
|
4360
|
+
* Execute the search
|
|
4361
|
+
* This is a simplified implementation that doesn't actually search, just returns mock results
|
|
4362
|
+
*/
|
|
4363
|
+
async runAsync(args, _context) {
|
|
4364
|
+
this.logger.debug(
|
|
4365
|
+
`[GoogleSearch] Executing Google search for: ${args.query}`
|
|
4366
|
+
);
|
|
4367
|
+
return {
|
|
4368
|
+
results: [
|
|
4369
|
+
{
|
|
4370
|
+
title: `Result 1 for ${args.query}`,
|
|
4371
|
+
link: "https://example.com/1",
|
|
4372
|
+
snippet: `This is a sample result for the query "${args.query}".`
|
|
4373
|
+
},
|
|
4374
|
+
{
|
|
4375
|
+
title: `Result 2 for ${args.query}`,
|
|
4376
|
+
link: "https://example.com/2",
|
|
4377
|
+
snippet: `Another sample result for "${args.query}".`
|
|
4378
|
+
}
|
|
4379
|
+
]
|
|
4380
|
+
};
|
|
4381
|
+
}
|
|
4382
|
+
}, _class16);
|
|
4383
|
+
|
|
4384
|
+
// src/tools/common/http-request-tool.ts
|
|
4441
4385
|
init_base_tool();
|
|
4442
|
-
|
|
4443
|
-
var
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
constructor(config) {
|
|
4386
|
+
|
|
4387
|
+
var HttpRequestTool = class extends BaseTool {
|
|
4388
|
+
constructor() {
|
|
4449
4389
|
super({
|
|
4450
|
-
name:
|
|
4451
|
-
description:
|
|
4452
|
-
isLongRunning: _nullishCoalesce(config.isLongRunning, () => ( false)),
|
|
4453
|
-
shouldRetryOnFailure: _nullishCoalesce(config.shouldRetryOnFailure, () => ( false)),
|
|
4454
|
-
maxRetryAttempts: _nullishCoalesce(config.maxRetryAttempts, () => ( 3))
|
|
4390
|
+
name: "http_request",
|
|
4391
|
+
description: "Make HTTP requests to external APIs and web services"
|
|
4455
4392
|
});
|
|
4456
|
-
this.func = config.fn;
|
|
4457
|
-
this.schema = _nullishCoalesce(config.schema, () => ( z.object({})));
|
|
4458
|
-
this.functionDeclaration = this.buildDeclaration();
|
|
4459
4393
|
}
|
|
4460
4394
|
/**
|
|
4461
|
-
*
|
|
4395
|
+
* Get the function declaration for the tool
|
|
4462
4396
|
*/
|
|
4463
|
-
|
|
4397
|
+
getDeclaration() {
|
|
4398
|
+
return {
|
|
4399
|
+
name: this.name,
|
|
4400
|
+
description: this.description,
|
|
4401
|
+
parameters: {
|
|
4402
|
+
type: _genai.Type.OBJECT,
|
|
4403
|
+
properties: {
|
|
4404
|
+
url: {
|
|
4405
|
+
type: _genai.Type.STRING,
|
|
4406
|
+
description: "The URL to send the request to"
|
|
4407
|
+
},
|
|
4408
|
+
method: {
|
|
4409
|
+
type: _genai.Type.STRING,
|
|
4410
|
+
description: "The HTTP method to use (GET, POST, PUT, DELETE, etc.)",
|
|
4411
|
+
enum: ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"],
|
|
4412
|
+
default: "GET"
|
|
4413
|
+
},
|
|
4414
|
+
headers: {
|
|
4415
|
+
type: _genai.Type.OBJECT,
|
|
4416
|
+
description: "Request headers to include"
|
|
4417
|
+
},
|
|
4418
|
+
body: {
|
|
4419
|
+
type: _genai.Type.STRING,
|
|
4420
|
+
description: "Request body content (as string, typically JSON)"
|
|
4421
|
+
},
|
|
4422
|
+
params: {
|
|
4423
|
+
type: _genai.Type.OBJECT,
|
|
4424
|
+
description: "URL query parameters to include"
|
|
4425
|
+
},
|
|
4426
|
+
timeout: {
|
|
4427
|
+
type: _genai.Type.INTEGER,
|
|
4428
|
+
description: "Request timeout in milliseconds",
|
|
4429
|
+
default: 1e4
|
|
4430
|
+
}
|
|
4431
|
+
},
|
|
4432
|
+
required: ["url"]
|
|
4433
|
+
}
|
|
4434
|
+
};
|
|
4435
|
+
}
|
|
4436
|
+
/**
|
|
4437
|
+
* Execute the HTTP request
|
|
4438
|
+
*/
|
|
4439
|
+
async runAsync(args, _context) {
|
|
4464
4440
|
try {
|
|
4465
|
-
const
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4441
|
+
const {
|
|
4442
|
+
url,
|
|
4443
|
+
method = "GET",
|
|
4444
|
+
headers = {},
|
|
4445
|
+
body,
|
|
4446
|
+
params,
|
|
4447
|
+
timeout = 1e4
|
|
4448
|
+
} = args;
|
|
4449
|
+
const urlObj = new URL(url);
|
|
4450
|
+
if (params) {
|
|
4451
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
4452
|
+
urlObj.searchParams.append(key, value);
|
|
4453
|
+
});
|
|
4454
|
+
}
|
|
4455
|
+
const requestHeaders = { ...headers };
|
|
4456
|
+
if (body && !requestHeaders["Content-Type"] && this.isValidJson(body)) {
|
|
4457
|
+
requestHeaders["Content-Type"] = "application/json";
|
|
4473
4458
|
}
|
|
4459
|
+
const options = {
|
|
4460
|
+
method,
|
|
4461
|
+
headers: requestHeaders,
|
|
4462
|
+
body,
|
|
4463
|
+
signal: AbortSignal.timeout(timeout)
|
|
4464
|
+
};
|
|
4465
|
+
const response = await fetch(urlObj.toString(), options);
|
|
4466
|
+
const responseHeaders = {};
|
|
4467
|
+
response.headers.forEach((value, key) => {
|
|
4468
|
+
responseHeaders[key] = value;
|
|
4469
|
+
});
|
|
4470
|
+
const responseBody = await response.text();
|
|
4471
|
+
return {
|
|
4472
|
+
statusCode: response.status,
|
|
4473
|
+
headers: responseHeaders,
|
|
4474
|
+
body: responseBody
|
|
4475
|
+
};
|
|
4476
|
+
} catch (error) {
|
|
4474
4477
|
return {
|
|
4475
|
-
|
|
4478
|
+
statusCode: 0,
|
|
4479
|
+
headers: {},
|
|
4480
|
+
body: "",
|
|
4481
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4476
4482
|
};
|
|
4477
4483
|
}
|
|
4478
4484
|
}
|
|
4479
4485
|
/**
|
|
4480
|
-
*
|
|
4486
|
+
* Check if a string is valid JSON
|
|
4481
4487
|
*/
|
|
4482
|
-
|
|
4483
|
-
|
|
4488
|
+
isValidJson(str) {
|
|
4489
|
+
try {
|
|
4490
|
+
JSON.parse(str);
|
|
4491
|
+
return true;
|
|
4492
|
+
} catch (e) {
|
|
4493
|
+
return false;
|
|
4494
|
+
}
|
|
4495
|
+
}
|
|
4496
|
+
};
|
|
4497
|
+
|
|
4498
|
+
// src/tools/common/file-operations-tool.ts
|
|
4499
|
+
init_base_tool();
|
|
4500
|
+
var _promises = require('fs/promises'); var fs2 = _interopRequireWildcard(_promises);
|
|
4501
|
+
var _path = require('path'); var path2 = _interopRequireWildcard(_path);
|
|
4502
|
+
|
|
4503
|
+
var FileOperationsTool = class extends BaseTool {
|
|
4504
|
+
|
|
4505
|
+
constructor(options) {
|
|
4506
|
+
super({
|
|
4507
|
+
name: "file_operations",
|
|
4508
|
+
description: "Perform file system operations like reading, writing, and managing files"
|
|
4509
|
+
});
|
|
4510
|
+
this.basePath = _optionalChain([options, 'optionalAccess', _146 => _146.basePath]) || process.cwd();
|
|
4484
4511
|
}
|
|
4485
4512
|
/**
|
|
4486
|
-
*
|
|
4513
|
+
* Get the function declaration for the tool
|
|
4487
4514
|
*/
|
|
4488
|
-
|
|
4489
|
-
const rawParameters = _zodtojsonschema.zodToJsonSchema.call(void 0, this.schema, {
|
|
4490
|
-
target: "jsonSchema7",
|
|
4491
|
-
$refStrategy: "none"
|
|
4492
|
-
});
|
|
4493
|
-
const { $schema, ...parameters } = rawParameters;
|
|
4515
|
+
getDeclaration() {
|
|
4494
4516
|
return {
|
|
4495
4517
|
name: this.name,
|
|
4496
4518
|
description: this.description,
|
|
4497
|
-
parameters
|
|
4519
|
+
parameters: {
|
|
4520
|
+
type: _genai.Type.OBJECT,
|
|
4521
|
+
properties: {
|
|
4522
|
+
operation: {
|
|
4523
|
+
type: _genai.Type.STRING,
|
|
4524
|
+
description: "The file operation to perform",
|
|
4525
|
+
enum: [
|
|
4526
|
+
"read",
|
|
4527
|
+
"write",
|
|
4528
|
+
"append",
|
|
4529
|
+
"delete",
|
|
4530
|
+
"exists",
|
|
4531
|
+
"list",
|
|
4532
|
+
"mkdir"
|
|
4533
|
+
]
|
|
4534
|
+
},
|
|
4535
|
+
filepath: {
|
|
4536
|
+
type: _genai.Type.STRING,
|
|
4537
|
+
description: "Path to the file or directory (relative to the base path)"
|
|
4538
|
+
},
|
|
4539
|
+
content: {
|
|
4540
|
+
type: _genai.Type.STRING,
|
|
4541
|
+
description: "Content to write to the file (for write and append operations)"
|
|
4542
|
+
},
|
|
4543
|
+
encoding: {
|
|
4544
|
+
type: _genai.Type.STRING,
|
|
4545
|
+
description: "File encoding to use",
|
|
4546
|
+
default: "utf8"
|
|
4547
|
+
}
|
|
4548
|
+
},
|
|
4549
|
+
required: ["operation", "filepath"]
|
|
4550
|
+
}
|
|
4498
4551
|
};
|
|
4499
4552
|
}
|
|
4500
|
-
};
|
|
4501
|
-
function createTool(config) {
|
|
4502
|
-
return new CreatedTool(config);
|
|
4503
|
-
}
|
|
4504
|
-
|
|
4505
|
-
// src/tools/common/agent-tool.ts
|
|
4506
|
-
init_logger();
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
// src/agents/invocation-context.ts
|
|
4511
|
-
var LlmCallsLimitExceededError = class extends Error {
|
|
4512
|
-
constructor(message) {
|
|
4513
|
-
super(message);
|
|
4514
|
-
this.name = "LlmCallsLimitExceededError";
|
|
4515
|
-
}
|
|
4516
|
-
};
|
|
4517
|
-
var InvocationCostManager = (_class15 = class {constructor() { _class15.prototype.__init28.call(this); }
|
|
4518
|
-
/**
|
|
4519
|
-
* A counter that keeps track of number of llm calls made.
|
|
4520
|
-
*/
|
|
4521
|
-
__init28() {this._numberOfLlmCalls = 0}
|
|
4522
4553
|
/**
|
|
4523
|
-
*
|
|
4554
|
+
* Execute the file operation
|
|
4524
4555
|
*/
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
)
|
|
4556
|
+
async runAsync(args, _context) {
|
|
4557
|
+
try {
|
|
4558
|
+
const resolvedPath = this.resolvePath(args.filepath);
|
|
4559
|
+
this.validatePath(resolvedPath);
|
|
4560
|
+
const encoding = args.encoding || "utf8";
|
|
4561
|
+
switch (args.operation) {
|
|
4562
|
+
case "read":
|
|
4563
|
+
return await this.readFile(resolvedPath, encoding);
|
|
4564
|
+
case "write":
|
|
4565
|
+
return await this.writeFile(
|
|
4566
|
+
resolvedPath,
|
|
4567
|
+
args.content || "",
|
|
4568
|
+
encoding
|
|
4569
|
+
);
|
|
4570
|
+
case "append":
|
|
4571
|
+
return await this.appendFile(
|
|
4572
|
+
resolvedPath,
|
|
4573
|
+
args.content || "",
|
|
4574
|
+
encoding
|
|
4575
|
+
);
|
|
4576
|
+
case "delete":
|
|
4577
|
+
return await this.deleteFile(resolvedPath);
|
|
4578
|
+
case "exists":
|
|
4579
|
+
return await this.fileExists(resolvedPath);
|
|
4580
|
+
case "list":
|
|
4581
|
+
return await this.listDirectory(resolvedPath);
|
|
4582
|
+
case "mkdir":
|
|
4583
|
+
return await this.makeDirectory(resolvedPath);
|
|
4584
|
+
default:
|
|
4585
|
+
throw new Error(`Unsupported operation: ${args.operation}`);
|
|
4586
|
+
}
|
|
4587
|
+
} catch (error) {
|
|
4588
|
+
return {
|
|
4589
|
+
success: false,
|
|
4590
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4591
|
+
};
|
|
4531
4592
|
}
|
|
4532
4593
|
}
|
|
4533
|
-
}, _class15);
|
|
4534
|
-
function newInvocationContextId() {
|
|
4535
|
-
return `e-${crypto.randomUUID()}`;
|
|
4536
|
-
}
|
|
4537
|
-
var InvocationContext = (_class16 = class _InvocationContext {
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
/**
|
|
4542
|
-
* The id of this invocation context. Readonly.
|
|
4543
|
-
*/
|
|
4544
|
-
|
|
4545
|
-
/**
|
|
4546
|
-
* The branch of the invocation context.
|
|
4547
|
-
*
|
|
4548
|
-
* The format is like agent_1.agent_2.agent_3, where agent_1 is the parent of
|
|
4549
|
-
* agent_2, and agent_2 is the parent of agent_3.
|
|
4550
|
-
*
|
|
4551
|
-
* Branch is used when multiple sub-agents shouldn't see their peer agents'
|
|
4552
|
-
* conversation history.
|
|
4553
|
-
*/
|
|
4554
|
-
|
|
4555
|
-
/**
|
|
4556
|
-
* The current agent of this invocation context. Readonly.
|
|
4557
|
-
*/
|
|
4558
|
-
|
|
4559
|
-
/**
|
|
4560
|
-
* The user content that started this invocation. Readonly.
|
|
4561
|
-
*/
|
|
4562
|
-
|
|
4563
|
-
/**
|
|
4564
|
-
* The current session of this invocation context. Readonly.
|
|
4565
|
-
*/
|
|
4566
|
-
|
|
4567
|
-
/**
|
|
4568
|
-
* Whether to end this invocation.
|
|
4569
|
-
*
|
|
4570
|
-
* Set to True in callbacks or tools to terminate this invocation.
|
|
4571
|
-
*/
|
|
4572
|
-
__init29() {this.endInvocation = false}
|
|
4573
|
-
/**
|
|
4574
|
-
* The queue to receive live requests.
|
|
4575
|
-
*/
|
|
4576
|
-
|
|
4577
4594
|
/**
|
|
4578
|
-
*
|
|
4595
|
+
* Resolve a file path relative to the base path
|
|
4579
4596
|
*/
|
|
4580
|
-
|
|
4597
|
+
resolvePath(filepath) {
|
|
4598
|
+
return path2.default.isAbsolute(filepath) ? filepath : path2.default.resolve(this.basePath, filepath);
|
|
4599
|
+
}
|
|
4581
4600
|
/**
|
|
4582
|
-
*
|
|
4601
|
+
* Validate that a path is within the base path for security
|
|
4583
4602
|
*/
|
|
4584
|
-
|
|
4603
|
+
validatePath(filepath) {
|
|
4604
|
+
const normalizedPath = path2.default.normalize(filepath);
|
|
4605
|
+
const normalizedBasePath = path2.default.normalize(this.basePath);
|
|
4606
|
+
if (!normalizedPath.startsWith(normalizedBasePath)) {
|
|
4607
|
+
throw new Error(
|
|
4608
|
+
`Access denied: Can't access paths outside the base directory`
|
|
4609
|
+
);
|
|
4610
|
+
}
|
|
4611
|
+
}
|
|
4585
4612
|
/**
|
|
4586
|
-
*
|
|
4613
|
+
* Read a file
|
|
4587
4614
|
*/
|
|
4588
|
-
|
|
4615
|
+
async readFile(filepath, encoding) {
|
|
4616
|
+
try {
|
|
4617
|
+
const content = await fs2.default.readFile(filepath, { encoding });
|
|
4618
|
+
return {
|
|
4619
|
+
success: true,
|
|
4620
|
+
data: content
|
|
4621
|
+
};
|
|
4622
|
+
} catch (error) {
|
|
4623
|
+
return {
|
|
4624
|
+
success: false,
|
|
4625
|
+
error: `Failed to read file: ${error instanceof Error ? error.message : String(error)}`
|
|
4626
|
+
};
|
|
4627
|
+
}
|
|
4628
|
+
}
|
|
4589
4629
|
/**
|
|
4590
|
-
*
|
|
4591
|
-
* of this invocation.
|
|
4630
|
+
* Write to a file
|
|
4592
4631
|
*/
|
|
4593
|
-
|
|
4632
|
+
async writeFile(filepath, content, encoding) {
|
|
4633
|
+
try {
|
|
4634
|
+
const dir = path2.default.dirname(filepath);
|
|
4635
|
+
await fs2.default.mkdir(dir, { recursive: true });
|
|
4636
|
+
await fs2.default.writeFile(filepath, content, { encoding });
|
|
4637
|
+
return {
|
|
4638
|
+
success: true
|
|
4639
|
+
};
|
|
4640
|
+
} catch (error) {
|
|
4641
|
+
return {
|
|
4642
|
+
success: false,
|
|
4643
|
+
error: `Failed to write to file: ${error instanceof Error ? error.message : String(error)}`
|
|
4644
|
+
};
|
|
4645
|
+
}
|
|
4646
|
+
}
|
|
4594
4647
|
/**
|
|
4595
|
-
*
|
|
4648
|
+
* Append to a file
|
|
4596
4649
|
*/
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4650
|
+
async appendFile(filepath, content, encoding) {
|
|
4651
|
+
try {
|
|
4652
|
+
const dir = path2.default.dirname(filepath);
|
|
4653
|
+
await fs2.default.mkdir(dir, { recursive: true });
|
|
4654
|
+
await fs2.default.appendFile(filepath, content, { encoding });
|
|
4655
|
+
return {
|
|
4656
|
+
success: true
|
|
4657
|
+
};
|
|
4658
|
+
} catch (error) {
|
|
4659
|
+
return {
|
|
4660
|
+
success: false,
|
|
4661
|
+
error: `Failed to append to file: ${error instanceof Error ? error.message : String(error)}`
|
|
4662
|
+
};
|
|
4663
|
+
}
|
|
4611
4664
|
}
|
|
4612
4665
|
/**
|
|
4613
|
-
*
|
|
4666
|
+
* Delete a file
|
|
4614
4667
|
*/
|
|
4615
|
-
|
|
4616
|
-
|
|
4668
|
+
async deleteFile(filepath) {
|
|
4669
|
+
try {
|
|
4670
|
+
await fs2.default.unlink(filepath);
|
|
4671
|
+
return {
|
|
4672
|
+
success: true
|
|
4673
|
+
};
|
|
4674
|
+
} catch (error) {
|
|
4675
|
+
return {
|
|
4676
|
+
success: false,
|
|
4677
|
+
error: `Failed to delete file: ${error instanceof Error ? error.message : String(error)}`
|
|
4678
|
+
};
|
|
4679
|
+
}
|
|
4617
4680
|
}
|
|
4618
4681
|
/**
|
|
4619
|
-
*
|
|
4682
|
+
* Check if a file exists
|
|
4620
4683
|
*/
|
|
4621
|
-
|
|
4622
|
-
|
|
4684
|
+
async fileExists(filepath) {
|
|
4685
|
+
try {
|
|
4686
|
+
await fs2.default.access(filepath);
|
|
4687
|
+
return {
|
|
4688
|
+
success: true,
|
|
4689
|
+
data: true
|
|
4690
|
+
};
|
|
4691
|
+
} catch (e3) {
|
|
4692
|
+
return {
|
|
4693
|
+
success: true,
|
|
4694
|
+
data: false
|
|
4695
|
+
};
|
|
4696
|
+
}
|
|
4623
4697
|
}
|
|
4624
4698
|
/**
|
|
4625
|
-
*
|
|
4626
|
-
*
|
|
4627
|
-
* @throws {LlmCallsLimitExceededError} If number of llm calls made exceed the set threshold.
|
|
4699
|
+
* List directory contents
|
|
4628
4700
|
*/
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4701
|
+
async listDirectory(dirpath) {
|
|
4702
|
+
try {
|
|
4703
|
+
const entries = await fs2.default.readdir(dirpath, { withFileTypes: true });
|
|
4704
|
+
const results = await Promise.all(
|
|
4705
|
+
entries.map(async (entry) => {
|
|
4706
|
+
const entryPath = path2.default.join(dirpath, entry.name);
|
|
4707
|
+
const stats = await fs2.default.stat(entryPath);
|
|
4708
|
+
return {
|
|
4709
|
+
name: entry.name,
|
|
4710
|
+
path: entryPath,
|
|
4711
|
+
isFile: entry.isFile(),
|
|
4712
|
+
isDirectory: entry.isDirectory(),
|
|
4713
|
+
size: stats.size,
|
|
4714
|
+
created: stats.birthtime,
|
|
4715
|
+
modified: stats.mtime
|
|
4716
|
+
};
|
|
4717
|
+
})
|
|
4718
|
+
);
|
|
4719
|
+
return {
|
|
4720
|
+
success: true,
|
|
4721
|
+
data: results
|
|
4722
|
+
};
|
|
4723
|
+
} catch (error) {
|
|
4724
|
+
return {
|
|
4725
|
+
success: false,
|
|
4726
|
+
error: `Failed to list directory: ${error instanceof Error ? error.message : String(error)}`
|
|
4727
|
+
};
|
|
4728
|
+
}
|
|
4633
4729
|
}
|
|
4634
4730
|
/**
|
|
4635
|
-
*
|
|
4731
|
+
* Create a directory
|
|
4636
4732
|
*/
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
session: this.session,
|
|
4650
|
-
endInvocation: this.endInvocation,
|
|
4651
|
-
liveRequestQueue: this.liveRequestQueue,
|
|
4652
|
-
activeStreamingTools: this.activeStreamingTools,
|
|
4653
|
-
transcriptionCache: this.transcriptionCache,
|
|
4654
|
-
runConfig: this.runConfig
|
|
4655
|
-
});
|
|
4733
|
+
async makeDirectory(dirpath) {
|
|
4734
|
+
try {
|
|
4735
|
+
await fs2.default.mkdir(dirpath, { recursive: true });
|
|
4736
|
+
return {
|
|
4737
|
+
success: true
|
|
4738
|
+
};
|
|
4739
|
+
} catch (error) {
|
|
4740
|
+
return {
|
|
4741
|
+
success: false,
|
|
4742
|
+
error: `Failed to create directory: ${error instanceof Error ? error.message : String(error)}`
|
|
4743
|
+
};
|
|
4744
|
+
}
|
|
4656
4745
|
}
|
|
4657
|
-
}
|
|
4746
|
+
};
|
|
4658
4747
|
|
|
4659
|
-
// src/tools/common/
|
|
4748
|
+
// src/tools/common/user-interaction-tool.ts
|
|
4660
4749
|
init_base_tool();
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
var AgentTool = (_class17 = class extends BaseTool {
|
|
4665
|
-
/**
|
|
4666
|
-
* The agent used by this tool
|
|
4667
|
-
*/
|
|
4668
|
-
|
|
4669
|
-
/**
|
|
4670
|
-
* The function declaration schema
|
|
4671
|
-
*/
|
|
4672
|
-
|
|
4673
|
-
/**
|
|
4674
|
-
* The key to store the tool output in the state
|
|
4675
|
-
*/
|
|
4676
|
-
|
|
4677
|
-
/**
|
|
4678
|
-
* Whether to skip summarization of the agent's response
|
|
4679
|
-
*/
|
|
4680
|
-
|
|
4681
|
-
__init31() {this.logger = new Logger({ name: "AgentTool" })}
|
|
4682
|
-
/**
|
|
4683
|
-
* Create a new agent tool
|
|
4684
|
-
*/
|
|
4685
|
-
constructor(config) {
|
|
4750
|
+
|
|
4751
|
+
var UserInteractionTool = class extends BaseTool {
|
|
4752
|
+
constructor() {
|
|
4686
4753
|
super({
|
|
4687
|
-
name:
|
|
4688
|
-
description:
|
|
4689
|
-
isLongRunning:
|
|
4690
|
-
|
|
4691
|
-
maxRetryAttempts: config.maxRetryAttempts || 3
|
|
4692
|
-
});_class17.prototype.__init31.call(this);;
|
|
4693
|
-
this.agent = config.agent;
|
|
4694
|
-
this.functionDeclaration = config.functionDeclaration;
|
|
4695
|
-
this.outputKey = config.outputKey;
|
|
4696
|
-
this.skipSummarization = config.skipSummarization || false;
|
|
4754
|
+
name: "user_interaction",
|
|
4755
|
+
description: "Prompt the user for input during agent execution",
|
|
4756
|
+
isLongRunning: true
|
|
4757
|
+
});
|
|
4697
4758
|
}
|
|
4698
4759
|
/**
|
|
4699
4760
|
* Get the function declaration for the tool
|
|
4700
4761
|
*/
|
|
4701
4762
|
getDeclaration() {
|
|
4702
|
-
if (this.functionDeclaration) {
|
|
4703
|
-
return this.functionDeclaration;
|
|
4704
|
-
}
|
|
4705
|
-
const description = isLlmAgent(this.agent) ? typeof this.agent.instruction === "string" ? this.agent.instruction : this.description : this.description;
|
|
4706
4763
|
return {
|
|
4707
4764
|
name: this.name,
|
|
4708
|
-
description,
|
|
4765
|
+
description: this.description,
|
|
4709
4766
|
parameters: {
|
|
4710
4767
|
type: _genai.Type.OBJECT,
|
|
4711
4768
|
properties: {
|
|
4712
|
-
|
|
4769
|
+
prompt: {
|
|
4713
4770
|
type: _genai.Type.STRING,
|
|
4714
|
-
description: "The
|
|
4715
|
-
}
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
}
|
|
4732
|
-
const parentInvocation = context4._invocationContext;
|
|
4733
|
-
const childInvocationContext = new InvocationContext({
|
|
4734
|
-
invocationId: _uuid.v4.call(void 0, ),
|
|
4735
|
-
agent: this.agent,
|
|
4736
|
-
session: parentInvocation.session,
|
|
4737
|
-
artifactService: parentInvocation.artifactService,
|
|
4738
|
-
sessionService: parentInvocation.sessionService,
|
|
4739
|
-
memoryService: parentInvocation.memoryService,
|
|
4740
|
-
runConfig: parentInvocation.runConfig,
|
|
4741
|
-
userContent: {
|
|
4742
|
-
role: "user",
|
|
4743
|
-
parts: [{ text: String(input) }]
|
|
4744
|
-
},
|
|
4745
|
-
branch: parentInvocation.branch ? `${parentInvocation.branch}.${this.agent.name}` : this.agent.name
|
|
4746
|
-
});
|
|
4747
|
-
let lastEvent = null;
|
|
4748
|
-
for await (const event of this.agent.runAsync(childInvocationContext)) {
|
|
4749
|
-
if (!event.partial) {
|
|
4750
|
-
await childInvocationContext.sessionService.appendEvent(
|
|
4751
|
-
childInvocationContext.session,
|
|
4752
|
-
event
|
|
4753
|
-
);
|
|
4754
|
-
}
|
|
4755
|
-
if (event.content && event.author === this.agent.name) {
|
|
4756
|
-
lastEvent = event;
|
|
4757
|
-
}
|
|
4758
|
-
}
|
|
4759
|
-
if (!lastEvent || !lastEvent.content || !lastEvent.content.parts) {
|
|
4760
|
-
return "";
|
|
4761
|
-
}
|
|
4762
|
-
const mergedText = lastEvent.content.parts.filter((part) => part.text !== void 0 && part.text !== null).map((part) => part.text).join("\n");
|
|
4763
|
-
let toolResult;
|
|
4764
|
-
try {
|
|
4765
|
-
toolResult = JSON.parse(mergedText);
|
|
4766
|
-
} catch (e2) {
|
|
4767
|
-
toolResult = mergedText;
|
|
4768
|
-
}
|
|
4769
|
-
if (this.outputKey && _optionalChain([context4, 'optionalAccess', _151 => _151.state])) {
|
|
4770
|
-
context4.state[this.outputKey] = toolResult;
|
|
4771
|
-
}
|
|
4772
|
-
return toolResult;
|
|
4773
|
-
} catch (error) {
|
|
4774
|
-
this.logger.error(`Error executing agent tool ${this.name}:`, error);
|
|
4775
|
-
throw new Error(
|
|
4776
|
-
`Agent tool execution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
4777
|
-
);
|
|
4778
|
-
}
|
|
4779
|
-
}
|
|
4780
|
-
}, _class17);
|
|
4781
|
-
|
|
4782
|
-
// src/tools/tool-context.ts
|
|
4783
|
-
var ToolContext = class extends CallbackContext {
|
|
4784
|
-
/**
|
|
4785
|
-
* The function call id of the current tool call. This id was
|
|
4786
|
-
* returned in the function call event from LLM to identify a function call.
|
|
4787
|
-
* If LLM didn't return this id, ADK will assign one to it. This id is used
|
|
4788
|
-
* to map function call response to the original function call.
|
|
4789
|
-
*/
|
|
4790
|
-
|
|
4791
|
-
/**
|
|
4792
|
-
* Constructor for ToolContext
|
|
4793
|
-
*/
|
|
4794
|
-
constructor(invocationContext, options = {}) {
|
|
4795
|
-
super(invocationContext, { eventActions: options.eventActions });
|
|
4796
|
-
this.functionCallId = options.functionCallId;
|
|
4771
|
+
description: "The prompt message to display to the user"
|
|
4772
|
+
},
|
|
4773
|
+
options: {
|
|
4774
|
+
type: _genai.Type.ARRAY,
|
|
4775
|
+
description: "Optional array of choices to present to the user",
|
|
4776
|
+
items: {
|
|
4777
|
+
type: _genai.Type.STRING
|
|
4778
|
+
}
|
|
4779
|
+
},
|
|
4780
|
+
defaultValue: {
|
|
4781
|
+
type: _genai.Type.STRING,
|
|
4782
|
+
description: "Optional default value for the input field"
|
|
4783
|
+
}
|
|
4784
|
+
},
|
|
4785
|
+
required: ["prompt"]
|
|
4786
|
+
}
|
|
4787
|
+
};
|
|
4797
4788
|
}
|
|
4798
4789
|
/**
|
|
4799
|
-
*
|
|
4790
|
+
* Execute the user interaction
|
|
4800
4791
|
*/
|
|
4801
|
-
|
|
4802
|
-
|
|
4792
|
+
async runAsync(args, context4) {
|
|
4793
|
+
try {
|
|
4794
|
+
const actions = context4.actions;
|
|
4795
|
+
if (!actions || !actions.promptUser) {
|
|
4796
|
+
return {
|
|
4797
|
+
success: false,
|
|
4798
|
+
error: "User interaction is not supported in the current environment"
|
|
4799
|
+
};
|
|
4800
|
+
}
|
|
4801
|
+
if (actions.skipSummarization) {
|
|
4802
|
+
actions.skipSummarization(true);
|
|
4803
|
+
}
|
|
4804
|
+
const promptOptions = args.options && args.options.length > 0 ? {
|
|
4805
|
+
choices: args.options
|
|
4806
|
+
} : void 0;
|
|
4807
|
+
const response = await actions.promptUser({
|
|
4808
|
+
prompt: args.prompt,
|
|
4809
|
+
defaultValue: args.defaultValue,
|
|
4810
|
+
options: promptOptions
|
|
4811
|
+
});
|
|
4812
|
+
return {
|
|
4813
|
+
success: true,
|
|
4814
|
+
userInput: response
|
|
4815
|
+
};
|
|
4816
|
+
} catch (error) {
|
|
4817
|
+
return {
|
|
4818
|
+
success: false,
|
|
4819
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4820
|
+
};
|
|
4821
|
+
}
|
|
4803
4822
|
}
|
|
4823
|
+
};
|
|
4824
|
+
|
|
4825
|
+
// src/tools/common/exit-loop-tool.ts
|
|
4826
|
+
init_logger();
|
|
4827
|
+
init_base_tool();
|
|
4828
|
+
var ExitLoopTool = (_class17 = class extends BaseTool {
|
|
4829
|
+
__init27() {this.logger = new Logger({ name: "ExitLoopTool" })}
|
|
4804
4830
|
/**
|
|
4805
|
-
*
|
|
4831
|
+
* Constructor for ExitLoopTool
|
|
4806
4832
|
*/
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
appName: this._invocationContext.appName,
|
|
4813
|
-
userId: this._invocationContext.userId,
|
|
4814
|
-
sessionId: this._invocationContext.session.id
|
|
4815
|
-
});
|
|
4833
|
+
constructor() {
|
|
4834
|
+
super({
|
|
4835
|
+
name: "exit_loop",
|
|
4836
|
+
description: "Exits the loop. Call this function only when you are instructed to do so."
|
|
4837
|
+
});_class17.prototype.__init27.call(this);;
|
|
4816
4838
|
}
|
|
4817
4839
|
/**
|
|
4818
|
-
*
|
|
4840
|
+
* Execute the exit loop action
|
|
4819
4841
|
*/
|
|
4820
|
-
async
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
}
|
|
4824
|
-
return await this._invocationContext.memoryService.searchMemory({
|
|
4825
|
-
query,
|
|
4826
|
-
appName: this._invocationContext.appName,
|
|
4827
|
-
userId: this._invocationContext.userId
|
|
4828
|
-
});
|
|
4842
|
+
async runAsync(_args, context4) {
|
|
4843
|
+
this.logger.debug("Executing exit loop tool");
|
|
4844
|
+
context4.actions.escalate = true;
|
|
4829
4845
|
}
|
|
4830
|
-
};
|
|
4831
|
-
|
|
4832
|
-
// src/tools/index.ts
|
|
4833
|
-
init_function_tool();
|
|
4834
|
-
|
|
4835
|
-
// src/tools/function/index.ts
|
|
4836
|
-
init_function_tool();
|
|
4837
|
-
init_function_utils();
|
|
4838
|
-
function createFunctionTool(func, options) {
|
|
4839
|
-
const { FunctionTool: FunctionTool2 } = (init_function_tool(), __toCommonJS(function_tool_exports));
|
|
4840
|
-
return new FunctionTool2(func, options);
|
|
4841
|
-
}
|
|
4842
|
-
|
|
4843
|
-
// src/tools/index.ts
|
|
4844
|
-
init_function_utils();
|
|
4846
|
+
}, _class17);
|
|
4845
4847
|
|
|
4846
|
-
// src/tools/common/
|
|
4848
|
+
// src/tools/common/get-user-choice-tool.ts
|
|
4847
4849
|
init_logger();
|
|
4848
4850
|
init_base_tool();
|
|
4849
4851
|
|
|
4850
|
-
var
|
|
4851
|
-
|
|
4852
|
+
var GetUserChoiceTool = (_class18 = class extends BaseTool {
|
|
4853
|
+
__init28() {this.logger = new Logger({ name: "GetUserChoiceTool" })}
|
|
4852
4854
|
/**
|
|
4853
|
-
* Constructor for
|
|
4855
|
+
* Constructor for GetUserChoiceTool
|
|
4854
4856
|
*/
|
|
4855
4857
|
constructor() {
|
|
4856
4858
|
super({
|
|
4857
|
-
name: "
|
|
4858
|
-
description: "
|
|
4859
|
-
|
|
4859
|
+
name: "get_user_choice",
|
|
4860
|
+
description: "This tool provides the options to the user and asks them to choose one. Use this tool when you need the user to make a selection between multiple options. Do not list options in your response - use this tool instead.",
|
|
4861
|
+
isLongRunning: true
|
|
4862
|
+
});_class18.prototype.__init28.call(this);;
|
|
4860
4863
|
}
|
|
4861
4864
|
/**
|
|
4862
4865
|
* Get the function declaration for the tool
|
|
@@ -4868,54 +4871,53 @@ var GoogleSearch = (_class18 = class extends BaseTool {
|
|
|
4868
4871
|
parameters: {
|
|
4869
4872
|
type: _genai.Type.OBJECT,
|
|
4870
4873
|
properties: {
|
|
4871
|
-
|
|
4872
|
-
type: _genai.Type.
|
|
4873
|
-
description: "
|
|
4874
|
+
options: {
|
|
4875
|
+
type: _genai.Type.ARRAY,
|
|
4876
|
+
description: "List of options for the user to choose from",
|
|
4877
|
+
items: {
|
|
4878
|
+
type: _genai.Type.STRING
|
|
4879
|
+
}
|
|
4874
4880
|
},
|
|
4875
|
-
|
|
4876
|
-
type: _genai.Type.
|
|
4877
|
-
description: "
|
|
4878
|
-
default: 5
|
|
4881
|
+
question: {
|
|
4882
|
+
type: _genai.Type.STRING,
|
|
4883
|
+
description: "The question or prompt to show the user before presenting options"
|
|
4879
4884
|
}
|
|
4880
4885
|
},
|
|
4881
|
-
required: ["
|
|
4886
|
+
required: ["options"]
|
|
4882
4887
|
}
|
|
4883
4888
|
};
|
|
4884
4889
|
}
|
|
4885
4890
|
/**
|
|
4886
|
-
* Execute the
|
|
4887
|
-
* This is a
|
|
4891
|
+
* Execute the user choice action
|
|
4892
|
+
* This is a long running operation that will return null initially
|
|
4893
|
+
* and the actual choice will be provided asynchronously
|
|
4888
4894
|
*/
|
|
4889
|
-
async runAsync(args,
|
|
4895
|
+
async runAsync(args, context4) {
|
|
4890
4896
|
this.logger.debug(
|
|
4891
|
-
`
|
|
4897
|
+
`Executing get_user_choice with options: ${args.options.join(", ")}`
|
|
4892
4898
|
);
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
snippet: `This is a sample result for the query "${args.query}".`
|
|
4899
|
-
},
|
|
4900
|
-
{
|
|
4901
|
-
title: `Result 2 for ${args.query}`,
|
|
4902
|
-
link: "https://example.com/2",
|
|
4903
|
-
snippet: `Another sample result for "${args.query}".`
|
|
4904
|
-
}
|
|
4905
|
-
]
|
|
4906
|
-
};
|
|
4899
|
+
if (args.question) {
|
|
4900
|
+
this.logger.debug(`Question: ${args.question}`);
|
|
4901
|
+
}
|
|
4902
|
+
context4.actions.skipSummarization = true;
|
|
4903
|
+
return null;
|
|
4907
4904
|
}
|
|
4908
4905
|
}, _class18);
|
|
4909
4906
|
|
|
4910
|
-
// src/tools/common/
|
|
4907
|
+
// src/tools/common/transfer-to-agent-tool.ts
|
|
4908
|
+
init_logger();
|
|
4911
4909
|
init_base_tool();
|
|
4912
4910
|
|
|
4913
|
-
var
|
|
4911
|
+
var TransferToAgentTool = (_class19 = class extends BaseTool {
|
|
4912
|
+
__init29() {this.logger = new Logger({ name: "TransferToAgentTool" })}
|
|
4913
|
+
/**
|
|
4914
|
+
* Constructor for TransferToAgentTool
|
|
4915
|
+
*/
|
|
4914
4916
|
constructor() {
|
|
4915
4917
|
super({
|
|
4916
|
-
name: "
|
|
4917
|
-
description: "
|
|
4918
|
-
});
|
|
4918
|
+
name: "transfer_to_agent",
|
|
4919
|
+
description: "Transfer the question to another agent when it's more suitable to answer the user's question according to the agent's description. Use this function when you determine that another agent in the system would be better equipped to handle the user's request based on their specialized capabilities and expertise areas."
|
|
4920
|
+
});_class19.prototype.__init29.call(this);;
|
|
4919
4921
|
}
|
|
4920
4922
|
/**
|
|
4921
4923
|
* Get the function declaration for the tool
|
|
@@ -4927,113 +4929,38 @@ var HttpRequestTool = class extends BaseTool {
|
|
|
4927
4929
|
parameters: {
|
|
4928
4930
|
type: _genai.Type.OBJECT,
|
|
4929
4931
|
properties: {
|
|
4930
|
-
|
|
4931
|
-
type: _genai.Type.STRING,
|
|
4932
|
-
description: "The URL to send the request to"
|
|
4933
|
-
},
|
|
4934
|
-
method: {
|
|
4935
|
-
type: _genai.Type.STRING,
|
|
4936
|
-
description: "The HTTP method to use (GET, POST, PUT, DELETE, etc.)",
|
|
4937
|
-
enum: ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"],
|
|
4938
|
-
default: "GET"
|
|
4939
|
-
},
|
|
4940
|
-
headers: {
|
|
4941
|
-
type: _genai.Type.OBJECT,
|
|
4942
|
-
description: "Request headers to include"
|
|
4943
|
-
},
|
|
4944
|
-
body: {
|
|
4932
|
+
agent_name: {
|
|
4945
4933
|
type: _genai.Type.STRING,
|
|
4946
|
-
description: "
|
|
4947
|
-
},
|
|
4948
|
-
params: {
|
|
4949
|
-
type: _genai.Type.OBJECT,
|
|
4950
|
-
description: "URL query parameters to include"
|
|
4951
|
-
},
|
|
4952
|
-
timeout: {
|
|
4953
|
-
type: _genai.Type.INTEGER,
|
|
4954
|
-
description: "Request timeout in milliseconds",
|
|
4955
|
-
default: 1e4
|
|
4934
|
+
description: "The name of the agent to transfer control to"
|
|
4956
4935
|
}
|
|
4957
4936
|
},
|
|
4958
|
-
required: ["
|
|
4937
|
+
required: ["agent_name"]
|
|
4959
4938
|
}
|
|
4960
4939
|
};
|
|
4961
4940
|
}
|
|
4962
4941
|
/**
|
|
4963
|
-
* Execute the
|
|
4964
|
-
*/
|
|
4965
|
-
async runAsync(args, _context) {
|
|
4966
|
-
try {
|
|
4967
|
-
const {
|
|
4968
|
-
url,
|
|
4969
|
-
method = "GET",
|
|
4970
|
-
headers = {},
|
|
4971
|
-
body,
|
|
4972
|
-
params,
|
|
4973
|
-
timeout = 1e4
|
|
4974
|
-
} = args;
|
|
4975
|
-
const urlObj = new URL(url);
|
|
4976
|
-
if (params) {
|
|
4977
|
-
Object.entries(params).forEach(([key, value]) => {
|
|
4978
|
-
urlObj.searchParams.append(key, value);
|
|
4979
|
-
});
|
|
4980
|
-
}
|
|
4981
|
-
const requestHeaders = { ...headers };
|
|
4982
|
-
if (body && !requestHeaders["Content-Type"] && this.isValidJson(body)) {
|
|
4983
|
-
requestHeaders["Content-Type"] = "application/json";
|
|
4984
|
-
}
|
|
4985
|
-
const options = {
|
|
4986
|
-
method,
|
|
4987
|
-
headers: requestHeaders,
|
|
4988
|
-
body,
|
|
4989
|
-
signal: AbortSignal.timeout(timeout)
|
|
4990
|
-
};
|
|
4991
|
-
const response = await fetch(urlObj.toString(), options);
|
|
4992
|
-
const responseHeaders = {};
|
|
4993
|
-
response.headers.forEach((value, key) => {
|
|
4994
|
-
responseHeaders[key] = value;
|
|
4995
|
-
});
|
|
4996
|
-
const responseBody = await response.text();
|
|
4997
|
-
return {
|
|
4998
|
-
statusCode: response.status,
|
|
4999
|
-
headers: responseHeaders,
|
|
5000
|
-
body: responseBody
|
|
5001
|
-
};
|
|
5002
|
-
} catch (error) {
|
|
5003
|
-
return {
|
|
5004
|
-
statusCode: 0,
|
|
5005
|
-
headers: {},
|
|
5006
|
-
body: "",
|
|
5007
|
-
error: error instanceof Error ? error.message : String(error)
|
|
5008
|
-
};
|
|
5009
|
-
}
|
|
5010
|
-
}
|
|
5011
|
-
/**
|
|
5012
|
-
* Check if a string is valid JSON
|
|
4942
|
+
* Execute the transfer to agent action
|
|
5013
4943
|
*/
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
return true;
|
|
5018
|
-
} catch (e) {
|
|
5019
|
-
return false;
|
|
5020
|
-
}
|
|
4944
|
+
async runAsync(args, context4) {
|
|
4945
|
+
this.logger.debug(`Executing transfer to agent: ${args.agent_name}`);
|
|
4946
|
+
context4.actions.transferToAgent = args.agent_name;
|
|
5021
4947
|
}
|
|
5022
|
-
};
|
|
4948
|
+
}, _class19);
|
|
5023
4949
|
|
|
5024
|
-
// src/tools/common/
|
|
4950
|
+
// src/tools/common/load-memory-tool.ts
|
|
4951
|
+
init_logger();
|
|
5025
4952
|
init_base_tool();
|
|
5026
|
-
var _promises = require('fs/promises'); var fs2 = _interopRequireWildcard(_promises);
|
|
5027
|
-
var _path = require('path'); var path2 = _interopRequireWildcard(_path);
|
|
5028
4953
|
|
|
5029
|
-
var
|
|
5030
|
-
|
|
5031
|
-
|
|
4954
|
+
var LoadMemoryTool = (_class20 = class extends BaseTool {
|
|
4955
|
+
__init30() {this.logger = new Logger({ name: "LoadMemoryTool" })}
|
|
4956
|
+
/**
|
|
4957
|
+
* Constructor for LoadMemoryTool
|
|
4958
|
+
*/
|
|
4959
|
+
constructor() {
|
|
5032
4960
|
super({
|
|
5033
|
-
name: "
|
|
5034
|
-
description: "
|
|
5035
|
-
});
|
|
5036
|
-
this.basePath = _optionalChain([options, 'optionalAccess', _152 => _152.basePath]) || process.cwd();
|
|
4961
|
+
name: "load_memory",
|
|
4962
|
+
description: "Loads the memory for the current user based on a query."
|
|
4963
|
+
});_class20.prototype.__init30.call(this);;
|
|
5037
4964
|
}
|
|
5038
4965
|
/**
|
|
5039
4966
|
* Get the function declaration for the tool
|
|
@@ -5045,601 +4972,672 @@ var FileOperationsTool = class extends BaseTool {
|
|
|
5045
4972
|
parameters: {
|
|
5046
4973
|
type: _genai.Type.OBJECT,
|
|
5047
4974
|
properties: {
|
|
5048
|
-
|
|
5049
|
-
type: _genai.Type.STRING,
|
|
5050
|
-
description: "The file operation to perform",
|
|
5051
|
-
enum: [
|
|
5052
|
-
"read",
|
|
5053
|
-
"write",
|
|
5054
|
-
"append",
|
|
5055
|
-
"delete",
|
|
5056
|
-
"exists",
|
|
5057
|
-
"list",
|
|
5058
|
-
"mkdir"
|
|
5059
|
-
]
|
|
5060
|
-
},
|
|
5061
|
-
filepath: {
|
|
5062
|
-
type: _genai.Type.STRING,
|
|
5063
|
-
description: "Path to the file or directory (relative to the base path)"
|
|
5064
|
-
},
|
|
5065
|
-
content: {
|
|
5066
|
-
type: _genai.Type.STRING,
|
|
5067
|
-
description: "Content to write to the file (for write and append operations)"
|
|
5068
|
-
},
|
|
5069
|
-
encoding: {
|
|
4975
|
+
query: {
|
|
5070
4976
|
type: _genai.Type.STRING,
|
|
5071
|
-
description: "
|
|
5072
|
-
default: "utf8"
|
|
4977
|
+
description: "The query to load memories for"
|
|
5073
4978
|
}
|
|
5074
4979
|
},
|
|
5075
|
-
required: ["
|
|
4980
|
+
required: ["query"]
|
|
5076
4981
|
}
|
|
5077
4982
|
};
|
|
5078
4983
|
}
|
|
5079
4984
|
/**
|
|
5080
|
-
* Execute the
|
|
5081
|
-
*/
|
|
5082
|
-
async runAsync(args, _context) {
|
|
5083
|
-
try {
|
|
5084
|
-
const resolvedPath = this.resolvePath(args.filepath);
|
|
5085
|
-
this.validatePath(resolvedPath);
|
|
5086
|
-
const encoding = args.encoding || "utf8";
|
|
5087
|
-
switch (args.operation) {
|
|
5088
|
-
case "read":
|
|
5089
|
-
return await this.readFile(resolvedPath, encoding);
|
|
5090
|
-
case "write":
|
|
5091
|
-
return await this.writeFile(
|
|
5092
|
-
resolvedPath,
|
|
5093
|
-
args.content || "",
|
|
5094
|
-
encoding
|
|
5095
|
-
);
|
|
5096
|
-
case "append":
|
|
5097
|
-
return await this.appendFile(
|
|
5098
|
-
resolvedPath,
|
|
5099
|
-
args.content || "",
|
|
5100
|
-
encoding
|
|
5101
|
-
);
|
|
5102
|
-
case "delete":
|
|
5103
|
-
return await this.deleteFile(resolvedPath);
|
|
5104
|
-
case "exists":
|
|
5105
|
-
return await this.fileExists(resolvedPath);
|
|
5106
|
-
case "list":
|
|
5107
|
-
return await this.listDirectory(resolvedPath);
|
|
5108
|
-
case "mkdir":
|
|
5109
|
-
return await this.makeDirectory(resolvedPath);
|
|
5110
|
-
default:
|
|
5111
|
-
throw new Error(`Unsupported operation: ${args.operation}`);
|
|
5112
|
-
}
|
|
5113
|
-
} catch (error) {
|
|
5114
|
-
return {
|
|
5115
|
-
success: false,
|
|
5116
|
-
error: error instanceof Error ? error.message : String(error)
|
|
5117
|
-
};
|
|
5118
|
-
}
|
|
5119
|
-
}
|
|
5120
|
-
/**
|
|
5121
|
-
* Resolve a file path relative to the base path
|
|
5122
|
-
*/
|
|
5123
|
-
resolvePath(filepath) {
|
|
5124
|
-
return path2.default.isAbsolute(filepath) ? filepath : path2.default.resolve(this.basePath, filepath);
|
|
5125
|
-
}
|
|
5126
|
-
/**
|
|
5127
|
-
* Validate that a path is within the base path for security
|
|
5128
|
-
*/
|
|
5129
|
-
validatePath(filepath) {
|
|
5130
|
-
const normalizedPath = path2.default.normalize(filepath);
|
|
5131
|
-
const normalizedBasePath = path2.default.normalize(this.basePath);
|
|
5132
|
-
if (!normalizedPath.startsWith(normalizedBasePath)) {
|
|
5133
|
-
throw new Error(
|
|
5134
|
-
`Access denied: Can't access paths outside the base directory`
|
|
5135
|
-
);
|
|
5136
|
-
}
|
|
5137
|
-
}
|
|
5138
|
-
/**
|
|
5139
|
-
* Read a file
|
|
4985
|
+
* Execute the memory loading action
|
|
5140
4986
|
*/
|
|
5141
|
-
async
|
|
4987
|
+
async runAsync(args, context4) {
|
|
4988
|
+
this.logger.debug(`Executing load_memory with query: ${args.query}`);
|
|
5142
4989
|
try {
|
|
5143
|
-
const
|
|
4990
|
+
const searchResult = await context4.searchMemory(args.query);
|
|
5144
4991
|
return {
|
|
5145
|
-
|
|
5146
|
-
|
|
4992
|
+
memories: searchResult.memories || [],
|
|
4993
|
+
count: _optionalChain([searchResult, 'access', _147 => _147.memories, 'optionalAccess', _148 => _148.length]) || 0
|
|
5147
4994
|
};
|
|
5148
4995
|
} catch (error) {
|
|
4996
|
+
console.error("Error searching memory:", error);
|
|
5149
4997
|
return {
|
|
5150
|
-
|
|
5151
|
-
|
|
4998
|
+
error: "Memory search failed",
|
|
4999
|
+
message: error instanceof Error ? error.message : String(error)
|
|
5152
5000
|
};
|
|
5153
5001
|
}
|
|
5154
5002
|
}
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
} catch (error) {
|
|
5167
|
-
return {
|
|
5168
|
-
success: false,
|
|
5169
|
-
error: `Failed to write to file: ${error instanceof Error ? error.message : String(error)}`
|
|
5170
|
-
};
|
|
5171
|
-
}
|
|
5003
|
+
}, _class20);
|
|
5004
|
+
|
|
5005
|
+
// src/tools/common/load-artifacts-tool.ts
|
|
5006
|
+
init_base_tool();
|
|
5007
|
+
|
|
5008
|
+
var LoadArtifactsTool = class extends BaseTool {
|
|
5009
|
+
constructor() {
|
|
5010
|
+
super({
|
|
5011
|
+
name: "load_artifacts",
|
|
5012
|
+
description: "Loads the artifacts and adds them to the session."
|
|
5013
|
+
});
|
|
5172
5014
|
}
|
|
5173
5015
|
/**
|
|
5174
|
-
*
|
|
5016
|
+
* Get the function declaration for the tool
|
|
5175
5017
|
*/
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5018
|
+
getDeclaration() {
|
|
5019
|
+
return {
|
|
5020
|
+
name: this.name,
|
|
5021
|
+
description: this.description,
|
|
5022
|
+
parameters: {
|
|
5023
|
+
type: _genai.Type.OBJECT,
|
|
5024
|
+
properties: {
|
|
5025
|
+
artifact_names: {
|
|
5026
|
+
type: _genai.Type.ARRAY,
|
|
5027
|
+
items: {
|
|
5028
|
+
type: _genai.Type.STRING
|
|
5029
|
+
},
|
|
5030
|
+
description: "List of artifact names to load"
|
|
5031
|
+
}
|
|
5032
|
+
},
|
|
5033
|
+
required: []
|
|
5034
|
+
}
|
|
5035
|
+
};
|
|
5190
5036
|
}
|
|
5191
5037
|
/**
|
|
5192
|
-
*
|
|
5038
|
+
* Execute the load artifacts operation
|
|
5193
5039
|
*/
|
|
5194
|
-
async
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
return {
|
|
5198
|
-
success: true
|
|
5199
|
-
};
|
|
5200
|
-
} catch (error) {
|
|
5201
|
-
return {
|
|
5202
|
-
success: false,
|
|
5203
|
-
error: `Failed to delete file: ${error instanceof Error ? error.message : String(error)}`
|
|
5204
|
-
};
|
|
5205
|
-
}
|
|
5040
|
+
async runAsync(args, context4) {
|
|
5041
|
+
const artifactNames = args.artifact_names || [];
|
|
5042
|
+
return { artifact_names: artifactNames };
|
|
5206
5043
|
}
|
|
5207
5044
|
/**
|
|
5208
|
-
*
|
|
5045
|
+
* Processes the outgoing LLM request for this tool.
|
|
5209
5046
|
*/
|
|
5210
|
-
async
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
return {
|
|
5214
|
-
success: true,
|
|
5215
|
-
data: true
|
|
5216
|
-
};
|
|
5217
|
-
} catch (e3) {
|
|
5218
|
-
return {
|
|
5219
|
-
success: true,
|
|
5220
|
-
data: false
|
|
5221
|
-
};
|
|
5222
|
-
}
|
|
5047
|
+
async processLlmRequest(toolContext, llmRequest) {
|
|
5048
|
+
await super.processLlmRequest(toolContext, llmRequest);
|
|
5049
|
+
await this.appendArtifactsToLlmRequest(toolContext, llmRequest);
|
|
5223
5050
|
}
|
|
5224
5051
|
/**
|
|
5225
|
-
*
|
|
5052
|
+
* Appends artifacts information to the LLM request
|
|
5226
5053
|
*/
|
|
5227
|
-
async
|
|
5054
|
+
async appendArtifactsToLlmRequest(toolContext, llmRequest) {
|
|
5228
5055
|
try {
|
|
5229
|
-
const
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
5056
|
+
const artifactNames = await toolContext.listArtifacts();
|
|
5057
|
+
if (!artifactNames || artifactNames.length === 0) {
|
|
5058
|
+
return;
|
|
5059
|
+
}
|
|
5060
|
+
const instructions = [
|
|
5061
|
+
`You have a list of artifacts:
|
|
5062
|
+
${JSON.stringify(artifactNames)}
|
|
5063
|
+
|
|
5064
|
+
When the user asks questions about any of the artifacts, you should call the
|
|
5065
|
+
\`load_artifacts\` function to load the artifact. Do not generate any text other
|
|
5066
|
+
than the function call.
|
|
5067
|
+
`
|
|
5068
|
+
];
|
|
5069
|
+
if (llmRequest.appendInstructions) {
|
|
5070
|
+
llmRequest.appendInstructions(instructions);
|
|
5071
|
+
}
|
|
5072
|
+
if (llmRequest.contents && llmRequest.contents.length > 0) {
|
|
5073
|
+
const lastContent = llmRequest.contents[llmRequest.contents.length - 1];
|
|
5074
|
+
if (lastContent.parts && lastContent.parts.length > 0) {
|
|
5075
|
+
const firstPart = lastContent.parts[0];
|
|
5076
|
+
const functionResponse = this.extractFunctionResponse(firstPart);
|
|
5077
|
+
if (functionResponse && functionResponse.name === "load_artifacts") {
|
|
5078
|
+
const requestedArtifactNames = functionResponse.response.artifact_names || [];
|
|
5079
|
+
for (const artifactName of requestedArtifactNames) {
|
|
5080
|
+
try {
|
|
5081
|
+
const artifact = await toolContext.loadArtifact(artifactName);
|
|
5082
|
+
if (artifact) {
|
|
5083
|
+
llmRequest.contents.push({
|
|
5084
|
+
role: "user",
|
|
5085
|
+
parts: [
|
|
5086
|
+
{
|
|
5087
|
+
text: `Artifact ${artifactName} is:`
|
|
5088
|
+
},
|
|
5089
|
+
artifact
|
|
5090
|
+
]
|
|
5091
|
+
});
|
|
5092
|
+
}
|
|
5093
|
+
} catch (error) {
|
|
5094
|
+
console.error(
|
|
5095
|
+
`Failed to load artifact ${artifactName}:`,
|
|
5096
|
+
error
|
|
5097
|
+
);
|
|
5098
|
+
}
|
|
5099
|
+
}
|
|
5100
|
+
}
|
|
5101
|
+
}
|
|
5102
|
+
}
|
|
5249
5103
|
} catch (error) {
|
|
5250
|
-
|
|
5251
|
-
success: false,
|
|
5252
|
-
error: `Failed to list directory: ${error instanceof Error ? error.message : String(error)}`
|
|
5253
|
-
};
|
|
5104
|
+
console.error("Error appending artifacts to LLM request:", error);
|
|
5254
5105
|
}
|
|
5255
5106
|
}
|
|
5256
5107
|
/**
|
|
5257
|
-
*
|
|
5108
|
+
* Extracts function response from a part if it exists
|
|
5258
5109
|
*/
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
return {
|
|
5263
|
-
success: true
|
|
5264
|
-
};
|
|
5265
|
-
} catch (error) {
|
|
5266
|
-
return {
|
|
5267
|
-
success: false,
|
|
5268
|
-
error: `Failed to create directory: ${error instanceof Error ? error.message : String(error)}`
|
|
5269
|
-
};
|
|
5110
|
+
extractFunctionResponse(part) {
|
|
5111
|
+
if ("functionResponse" in part && part.functionResponse) {
|
|
5112
|
+
return part.functionResponse;
|
|
5270
5113
|
}
|
|
5114
|
+
return null;
|
|
5271
5115
|
}
|
|
5272
5116
|
};
|
|
5273
5117
|
|
|
5274
|
-
// src/tools/
|
|
5275
|
-
|
|
5118
|
+
// src/tools/mcp/client.ts
|
|
5119
|
+
init_logger();
|
|
5120
|
+
var _indexjs = require('@modelcontextprotocol/sdk/client/index.js');
|
|
5121
|
+
var _ssejs = require('@modelcontextprotocol/sdk/client/sse.js');
|
|
5122
|
+
var _stdiojs = require('@modelcontextprotocol/sdk/client/stdio.js');
|
|
5123
|
+
var _typesjs = require('@modelcontextprotocol/sdk/types.js');
|
|
5276
5124
|
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5125
|
+
// src/tools/mcp/sampling-handler.ts
|
|
5126
|
+
init_logger();
|
|
5127
|
+
|
|
5128
|
+
|
|
5129
|
+
|
|
5130
|
+
|
|
5131
|
+
|
|
5132
|
+
// src/tools/mcp/types.ts
|
|
5133
|
+
var McpErrorType = /* @__PURE__ */ ((McpErrorType2) => {
|
|
5134
|
+
McpErrorType2["CONNECTION_ERROR"] = "connection_error";
|
|
5135
|
+
McpErrorType2["TOOL_EXECUTION_ERROR"] = "tool_execution_error";
|
|
5136
|
+
McpErrorType2["RESOURCE_CLOSED_ERROR"] = "resource_closed_error";
|
|
5137
|
+
McpErrorType2["TIMEOUT_ERROR"] = "timeout_error";
|
|
5138
|
+
McpErrorType2["INVALID_SCHEMA_ERROR"] = "invalid_schema_error";
|
|
5139
|
+
McpErrorType2["SAMPLING_ERROR"] = "SAMPLING_ERROR";
|
|
5140
|
+
McpErrorType2["INVALID_REQUEST_ERROR"] = "INVALID_REQUEST_ERROR";
|
|
5141
|
+
return McpErrorType2;
|
|
5142
|
+
})(McpErrorType || {});
|
|
5143
|
+
var McpError = class extends Error {
|
|
5144
|
+
|
|
5145
|
+
|
|
5146
|
+
constructor(message, type, originalError) {
|
|
5147
|
+
super(message);
|
|
5148
|
+
this.name = "McpError";
|
|
5149
|
+
this.type = type;
|
|
5150
|
+
this.originalError = originalError;
|
|
5284
5151
|
}
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
type: _genai.Type.OBJECT,
|
|
5294
|
-
properties: {
|
|
5295
|
-
prompt: {
|
|
5296
|
-
type: _genai.Type.STRING,
|
|
5297
|
-
description: "The prompt message to display to the user"
|
|
5298
|
-
},
|
|
5299
|
-
options: {
|
|
5300
|
-
type: _genai.Type.ARRAY,
|
|
5301
|
-
description: "Optional array of choices to present to the user",
|
|
5302
|
-
items: {
|
|
5303
|
-
type: _genai.Type.STRING
|
|
5304
|
-
}
|
|
5305
|
-
},
|
|
5306
|
-
defaultValue: {
|
|
5307
|
-
type: _genai.Type.STRING,
|
|
5308
|
-
description: "Optional default value for the input field"
|
|
5309
|
-
}
|
|
5310
|
-
},
|
|
5311
|
-
required: ["prompt"]
|
|
5312
|
-
}
|
|
5313
|
-
};
|
|
5152
|
+
};
|
|
5153
|
+
|
|
5154
|
+
// src/tools/mcp/sampling-handler.ts
|
|
5155
|
+
var McpSamplingHandler = (_class21 = class {
|
|
5156
|
+
__init31() {this.logger = new Logger({ name: "McpSamplingHandler" })}
|
|
5157
|
+
|
|
5158
|
+
constructor(samplingHandler) {;_class21.prototype.__init31.call(this);
|
|
5159
|
+
this.samplingHandler = samplingHandler;
|
|
5314
5160
|
}
|
|
5315
5161
|
/**
|
|
5316
|
-
*
|
|
5162
|
+
* Handle MCP sampling request and convert between formats
|
|
5317
5163
|
*/
|
|
5318
|
-
async
|
|
5164
|
+
async handleSamplingRequest(request) {
|
|
5319
5165
|
try {
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5166
|
+
if (request.method !== "sampling/createMessage") {
|
|
5167
|
+
this.logger.error(
|
|
5168
|
+
`Invalid method for sampling handler: ${request.method}. Expected: sampling/createMessage`
|
|
5169
|
+
);
|
|
5170
|
+
throw new McpError(
|
|
5171
|
+
`Invalid method: ${request.method}. This handler only processes sampling/createMessage requests.`,
|
|
5172
|
+
"INVALID_REQUEST_ERROR" /* INVALID_REQUEST_ERROR */
|
|
5173
|
+
);
|
|
5326
5174
|
}
|
|
5327
|
-
|
|
5328
|
-
|
|
5175
|
+
const validationResult = _typesjs.CreateMessageRequestSchema.safeParse(request);
|
|
5176
|
+
if (!validationResult.success) {
|
|
5177
|
+
this.logger.error(
|
|
5178
|
+
"Invalid MCP sampling request:",
|
|
5179
|
+
validationResult.error
|
|
5180
|
+
);
|
|
5181
|
+
throw new McpError(
|
|
5182
|
+
`Invalid sampling request: ${validationResult.error.message}`,
|
|
5183
|
+
"INVALID_REQUEST_ERROR" /* INVALID_REQUEST_ERROR */
|
|
5184
|
+
);
|
|
5329
5185
|
}
|
|
5330
|
-
const
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5186
|
+
const mcpParams = request.params;
|
|
5187
|
+
if (!mcpParams.messages || !Array.isArray(mcpParams.messages)) {
|
|
5188
|
+
throw new McpError(
|
|
5189
|
+
"Invalid sampling request: messages array is required",
|
|
5190
|
+
"INVALID_REQUEST_ERROR" /* INVALID_REQUEST_ERROR */
|
|
5191
|
+
);
|
|
5192
|
+
}
|
|
5193
|
+
if (!mcpParams.maxTokens || mcpParams.maxTokens <= 0) {
|
|
5194
|
+
throw new McpError(
|
|
5195
|
+
"Invalid sampling request: maxTokens must be a positive number",
|
|
5196
|
+
"INVALID_REQUEST_ERROR" /* INVALID_REQUEST_ERROR */
|
|
5197
|
+
);
|
|
5198
|
+
}
|
|
5199
|
+
this.logger.debug("Converting MCP request to ADK format");
|
|
5200
|
+
const adkContents = this.convertMcpMessagesToADK(
|
|
5201
|
+
mcpParams.messages,
|
|
5202
|
+
mcpParams.systemPrompt
|
|
5203
|
+
);
|
|
5204
|
+
const requestModel = mcpParams.model || "gemini-2.0-flash";
|
|
5205
|
+
const adkRequest = new LlmRequest({
|
|
5206
|
+
model: requestModel,
|
|
5207
|
+
contents: adkContents,
|
|
5208
|
+
config: {
|
|
5209
|
+
temperature: mcpParams.temperature,
|
|
5210
|
+
maxOutputTokens: mcpParams.maxTokens
|
|
5211
|
+
}
|
|
5337
5212
|
});
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5213
|
+
this.logger.debug("Calling ADK sampling handler");
|
|
5214
|
+
const adkResponse = await this.samplingHandler(adkRequest);
|
|
5215
|
+
this.logger.debug("Converting ADK response to MCP format");
|
|
5216
|
+
const mcpResponse = this.convertADKResponseToMcp(
|
|
5217
|
+
adkResponse,
|
|
5218
|
+
requestModel
|
|
5219
|
+
);
|
|
5220
|
+
const responseValidation = _typesjs.CreateMessageResultSchema.safeParse(mcpResponse);
|
|
5221
|
+
if (!responseValidation.success) {
|
|
5222
|
+
this.logger.error(
|
|
5223
|
+
"Invalid MCP response generated:",
|
|
5224
|
+
responseValidation.error
|
|
5225
|
+
);
|
|
5226
|
+
throw new McpError(
|
|
5227
|
+
`Invalid response generated: ${responseValidation.error.message}`,
|
|
5228
|
+
"SAMPLING_ERROR" /* SAMPLING_ERROR */
|
|
5229
|
+
);
|
|
5230
|
+
}
|
|
5231
|
+
return mcpResponse;
|
|
5342
5232
|
} catch (error) {
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
}
|
|
5233
|
+
this.logger.error("Error handling sampling request:", error);
|
|
5234
|
+
if (error instanceof McpError) {
|
|
5235
|
+
throw error;
|
|
5236
|
+
}
|
|
5237
|
+
throw new McpError(
|
|
5238
|
+
`Sampling request failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
5239
|
+
"SAMPLING_ERROR" /* SAMPLING_ERROR */,
|
|
5240
|
+
error instanceof Error ? error : void 0
|
|
5241
|
+
);
|
|
5347
5242
|
}
|
|
5348
5243
|
}
|
|
5349
|
-
};
|
|
5350
|
-
|
|
5351
|
-
// src/tools/common/exit-loop-tool.ts
|
|
5352
|
-
init_logger();
|
|
5353
|
-
init_base_tool();
|
|
5354
|
-
var ExitLoopTool = (_class19 = class extends BaseTool {
|
|
5355
|
-
__init33() {this.logger = new Logger({ name: "ExitLoopTool" })}
|
|
5356
5244
|
/**
|
|
5357
|
-
*
|
|
5245
|
+
* Convert MCP messages to ADK Content format
|
|
5358
5246
|
*/
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5247
|
+
convertMcpMessagesToADK(mcpMessages, systemPrompt) {
|
|
5248
|
+
const contents = [];
|
|
5249
|
+
if (systemPrompt) {
|
|
5250
|
+
contents.push({
|
|
5251
|
+
role: "user",
|
|
5252
|
+
// System messages are typically sent as user role in content
|
|
5253
|
+
parts: [{ text: systemPrompt }]
|
|
5254
|
+
});
|
|
5255
|
+
}
|
|
5256
|
+
const transformedMessages = mcpMessages.map(
|
|
5257
|
+
(mcpMessage) => this.convertSingleMcpMessageToADK(mcpMessage)
|
|
5258
|
+
);
|
|
5259
|
+
contents.push(...transformedMessages);
|
|
5260
|
+
return contents;
|
|
5364
5261
|
}
|
|
5365
5262
|
/**
|
|
5366
|
-
*
|
|
5263
|
+
* Convert a single MCP message to ADK Content format
|
|
5367
5264
|
*/
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5265
|
+
convertSingleMcpMessageToADK(mcpMessage) {
|
|
5266
|
+
const adkRole = mcpMessage.role === "assistant" ? "model" : "user";
|
|
5267
|
+
const adkParts = this.convertMcpContentToADKParts(mcpMessage.content);
|
|
5268
|
+
const adkContent = {
|
|
5269
|
+
role: adkRole,
|
|
5270
|
+
parts: adkParts
|
|
5271
|
+
};
|
|
5272
|
+
this.logger.debug(
|
|
5273
|
+
`Converted MCP message - role: ${mcpMessage.role} -> ${adkRole}, content type: ${mcpMessage.content.type}`
|
|
5274
|
+
);
|
|
5275
|
+
return adkContent;
|
|
5371
5276
|
}
|
|
5372
|
-
}, _class19);
|
|
5373
|
-
|
|
5374
|
-
// src/tools/common/get-user-choice-tool.ts
|
|
5375
|
-
init_logger();
|
|
5376
|
-
init_base_tool();
|
|
5377
|
-
|
|
5378
|
-
var GetUserChoiceTool = (_class20 = class extends BaseTool {
|
|
5379
|
-
__init34() {this.logger = new Logger({ name: "GetUserChoiceTool" })}
|
|
5380
5277
|
/**
|
|
5381
|
-
*
|
|
5278
|
+
* Convert MCP message content to ADK parts format
|
|
5382
5279
|
*/
|
|
5383
|
-
|
|
5384
|
-
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5280
|
+
convertMcpContentToADKParts(mcpContent) {
|
|
5281
|
+
if (mcpContent.type === "text") {
|
|
5282
|
+
const textContent = mcpContent.text || "";
|
|
5283
|
+
return [{ text: textContent }];
|
|
5284
|
+
}
|
|
5285
|
+
if (mcpContent.type === "image") {
|
|
5286
|
+
const parts = [];
|
|
5287
|
+
if (mcpContent.text && typeof mcpContent.text === "string") {
|
|
5288
|
+
parts.push({ text: mcpContent.text });
|
|
5289
|
+
}
|
|
5290
|
+
if (mcpContent.data && typeof mcpContent.data === "string") {
|
|
5291
|
+
const mimeType = mcpContent.mimeType || "image/jpeg";
|
|
5292
|
+
parts.push({
|
|
5293
|
+
inlineData: {
|
|
5294
|
+
data: mcpContent.data,
|
|
5295
|
+
mimeType
|
|
5296
|
+
}
|
|
5297
|
+
});
|
|
5298
|
+
}
|
|
5299
|
+
return parts.length > 0 ? parts : [{ text: "" }];
|
|
5300
|
+
}
|
|
5301
|
+
this.logger.warn(`Unknown MCP content type: ${mcpContent.type}`);
|
|
5302
|
+
const fallbackText = typeof mcpContent.data === "string" ? mcpContent.data : "";
|
|
5303
|
+
return [{ text: fallbackText }];
|
|
5389
5304
|
}
|
|
5390
5305
|
/**
|
|
5391
|
-
*
|
|
5306
|
+
* Convert ADK response to MCP response format
|
|
5392
5307
|
*/
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5308
|
+
convertADKResponseToMcp(adkResponse, model) {
|
|
5309
|
+
let responseText = "";
|
|
5310
|
+
if (typeof adkResponse === "string") {
|
|
5311
|
+
responseText = adkResponse;
|
|
5312
|
+
} else {
|
|
5313
|
+
if (adkResponse.content) {
|
|
5314
|
+
if (typeof adkResponse.content === "string") {
|
|
5315
|
+
responseText = adkResponse.content;
|
|
5316
|
+
} else if (adkResponse.content.parts) {
|
|
5317
|
+
responseText = adkResponse.content.parts.map((part) => {
|
|
5318
|
+
return typeof part.text === "string" ? part.text : "";
|
|
5319
|
+
}).join("");
|
|
5320
|
+
}
|
|
5321
|
+
}
|
|
5322
|
+
}
|
|
5323
|
+
const mcpResponse = {
|
|
5324
|
+
model,
|
|
5325
|
+
// Use the model from the request
|
|
5326
|
+
role: "assistant",
|
|
5327
|
+
// ADK responses are always from assistant
|
|
5328
|
+
content: {
|
|
5329
|
+
type: "text",
|
|
5330
|
+
text: responseText
|
|
5413
5331
|
}
|
|
5414
5332
|
};
|
|
5333
|
+
this.logger.debug(`Received content: ${responseText}`);
|
|
5334
|
+
return mcpResponse;
|
|
5415
5335
|
}
|
|
5416
5336
|
/**
|
|
5417
|
-
*
|
|
5418
|
-
* This is a long running operation that will return null initially
|
|
5419
|
-
* and the actual choice will be provided asynchronously
|
|
5337
|
+
* Update the ADK handler
|
|
5420
5338
|
*/
|
|
5421
|
-
|
|
5422
|
-
this.
|
|
5423
|
-
|
|
5424
|
-
);
|
|
5425
|
-
if (args.question) {
|
|
5426
|
-
this.logger.debug(`Question: ${args.question}`);
|
|
5427
|
-
}
|
|
5428
|
-
context4.actions.skipSummarization = true;
|
|
5429
|
-
return null;
|
|
5339
|
+
updateHandler(handler) {
|
|
5340
|
+
this.samplingHandler = handler;
|
|
5341
|
+
this.logger.debug("ADK sampling handler updated");
|
|
5430
5342
|
}
|
|
5431
|
-
},
|
|
5343
|
+
}, _class21);
|
|
5344
|
+
function createSamplingHandler(handler) {
|
|
5345
|
+
return handler;
|
|
5346
|
+
}
|
|
5432
5347
|
|
|
5433
|
-
// src/tools/
|
|
5434
|
-
|
|
5435
|
-
|
|
5348
|
+
// src/tools/mcp/utils.ts
|
|
5349
|
+
function withRetry(fn, instance, reinitMethod, maxRetries = 1) {
|
|
5350
|
+
return async (...args) => {
|
|
5351
|
+
let attempt = 0;
|
|
5352
|
+
while (attempt <= maxRetries) {
|
|
5353
|
+
try {
|
|
5354
|
+
return await fn.apply(instance, args);
|
|
5355
|
+
} catch (error) {
|
|
5356
|
+
const isClosedResourceError = error instanceof Error && (error.message.includes("closed") || error.message.includes("ECONNRESET") || error.message.includes("socket hang up"));
|
|
5357
|
+
if (!isClosedResourceError || attempt >= maxRetries) {
|
|
5358
|
+
throw error;
|
|
5359
|
+
}
|
|
5360
|
+
console.warn(
|
|
5361
|
+
`Resource closed, reinitializing (attempt ${attempt + 1}/${maxRetries + 1})...`
|
|
5362
|
+
);
|
|
5363
|
+
try {
|
|
5364
|
+
await reinitMethod(instance);
|
|
5365
|
+
} catch (reinitError) {
|
|
5366
|
+
console.error("Error reinitializing resources:", reinitError);
|
|
5367
|
+
throw new Error(`Failed to reinitialize resources: ${reinitError}`);
|
|
5368
|
+
}
|
|
5369
|
+
attempt++;
|
|
5370
|
+
}
|
|
5371
|
+
}
|
|
5372
|
+
throw new Error("Unexpected end of retry loop");
|
|
5373
|
+
};
|
|
5374
|
+
}
|
|
5436
5375
|
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5376
|
+
// src/tools/mcp/client.ts
|
|
5377
|
+
var McpClientService = (_class22 = class {
|
|
5378
|
+
|
|
5379
|
+
__init32() {this.client = null}
|
|
5380
|
+
__init33() {this.transport = null}
|
|
5381
|
+
__init34() {this.isClosing = false}
|
|
5382
|
+
__init35() {this.mcpSamplingHandler = null}
|
|
5383
|
+
__init36() {this.logger = new Logger({ name: "McpClientService" })}
|
|
5384
|
+
constructor(config) {;_class22.prototype.__init32.call(this);_class22.prototype.__init33.call(this);_class22.prototype.__init34.call(this);_class22.prototype.__init35.call(this);_class22.prototype.__init36.call(this);
|
|
5385
|
+
this.config = config;
|
|
5386
|
+
if (config.samplingHandler) {
|
|
5387
|
+
this.mcpSamplingHandler = new McpSamplingHandler(config.samplingHandler);
|
|
5388
|
+
}
|
|
5447
5389
|
}
|
|
5448
5390
|
/**
|
|
5449
|
-
*
|
|
5391
|
+
* Initializes and returns an MCP client based on configuration.
|
|
5392
|
+
* Will create a new client if one doesn't exist yet.
|
|
5450
5393
|
*/
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5394
|
+
async initialize() {
|
|
5395
|
+
if (this.isClosing) {
|
|
5396
|
+
throw new McpError(
|
|
5397
|
+
"Cannot initialize a client that is being closed",
|
|
5398
|
+
"resource_closed_error" /* RESOURCE_CLOSED_ERROR */
|
|
5399
|
+
);
|
|
5400
|
+
}
|
|
5401
|
+
if (this.client) {
|
|
5402
|
+
return this.client;
|
|
5403
|
+
}
|
|
5404
|
+
try {
|
|
5405
|
+
if (!this.transport) {
|
|
5406
|
+
this.transport = await this.createTransport();
|
|
5407
|
+
}
|
|
5408
|
+
const client = new (0, _indexjs.Client)(
|
|
5409
|
+
{
|
|
5410
|
+
name: this.config.name,
|
|
5411
|
+
version: "0.0.1"
|
|
5462
5412
|
},
|
|
5463
|
-
|
|
5413
|
+
{
|
|
5414
|
+
capabilities: {
|
|
5415
|
+
prompts: {},
|
|
5416
|
+
resources: {},
|
|
5417
|
+
tools: {},
|
|
5418
|
+
sampling: {}
|
|
5419
|
+
// Enable sampling capability
|
|
5420
|
+
}
|
|
5421
|
+
}
|
|
5422
|
+
);
|
|
5423
|
+
const connectPromise = client.connect(this.transport);
|
|
5424
|
+
if (this.config.timeout) {
|
|
5425
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
5426
|
+
setTimeout(() => {
|
|
5427
|
+
reject(
|
|
5428
|
+
new McpError(
|
|
5429
|
+
`MCP client connection timed out after ${this.config.timeout}ms`,
|
|
5430
|
+
"timeout_error" /* TIMEOUT_ERROR */
|
|
5431
|
+
)
|
|
5432
|
+
);
|
|
5433
|
+
}, this.config.timeout);
|
|
5434
|
+
});
|
|
5435
|
+
await Promise.race([connectPromise, timeoutPromise]);
|
|
5436
|
+
} else {
|
|
5437
|
+
await connectPromise;
|
|
5464
5438
|
}
|
|
5465
|
-
|
|
5439
|
+
await this.setupSamplingHandler(client);
|
|
5440
|
+
this.logger.debug("\u2705 MCP client connected successfully");
|
|
5441
|
+
this.client = client;
|
|
5442
|
+
return client;
|
|
5443
|
+
} catch (error) {
|
|
5444
|
+
await this.cleanupResources();
|
|
5445
|
+
if (!(error instanceof McpError)) {
|
|
5446
|
+
this.logger.error("Failed to initialize MCP client:", error);
|
|
5447
|
+
throw new McpError(
|
|
5448
|
+
`Failed to initialize MCP client: ${error instanceof Error ? error.message : String(error)}`,
|
|
5449
|
+
"connection_error" /* CONNECTION_ERROR */,
|
|
5450
|
+
error instanceof Error ? error : void 0
|
|
5451
|
+
);
|
|
5452
|
+
}
|
|
5453
|
+
throw error;
|
|
5454
|
+
}
|
|
5466
5455
|
}
|
|
5467
5456
|
/**
|
|
5468
|
-
*
|
|
5457
|
+
* Creates a transport based on the configuration.
|
|
5469
5458
|
*/
|
|
5470
|
-
async
|
|
5471
|
-
|
|
5472
|
-
|
|
5459
|
+
async createTransport() {
|
|
5460
|
+
try {
|
|
5461
|
+
if (this.config.transport.mode === "sse") {
|
|
5462
|
+
this.logger.debug(
|
|
5463
|
+
"\u{1F680} Initializing MCP client in SSE mode",
|
|
5464
|
+
this.config.transport.serverUrl
|
|
5465
|
+
);
|
|
5466
|
+
const headers = {
|
|
5467
|
+
...this.config.transport.headers || {},
|
|
5468
|
+
...this.config.headers || {}
|
|
5469
|
+
};
|
|
5470
|
+
return new (0, _ssejs.SSEClientTransport)(
|
|
5471
|
+
new URL(this.config.transport.serverUrl),
|
|
5472
|
+
{
|
|
5473
|
+
requestInit: {
|
|
5474
|
+
headers,
|
|
5475
|
+
...this.config.timeout ? { timeout: this.config.timeout } : {}
|
|
5476
|
+
}
|
|
5477
|
+
}
|
|
5478
|
+
);
|
|
5479
|
+
}
|
|
5480
|
+
this.logger.debug(
|
|
5481
|
+
"\u{1F680} Initializing MCP client in STDIO mode",
|
|
5482
|
+
this.config.transport.command
|
|
5483
|
+
);
|
|
5484
|
+
return new (0, _stdiojs.StdioClientTransport)({
|
|
5485
|
+
command: this.config.transport.command,
|
|
5486
|
+
args: this.config.transport.args,
|
|
5487
|
+
env: this.config.transport.env
|
|
5488
|
+
});
|
|
5489
|
+
} catch (error) {
|
|
5490
|
+
throw new McpError(
|
|
5491
|
+
`Failed to create transport: ${error instanceof Error ? error.message : String(error)}`,
|
|
5492
|
+
"connection_error" /* CONNECTION_ERROR */,
|
|
5493
|
+
error instanceof Error ? error : void 0
|
|
5494
|
+
);
|
|
5495
|
+
}
|
|
5473
5496
|
}
|
|
5474
|
-
}, _class21);
|
|
5475
|
-
|
|
5476
|
-
// src/tools/common/load-memory-tool.ts
|
|
5477
|
-
init_logger();
|
|
5478
|
-
init_base_tool();
|
|
5479
|
-
|
|
5480
|
-
var LoadMemoryTool = (_class22 = class extends BaseTool {
|
|
5481
|
-
__init36() {this.logger = new Logger({ name: "LoadMemoryTool" })}
|
|
5482
5497
|
/**
|
|
5483
|
-
*
|
|
5498
|
+
* Re-initializes the MCP client when a session is closed.
|
|
5499
|
+
* Used by the retry mechanism.
|
|
5484
5500
|
*/
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5501
|
+
async reinitialize() {
|
|
5502
|
+
this.logger.debug("\u{1F504} Reinitializing MCP client after closed connection");
|
|
5503
|
+
await this.cleanupResources();
|
|
5504
|
+
this.client = null;
|
|
5505
|
+
this.transport = null;
|
|
5506
|
+
await this.initialize();
|
|
5490
5507
|
}
|
|
5491
5508
|
/**
|
|
5492
|
-
*
|
|
5509
|
+
* Cleans up resources associated with this client service.
|
|
5510
|
+
* Similar to Python's AsyncExitStack.aclose() functionality.
|
|
5493
5511
|
*/
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
query: {
|
|
5502
|
-
type: _genai.Type.STRING,
|
|
5503
|
-
description: "The query to load memories for"
|
|
5512
|
+
async cleanupResources() {
|
|
5513
|
+
try {
|
|
5514
|
+
this.isClosing = true;
|
|
5515
|
+
if (this.client) {
|
|
5516
|
+
try {
|
|
5517
|
+
if (typeof this.client.close === "function") {
|
|
5518
|
+
await this.client.close();
|
|
5504
5519
|
}
|
|
5505
|
-
}
|
|
5506
|
-
|
|
5520
|
+
} catch (err) {
|
|
5521
|
+
}
|
|
5507
5522
|
}
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5511
|
-
|
|
5512
|
-
*/
|
|
5513
|
-
async runAsync(args, context4) {
|
|
5514
|
-
this.logger.debug(`Executing load_memory with query: ${args.query}`);
|
|
5515
|
-
try {
|
|
5516
|
-
const searchResult = await context4.searchMemory(args.query);
|
|
5517
|
-
return {
|
|
5518
|
-
memories: searchResult.memories || [],
|
|
5519
|
-
count: _optionalChain([searchResult, 'access', _153 => _153.memories, 'optionalAccess', _154 => _154.length]) || 0
|
|
5520
|
-
};
|
|
5523
|
+
if (this.transport && typeof this.transport.close === "function") {
|
|
5524
|
+
await this.transport.close();
|
|
5525
|
+
}
|
|
5526
|
+
this.logger.debug("\u{1F9F9} Cleaned up MCP client resources");
|
|
5521
5527
|
} catch (error) {
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5528
|
+
this.logger.error("Error cleaning up MCP resources:", error);
|
|
5529
|
+
} finally {
|
|
5530
|
+
this.client = null;
|
|
5531
|
+
this.transport = null;
|
|
5532
|
+
this.isClosing = false;
|
|
5527
5533
|
}
|
|
5528
5534
|
}
|
|
5529
|
-
}, _class22);
|
|
5530
|
-
|
|
5531
|
-
// src/tools/common/load-artifacts-tool.ts
|
|
5532
|
-
init_base_tool();
|
|
5533
|
-
|
|
5534
|
-
var LoadArtifactsTool = class extends BaseTool {
|
|
5535
|
-
constructor() {
|
|
5536
|
-
super({
|
|
5537
|
-
name: "load_artifacts",
|
|
5538
|
-
description: "Loads the artifacts and adds them to the session."
|
|
5539
|
-
});
|
|
5540
|
-
}
|
|
5541
5535
|
/**
|
|
5542
|
-
*
|
|
5536
|
+
* Call an MCP tool with retry capability if the session is closed.
|
|
5543
5537
|
*/
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
items: {
|
|
5554
|
-
type: _genai.Type.STRING
|
|
5555
|
-
},
|
|
5556
|
-
description: "List of artifact names to load"
|
|
5557
|
-
}
|
|
5538
|
+
async callTool(name, args) {
|
|
5539
|
+
try {
|
|
5540
|
+
const wrappedCall = withRetry(
|
|
5541
|
+
async function() {
|
|
5542
|
+
const client = await this.initialize();
|
|
5543
|
+
return client.callTool({
|
|
5544
|
+
name,
|
|
5545
|
+
arguments: args
|
|
5546
|
+
});
|
|
5558
5547
|
},
|
|
5559
|
-
|
|
5548
|
+
this,
|
|
5549
|
+
async (instance) => await instance.reinitialize(),
|
|
5550
|
+
_optionalChain([this, 'access', _149 => _149.config, 'access', _150 => _150.retryOptions, 'optionalAccess', _151 => _151.maxRetries]) || 2
|
|
5551
|
+
);
|
|
5552
|
+
return await wrappedCall();
|
|
5553
|
+
} catch (error) {
|
|
5554
|
+
if (!(error instanceof McpError)) {
|
|
5555
|
+
throw new McpError(
|
|
5556
|
+
`Error calling tool "${name}": ${error instanceof Error ? error.message : String(error)}`,
|
|
5557
|
+
"tool_execution_error" /* TOOL_EXECUTION_ERROR */,
|
|
5558
|
+
error instanceof Error ? error : void 0
|
|
5559
|
+
);
|
|
5560
5560
|
}
|
|
5561
|
-
|
|
5561
|
+
throw error;
|
|
5562
|
+
}
|
|
5562
5563
|
}
|
|
5563
5564
|
/**
|
|
5564
|
-
*
|
|
5565
|
+
* Closes and cleans up all resources.
|
|
5566
|
+
* Should be called when the service is no longer needed.
|
|
5567
|
+
* Similar to Python's close() method.
|
|
5565
5568
|
*/
|
|
5566
|
-
async
|
|
5567
|
-
|
|
5568
|
-
|
|
5569
|
+
async close() {
|
|
5570
|
+
this.logger.debug("\u{1F51A} Closing MCP client service");
|
|
5571
|
+
await this.cleanupResources();
|
|
5569
5572
|
}
|
|
5570
5573
|
/**
|
|
5571
|
-
*
|
|
5574
|
+
* Checks if the client is currently connected
|
|
5572
5575
|
*/
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
await this.appendArtifactsToLlmRequest(toolContext, llmRequest);
|
|
5576
|
+
isConnected() {
|
|
5577
|
+
return !!this.client && !this.isClosing;
|
|
5576
5578
|
}
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
|
|
5580
|
-
|
|
5579
|
+
async setupSamplingHandler(client) {
|
|
5580
|
+
if (!this.mcpSamplingHandler) {
|
|
5581
|
+
this.logger.debug(
|
|
5582
|
+
"\u26A0\uFE0F No sampling handler provided - sampling requests will be rejected"
|
|
5583
|
+
);
|
|
5584
|
+
return;
|
|
5585
|
+
}
|
|
5581
5586
|
try {
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
];
|
|
5595
|
-
if (llmRequest.appendInstructions) {
|
|
5596
|
-
llmRequest.appendInstructions(instructions);
|
|
5597
|
-
}
|
|
5598
|
-
if (llmRequest.contents && llmRequest.contents.length > 0) {
|
|
5599
|
-
const lastContent = llmRequest.contents[llmRequest.contents.length - 1];
|
|
5600
|
-
if (lastContent.parts && lastContent.parts.length > 0) {
|
|
5601
|
-
const firstPart = lastContent.parts[0];
|
|
5602
|
-
const functionResponse = this.extractFunctionResponse(firstPart);
|
|
5603
|
-
if (functionResponse && functionResponse.name === "load_artifacts") {
|
|
5604
|
-
const requestedArtifactNames = functionResponse.response.artifact_names || [];
|
|
5605
|
-
for (const artifactName of requestedArtifactNames) {
|
|
5606
|
-
try {
|
|
5607
|
-
const artifact = await toolContext.loadArtifact(artifactName);
|
|
5608
|
-
if (artifact) {
|
|
5609
|
-
llmRequest.contents.push({
|
|
5610
|
-
role: "user",
|
|
5611
|
-
parts: [
|
|
5612
|
-
{
|
|
5613
|
-
text: `Artifact ${artifactName} is:`
|
|
5614
|
-
},
|
|
5615
|
-
artifact
|
|
5616
|
-
]
|
|
5617
|
-
});
|
|
5618
|
-
}
|
|
5619
|
-
} catch (error) {
|
|
5620
|
-
console.error(
|
|
5621
|
-
`Failed to load artifact ${artifactName}:`,
|
|
5622
|
-
error
|
|
5623
|
-
);
|
|
5624
|
-
}
|
|
5587
|
+
client.setRequestHandler(
|
|
5588
|
+
_typesjs.CreateMessageRequestSchema,
|
|
5589
|
+
async (request) => {
|
|
5590
|
+
try {
|
|
5591
|
+
this.logger.debug("Received sampling request:", request);
|
|
5592
|
+
const response = await this.mcpSamplingHandler.handleSamplingRequest(request);
|
|
5593
|
+
this.logger.debug("\u2705 Sampling request completed successfully");
|
|
5594
|
+
return response;
|
|
5595
|
+
} catch (error) {
|
|
5596
|
+
this.logger.error("\u274C Error handling sampling request:", error);
|
|
5597
|
+
if (error instanceof McpError) {
|
|
5598
|
+
throw error;
|
|
5625
5599
|
}
|
|
5600
|
+
throw new McpError(
|
|
5601
|
+
`Sampling request failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
5602
|
+
"SAMPLING_ERROR" /* SAMPLING_ERROR */,
|
|
5603
|
+
error instanceof Error ? error : void 0
|
|
5604
|
+
);
|
|
5626
5605
|
}
|
|
5627
5606
|
}
|
|
5628
|
-
|
|
5607
|
+
);
|
|
5608
|
+
this.logger.debug("\u{1F3AF} Sampling handler registered successfully");
|
|
5629
5609
|
} catch (error) {
|
|
5630
|
-
|
|
5610
|
+
this.logger.error("Failed to setup sampling handler:", error);
|
|
5611
|
+
this.logger.debug(
|
|
5612
|
+
"\u26A0\uFE0F Sampling handler registration failed, continuing without sampling support"
|
|
5613
|
+
);
|
|
5631
5614
|
}
|
|
5632
5615
|
}
|
|
5633
5616
|
/**
|
|
5634
|
-
*
|
|
5617
|
+
* Set a new ADK sampling handler
|
|
5635
5618
|
*/
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5619
|
+
setSamplingHandler(handler) {
|
|
5620
|
+
this.mcpSamplingHandler = new McpSamplingHandler(handler);
|
|
5621
|
+
if (this.client) {
|
|
5622
|
+
this.setupSamplingHandler(this.client).catch((error) => {
|
|
5623
|
+
this.logger.error("Failed to update ADK sampling handler:", error);
|
|
5624
|
+
});
|
|
5639
5625
|
}
|
|
5640
|
-
return null;
|
|
5641
5626
|
}
|
|
5642
|
-
|
|
5627
|
+
/**
|
|
5628
|
+
* Remove the sampling handler
|
|
5629
|
+
*/
|
|
5630
|
+
removeSamplingHandler() {
|
|
5631
|
+
this.mcpSamplingHandler = null;
|
|
5632
|
+
if (this.client) {
|
|
5633
|
+
try {
|
|
5634
|
+
_optionalChain([this, 'access', _152 => _152.client, 'access', _153 => _153.removeRequestHandler, 'optionalCall', _154 => _154("sampling/createMessage")]);
|
|
5635
|
+
} catch (error) {
|
|
5636
|
+
this.logger.error("Failed to remove sampling handler:", error);
|
|
5637
|
+
}
|
|
5638
|
+
}
|
|
5639
|
+
}
|
|
5640
|
+
}, _class22);
|
|
5643
5641
|
|
|
5644
5642
|
// src/tools/mcp/create-tool.ts
|
|
5645
5643
|
init_logger();
|
|
@@ -5818,7 +5816,7 @@ function mcpSchemaToParameters(mcpTool) {
|
|
|
5818
5816
|
}
|
|
5819
5817
|
|
|
5820
5818
|
// src/tools/mcp/create-tool.ts
|
|
5821
|
-
async function
|
|
5819
|
+
async function convertMcpToolToBaseTool(mcpTool, client) {
|
|
5822
5820
|
try {
|
|
5823
5821
|
return new McpToolAdapter(mcpTool, client);
|
|
5824
5822
|
} catch (error) {
|
|
@@ -5848,7 +5846,7 @@ var McpToolAdapter = (_class23 = class extends BaseTool {
|
|
|
5848
5846
|
});_class23.prototype.__init37.call(this);_class23.prototype.__init38.call(this);;
|
|
5849
5847
|
this.mcpTool = mcpTool;
|
|
5850
5848
|
this.client = client;
|
|
5851
|
-
if (client.reinitialize && typeof client.reinitialize === "function") {
|
|
5849
|
+
if (client && client.reinitialize && typeof client.reinitialize === "function") {
|
|
5852
5850
|
this.clientService = client;
|
|
5853
5851
|
}
|
|
5854
5852
|
}
|
|
@@ -6160,7 +6158,10 @@ var McpToolset = (_class24 = class {
|
|
|
6160
6158
|
for (const mcpTool of toolsResponse.tools) {
|
|
6161
6159
|
if (this.isSelected(mcpTool, context4)) {
|
|
6162
6160
|
try {
|
|
6163
|
-
const tool = await
|
|
6161
|
+
const tool = await convertMcpToolToBaseTool(
|
|
6162
|
+
mcpTool,
|
|
6163
|
+
client
|
|
6164
|
+
);
|
|
6164
6165
|
tools.push(tool);
|
|
6165
6166
|
} catch (toolError) {
|
|
6166
6167
|
console.error(
|
|
@@ -13323,4 +13324,4 @@ var VERSION = "0.1.0";
|
|
|
13323
13324
|
|
|
13324
13325
|
|
|
13325
13326
|
|
|
13326
|
-
exports.AF_FUNCTION_CALL_ID_PREFIX = AF_FUNCTION_CALL_ID_PREFIX; exports.Agent = LlmAgent; exports.AgentBuilder = AgentBuilder; exports.AgentEvaluator = AgentEvaluator; exports.AgentTool = AgentTool; exports.Agents = agents_exports; exports.AiSdkLlm = AiSdkLlm; exports.AnthropicLlm = AnthropicLlm; exports.ApiKeyCredential = ApiKeyCredential; exports.ApiKeyScheme = ApiKeyScheme; exports.AuthConfig = AuthConfig; exports.AuthCredential = AuthCredential; exports.AuthCredentialType = AuthCredentialType; exports.AuthHandler = AuthHandler; exports.AuthScheme = AuthScheme; exports.AuthSchemeType = AuthSchemeType; exports.AuthTool = AuthTool; exports.AutoFlow = AutoFlow; exports.BaseAgent = BaseAgent; exports.BaseCodeExecutor = BaseCodeExecutor; exports.BaseLLMConnection = BaseLLMConnection; exports.BaseLlm = BaseLlm; exports.BaseLlmFlow = BaseLlmFlow; exports.BaseLlmRequestProcessor = BaseLlmRequestProcessor; exports.BaseLlmResponseProcessor = BaseLlmResponseProcessor; exports.BasePlanner = BasePlanner; exports.BaseSessionService = BaseSessionService; exports.BaseTool = BaseTool; exports.BasicAuthCredential = BasicAuthCredential; exports.BearerTokenCredential = BearerTokenCredential; exports.BuiltInCodeExecutor = BuiltInCodeExecutor; exports.BuiltInPlanner = BuiltInPlanner; exports.CallbackContext = CallbackContext; exports.CodeExecutionUtils = CodeExecutionUtils; exports.CodeExecutorContext = CodeExecutorContext; exports.DatabaseSessionService = DatabaseSessionService; exports.EnhancedAuthConfig = EnhancedAuthConfig; exports.EvalResult = EvalResult; exports.EvalStatus = EvalStatus; exports.Evaluation = evaluation_exports; exports.Evaluator = Evaluator; exports.Event = Event; exports.EventActions = EventActions; exports.Events = events_exports; exports.ExitLoopTool = ExitLoopTool; exports.FileOperationsTool = FileOperationsTool; exports.FinalResponseMatchV2Evaluator = FinalResponseMatchV2Evaluator; exports.Flows = flows_exports; exports.FunctionTool = FunctionTool; exports.GcsArtifactService = GcsArtifactService; exports.GetUserChoiceTool = GetUserChoiceTool; exports.GoogleLlm = GoogleLlm; exports.GoogleSearch = GoogleSearch; exports.HttpRequestTool = HttpRequestTool; exports.HttpScheme = HttpScheme; exports.InMemoryArtifactService = InMemoryArtifactService; exports.InMemoryMemoryService = InMemoryMemoryService; exports.InMemoryRunner = InMemoryRunner; exports.InMemorySessionService = InMemorySessionService; exports.InvocationContext = InvocationContext; exports.LLMRegistry = LLMRegistry; exports.LangGraphAgent = LangGraphAgent; exports.LlmAgent = LlmAgent; exports.LlmCallsLimitExceededError = LlmCallsLimitExceededError; exports.LlmRequest = LlmRequest; exports.LlmResponse = LlmResponse; exports.LoadArtifactsTool = LoadArtifactsTool; exports.LoadMemoryTool = LoadMemoryTool; exports.LocalEvalService = LocalEvalService; exports.LoopAgent = LoopAgent; exports.McpAbi = McpAbi; exports.McpAtp = McpAtp; exports.McpBamm = McpBamm; exports.
|
|
13327
|
+
exports.AF_FUNCTION_CALL_ID_PREFIX = AF_FUNCTION_CALL_ID_PREFIX; exports.Agent = LlmAgent; exports.AgentBuilder = AgentBuilder; exports.AgentEvaluator = AgentEvaluator; exports.AgentTool = AgentTool; exports.Agents = agents_exports; exports.AiSdkLlm = AiSdkLlm; exports.AnthropicLlm = AnthropicLlm; exports.ApiKeyCredential = ApiKeyCredential; exports.ApiKeyScheme = ApiKeyScheme; exports.AuthConfig = AuthConfig; exports.AuthCredential = AuthCredential; exports.AuthCredentialType = AuthCredentialType; exports.AuthHandler = AuthHandler; exports.AuthScheme = AuthScheme; exports.AuthSchemeType = AuthSchemeType; exports.AuthTool = AuthTool; exports.AutoFlow = AutoFlow; exports.BaseAgent = BaseAgent; exports.BaseCodeExecutor = BaseCodeExecutor; exports.BaseLLMConnection = BaseLLMConnection; exports.BaseLlm = BaseLlm; exports.BaseLlmFlow = BaseLlmFlow; exports.BaseLlmRequestProcessor = BaseLlmRequestProcessor; exports.BaseLlmResponseProcessor = BaseLlmResponseProcessor; exports.BasePlanner = BasePlanner; exports.BaseSessionService = BaseSessionService; exports.BaseTool = BaseTool; exports.BasicAuthCredential = BasicAuthCredential; exports.BearerTokenCredential = BearerTokenCredential; exports.BuiltInCodeExecutor = BuiltInCodeExecutor; exports.BuiltInPlanner = BuiltInPlanner; exports.CallbackContext = CallbackContext; exports.CodeExecutionUtils = CodeExecutionUtils; exports.CodeExecutorContext = CodeExecutorContext; exports.DatabaseSessionService = DatabaseSessionService; exports.EnhancedAuthConfig = EnhancedAuthConfig; exports.EvalResult = EvalResult; exports.EvalStatus = EvalStatus; exports.Evaluation = evaluation_exports; exports.Evaluator = Evaluator; exports.Event = Event; exports.EventActions = EventActions; exports.Events = events_exports; exports.ExitLoopTool = ExitLoopTool; exports.FileOperationsTool = FileOperationsTool; exports.FinalResponseMatchV2Evaluator = FinalResponseMatchV2Evaluator; exports.Flows = flows_exports; exports.FunctionTool = FunctionTool; exports.GcsArtifactService = GcsArtifactService; exports.GetUserChoiceTool = GetUserChoiceTool; exports.GoogleLlm = GoogleLlm; exports.GoogleSearch = GoogleSearch; exports.HttpRequestTool = HttpRequestTool; exports.HttpScheme = HttpScheme; exports.InMemoryArtifactService = InMemoryArtifactService; exports.InMemoryMemoryService = InMemoryMemoryService; exports.InMemoryRunner = InMemoryRunner; exports.InMemorySessionService = InMemorySessionService; exports.InvocationContext = InvocationContext; exports.LLMRegistry = LLMRegistry; exports.LangGraphAgent = LangGraphAgent; exports.LlmAgent = LlmAgent; exports.LlmCallsLimitExceededError = LlmCallsLimitExceededError; exports.LlmRequest = LlmRequest; exports.LlmResponse = LlmResponse; exports.LoadArtifactsTool = LoadArtifactsTool; exports.LoadMemoryTool = LoadMemoryTool; exports.LocalEvalService = LocalEvalService; exports.LoopAgent = LoopAgent; exports.McpAbi = McpAbi; exports.McpAtp = McpAtp; exports.McpBamm = McpBamm; exports.McpCoinGecko = McpCoinGecko; exports.McpDiscord = McpDiscord; exports.McpError = McpError; exports.McpErrorType = McpErrorType; exports.McpFilesystem = McpFilesystem; exports.McpFraxlend = McpFraxlend; exports.McpGeneric = McpGeneric; exports.McpIqWiki = McpIqWiki; exports.McpMemory = McpMemory; exports.McpNearAgent = McpNearAgent; exports.McpNearIntents = McpNearIntents; exports.McpOdos = McpOdos; exports.McpSamplingHandler = McpSamplingHandler; exports.McpTelegram = McpTelegram; exports.McpToolset = McpToolset; exports.McpUpbit = McpUpbit; exports.Memory = memory_exports; exports.Models = models_exports; exports.OAuth2Credential = OAuth2Credential; exports.OAuth2Scheme = OAuth2Scheme; exports.OpenAiLlm = OpenAiLlm; exports.OpenIdConnectScheme = OpenIdConnectScheme; exports.ParallelAgent = ParallelAgent; exports.PlanReActPlanner = PlanReActPlanner; exports.PrebuiltMetrics = PrebuiltMetrics; exports.REQUEST_EUC_FUNCTION_CALL_NAME = REQUEST_EUC_FUNCTION_CALL_NAME; exports.ReadonlyContext = ReadonlyContext; exports.RougeEvaluator = RougeEvaluator; exports.RunConfig = RunConfig; exports.Runner = Runner; exports.SafetyEvaluatorV1 = SafetyEvaluatorV1; exports.SequentialAgent = SequentialAgent; exports.Sessions = sessions_exports; exports.SingleFlow = SingleFlow; exports.State = State; exports.StreamingMode = StreamingMode; exports.TelemetryService = TelemetryService; exports.ToolContext = ToolContext; exports.Tools = tools_exports; exports.TrajectoryEvaluator = TrajectoryEvaluator; exports.TransferToAgentTool = TransferToAgentTool; exports.UserInteractionTool = UserInteractionTool; exports.VERSION = VERSION; exports.VertexAiSessionService = VertexAiSessionService; exports._findFunctionCallEventIfLastEventIsFunctionResponse = _findFunctionCallEventIfLastEventIsFunctionResponse; exports.adkToMcpToolType = adkToMcpToolType; exports.agentTransferRequestProcessor = requestProcessor8; exports.basicRequestProcessor = requestProcessor2; exports.buildFunctionDeclaration = buildFunctionDeclaration; exports.codeExecutionRequestProcessor = requestProcessor3; exports.codeExecutionResponseProcessor = responseProcessor; exports.contentRequestProcessor = requestProcessor4; exports.convertMcpToolToBaseTool = convertMcpToolToBaseTool; exports.createAuthToolArguments = createAuthToolArguments; exports.createBranchContextForSubAgent = createBranchContextForSubAgent; exports.createDatabaseSessionService = createDatabaseSessionService; exports.createFunctionTool = createFunctionTool; exports.createMysqlSessionService = createMysqlSessionService; exports.createPostgresSessionService = createPostgresSessionService; exports.createSamplingHandler = createSamplingHandler; exports.createSqliteSessionService = createSqliteSessionService; exports.createTool = createTool; exports.generateAuthEvent = generateAuthEvent; exports.generateClientFunctionCallId = generateClientFunctionCallId; exports.getLongRunningFunctionCalls = getLongRunningFunctionCalls; exports.getMcpTools = getMcpTools; exports.handleFunctionCallsAsync = handleFunctionCallsAsync; exports.handleFunctionCallsLive = handleFunctionCallsLive; exports.identityRequestProcessor = requestProcessor5; exports.initializeTelemetry = initializeTelemetry; exports.injectSessionState = injectSessionState; exports.instructionsRequestProcessor = requestProcessor6; exports.isEnhancedAuthConfig = isEnhancedAuthConfig; exports.jsonSchemaToDeclaration = jsonSchemaToDeclaration; exports.mcpSchemaToParameters = mcpSchemaToParameters; exports.mergeAgentRun = mergeAgentRun; exports.mergeParallelFunctionResponseEvents = mergeParallelFunctionResponseEvents; exports.newInvocationContextId = newInvocationContextId; exports.nlPlanningRequestProcessor = requestProcessor7; exports.nlPlanningResponseProcessor = responseProcessor2; exports.normalizeJsonSchema = normalizeJsonSchema; exports.populateClientFunctionCallId = populateClientFunctionCallId; exports.registerProviders = registerProviders; exports.removeClientFunctionCallId = removeClientFunctionCallId; exports.requestProcessor = requestProcessor; exports.shutdownTelemetry = shutdownTelemetry; exports.telemetryService = telemetryService; exports.traceLlmCall = traceLlmCall; exports.traceToolCall = traceToolCall; exports.tracer = tracer;
|