@langchain/core 0.3.43 → 0.3.44

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.
@@ -8,6 +8,7 @@ import { CallbackManager, Callbacks } from "../callbacks/manager.js";
8
8
  import { AsyncCaller, AsyncCallerParams } from "../utils/async_caller.js";
9
9
  import { Runnable, type RunnableInterface } from "../runnables/base.js";
10
10
  import { RunnableConfig } from "../runnables/config.js";
11
+ import { JSONSchema } from "../utils/json_schema.js";
11
12
  export declare const getModelNameForTiktoken: (modelName: string) => TiktokenModel;
12
13
  export declare const getEmbeddingContextSize: (modelName?: string) => number;
13
14
  export declare const getModelContextSize: (modelName: string) => number;
@@ -83,7 +84,7 @@ export interface FunctionDefinition {
83
84
  * To describe a function that accepts no parameters, provide the value
84
85
  * `{"type": "object", "properties": {}}`.
85
86
  */
86
- parameters: Record<string, unknown>;
87
+ parameters: Record<string, unknown> | JSONSchema;
87
88
  /**
88
89
  * A description of what the function does, used by the model to choose when and
89
90
  * how to call the function.
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.tool = exports.BaseToolkit = exports.DynamicStructuredTool = exports.DynamicTool = exports.Tool = exports.StructuredTool = exports.ToolInputParsingException = void 0;
4
4
  const zod_1 = require("zod");
5
+ const json_schema_1 = require("@cfworker/json-schema");
5
6
  const manager_js_1 = require("../callbacks/manager.cjs");
6
7
  const base_js_1 = require("../language_models/base.cjs");
7
8
  const config_js_1 = require("../runnables/config.cjs");
@@ -10,6 +11,7 @@ const index_js_1 = require("../singletons/index.cjs");
10
11
  const utils_js_1 = require("./utils.cjs");
11
12
  Object.defineProperty(exports, "ToolInputParsingException", { enumerable: true, get: function () { return utils_js_1.ToolInputParsingException; } });
12
13
  const is_zod_schema_js_1 = require("../utils/types/is_zod_schema.cjs");
14
+ const json_schema_js_1 = require("../utils/json_schema.cjs");
13
15
  /**
14
16
  * Base class for Tools that accept input of any shape defined by a Zod schema.
15
17
  */
@@ -97,17 +99,30 @@ class StructuredTool extends base_js_1.BaseLangChain {
97
99
  async call(arg, configArg,
98
100
  /** @deprecated */
99
101
  tags) {
100
- let parsed;
101
- try {
102
- parsed = await this.schema.parseAsync(arg);
103
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
102
+ let parsed = arg;
103
+ if ((0, is_zod_schema_js_1.isZodSchema)(this.schema)) {
104
+ try {
105
+ parsed = await this.schema.parseAsync(arg);
106
+ }
107
+ catch (e) {
108
+ let message = `Received tool input did not match expected schema`;
109
+ if (this.verboseParsingErrors) {
110
+ message = `${message}\nDetails: ${e.message}`;
111
+ }
112
+ throw new utils_js_1.ToolInputParsingException(message, JSON.stringify(arg));
113
+ }
104
114
  }
105
- catch (e) {
106
- let message = `Received tool input did not match expected schema`;
107
- if (this.verboseParsingErrors) {
108
- message = `${message}\nDetails: ${e.message}`;
115
+ else {
116
+ const result = (0, json_schema_1.validate)(arg, this.schema);
117
+ if (!result.valid) {
118
+ let message = `Received tool input did not match expected schema`;
119
+ if (this.verboseParsingErrors) {
120
+ message = `${message}\nDetails: ${result.errors
121
+ .map((e) => `${e.keywordLocation}: ${e.error}`)
122
+ .join("\n")}`;
123
+ }
124
+ throw new utils_js_1.ToolInputParsingException(message, JSON.stringify(arg));
109
125
  }
110
- throw new utils_js_1.ToolInputParsingException(message, JSON.stringify(arg));
111
126
  }
112
127
  const config = (0, manager_js_1.parseCallbackConfigArg)(configArg);
113
128
  const callbackManager_ = manager_js_1.CallbackManager.configure(config.callbacks, this.callbacks, config.tags || tags, this.tags, config.metadata, this.metadata, { verbose: this.verbose });
@@ -116,7 +131,6 @@ class StructuredTool extends base_js_1.BaseLangChain {
116
131
  let result;
117
132
  try {
118
133
  result = await this._call(parsed, runManager, config);
119
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
120
134
  }
121
135
  catch (e) {
122
136
  await runManager?.handleToolError(e);
@@ -271,7 +285,7 @@ class DynamicStructuredTool extends StructuredTool {
271
285
  this.description = fields.description;
272
286
  this.func = fields.func;
273
287
  this.returnDirect = fields.returnDirect ?? this.returnDirect;
274
- this.schema = ((0, is_zod_schema_js_1.isZodSchema)(fields.schema) ? fields.schema : zod_1.z.object({}).passthrough());
288
+ this.schema = fields.schema;
275
289
  }
276
290
  /**
277
291
  * @deprecated Use .invoke() instead. Will be removed in 0.3.0.
@@ -286,7 +300,6 @@ class DynamicStructuredTool extends StructuredTool {
286
300
  return super.call(arg, config, tags);
287
301
  }
288
302
  _call(arg, runManager, parentConfig) {
289
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
290
303
  return this.func(arg, runManager, parentConfig);
291
304
  }
292
305
  }
@@ -303,10 +316,12 @@ class BaseToolkit {
303
316
  }
304
317
  exports.BaseToolkit = BaseToolkit;
305
318
  function tool(func, fields) {
306
- // If the schema is not provided, or it's a string schema, create a DynamicTool
307
- if (!fields.schema ||
308
- ((0, is_zod_schema_js_1.isZodSchema)(fields.schema) &&
309
- (!("shape" in fields.schema) || !fields.schema.shape))) {
319
+ const isShapelessZodSchema = fields.schema &&
320
+ (0, is_zod_schema_js_1.isZodSchema)(fields.schema) &&
321
+ (!("shape" in fields.schema) || !fields.schema.shape);
322
+ const isStringJSONSchema = (0, json_schema_js_1.validatesOnlyStrings)(fields.schema);
323
+ // If the schema is not provided, or it's a shapeless schema (e.g. a ZodString), create a DynamicTool
324
+ if (!fields.schema || isShapelessZodSchema || isStringJSONSchema) {
310
325
  return new DynamicTool({
311
326
  ...fields,
312
327
  description: fields.description ??
@@ -331,13 +346,14 @@ function tool(func, fields) {
331
346
  },
332
347
  });
333
348
  }
334
- const description = fields.description ?? fields.schema.description ?? `${fields.name} tool`;
349
+ const schema = fields.schema;
350
+ const description = fields.description ??
351
+ fields.schema.description ??
352
+ `${fields.name} tool`;
335
353
  return new DynamicStructuredTool({
336
354
  ...fields,
337
355
  description,
338
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
339
- schema: fields.schema,
340
- // TODO: Consider moving into DynamicStructuredTool constructor
356
+ schema,
341
357
  func: async (input, runManager, config) => {
342
358
  return new Promise((resolve, reject) => {
343
359
  const childConfig = (0, config_js_1.patchConfig)(config, {
@@ -345,8 +361,6 @@ function tool(func, fields) {
345
361
  });
346
362
  void index_js_1.AsyncLocalStorageProviderSingleton.runWithConfig((0, config_js_1.pickRunnableConfigKeys)(childConfig), async () => {
347
363
  try {
348
- // TS doesn't restrict the type here based on the guard above
349
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
350
364
  resolve(func(input, childConfig));
351
365
  }
352
366
  catch (e) {
@@ -1,94 +1,21 @@
1
1
  import { z } from "zod";
2
2
  import { CallbackManagerForToolRun, Callbacks } from "../callbacks/manager.js";
3
- import { BaseLangChain, type BaseLangChainParams } from "../language_models/base.js";
3
+ import { BaseLangChain } from "../language_models/base.js";
4
4
  import { type RunnableConfig } from "../runnables/config.js";
5
- import type { RunnableFunc, RunnableInterface } from "../runnables/base.js";
5
+ import type { RunnableFunc } from "../runnables/base.js";
6
6
  import { ToolCall } from "../messages/tool.js";
7
- import { MessageContent } from "../messages/base.js";
8
7
  import { ToolInputParsingException } from "./utils.js";
8
+ import type { StructuredToolCallInput, ToolInputSchemaBase, ToolReturnType, ResponseFormat, ToolInputSchemaInputType, ToolInputSchemaOutputType, ToolParams, ToolRunnableConfig, StructuredToolInterface, DynamicToolInput, DynamicStructuredToolInput, ZodObjectAny } from "./types.js";
9
+ import { type JSONSchema } from "../utils/json_schema.js";
10
+ export type { BaseDynamicToolInput, ContentAndArtifact, DynamicToolInput, DynamicStructuredToolInput, isLangChainTool, isRunnableToolLike, isStructuredTool, isStructuredToolParams, ResponseFormat, StructuredToolCallInput, StructuredToolInterface, StructuredToolParams, ToolInterface, ToolParams, ToolReturnType, ToolRunnableConfig, ToolInputSchemaBase as ToolSchemaBase, } from "./types.js";
9
11
  export { ToolInputParsingException };
10
- export type ResponseFormat = "content" | "content_and_artifact" | string;
11
- type ToolReturnType = any;
12
- export type ContentAndArtifact = [MessageContent, any];
13
- type ZodObjectAny = z.ZodObject<any, any, any, any>;
14
- /**
15
- * Parameters for the Tool classes.
16
- */
17
- export interface ToolParams extends BaseLangChainParams {
18
- /**
19
- * The tool response format.
20
- *
21
- * If "content" then the output of the tool is interpreted as the contents of a
22
- * ToolMessage. If "content_and_artifact" then the output is expected to be a
23
- * two-tuple corresponding to the (content, artifact) of a ToolMessage.
24
- *
25
- * @default "content"
26
- */
27
- responseFormat?: ResponseFormat;
28
- /**
29
- * Whether to show full details in the thrown parsing errors.
30
- *
31
- * @default false
32
- */
33
- verboseParsingErrors?: boolean;
34
- }
35
- export type ToolRunnableConfig<ConfigurableFieldType extends Record<string, any> = Record<string, any>> = RunnableConfig<ConfigurableFieldType> & {
36
- toolCall?: ToolCall;
37
- };
38
- /**
39
- * Schema for defining tools.
40
- *
41
- * @version 0.2.19
42
- */
43
- export interface StructuredToolParams extends Pick<StructuredToolInterface, "name" | "schema"> {
44
- /**
45
- * An optional description of the tool to pass to the model.
46
- */
47
- description?: string;
48
- }
49
- export interface StructuredToolInterface<T extends ZodObjectAny = ZodObjectAny> extends RunnableInterface<(z.output<T> extends string ? string : never) | z.input<T> | ToolCall, ToolReturnType> {
50
- lc_namespace: string[];
51
- /**
52
- * A Zod schema representing the parameters of the tool.
53
- */
54
- schema: T | z.ZodEffects<T>;
55
- /**
56
- * @deprecated Use .invoke() instead. Will be removed in 0.3.0.
57
- *
58
- * Calls the tool with the provided argument, configuration, and tags. It
59
- * parses the input according to the schema, handles any errors, and
60
- * manages callbacks.
61
- * @param arg The input argument for the tool.
62
- * @param configArg Optional configuration or callbacks for the tool.
63
- * @param tags Optional tags for the tool.
64
- * @returns A Promise that resolves with a string.
65
- */
66
- call(arg: (z.output<T> extends string ? string : never) | z.input<T> | ToolCall, configArg?: Callbacks | RunnableConfig,
67
- /** @deprecated */
68
- tags?: string[]): Promise<ToolReturnType>;
69
- /**
70
- * The name of the tool.
71
- */
72
- name: string;
73
- /**
74
- * A description of the tool.
75
- */
76
- description: string;
77
- /**
78
- * Whether to return the tool's output directly.
79
- *
80
- * Setting this to true means that after the tool is called,
81
- * an agent should stop looping.
82
- */
83
- returnDirect: boolean;
84
- }
85
12
  /**
86
13
  * Base class for Tools that accept input of any shape defined by a Zod schema.
87
14
  */
88
- export declare abstract class StructuredTool<T extends ZodObjectAny = ZodObjectAny> extends BaseLangChain<(z.output<T> extends string ? string : never) | z.input<T> | ToolCall, ToolReturnType> {
15
+ export declare abstract class StructuredTool<SchemaT extends ToolInputSchemaBase = ZodObjectAny, SchemaOutputT = ToolInputSchemaOutputType<SchemaT>, SchemaInputT = ToolInputSchemaInputType<SchemaT>> extends BaseLangChain<StructuredToolCallInput<SchemaT, SchemaInputT>, ToolReturnType> {
89
16
  abstract name: string;
90
17
  abstract description: string;
91
- abstract schema: T | z.ZodEffects<T>;
18
+ abstract schema: SchemaT;
92
19
  /**
93
20
  * Whether to return the tool's output directly.
94
21
  *
@@ -109,14 +36,14 @@ export declare abstract class StructuredTool<T extends ZodObjectAny = ZodObjectA
109
36
  */
110
37
  responseFormat?: ResponseFormat;
111
38
  constructor(fields?: ToolParams);
112
- protected abstract _call(arg: z.output<T>, runManager?: CallbackManagerForToolRun, parentConfig?: ToolRunnableConfig): Promise<ToolReturnType>;
39
+ protected abstract _call(arg: SchemaOutputT, runManager?: CallbackManagerForToolRun, parentConfig?: ToolRunnableConfig): Promise<ToolReturnType>;
113
40
  /**
114
41
  * Invokes the tool with the provided input and configuration.
115
42
  * @param input The input for the tool.
116
43
  * @param config Optional configuration for the tool.
117
44
  * @returns A Promise that resolves with a string.
118
45
  */
119
- invoke(input: (z.output<T> extends string ? string : never) | z.input<T> | ToolCall, config?: RunnableConfig): Promise<ToolReturnType>;
46
+ invoke(input: StructuredToolCallInput<SchemaT, SchemaInputT>, config?: RunnableConfig): Promise<ToolReturnType>;
120
47
  /**
121
48
  * @deprecated Use .invoke() instead. Will be removed in 0.3.0.
122
49
  *
@@ -128,26 +55,16 @@ export declare abstract class StructuredTool<T extends ZodObjectAny = ZodObjectA
128
55
  * @param tags Optional tags for the tool.
129
56
  * @returns A Promise that resolves with a string.
130
57
  */
131
- call(arg: (z.output<T> extends string ? string : never) | z.input<T>, configArg?: Callbacks | ToolRunnableConfig,
58
+ call(arg: StructuredToolCallInput<SchemaT, SchemaInputT>, configArg?: Callbacks | ToolRunnableConfig,
132
59
  /** @deprecated */
133
60
  tags?: string[]): Promise<ToolReturnType>;
134
61
  }
135
- export interface ToolInterface<T extends ZodObjectAny = ZodObjectAny> extends StructuredToolInterface<T> {
136
- /**
137
- * @deprecated Use .invoke() instead. Will be removed in 0.3.0.
138
- *
139
- * Calls the tool with the provided argument and callbacks. It handles
140
- * string inputs specifically.
141
- * @param arg The input argument for the tool, which can be a string, undefined, or an input of the tool's schema.
142
- * @param callbacks Optional callbacks for the tool.
143
- * @returns A Promise that resolves with a string.
144
- */
145
- call(arg: string | undefined | z.input<this["schema"]> | ToolCall, callbacks?: Callbacks | RunnableConfig): Promise<ToolReturnType>;
146
- }
147
62
  /**
148
63
  * Base class for Tools that accept input as a string.
149
64
  */
150
- export declare abstract class Tool extends StructuredTool<ZodObjectAny> {
65
+ export declare abstract class Tool extends StructuredTool<z.ZodEffects<z.ZodObject<{
66
+ input: z.ZodOptional<z.ZodString>;
67
+ }, "strip", z.ZodTypeAny, any, any>, any, any>> {
151
68
  schema: z.ZodEffects<z.ZodObject<{
152
69
  input: z.ZodOptional<z.ZodString>;
153
70
  }, "strip", z.ZodTypeAny, {
@@ -169,30 +86,6 @@ export declare abstract class Tool extends StructuredTool<ZodObjectAny> {
169
86
  */
170
87
  call(arg: string | undefined | z.input<this["schema"]> | ToolCall, callbacks?: Callbacks | RunnableConfig): Promise<ToolReturnType>;
171
88
  }
172
- export interface BaseDynamicToolInput extends ToolParams {
173
- name: string;
174
- description: string;
175
- /**
176
- * Whether to return the tool's output directly.
177
- *
178
- * Setting this to true means that after the tool is called,
179
- * an agent should stop looping.
180
- */
181
- returnDirect?: boolean;
182
- }
183
- /**
184
- * Interface for the input parameters of the DynamicTool class.
185
- */
186
- export interface DynamicToolInput extends BaseDynamicToolInput {
187
- func: (input: string, runManager?: CallbackManagerForToolRun, config?: ToolRunnableConfig) => Promise<ToolReturnType>;
188
- }
189
- /**
190
- * Interface for the input parameters of the DynamicStructuredTool class.
191
- */
192
- export interface DynamicStructuredToolInput<T extends ZodObjectAny | Record<string, any> = ZodObjectAny> extends BaseDynamicToolInput {
193
- func: (input: BaseDynamicToolInput["responseFormat"] extends "content_and_artifact" ? ToolCall : T extends ZodObjectAny ? z.infer<T> : T, runManager?: CallbackManagerForToolRun, config?: RunnableConfig) => Promise<ToolReturnType>;
194
- schema: T extends ZodObjectAny ? T : T;
195
- }
196
89
  /**
197
90
  * A tool that can be created dynamically from a function, name, and description.
198
91
  */
@@ -218,20 +111,20 @@ export declare class DynamicTool extends Tool {
218
111
  * Schema can be passed as Zod or JSON schema. The tool will not validate
219
112
  * input if JSON schema is passed.
220
113
  */
221
- export declare class DynamicStructuredTool<T extends ZodObjectAny | Record<string, any> = ZodObjectAny> extends StructuredTool<T extends ZodObjectAny ? T : ZodObjectAny> {
114
+ export declare class DynamicStructuredTool<SchemaT extends ToolInputSchemaBase = ZodObjectAny, SchemaOutputT = ToolInputSchemaOutputType<SchemaT>, SchemaInputT = ToolInputSchemaInputType<SchemaT>> extends StructuredTool<SchemaT, SchemaOutputT, SchemaInputT> {
222
115
  static lc_name(): string;
223
116
  name: string;
224
117
  description: string;
225
- func: DynamicStructuredToolInput<T>["func"];
226
- schema: T extends ZodObjectAny ? T : ZodObjectAny;
227
- constructor(fields: DynamicStructuredToolInput<T>);
118
+ func: DynamicStructuredToolInput<SchemaT, SchemaOutputT>["func"];
119
+ schema: SchemaT;
120
+ constructor(fields: DynamicStructuredToolInput<SchemaT, SchemaOutputT>);
228
121
  /**
229
122
  * @deprecated Use .invoke() instead. Will be removed in 0.3.0.
230
123
  */
231
- call(arg: (T extends ZodObjectAny ? z.output<T> : T) | ToolCall, configArg?: RunnableConfig | Callbacks,
124
+ call(arg: StructuredToolCallInput<SchemaT, SchemaInputT>, configArg?: RunnableConfig | Callbacks,
232
125
  /** @deprecated */
233
126
  tags?: string[]): Promise<ToolReturnType>;
234
- protected _call(arg: (T extends ZodObjectAny ? z.output<T> : T) | ToolCall, runManager?: CallbackManagerForToolRun, parentConfig?: RunnableConfig): Promise<ToolReturnType>;
127
+ protected _call(arg: Parameters<DynamicStructuredToolInput<SchemaT, SchemaOutputT>["func"]>[0], runManager?: CallbackManagerForToolRun, parentConfig?: RunnableConfig): Promise<ToolReturnType>;
235
128
  }
236
129
  /**
237
130
  * Abstract base class for toolkits in LangChain. Toolkits are collections
@@ -245,10 +138,10 @@ export declare abstract class BaseToolkit {
245
138
  /**
246
139
  * Parameters for the tool function.
247
140
  * Schema can be provided as Zod or JSON schema.
248
- * If you pass JSON schema, tool inputs will not be validated.
249
- * @template {ZodObjectAny | z.ZodString | Record<string, any> = ZodObjectAny} RunInput The input schema for the tool. Either any Zod object, a Zod string, or JSON schema.
141
+ * Both schema types will be validated.
142
+ * @template {ZodObjectAny | z.ZodString | JSONSchema = ZodObjectAny} RunInput The input schema for the tool. Either any Zod object, a Zod string, or JSON schema.
250
143
  */
251
- interface ToolWrapperParams<RunInput extends ZodObjectAny | z.ZodString | Record<string, any> = ZodObjectAny> extends ToolParams {
144
+ interface ToolWrapperParams<RunInput extends ZodObjectAny | z.ZodString | JSONSchema = ZodObjectAny> extends ToolParams {
252
145
  /**
253
146
  * The name of the tool. If using with an LLM, this
254
147
  * will be passed as the tool name.
@@ -286,20 +179,19 @@ interface ToolWrapperParams<RunInput extends ZodObjectAny | z.ZodString | Record
286
179
  /**
287
180
  * Creates a new StructuredTool instance with the provided function, name, description, and schema.
288
181
  *
289
- * Schema can be provided as Zod or JSON schema.
290
- * If you pass JSON schema, tool inputs will not be validated.
182
+ * Schema can be provided as Zod or JSON schema, and both will be validated.
291
183
  *
292
184
  * @function
293
- * @template {ZodObjectAny | z.ZodString | Record<string, any> = ZodObjectAny} T The input schema for the tool. Either any Zod object, a Zod string, or JSON schema instance.
185
+ * @template {ZodObjectAny | z.ZodString | JSONSchema = ZodObjectAny} SchemaT The input schema for the tool. Either any Zod object, a Zod string, or JSON schema instance.
294
186
  *
295
- * @param {RunnableFunc<z.output<T>, ToolReturnType>} func - The function to invoke when the tool is called.
296
- * @param {ToolWrapperParams<T>} fields - An object containing the following properties:
187
+ * @param {RunnableFunc<z.output<SchemaT>, ToolReturnType>} func - The function to invoke when the tool is called.
188
+ * @param {ToolWrapperParams<SchemaT>} fields - An object containing the following properties:
297
189
  * @param {string} fields.name The name of the tool.
298
190
  * @param {string | undefined} fields.description The description of the tool. Defaults to either the description on the Zod schema, or `${fields.name} tool`.
299
191
  * @param {ZodObjectAny | z.ZodString | undefined} fields.schema The Zod schema defining the input for the tool. If undefined, it will default to a Zod string schema.
300
192
  *
301
- * @returns {DynamicStructuredTool<T>} A new StructuredTool instance.
193
+ * @returns {DynamicStructuredTool<SchemaT>} A new StructuredTool instance.
302
194
  */
303
- export declare function tool<T extends z.ZodString>(func: RunnableFunc<z.output<T>, ToolReturnType, ToolRunnableConfig>, fields: ToolWrapperParams<T>): DynamicTool;
304
- export declare function tool<T extends ZodObjectAny>(func: RunnableFunc<z.output<T>, ToolReturnType, ToolRunnableConfig>, fields: ToolWrapperParams<T>): DynamicStructuredTool<T>;
305
- export declare function tool<T extends Record<string, any>>(func: RunnableFunc<T, ToolReturnType, ToolRunnableConfig>, fields: ToolWrapperParams<T>): DynamicStructuredTool<T>;
195
+ export declare function tool<SchemaT extends z.ZodString>(func: RunnableFunc<SchemaT extends z.ZodString ? z.output<SchemaT> : string, ToolReturnType, ToolRunnableConfig>, fields: ToolWrapperParams<SchemaT>): DynamicTool;
196
+ export declare function tool<SchemaT extends ZodObjectAny, SchemaOutputT = z.output<SchemaT>, SchemaInputT = z.input<SchemaT>>(func: RunnableFunc<SchemaOutputT, ToolReturnType, ToolRunnableConfig>, fields: ToolWrapperParams<SchemaT>): DynamicStructuredTool<SchemaT, SchemaOutputT, SchemaInputT>;
197
+ export declare function tool<SchemaT extends JSONSchema, SchemaOutputT = ToolInputSchemaOutputType<SchemaT>, SchemaInputT = ToolInputSchemaInputType<SchemaT>>(func: RunnableFunc<Parameters<DynamicStructuredToolInput<SchemaT>["func"]>[0], ToolReturnType, ToolRunnableConfig>, fields: ToolWrapperParams<SchemaT>): DynamicStructuredTool<SchemaT, SchemaOutputT, SchemaInputT>;
@@ -1,11 +1,13 @@
1
1
  import { z } from "zod";
2
+ import { validate, } from "@cfworker/json-schema";
2
3
  import { CallbackManager, parseCallbackConfigArg, } from "../callbacks/manager.js";
3
- import { BaseLangChain, } from "../language_models/base.js";
4
+ import { BaseLangChain } from "../language_models/base.js";
4
5
  import { ensureConfig, patchConfig, pickRunnableConfigKeys, } from "../runnables/config.js";
5
6
  import { isDirectToolOutput, ToolMessage } from "../messages/tool.js";
6
7
  import { AsyncLocalStorageProviderSingleton } from "../singletons/index.js";
7
8
  import { _isToolCall, ToolInputParsingException } from "./utils.js";
8
9
  import { isZodSchema } from "../utils/types/is_zod_schema.js";
10
+ import { validatesOnlyStrings } from "../utils/json_schema.js";
9
11
  export { ToolInputParsingException };
10
12
  /**
11
13
  * Base class for Tools that accept input of any shape defined by a Zod schema.
@@ -94,17 +96,30 @@ export class StructuredTool extends BaseLangChain {
94
96
  async call(arg, configArg,
95
97
  /** @deprecated */
96
98
  tags) {
97
- let parsed;
98
- try {
99
- parsed = await this.schema.parseAsync(arg);
100
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
99
+ let parsed = arg;
100
+ if (isZodSchema(this.schema)) {
101
+ try {
102
+ parsed = await this.schema.parseAsync(arg);
103
+ }
104
+ catch (e) {
105
+ let message = `Received tool input did not match expected schema`;
106
+ if (this.verboseParsingErrors) {
107
+ message = `${message}\nDetails: ${e.message}`;
108
+ }
109
+ throw new ToolInputParsingException(message, JSON.stringify(arg));
110
+ }
101
111
  }
102
- catch (e) {
103
- let message = `Received tool input did not match expected schema`;
104
- if (this.verboseParsingErrors) {
105
- message = `${message}\nDetails: ${e.message}`;
112
+ else {
113
+ const result = validate(arg, this.schema);
114
+ if (!result.valid) {
115
+ let message = `Received tool input did not match expected schema`;
116
+ if (this.verboseParsingErrors) {
117
+ message = `${message}\nDetails: ${result.errors
118
+ .map((e) => `${e.keywordLocation}: ${e.error}`)
119
+ .join("\n")}`;
120
+ }
121
+ throw new ToolInputParsingException(message, JSON.stringify(arg));
106
122
  }
107
- throw new ToolInputParsingException(message, JSON.stringify(arg));
108
123
  }
109
124
  const config = parseCallbackConfigArg(configArg);
110
125
  const callbackManager_ = CallbackManager.configure(config.callbacks, this.callbacks, config.tags || tags, this.tags, config.metadata, this.metadata, { verbose: this.verbose });
@@ -113,7 +128,6 @@ export class StructuredTool extends BaseLangChain {
113
128
  let result;
114
129
  try {
115
130
  result = await this._call(parsed, runManager, config);
116
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
117
131
  }
118
132
  catch (e) {
119
133
  await runManager?.handleToolError(e);
@@ -265,7 +279,7 @@ export class DynamicStructuredTool extends StructuredTool {
265
279
  this.description = fields.description;
266
280
  this.func = fields.func;
267
281
  this.returnDirect = fields.returnDirect ?? this.returnDirect;
268
- this.schema = (isZodSchema(fields.schema) ? fields.schema : z.object({}).passthrough());
282
+ this.schema = fields.schema;
269
283
  }
270
284
  /**
271
285
  * @deprecated Use .invoke() instead. Will be removed in 0.3.0.
@@ -280,7 +294,6 @@ export class DynamicStructuredTool extends StructuredTool {
280
294
  return super.call(arg, config, tags);
281
295
  }
282
296
  _call(arg, runManager, parentConfig) {
283
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
284
297
  return this.func(arg, runManager, parentConfig);
285
298
  }
286
299
  }
@@ -295,10 +308,12 @@ export class BaseToolkit {
295
308
  }
296
309
  }
297
310
  export function tool(func, fields) {
298
- // If the schema is not provided, or it's a string schema, create a DynamicTool
299
- if (!fields.schema ||
300
- (isZodSchema(fields.schema) &&
301
- (!("shape" in fields.schema) || !fields.schema.shape))) {
311
+ const isShapelessZodSchema = fields.schema &&
312
+ isZodSchema(fields.schema) &&
313
+ (!("shape" in fields.schema) || !fields.schema.shape);
314
+ const isStringJSONSchema = validatesOnlyStrings(fields.schema);
315
+ // If the schema is not provided, or it's a shapeless schema (e.g. a ZodString), create a DynamicTool
316
+ if (!fields.schema || isShapelessZodSchema || isStringJSONSchema) {
302
317
  return new DynamicTool({
303
318
  ...fields,
304
319
  description: fields.description ??
@@ -323,13 +338,14 @@ export function tool(func, fields) {
323
338
  },
324
339
  });
325
340
  }
326
- const description = fields.description ?? fields.schema.description ?? `${fields.name} tool`;
341
+ const schema = fields.schema;
342
+ const description = fields.description ??
343
+ fields.schema.description ??
344
+ `${fields.name} tool`;
327
345
  return new DynamicStructuredTool({
328
346
  ...fields,
329
347
  description,
330
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
331
- schema: fields.schema,
332
- // TODO: Consider moving into DynamicStructuredTool constructor
348
+ schema,
333
349
  func: async (input, runManager, config) => {
334
350
  return new Promise((resolve, reject) => {
335
351
  const childConfig = patchConfig(config, {
@@ -337,8 +353,6 @@ export function tool(func, fields) {
337
353
  });
338
354
  void AsyncLocalStorageProviderSingleton.runWithConfig(pickRunnableConfigKeys(childConfig), async () => {
339
355
  try {
340
- // TS doesn't restrict the type here based on the guard above
341
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
342
356
  resolve(func(input, childConfig));
343
357
  }
344
358
  catch (e) {
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isLangChainTool = exports.isStructuredToolParams = exports.isRunnableToolLike = exports.isStructuredTool = void 0;
4
+ const base_js_1 = require("../runnables/base.cjs");
5
+ const is_zod_schema_js_1 = require("../utils/types/is_zod_schema.cjs");
6
+ /**
7
+ * Confirm whether the inputted tool is an instance of `StructuredToolInterface`.
8
+ *
9
+ * @param {StructuredToolInterface | JSONSchema | undefined} tool The tool to check if it is an instance of `StructuredToolInterface`.
10
+ * @returns {tool is StructuredToolInterface} Whether the inputted tool is an instance of `StructuredToolInterface`.
11
+ */
12
+ function isStructuredTool(tool) {
13
+ return (tool !== undefined &&
14
+ Array.isArray(tool.lc_namespace));
15
+ }
16
+ exports.isStructuredTool = isStructuredTool;
17
+ /**
18
+ * Confirm whether the inputted tool is an instance of `RunnableToolLike`.
19
+ *
20
+ * @param {unknown | undefined} tool The tool to check if it is an instance of `RunnableToolLike`.
21
+ * @returns {tool is RunnableToolLike} Whether the inputted tool is an instance of `RunnableToolLike`.
22
+ */
23
+ function isRunnableToolLike(tool) {
24
+ return (tool !== undefined &&
25
+ base_js_1.Runnable.isRunnable(tool) &&
26
+ "lc_name" in tool.constructor &&
27
+ typeof tool.constructor.lc_name === "function" &&
28
+ tool.constructor.lc_name() === "RunnableToolLike");
29
+ }
30
+ exports.isRunnableToolLike = isRunnableToolLike;
31
+ /**
32
+ * Confirm whether or not the tool contains the necessary properties to be considered a `StructuredToolParams`.
33
+ *
34
+ * @param {unknown | undefined} tool The object to check if it is a `StructuredToolParams`.
35
+ * @returns {tool is StructuredToolParams} Whether the inputted object is a `StructuredToolParams`.
36
+ */
37
+ function isStructuredToolParams(tool) {
38
+ return (!!tool &&
39
+ typeof tool === "object" &&
40
+ "name" in tool &&
41
+ "schema" in tool &&
42
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
+ (0, is_zod_schema_js_1.isZodSchema)(tool.schema));
44
+ }
45
+ exports.isStructuredToolParams = isStructuredToolParams;
46
+ /**
47
+ * Whether or not the tool is one of StructuredTool, RunnableTool or StructuredToolParams.
48
+ * It returns `is StructuredToolParams` since that is the most minimal interface of the three,
49
+ * while still containing the necessary properties to be passed to a LLM for tool calling.
50
+ *
51
+ * @param {unknown | undefined} tool The tool to check if it is a LangChain tool.
52
+ * @returns {tool is StructuredToolParams} Whether the inputted tool is a LangChain tool.
53
+ */
54
+ function isLangChainTool(tool) {
55
+ return (isStructuredToolParams(tool) ||
56
+ isRunnableToolLike(tool) ||
57
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
58
+ isStructuredTool(tool));
59
+ }
60
+ exports.isLangChainTool = isLangChainTool;