diff --git a/langchain-core/src/tools.ts b/langchain-core/src/tools.ts index a5a78f4afc66..a4b47c25f07c 100644 --- a/langchain-core/src/tools.ts +++ b/langchain-core/src/tools.ts @@ -12,6 +12,9 @@ import { import { ensureConfig, type RunnableConfig } from "./runnables/config.js"; import type { RunnableFunc, RunnableInterface } from "./runnables/base.js"; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type ZodAny = z.ZodObject; + /** * Parameters for the Tool classes. */ @@ -33,7 +36,9 @@ export class ToolInputParsingException extends Error { export interface StructuredToolInterface< // eslint-disable-next-line @typescript-eslint/no-explicit-any - T extends z.ZodObject = z.ZodObject + T extends z.ZodObject = z.ZodObject, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + RunOutput = any > extends RunnableInterface< (z.output extends string ? string : never) | z.input, string @@ -58,7 +63,7 @@ export interface StructuredToolInterface< configArg?: Callbacks | RunnableConfig, /** @deprecated */ tags?: string[] - ): Promise; + ): Promise; name: string; @@ -72,10 +77,12 @@ export interface StructuredToolInterface< */ export abstract class StructuredTool< // eslint-disable-next-line @typescript-eslint/no-explicit-any - T extends z.ZodObject = z.ZodObject + T extends ZodAny = ZodAny, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + RunOutput = any > extends BaseLangChain< (z.output extends string ? string : never) | z.input, - string + RunOutput > { abstract schema: T | z.ZodEffects; @@ -91,7 +98,7 @@ export abstract class StructuredTool< arg: z.output, runManager?: CallbackManagerForToolRun, config?: RunnableConfig - ): Promise; + ): Promise; /** * Invokes the tool with the provided input and configuration. @@ -102,7 +109,7 @@ export abstract class StructuredTool< async invoke( input: (z.output extends string ? string : never) | z.input, config?: RunnableConfig - ): Promise { + ): Promise { return this.call(input, ensureConfig(config)); } @@ -122,7 +129,7 @@ export abstract class StructuredTool< configArg?: Callbacks | RunnableConfig, /** @deprecated */ tags?: string[] - ): Promise { + ): Promise { let parsed; try { parsed = await this.schema.parseAsync(arg); @@ -159,7 +166,7 @@ export abstract class StructuredTool< await runManager?.handleToolError(e); throw e; } - await runManager?.handleToolEnd(result); + await runManager?.handleToolEnd(JSON.stringify(result)); return result; } @@ -189,7 +196,11 @@ export interface ToolInterface extends StructuredToolInterface { /** * Base class for Tools that accept input as a string. */ -export abstract class Tool extends StructuredTool { +export abstract class Tool< + // eslint-disable-next-line @typescript-eslint/no-explicit-any + RunOutput = any + // eslint-disable-next-line @typescript-eslint/no-explicit-any +> extends StructuredTool { schema = z .object({ input: z.string().optional() }) .transform((obj) => obj.input); @@ -210,7 +221,7 @@ export abstract class Tool extends StructuredTool { call( arg: string | undefined | z.input, callbacks?: Callbacks | RunnableConfig - ): Promise { + ): Promise { return super.call( typeof arg === "string" || !arg ? { input: arg } : arg, callbacks @@ -227,12 +238,15 @@ export interface BaseDynamicToolInput extends ToolParams { /** * Interface for the input parameters of the DynamicTool class. */ -export interface DynamicToolInput extends BaseDynamicToolInput { +export interface DynamicToolInput< + // eslint-disable-next-line @typescript-eslint/no-explicit-any + RunOutput = any +> extends BaseDynamicToolInput { func: ( input: string, runManager?: CallbackManagerForToolRun, config?: RunnableConfig - ) => Promise; + ) => Promise; } /** @@ -240,20 +254,25 @@ export interface DynamicToolInput extends BaseDynamicToolInput { */ export interface DynamicStructuredToolInput< // eslint-disable-next-line @typescript-eslint/no-explicit-any - T extends z.ZodObject = z.ZodObject + T extends ZodAny = ZodAny, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + RunOutput = any > extends BaseDynamicToolInput { func: ( input: z.infer, runManager?: CallbackManagerForToolRun, config?: RunnableConfig - ) => Promise; + ) => Promise; schema: T; } /** * A tool that can be created dynamically from a function, name, and description. */ -export class DynamicTool extends Tool { +export class DynamicTool< + // eslint-disable-next-line @typescript-eslint/no-explicit-any + RunOutput = any +> extends Tool { static lc_name() { return "DynamicTool"; } @@ -262,9 +281,9 @@ export class DynamicTool extends Tool { description: string; - func: DynamicToolInput["func"]; + func: DynamicToolInput["func"]; - constructor(fields: DynamicToolInput) { + constructor(fields: DynamicToolInput) { super(fields); this.name = fields.name; this.description = fields.description; @@ -278,7 +297,7 @@ export class DynamicTool extends Tool { async call( arg: string | undefined | z.input, configArg?: RunnableConfig | Callbacks - ): Promise { + ): Promise { const config = parseCallbackConfigArg(configArg); if (config.runName === undefined) { config.runName = this.name; @@ -291,7 +310,7 @@ export class DynamicTool extends Tool { input: string, runManager?: CallbackManagerForToolRun, config?: RunnableConfig - ): Promise { + ): Promise { return this.func(input, runManager, config); } } @@ -304,8 +323,10 @@ export class DynamicTool extends Tool { */ export class DynamicStructuredTool< // eslint-disable-next-line @typescript-eslint/no-explicit-any - T extends z.ZodObject = z.ZodObject -> extends StructuredTool { + T extends ZodAny = ZodAny, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + RunOutput = any +> extends StructuredTool { static lc_name() { return "DynamicStructuredTool"; } @@ -314,11 +335,11 @@ export class DynamicStructuredTool< description: string; - func: DynamicStructuredToolInput["func"]; + func: DynamicStructuredToolInput["func"]; schema: T; - constructor(fields: DynamicStructuredToolInput) { + constructor(fields: DynamicStructuredToolInput) { super(fields); this.name = fields.name; this.description = fields.description; @@ -335,7 +356,7 @@ export class DynamicStructuredTool< configArg?: RunnableConfig | Callbacks, /** @deprecated */ tags?: string[] - ): Promise { + ): Promise { const config = parseCallbackConfigArg(configArg); if (config.runName === undefined) { config.runName = this.name; @@ -347,7 +368,7 @@ export class DynamicStructuredTool< arg: z.output, runManager?: CallbackManagerForToolRun, config?: RunnableConfig - ): Promise { + ): Promise { return this.func(arg, runManager, config); } } @@ -365,19 +386,20 @@ export abstract class BaseToolkit { } } -// eslint-disable-next-line @typescript-eslint/no-explicit-any -type ZodAny = z.ZodObject; - /** * Private class used for constructing a new StructuredTool instance internally. */ class _Tool< RunInput extends ZodAny = ZodAny, - RunOutput = unknown + // eslint-disable-next-line @typescript-eslint/no-explicit-any + RunOutput = any > extends StructuredTool { name: string; + description: string; + schema: RunInput; + func: RunnableFunc; constructor(fields: { @@ -413,10 +435,13 @@ class _Tool< * @param {string} fields.name The name of the tool. * @param {string | undefined} fields.description The description of the tool. * @param {z.ZodObject} fields.schema The Zod schema defining the input for the tool. - * + * * @returns {StructuredTool} A new StructuredTool instance. */ -export function tool( +export function tool< + RunInput extends ZodAny, // eslint-disable-next-line @typescript-eslint/no-explicit-any + RunOutput = any +>( func: RunnableFunc, fields: { name: string;