@iqai/adk 0.2.0 → 0.2.1

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