@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/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/mcp/client.ts
3914
- init_logger();
3915
- var _indexjs = require('@modelcontextprotocol/sdk/client/index.js');
3916
- var _ssejs = require('@modelcontextprotocol/sdk/client/sse.js');
3917
- var _stdiojs = require('@modelcontextprotocol/sdk/client/stdio.js');
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(samplingHandler) {;_class13.prototype.__init22.call(this);
3954
- this.samplingHandler = samplingHandler;
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
- * Handle MCP sampling request and convert between formats
3935
+ * Executes the tool function with validation
3958
3936
  */
3959
- async handleSamplingRequest(request) {
3937
+ async runAsync(args, context4) {
3960
3938
  try {
3961
- if (request.method !== "sampling/createMessage") {
3962
- this.logger.error(
3963
- `Invalid method for sampling handler: ${request.method}. Expected: sampling/createMessage`
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
- this.logger.error("Error handling sampling request:", error);
4029
- if (error instanceof McpError) {
4030
- throw error;
3943
+ if (error instanceof z.ZodError) {
3944
+ return {
3945
+ error: `Invalid arguments for ${this.name}: ${error.message}`
3946
+ };
4031
3947
  }
4032
- throw new McpError(
4033
- `Sampling request failed: ${error instanceof Error ? error.message : String(error)}`,
4034
- "SAMPLING_ERROR" /* SAMPLING_ERROR */,
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
- * Convert MCP messages to ADK Content format
3954
+ * Returns the function declaration for this tool
4041
3955
  */
4042
- convertMcpMessagesToADK(mcpMessages, systemPrompt) {
4043
- const contents = [];
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
- * Convert a single MCP message to ADK Content format
3960
+ * Builds the function declaration from the Zod schema
4059
3961
  */
4060
- convertSingleMcpMessageToADK(mcpMessage) {
4061
- const adkRole = mcpMessage.role === "assistant" ? "model" : "user";
4062
- const adkParts = this.convertMcpContentToADKParts(mcpMessage.content);
4063
- const adkContent = {
4064
- role: adkRole,
4065
- parts: adkParts
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
- * Convert MCP message content to ADK parts format
3993
+ * A counter that keeps track of number of llm calls made.
4074
3994
  */
4075
- convertMcpContentToADKParts(mcpContent) {
4076
- if (mcpContent.type === "text") {
4077
- const textContent = mcpContent.text || "";
4078
- return [{ text: textContent }];
4079
- }
4080
- if (mcpContent.type === "image") {
4081
- const parts = [];
4082
- if (mcpContent.text && typeof mcpContent.text === "string") {
4083
- parts.push({ text: mcpContent.text });
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
- * Convert ADK response to MCP response format
4016
+ * The id of this invocation context. Readonly.
4102
4017
  */
4103
- convertADKResponseToMcp(adkResponse, model) {
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
- * Update the ADK handler
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
- updateHandler(handler) {
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
- * Initializes and returns an MCP client based on configuration.
4187
- * Will create a new client if one doesn't exist yet.
4030
+ * The current agent of this invocation context. Readonly.
4188
4031
  */
4189
- async initialize() {
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
- * Creates a transport based on the configuration.
4034
+ * The user content that started this invocation. Readonly.
4253
4035
  */
4254
- async createTransport() {
4255
- try {
4256
- if (this.config.transport.mode === "sse") {
4257
- this.logger.debug(
4258
- "\u{1F680} Initializing MCP client in SSE mode",
4259
- this.config.transport.serverUrl
4260
- );
4261
- const headers = {
4262
- ...this.config.transport.headers || {},
4263
- ...this.config.headers || {}
4264
- };
4265
- return new (0, _ssejs.SSEClientTransport)(
4266
- new URL(this.config.transport.serverUrl),
4267
- {
4268
- requestInit: {
4269
- headers,
4270
- ...this.config.timeout ? { timeout: this.config.timeout } : {}
4271
- }
4272
- }
4273
- );
4274
- }
4275
- this.logger.debug(
4276
- "\u{1F680} Initializing MCP client in STDIO mode",
4277
- this.config.transport.command
4278
- );
4279
- return new (0, _stdiojs.StdioClientTransport)({
4280
- command: this.config.transport.command,
4281
- args: this.config.transport.args,
4282
- env: this.config.transport.env
4283
- });
4284
- } catch (error) {
4285
- throw new McpError(
4286
- `Failed to create transport: ${error instanceof Error ? error.message : String(error)}`,
4287
- "connection_error" /* CONNECTION_ERROR */,
4288
- error instanceof Error ? error : void 0
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
- * Re-initializes the MCP client when a session is closed.
4294
- * Used by the retry mechanism.
4087
+ * App name from the session
4295
4088
  */
4296
- async reinitialize() {
4297
- this.logger.debug("\u{1F504} Reinitializing MCP client after closed connection");
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
- * Cleans up resources associated with this client service.
4305
- * Similar to Python's AsyncExitStack.aclose() functionality.
4093
+ * User ID from the session
4306
4094
  */
4307
- async cleanupResources() {
4308
- try {
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
- * Call an MCP tool with retry capability if the session is closed.
4099
+ * Tracks number of llm calls made.
4100
+ *
4101
+ * @throws {LlmCallsLimitExceededError} If number of llm calls made exceed the set threshold.
4332
4102
  */
4333
- async callTool(name, args) {
4334
- try {
4335
- const wrappedCall = withRetry(
4336
- async function() {
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
- * Closes and cleans up all resources.
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
- async close() {
4365
- this.logger.debug("\u{1F51A} Closing MCP client service");
4366
- await this.cleanupResources();
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
- * Checks if the client is currently connected
4140
+ * The agent used by this tool
4370
4141
  */
4371
- isConnected() {
4372
- return !!this.client && !this.isClosing;
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
- async setupSamplingHandler(client) {
4375
- if (!this.mcpSamplingHandler) {
4376
- this.logger.debug(
4377
- "\u26A0\uFE0F No sampling handler provided - sampling requests will be rejected"
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
- try {
4382
- client.setRequestHandler(
4383
- _typesjs.CreateMessageRequestSchema,
4384
- async (request) => {
4385
- try {
4386
- this.logger.debug("Received sampling request:", request);
4387
- const response = await this.mcpSamplingHandler.handleSamplingRequest(request);
4388
- this.logger.debug("\u2705 Sampling request completed successfully");
4389
- return response;
4390
- } catch (error) {
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
- this.logger.debug("\u{1F3AF} Sampling handler registered successfully");
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("Failed to setup sampling handler:", error);
4406
- this.logger.debug(
4407
- "\u26A0\uFE0F Sampling handler registration failed, continuing without sampling support"
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
- * Set a new ADK sampling handler
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
- setSamplingHandler(handler) {
4415
- this.mcpSamplingHandler = new McpSamplingHandler(handler);
4416
- if (this.client) {
4417
- this.setupSamplingHandler(this.client).catch((error) => {
4418
- this.logger.error("Failed to update ADK sampling handler:", error);
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
- * Remove the sampling handler
4292
+ * Searches the memory of the current user
4424
4293
  */
4425
- removeSamplingHandler() {
4426
- this.mcpSamplingHandler = null;
4427
- if (this.client) {
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
- }, _class14);
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
- // src/tools/base/create-tool.ts
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
- var _zod = require('zod'); var z = _interopRequireWildcard(_zod);
4443
- var _zodtojsonschema = require('zod-to-json-schema');
4444
- var CreatedTool = class extends BaseTool {
4445
-
4446
-
4447
-
4448
- constructor(config) {
4386
+
4387
+ var HttpRequestTool = class extends BaseTool {
4388
+ constructor() {
4449
4389
  super({
4450
- name: config.name,
4451
- description: config.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
- * Executes the tool function with validation
4395
+ * Get the function declaration for the tool
4462
4396
  */
4463
- async runAsync(args, context4) {
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 validatedArgs = this.schema.parse(args);
4466
- const result = await Promise.resolve(this.func(validatedArgs, context4));
4467
- return _nullishCoalesce(result, () => ( {}));
4468
- } catch (error) {
4469
- if (error instanceof z.ZodError) {
4470
- return {
4471
- error: `Invalid arguments for ${this.name}: ${error.message}`
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
- error: `Error executing ${this.name}: ${error instanceof Error ? error.message : String(error)}`
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
- * Returns the function declaration for this tool
4486
+ * Check if a string is valid JSON
4481
4487
  */
4482
- getDeclaration() {
4483
- return this.functionDeclaration;
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
- * Builds the function declaration from the Zod schema
4513
+ * Get the function declaration for the tool
4487
4514
  */
4488
- buildDeclaration() {
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
- * Increments _numberOfLlmCalls and enforces the limit.
4554
+ * Execute the file operation
4524
4555
  */
4525
- incrementAndEnforceLlmCallsLimit(runConfig) {
4526
- this._numberOfLlmCalls += 1;
4527
- if (runConfig && runConfig.maxLlmCalls > 0 && this._numberOfLlmCalls > runConfig.maxLlmCalls) {
4528
- throw new LlmCallsLimitExceededError(
4529
- `Max number of llm calls limit of \`${runConfig.maxLlmCalls}\` exceeded`
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
- * The running streaming tools of this invocation.
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
- * Caches necessary, data audio or contents, that are needed by transcription.
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
- * Configurations for live agents under this invocation.
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
- * A container to keep track of different kinds of costs incurred as a part
4591
- * of this invocation.
4630
+ * Write to a file
4592
4631
  */
4593
- __init30() {this._invocationCostManager = new InvocationCostManager()}
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
- * Constructor for InvocationContext
4648
+ * Append to a file
4596
4649
  */
4597
- constructor(options) {;_class16.prototype.__init29.call(this);_class16.prototype.__init30.call(this);
4598
- this.artifactService = options.artifactService;
4599
- this.sessionService = options.sessionService;
4600
- this.memoryService = options.memoryService;
4601
- this.invocationId = options.invocationId || newInvocationContextId();
4602
- this.branch = options.branch;
4603
- this.agent = options.agent;
4604
- this.userContent = options.userContent;
4605
- this.session = options.session;
4606
- this.endInvocation = options.endInvocation || false;
4607
- this.liveRequestQueue = options.liveRequestQueue;
4608
- this.activeStreamingTools = options.activeStreamingTools;
4609
- this.transcriptionCache = options.transcriptionCache;
4610
- this.runConfig = options.runConfig;
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
- * App name from the session
4666
+ * Delete a file
4614
4667
  */
4615
- get appName() {
4616
- return this.session.appName;
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
- * User ID from the session
4682
+ * Check if a file exists
4620
4683
  */
4621
- get userId() {
4622
- return this.session.userId;
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
- * Tracks number of llm calls made.
4626
- *
4627
- * @throws {LlmCallsLimitExceededError} If number of llm calls made exceed the set threshold.
4699
+ * List directory contents
4628
4700
  */
4629
- incrementLlmCallCount() {
4630
- this._invocationCostManager.incrementAndEnforceLlmCallsLimit(
4631
- this.runConfig
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
- * Creates a child invocation context for a sub-agent
4731
+ * Create a directory
4636
4732
  */
4637
- createChildContext(agent) {
4638
- return new _InvocationContext({
4639
- artifactService: this.artifactService,
4640
- sessionService: this.sessionService,
4641
- memoryService: this.memoryService,
4642
- invocationId: this.invocationId,
4643
- // Keep same invocation ID
4644
- branch: this.branch ? `${this.branch}.${agent.name}` : agent.name,
4645
- // Update branch
4646
- agent,
4647
- // Update to the new agent
4648
- userContent: this.userContent,
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
- }, _class16);
4746
+ };
4658
4747
 
4659
- // src/tools/common/agent-tool.ts
4748
+ // src/tools/common/user-interaction-tool.ts
4660
4749
  init_base_tool();
4661
- function isLlmAgent(agent) {
4662
- return true;
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: config.name,
4688
- description: config.description || config.agent.description,
4689
- isLongRunning: config.isLongRunning || false,
4690
- shouldRetryOnFailure: config.shouldRetryOnFailure || false,
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
- input: {
4769
+ prompt: {
4713
4770
  type: _genai.Type.STRING,
4714
- description: "The input to provide to the agent"
4715
- }
4716
- },
4717
- required: ["input"]
4718
- }
4719
- };
4720
- }
4721
- /**
4722
- * Execute the tool by running the agent with the provided input
4723
- */
4724
- async runAsync(params, context4) {
4725
- try {
4726
- const input = params.input || Object.values(params)[0];
4727
- if (!isLlmAgent(this.agent)) {
4728
- throw new Error(
4729
- `Agent ${this.name} does not support running as a tool`
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
- * Gets the event actions of the current tool call
4790
+ * Execute the user interaction
4800
4791
  */
4801
- get actions() {
4802
- return this.eventActions;
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
- * Lists the filenames of the artifacts attached to the current session
4831
+ * Constructor for ExitLoopTool
4806
4832
  */
4807
- async listArtifacts() {
4808
- if (!this._invocationContext.artifactService) {
4809
- throw new Error("Artifact service is not initialized.");
4810
- }
4811
- return await this._invocationContext.artifactService.listArtifactKeys({
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
- * Searches the memory of the current user
4840
+ * Execute the exit loop action
4819
4841
  */
4820
- async searchMemory(query) {
4821
- if (!this._invocationContext.memoryService) {
4822
- throw new Error("Memory service is not available.");
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/google-search.ts
4848
+ // src/tools/common/get-user-choice-tool.ts
4847
4849
  init_logger();
4848
4850
  init_base_tool();
4849
4851
 
4850
- var GoogleSearch = (_class18 = class extends BaseTool {
4851
- __init32() {this.logger = new Logger({ name: "GoogleSearch" })}
4852
+ var GetUserChoiceTool = (_class18 = class extends BaseTool {
4853
+ __init28() {this.logger = new Logger({ name: "GetUserChoiceTool" })}
4852
4854
  /**
4853
- * Constructor for GoogleSearch
4855
+ * Constructor for GetUserChoiceTool
4854
4856
  */
4855
4857
  constructor() {
4856
4858
  super({
4857
- name: "google_search",
4858
- description: "Search the web using Google"
4859
- });_class18.prototype.__init32.call(this);;
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
- query: {
4872
- type: _genai.Type.STRING,
4873
- description: "The search query to execute"
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
- num_results: {
4876
- type: _genai.Type.INTEGER,
4877
- description: "Number of results to return (max 10)",
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: ["query"]
4886
+ required: ["options"]
4882
4887
  }
4883
4888
  };
4884
4889
  }
4885
4890
  /**
4886
- * Execute the search
4887
- * This is a simplified implementation that doesn't actually search, just returns mock results
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, _context) {
4895
+ async runAsync(args, context4) {
4890
4896
  this.logger.debug(
4891
- `[GoogleSearch] Executing Google search for: ${args.query}`
4897
+ `Executing get_user_choice with options: ${args.options.join(", ")}`
4892
4898
  );
4893
- return {
4894
- results: [
4895
- {
4896
- title: `Result 1 for ${args.query}`,
4897
- link: "https://example.com/1",
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/http-request-tool.ts
4907
+ // src/tools/common/transfer-to-agent-tool.ts
4908
+ init_logger();
4911
4909
  init_base_tool();
4912
4910
 
4913
- var HttpRequestTool = class extends BaseTool {
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: "http_request",
4917
- description: "Make HTTP requests to external APIs and web services"
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
- url: {
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: "Request body content (as string, typically JSON)"
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: ["url"]
4937
+ required: ["agent_name"]
4959
4938
  }
4960
4939
  };
4961
4940
  }
4962
4941
  /**
4963
- * Execute the HTTP request
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
- isValidJson(str) {
5015
- try {
5016
- JSON.parse(str);
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/file-operations-tool.ts
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 FileOperationsTool = class extends BaseTool {
5030
-
5031
- constructor(options) {
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: "file_operations",
5034
- description: "Perform file system operations like reading, writing, and managing files"
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
- operation: {
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: "File encoding to use",
5072
- default: "utf8"
4977
+ description: "The query to load memories for"
5073
4978
  }
5074
4979
  },
5075
- required: ["operation", "filepath"]
4980
+ required: ["query"]
5076
4981
  }
5077
4982
  };
5078
4983
  }
5079
4984
  /**
5080
- * Execute the file operation
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 readFile(filepath, encoding) {
4987
+ async runAsync(args, context4) {
4988
+ this.logger.debug(`Executing load_memory with query: ${args.query}`);
5142
4989
  try {
5143
- const content = await fs2.default.readFile(filepath, { encoding });
4990
+ const searchResult = await context4.searchMemory(args.query);
5144
4991
  return {
5145
- success: true,
5146
- data: content
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
- success: false,
5151
- error: `Failed to read file: ${error instanceof Error ? error.message : String(error)}`
4998
+ error: "Memory search failed",
4999
+ message: error instanceof Error ? error.message : String(error)
5152
5000
  };
5153
5001
  }
5154
5002
  }
5155
- /**
5156
- * Write to a file
5157
- */
5158
- async writeFile(filepath, content, encoding) {
5159
- try {
5160
- const dir = path2.default.dirname(filepath);
5161
- await fs2.default.mkdir(dir, { recursive: true });
5162
- await fs2.default.writeFile(filepath, content, { encoding });
5163
- return {
5164
- success: true
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
- * Append to a file
5016
+ * Get the function declaration for the tool
5175
5017
  */
5176
- async appendFile(filepath, content, encoding) {
5177
- try {
5178
- const dir = path2.default.dirname(filepath);
5179
- await fs2.default.mkdir(dir, { recursive: true });
5180
- await fs2.default.appendFile(filepath, content, { encoding });
5181
- return {
5182
- success: true
5183
- };
5184
- } catch (error) {
5185
- return {
5186
- success: false,
5187
- error: `Failed to append to file: ${error instanceof Error ? error.message : String(error)}`
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
- * Delete a file
5038
+ * Execute the load artifacts operation
5193
5039
  */
5194
- async deleteFile(filepath) {
5195
- try {
5196
- await fs2.default.unlink(filepath);
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
- * Check if a file exists
5045
+ * Processes the outgoing LLM request for this tool.
5209
5046
  */
5210
- async fileExists(filepath) {
5211
- try {
5212
- await fs2.default.access(filepath);
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
- * List directory contents
5052
+ * Appends artifacts information to the LLM request
5226
5053
  */
5227
- async listDirectory(dirpath) {
5054
+ async appendArtifactsToLlmRequest(toolContext, llmRequest) {
5228
5055
  try {
5229
- const entries = await fs2.default.readdir(dirpath, { withFileTypes: true });
5230
- const results = await Promise.all(
5231
- entries.map(async (entry) => {
5232
- const entryPath = path2.default.join(dirpath, entry.name);
5233
- const stats = await fs2.default.stat(entryPath);
5234
- return {
5235
- name: entry.name,
5236
- path: entryPath,
5237
- isFile: entry.isFile(),
5238
- isDirectory: entry.isDirectory(),
5239
- size: stats.size,
5240
- created: stats.birthtime,
5241
- modified: stats.mtime
5242
- };
5243
- })
5244
- );
5245
- return {
5246
- success: true,
5247
- data: results
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
- return {
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
- * Create a directory
5108
+ * Extracts function response from a part if it exists
5258
5109
  */
5259
- async makeDirectory(dirpath) {
5260
- try {
5261
- await fs2.default.mkdir(dirpath, { recursive: true });
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/common/user-interaction-tool.ts
5275
- init_base_tool();
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
- var UserInteractionTool = class extends BaseTool {
5278
- constructor() {
5279
- super({
5280
- name: "user_interaction",
5281
- description: "Prompt the user for input during agent execution",
5282
- isLongRunning: true
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
- * Get the function declaration for the tool
5287
- */
5288
- getDeclaration() {
5289
- return {
5290
- name: this.name,
5291
- description: this.description,
5292
- parameters: {
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
- * Execute the user interaction
5162
+ * Handle MCP sampling request and convert between formats
5317
5163
  */
5318
- async runAsync(args, context4) {
5164
+ async handleSamplingRequest(request) {
5319
5165
  try {
5320
- const actions = context4.actions;
5321
- if (!actions || !actions.promptUser) {
5322
- return {
5323
- success: false,
5324
- error: "User interaction is not supported in the current environment"
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
- if (actions.skipSummarization) {
5328
- actions.skipSummarization(true);
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 promptOptions = args.options && args.options.length > 0 ? {
5331
- choices: args.options
5332
- } : void 0;
5333
- const response = await actions.promptUser({
5334
- prompt: args.prompt,
5335
- defaultValue: args.defaultValue,
5336
- options: promptOptions
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
- return {
5339
- success: true,
5340
- userInput: response
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
- return {
5344
- success: false,
5345
- error: error instanceof Error ? error.message : String(error)
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
- * Constructor for ExitLoopTool
5245
+ * Convert MCP messages to ADK Content format
5358
5246
  */
5359
- constructor() {
5360
- super({
5361
- name: "exit_loop",
5362
- description: "Exits the loop. Call this function only when you are instructed to do so."
5363
- });_class19.prototype.__init33.call(this);;
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
- * Execute the exit loop action
5263
+ * Convert a single MCP message to ADK Content format
5367
5264
  */
5368
- async runAsync(_args, context4) {
5369
- this.logger.debug("Executing exit loop tool");
5370
- context4.actions.escalate = true;
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
- * Constructor for GetUserChoiceTool
5278
+ * Convert MCP message content to ADK parts format
5382
5279
  */
5383
- constructor() {
5384
- super({
5385
- name: "get_user_choice",
5386
- 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.",
5387
- isLongRunning: true
5388
- });_class20.prototype.__init34.call(this);;
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
- * Get the function declaration for the tool
5306
+ * Convert ADK response to MCP response format
5392
5307
  */
5393
- getDeclaration() {
5394
- return {
5395
- name: this.name,
5396
- description: this.description,
5397
- parameters: {
5398
- type: _genai.Type.OBJECT,
5399
- properties: {
5400
- options: {
5401
- type: _genai.Type.ARRAY,
5402
- description: "List of options for the user to choose from",
5403
- items: {
5404
- type: _genai.Type.STRING
5405
- }
5406
- },
5407
- question: {
5408
- type: _genai.Type.STRING,
5409
- description: "The question or prompt to show the user before presenting options"
5410
- }
5411
- },
5412
- required: ["options"]
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
- * Execute the user choice action
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
- async runAsync(args, context4) {
5422
- this.logger.debug(
5423
- `Executing get_user_choice with options: ${args.options.join(", ")}`
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
- }, _class20);
5343
+ }, _class21);
5344
+ function createSamplingHandler(handler) {
5345
+ return handler;
5346
+ }
5432
5347
 
5433
- // src/tools/common/transfer-to-agent-tool.ts
5434
- init_logger();
5435
- init_base_tool();
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
- var TransferToAgentTool = (_class21 = class extends BaseTool {
5438
- __init35() {this.logger = new Logger({ name: "TransferToAgentTool" })}
5439
- /**
5440
- * Constructor for TransferToAgentTool
5441
- */
5442
- constructor() {
5443
- super({
5444
- name: "transfer_to_agent",
5445
- 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."
5446
- });_class21.prototype.__init35.call(this);;
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
- * Get the function declaration for the tool
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
- getDeclaration() {
5452
- return {
5453
- name: this.name,
5454
- description: this.description,
5455
- parameters: {
5456
- type: _genai.Type.OBJECT,
5457
- properties: {
5458
- agent_name: {
5459
- type: _genai.Type.STRING,
5460
- description: "The name of the agent to transfer control to"
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
- required: ["agent_name"]
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
- * Execute the transfer to agent action
5457
+ * Creates a transport based on the configuration.
5469
5458
  */
5470
- async runAsync(args, context4) {
5471
- this.logger.debug(`Executing transfer to agent: ${args.agent_name}`);
5472
- context4.actions.transferToAgent = args.agent_name;
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
- * Constructor for LoadMemoryTool
5498
+ * Re-initializes the MCP client when a session is closed.
5499
+ * Used by the retry mechanism.
5484
5500
  */
5485
- constructor() {
5486
- super({
5487
- name: "load_memory",
5488
- description: "Loads the memory for the current user based on a query."
5489
- });_class22.prototype.__init36.call(this);;
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
- * Get the function declaration for the tool
5509
+ * Cleans up resources associated with this client service.
5510
+ * Similar to Python's AsyncExitStack.aclose() functionality.
5493
5511
  */
5494
- getDeclaration() {
5495
- return {
5496
- name: this.name,
5497
- description: this.description,
5498
- parameters: {
5499
- type: _genai.Type.OBJECT,
5500
- properties: {
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
- required: ["query"]
5520
+ } catch (err) {
5521
+ }
5507
5522
  }
5508
- };
5509
- }
5510
- /**
5511
- * Execute the memory loading action
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
- console.error("Error searching memory:", error);
5523
- return {
5524
- error: "Memory search failed",
5525
- message: error instanceof Error ? error.message : String(error)
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
- * Get the function declaration for the tool
5536
+ * Call an MCP tool with retry capability if the session is closed.
5543
5537
  */
5544
- getDeclaration() {
5545
- return {
5546
- name: this.name,
5547
- description: this.description,
5548
- parameters: {
5549
- type: _genai.Type.OBJECT,
5550
- properties: {
5551
- artifact_names: {
5552
- type: _genai.Type.ARRAY,
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
- required: []
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
- * Execute the load artifacts operation
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 runAsync(args, context4) {
5567
- const artifactNames = args.artifact_names || [];
5568
- return { artifact_names: artifactNames };
5569
+ async close() {
5570
+ this.logger.debug("\u{1F51A} Closing MCP client service");
5571
+ await this.cleanupResources();
5569
5572
  }
5570
5573
  /**
5571
- * Processes the outgoing LLM request for this tool.
5574
+ * Checks if the client is currently connected
5572
5575
  */
5573
- async processLlmRequest(toolContext, llmRequest) {
5574
- await super.processLlmRequest(toolContext, llmRequest);
5575
- await this.appendArtifactsToLlmRequest(toolContext, llmRequest);
5576
+ isConnected() {
5577
+ return !!this.client && !this.isClosing;
5576
5578
  }
5577
- /**
5578
- * Appends artifacts information to the LLM request
5579
- */
5580
- async appendArtifactsToLlmRequest(toolContext, llmRequest) {
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
- const artifactNames = await toolContext.listArtifacts();
5583
- if (!artifactNames || artifactNames.length === 0) {
5584
- return;
5585
- }
5586
- const instructions = [
5587
- `You have a list of artifacts:
5588
- ${JSON.stringify(artifactNames)}
5589
-
5590
- When the user asks questions about any of the artifacts, you should call the
5591
- \`load_artifacts\` function to load the artifact. Do not generate any text other
5592
- than the function call.
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
- console.error("Error appending artifacts to LLM request:", error);
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
- * Extracts function response from a part if it exists
5617
+ * Set a new ADK sampling handler
5635
5618
  */
5636
- extractFunctionResponse(part) {
5637
- if ("functionResponse" in part && part.functionResponse) {
5638
- return part.functionResponse;
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 createTool2(mcpTool, client) {
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 createTool2(mcpTool, client);
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.McpClientService = McpClientService; 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.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;
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;