From 27fe0ffae1f4b32f89c1affdf92fbcb371d2aa1a Mon Sep 17 00:00:00 2001 From: bracesproul Date: Wed, 10 Jul 2024 15:45:57 -0700 Subject: [PATCH] implemented without generics --- langchain-core/src/runnables/base.ts | 80 ++++++++++++++++++++++++++++ langchain-core/src/runnables/tool.ts | 34 ------------ 2 files changed, 80 insertions(+), 34 deletions(-) delete mode 100644 langchain-core/src/runnables/tool.ts diff --git a/langchain-core/src/runnables/base.ts b/langchain-core/src/runnables/base.ts index 446ce87839dd..2d371e3746d5 100644 --- a/langchain-core/src/runnables/base.ts +++ b/langchain-core/src/runnables/base.ts @@ -6,6 +6,7 @@ import { type TraceableFunction, isTraceableFunction, } from "langsmith/singletons/traceable"; +import { zodToJsonSchema } from "zod-to-json-schema"; import type { RunnableInterface, RunnableBatchOptions } from "./types.js"; import { CallbackManagerForChainRun } from "../callbacks/manager.js"; import { @@ -1078,6 +1079,14 @@ export abstract class Runnable< ], }); } + + asTool(fields: { + name?: string; + description?: string; + schema: z.ZodAny; + }): RunnableToolLike { + return convertRunnableToTool(this, fields); + } } export type RunnableBindingArgs< @@ -2783,3 +2792,74 @@ export class RunnablePick< return IterableReadableStream.fromAsyncGenerator(wrappedGenerator); } } + +export interface RunnableToolLikeFields { + name?: string; + + description?: string; + + schema: RunInput; + + func: + | ((input: RunInput, config?: RunnableConfig) => RunOutput) + | ((input: RunInput, config?: RunnableConfig) => Promise); +} + +export class RunnableToolLike< + RunInput extends z.ZodType = z.ZodType, + RunOutput = string +> extends RunnableLambda { + description?: string; + + schema: RunInput; + + constructor(fields: RunnableToolLikeFields) { + super({ + func: fields.func, + }); + + this.name = fields.name; + this.description = fields.description; + this.schema = fields.schema; + } +} + +/** + * Generate a placeholder description of a runnable + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const _getDescriptionFromRunnable = (schema: Record): string => { + return `Takes ${JSON.stringify(schema, null, 2)}`; +}; + +/** + * Given a runnable and a Zod schema, convert the runnable to a tool. + * + * @template RunInput The input schema for the runnable. + * @param {Runnable} runnable The runnable to convert to a tool. + * @param fields + * @param {string | undefined} [fields.name] The name of the tool. If not provided, it will default to the name of the runnable. + * @param {string | undefined} [fields.description] The description of the tool. If not provided, it will default to `Takes {schema}` where `schema` is a JSON string representation of the input schema. + * @param {z.ZodType | z.ZodString} [fields.schema] The Zod schema for the input of the tool. Either the schema itself or a ZodString. + * @returns {DynamicTool | DynamicStructuredTool>} The tool created from the runnable. DynamicTool if the schema is a ZodString, DynamicStructuredTool if the schema is a ZodType. + */ +export function convertRunnableToTool( + runnable: Runnable, + fields: { + name?: string; + description?: string; + schema: z.ZodAny; + } +): RunnableToolLike { + const description = + fields.description ?? + _getDescriptionFromRunnable(zodToJsonSchema(fields.schema)); + const name = fields.name ?? runnable.getName(); + + return new RunnableToolLike({ + name, + description, + schema: fields.schema, + func: runnable.invoke, + }); +} diff --git a/langchain-core/src/runnables/tool.ts b/langchain-core/src/runnables/tool.ts deleted file mode 100644 index eec6be2a61a6..000000000000 --- a/langchain-core/src/runnables/tool.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ZodAny } from "../types/zod.js"; -import { RunnableLambda } from "./base.js"; -import { RunnableConfig } from "./config.js"; - -export interface RunnableToolLikeFields { - name?: string; - - description?: string; - - schema: RunInput; - - func: - | ((input: RunInput, config?: RunnableConfig) => RunOutput) - | ((input: RunInput, config?: RunnableConfig) => Promise); -} - -export class RunnableToolLike< - RunInput extends ZodAny, - RunOutput = string -> extends RunnableLambda { - description?: string; - - schema: RunInput; - - constructor(fields: RunnableToolLikeFields) { - super({ - func: fields.func, - }); - - this.name = fields.name; - this.description = fields.description; - this.schema = fields.schema; - } -}