Skip to content

Commit

Permalink
implemented without generics
Browse files Browse the repository at this point in the history
  • Loading branch information
bracesproul committed Jul 10, 2024
1 parent af5b8ad commit 27fe0ff
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 34 deletions.
80 changes: 80 additions & 0 deletions langchain-core/src/runnables/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -1078,6 +1079,14 @@ export abstract class Runnable<
],
});
}

asTool(fields: {
name?: string;
description?: string;
schema: z.ZodAny;
}): RunnableToolLike<z.ZodAny, string> {
return convertRunnableToTool(this, fields);
}
}

export type RunnableBindingArgs<
Expand Down Expand Up @@ -2783,3 +2792,74 @@ export class RunnablePick<
return IterableReadableStream.fromAsyncGenerator(wrappedGenerator);
}
}

export interface RunnableToolLikeFields<RunInput, RunOutput> {
name?: string;

description?: string;

schema: RunInput;

func:
| ((input: RunInput, config?: RunnableConfig) => RunOutput)
| ((input: RunInput, config?: RunnableConfig) => Promise<RunOutput>);
}

export class RunnableToolLike<
RunInput extends z.ZodType = z.ZodType,
RunOutput = string
> extends RunnableLambda<RunInput, RunOutput> {
description?: string;

schema: RunInput;

constructor(fields: RunnableToolLikeFields<RunInput, RunOutput>) {
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, any>): 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<RunInput, string>} 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<RunInput> | z.ZodString} [fields.schema] The Zod schema for the input of the tool. Either the schema itself or a ZodString.
* @returns {DynamicTool | DynamicStructuredTool<z.ZodType<RunInput>>} 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<z.ZodAny, string> {
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,
});
}
34 changes: 0 additions & 34 deletions langchain-core/src/runnables/tool.ts

This file was deleted.

0 comments on commit 27fe0ff

Please sign in to comment.