@langchain/core 0.2.15 → 0.2.17

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.
Files changed (103) hide show
  1. package/caches.cjs +1 -1
  2. package/caches.d.cts +1 -1
  3. package/caches.d.ts +1 -1
  4. package/caches.js +1 -1
  5. package/callbacks/dispatch/web.cjs +1 -0
  6. package/callbacks/dispatch/web.d.cts +1 -0
  7. package/callbacks/dispatch/web.d.ts +1 -0
  8. package/callbacks/dispatch/web.js +1 -0
  9. package/callbacks/dispatch.cjs +1 -0
  10. package/callbacks/dispatch.d.cts +1 -0
  11. package/callbacks/dispatch.d.ts +1 -0
  12. package/callbacks/dispatch.js +1 -0
  13. package/dist/{caches.cjs → caches/base.cjs} +6 -6
  14. package/dist/{caches.d.ts → caches/base.d.ts} +7 -7
  15. package/dist/{caches.js → caches/base.js} +6 -6
  16. package/dist/caches/tests/in_memory_cache.test.d.ts +1 -0
  17. package/dist/caches/tests/in_memory_cache.test.js +33 -0
  18. package/dist/callbacks/base.cjs +8 -0
  19. package/dist/callbacks/base.d.ts +16 -10
  20. package/dist/callbacks/base.js +8 -0
  21. package/dist/callbacks/dispatch/index.cjs +49 -0
  22. package/dist/callbacks/dispatch/index.d.ts +35 -0
  23. package/dist/callbacks/dispatch/index.js +45 -0
  24. package/dist/callbacks/dispatch/web.cjs +61 -0
  25. package/dist/callbacks/dispatch/web.d.ts +32 -0
  26. package/dist/callbacks/dispatch/web.js +57 -0
  27. package/dist/callbacks/manager.cjs +20 -0
  28. package/dist/callbacks/manager.d.ts +2 -1
  29. package/dist/callbacks/manager.js +20 -0
  30. package/dist/language_models/base.cjs +4 -4
  31. package/dist/language_models/base.d.ts +2 -2
  32. package/dist/language_models/base.js +1 -1
  33. package/dist/language_models/chat_models.d.ts +22 -5
  34. package/dist/language_models/llms.d.ts +1 -1
  35. package/dist/language_models/tests/chat_models.test.js +33 -0
  36. package/dist/load/import_map.cjs +2 -2
  37. package/dist/load/import_map.d.ts +2 -2
  38. package/dist/load/import_map.js +2 -2
  39. package/dist/messages/ai.cjs +19 -0
  40. package/dist/messages/ai.d.ts +2 -0
  41. package/dist/messages/ai.js +19 -0
  42. package/dist/messages/base.cjs +95 -5
  43. package/dist/messages/base.d.ts +5 -1
  44. package/dist/messages/base.js +93 -4
  45. package/dist/messages/chat.cjs +12 -0
  46. package/dist/messages/chat.d.ts +2 -0
  47. package/dist/messages/chat.js +12 -0
  48. package/dist/messages/index.cjs +1 -0
  49. package/dist/messages/index.d.ts +2 -1
  50. package/dist/messages/index.js +1 -0
  51. package/dist/messages/modifier.cjs +35 -0
  52. package/dist/messages/modifier.d.ts +19 -0
  53. package/dist/messages/modifier.js +31 -0
  54. package/dist/messages/tests/base_message.test.js +134 -2
  55. package/dist/messages/tests/message_utils.test.js +54 -2
  56. package/dist/messages/tool.cjs +45 -0
  57. package/dist/messages/tool.d.ts +29 -0
  58. package/dist/messages/tool.js +46 -1
  59. package/dist/messages/transformers.cjs +6 -0
  60. package/dist/messages/transformers.d.ts +3 -2
  61. package/dist/messages/transformers.js +6 -0
  62. package/dist/messages/utils.cjs +5 -1
  63. package/dist/messages/utils.js +5 -1
  64. package/dist/output_parsers/openai_tools/json_output_tools_parsers.cjs +2 -0
  65. package/dist/output_parsers/openai_tools/json_output_tools_parsers.js +2 -0
  66. package/dist/runnables/base.cjs +104 -1
  67. package/dist/runnables/base.d.ts +50 -0
  68. package/dist/runnables/base.js +101 -0
  69. package/dist/runnables/index.cjs +2 -1
  70. package/dist/runnables/index.d.ts +1 -1
  71. package/dist/runnables/index.js +1 -1
  72. package/dist/runnables/tests/runnable_stream_events.test.js +1 -1
  73. package/dist/runnables/tests/runnable_stream_events_v2.test.js +106 -1
  74. package/dist/runnables/tests/runnable_tools.test.d.ts +1 -0
  75. package/dist/runnables/tests/runnable_tools.test.js +149 -0
  76. package/dist/{tools.cjs → tools/index.cjs} +135 -47
  77. package/dist/{tools.d.ts → tools/index.d.ts} +76 -47
  78. package/dist/{tools.js → tools/index.js} +134 -45
  79. package/dist/tools/tests/tools.test.d.ts +1 -0
  80. package/dist/tools/tests/tools.test.js +85 -0
  81. package/dist/tools/utils.cjs +28 -0
  82. package/dist/tools/utils.d.ts +11 -0
  83. package/dist/tools/utils.js +23 -0
  84. package/dist/tracers/base.cjs +1 -0
  85. package/dist/tracers/base.d.ts +1 -1
  86. package/dist/tracers/base.js +1 -0
  87. package/dist/tracers/event_stream.cjs +15 -0
  88. package/dist/tracers/event_stream.d.ts +1 -0
  89. package/dist/tracers/event_stream.js +15 -0
  90. package/dist/types/zod.cjs +2 -0
  91. package/dist/types/zod.d.ts +2 -0
  92. package/dist/types/zod.js +1 -0
  93. package/dist/utils/function_calling.cjs +38 -10
  94. package/dist/utils/function_calling.d.ts +32 -11
  95. package/dist/utils/function_calling.js +36 -9
  96. package/dist/utils/testing/index.cjs +10 -3
  97. package/dist/utils/testing/index.d.ts +1 -1
  98. package/dist/utils/testing/index.js +9 -2
  99. package/package.json +28 -1
  100. package/tools.cjs +1 -1
  101. package/tools.d.cts +1 -1
  102. package/tools.d.ts +1 -1
  103. package/tools.js +1 -1
@@ -1,24 +1,32 @@
1
1
  import { z } from "zod";
2
- import { CallbackManagerForToolRun, Callbacks } from "./callbacks/manager.js";
3
- import { BaseLangChain, type BaseLangChainParams } from "./language_models/base.js";
4
- import { type RunnableConfig } from "./runnables/config.js";
5
- import type { RunnableFunc, RunnableInterface } from "./runnables/base.js";
6
- type ZodAny = z.ZodObject<any, any, any, any>;
2
+ import { CallbackManagerForToolRun, Callbacks } from "../callbacks/manager.js";
3
+ import { BaseLangChain, type BaseLangChainParams } from "../language_models/base.js";
4
+ import { type RunnableConfig } from "../runnables/config.js";
5
+ import type { RunnableFunc, RunnableInterface } from "../runnables/base.js";
6
+ import { ToolCall } from "../messages/tool.js";
7
+ import { ZodObjectAny } from "../types/zod.js";
8
+ import { MessageContent } from "../messages/base.js";
9
+ import { ToolInputParsingException } from "./utils.js";
10
+ export { ToolInputParsingException };
11
+ export type ResponseFormat = "content" | "content_and_artifact" | string;
12
+ type ToolReturnType = any;
13
+ export type ContentAndArtifact = [MessageContent, any];
7
14
  /**
8
15
  * Parameters for the Tool classes.
9
16
  */
10
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;
11
28
  }
12
- /**
13
- * Custom error class used to handle exceptions related to tool input parsing.
14
- * It extends the built-in `Error` class and adds an optional `output`
15
- * property that can hold the output that caused the exception.
16
- */
17
- export declare class ToolInputParsingException extends Error {
18
- output?: string;
19
- constructor(message: string, output?: string);
20
- }
21
- export interface StructuredToolInterface<T extends ZodAny = ZodAny> extends RunnableInterface<(z.output<T> extends string ? string : never) | z.input<T>, string> {
29
+ export interface StructuredToolInterface<T extends ZodObjectAny = ZodObjectAny> extends RunnableInterface<(z.output<T> extends string ? string : never) | z.input<T> | ToolCall, ToolReturnType> {
22
30
  lc_namespace: string[];
23
31
  schema: T | z.ZodEffects<T>;
24
32
  /**
@@ -32,9 +40,9 @@ export interface StructuredToolInterface<T extends ZodAny = ZodAny> extends Runn
32
40
  * @param tags Optional tags for the tool.
33
41
  * @returns A Promise that resolves with a string.
34
42
  */
35
- call(arg: (z.output<T> extends string ? string : never) | z.input<T>, configArg?: Callbacks | RunnableConfig,
43
+ call(arg: (z.output<T> extends string ? string : never) | z.input<T> | ToolCall, configArg?: Callbacks | RunnableConfig,
36
44
  /** @deprecated */
37
- tags?: string[]): Promise<string>;
45
+ tags?: string[]): Promise<ToolReturnType>;
38
46
  name: string;
39
47
  description: string;
40
48
  returnDirect: boolean;
@@ -42,18 +50,31 @@ export interface StructuredToolInterface<T extends ZodAny = ZodAny> extends Runn
42
50
  /**
43
51
  * Base class for Tools that accept input of any shape defined by a Zod schema.
44
52
  */
45
- export declare abstract class StructuredTool<T extends ZodAny = ZodAny> extends BaseLangChain<(z.output<T> extends string ? string : never) | z.input<T>, string> {
53
+ export declare abstract class StructuredTool<T extends ZodObjectAny = ZodObjectAny> extends BaseLangChain<(z.output<T> extends string ? string : never) | z.input<T> | ToolCall, ToolReturnType> {
54
+ abstract name: string;
55
+ abstract description: string;
46
56
  abstract schema: T | z.ZodEffects<T>;
57
+ returnDirect: boolean;
47
58
  get lc_namespace(): string[];
59
+ /**
60
+ * The tool response format.
61
+ *
62
+ * If "content" then the output of the tool is interpreted as the contents of a
63
+ * ToolMessage. If "content_and_artifact" then the output is expected to be a
64
+ * two-tuple corresponding to the (content, artifact) of a ToolMessage.
65
+ *
66
+ * @default "content"
67
+ */
68
+ responseFormat?: ResponseFormat;
48
69
  constructor(fields?: ToolParams);
49
- protected abstract _call(arg: z.output<T>, runManager?: CallbackManagerForToolRun, config?: RunnableConfig): Promise<string>;
70
+ protected abstract _call(arg: z.output<T>, runManager?: CallbackManagerForToolRun, parentConfig?: RunnableConfig): Promise<ToolReturnType>;
50
71
  /**
51
72
  * Invokes the tool with the provided input and configuration.
52
73
  * @param input The input for the tool.
53
74
  * @param config Optional configuration for the tool.
54
75
  * @returns A Promise that resolves with a string.
55
76
  */
56
- invoke(input: (z.output<T> extends string ? string : never) | z.input<T>, config?: RunnableConfig): Promise<string>;
77
+ invoke(input: (z.output<T> extends string ? string : never) | z.input<T> | ToolCall, config?: RunnableConfig): Promise<ToolReturnType>;
57
78
  /**
58
79
  * @deprecated Use .invoke() instead. Will be removed in 0.3.0.
59
80
  *
@@ -65,14 +86,11 @@ export declare abstract class StructuredTool<T extends ZodAny = ZodAny> extends
65
86
  * @param tags Optional tags for the tool.
66
87
  * @returns A Promise that resolves with a string.
67
88
  */
68
- call(arg: (z.output<T> extends string ? string : never) | z.input<T>, configArg?: Callbacks | RunnableConfig,
89
+ call(arg: (z.output<T> extends string ? string : never) | z.input<T> | ToolCall, configArg?: Callbacks | RunnableConfig,
69
90
  /** @deprecated */
70
- tags?: string[]): Promise<string>;
71
- abstract name: string;
72
- abstract description: string;
73
- returnDirect: boolean;
91
+ tags?: string[]): Promise<ToolReturnType>;
74
92
  }
75
- export interface ToolInterface extends StructuredToolInterface {
93
+ export interface ToolInterface<T extends ZodObjectAny = ZodObjectAny> extends StructuredToolInterface<T> {
76
94
  /**
77
95
  * @deprecated Use .invoke() instead. Will be removed in 0.3.0.
78
96
  *
@@ -82,12 +100,12 @@ export interface ToolInterface extends StructuredToolInterface {
82
100
  * @param callbacks Optional callbacks for the tool.
83
101
  * @returns A Promise that resolves with a string.
84
102
  */
85
- call(arg: string | undefined | z.input<this["schema"]>, callbacks?: Callbacks | RunnableConfig): Promise<string>;
103
+ call(arg: string | undefined | z.input<this["schema"]> | ToolCall, callbacks?: Callbacks | RunnableConfig): Promise<ToolReturnType>;
86
104
  }
87
105
  /**
88
106
  * Base class for Tools that accept input as a string.
89
107
  */
90
- export declare abstract class Tool extends StructuredTool {
108
+ export declare abstract class Tool extends StructuredTool<ZodObjectAny> {
91
109
  schema: z.ZodEffects<z.ZodObject<{
92
110
  input: z.ZodOptional<z.ZodString>;
93
111
  }, "strip", z.ZodTypeAny, {
@@ -107,7 +125,7 @@ export declare abstract class Tool extends StructuredTool {
107
125
  * @param callbacks Optional callbacks for the tool.
108
126
  * @returns A Promise that resolves with a string.
109
127
  */
110
- call(arg: string | undefined | z.input<this["schema"]>, callbacks?: Callbacks | RunnableConfig): Promise<string>;
128
+ call(arg: string | undefined | z.input<this["schema"]> | ToolCall, callbacks?: Callbacks | RunnableConfig): Promise<ToolReturnType>;
111
129
  }
112
130
  export interface BaseDynamicToolInput extends ToolParams {
113
131
  name: string;
@@ -118,13 +136,13 @@ export interface BaseDynamicToolInput extends ToolParams {
118
136
  * Interface for the input parameters of the DynamicTool class.
119
137
  */
120
138
  export interface DynamicToolInput extends BaseDynamicToolInput {
121
- func: (input: string, runManager?: CallbackManagerForToolRun, config?: RunnableConfig) => Promise<string>;
139
+ func: (input: string, runManager?: CallbackManagerForToolRun, config?: RunnableConfig) => Promise<ToolReturnType>;
122
140
  }
123
141
  /**
124
142
  * Interface for the input parameters of the DynamicStructuredTool class.
125
143
  */
126
- export interface DynamicStructuredToolInput<T extends ZodAny = ZodAny> extends BaseDynamicToolInput {
127
- func: (input: z.infer<T>, runManager?: CallbackManagerForToolRun, config?: RunnableConfig) => Promise<string>;
144
+ export interface DynamicStructuredToolInput<T extends ZodObjectAny = ZodObjectAny> extends BaseDynamicToolInput {
145
+ func: (input: BaseDynamicToolInput["responseFormat"] extends "content_and_artifact" ? ToolCall : z.infer<T>, runManager?: CallbackManagerForToolRun, config?: RunnableConfig) => Promise<ToolReturnType>;
128
146
  schema: T;
129
147
  }
130
148
  /**
@@ -139,9 +157,9 @@ export declare class DynamicTool extends Tool {
139
157
  /**
140
158
  * @deprecated Use .invoke() instead. Will be removed in 0.3.0.
141
159
  */
142
- call(arg: string | undefined | z.input<this["schema"]>, configArg?: RunnableConfig | Callbacks): Promise<string>;
160
+ call(arg: string | undefined | z.input<this["schema"]> | ToolCall, configArg?: RunnableConfig | Callbacks): Promise<ToolReturnType>;
143
161
  /** @ignore */
144
- _call(input: string, runManager?: CallbackManagerForToolRun, config?: RunnableConfig): Promise<string>;
162
+ _call(input: string, runManager?: CallbackManagerForToolRun, parentConfig?: RunnableConfig): Promise<ToolReturnType>;
145
163
  }
146
164
  /**
147
165
  * A tool that can be created dynamically from a function, name, and
@@ -149,7 +167,7 @@ export declare class DynamicTool extends Tool {
149
167
  * StructuredTool class and overrides the _call method to execute the
150
168
  * provided function when the tool is called.
151
169
  */
152
- export declare class DynamicStructuredTool<T extends ZodAny = ZodAny> extends StructuredTool<T> {
170
+ export declare class DynamicStructuredTool<T extends ZodObjectAny = ZodObjectAny> extends StructuredTool<T> {
153
171
  static lc_name(): string;
154
172
  name: string;
155
173
  description: string;
@@ -159,10 +177,10 @@ export declare class DynamicStructuredTool<T extends ZodAny = ZodAny> extends St
159
177
  /**
160
178
  * @deprecated Use .invoke() instead. Will be removed in 0.3.0.
161
179
  */
162
- call(arg: z.output<T>, configArg?: RunnableConfig | Callbacks,
180
+ call(arg: z.output<T> | ToolCall, configArg?: RunnableConfig | Callbacks,
163
181
  /** @deprecated */
164
- tags?: string[]): Promise<string>;
165
- protected _call(arg: z.output<T>, runManager?: CallbackManagerForToolRun, config?: RunnableConfig): Promise<string>;
182
+ tags?: string[]): Promise<ToolReturnType>;
183
+ protected _call(arg: z.output<T> | ToolCall, runManager?: CallbackManagerForToolRun, parentConfig?: RunnableConfig): Promise<ToolReturnType>;
166
184
  }
167
185
  /**
168
186
  * Abstract base class for toolkits in LangChain. Toolkits are collections
@@ -175,9 +193,9 @@ export declare abstract class BaseToolkit {
175
193
  }
176
194
  /**
177
195
  * Parameters for the tool function.
178
- * @template {ZodAny} RunInput The input schema for the tool.
196
+ * @template {ZodObjectAny | z.ZodString = ZodObjectAny} RunInput The input schema for the tool. Either any Zod object, or a Zod string.
179
197
  */
180
- interface ToolWrapperParams<RunInput extends ZodAny = ZodAny> extends ToolParams {
198
+ interface ToolWrapperParams<RunInput extends ZodObjectAny | z.ZodString = ZodObjectAny> extends ToolParams {
181
199
  /**
182
200
  * The name of the tool. If using with an LLM, this
183
201
  * will be passed as the tool name.
@@ -194,19 +212,30 @@ interface ToolWrapperParams<RunInput extends ZodAny = ZodAny> extends ToolParams
194
212
  * for.
195
213
  */
196
214
  schema?: RunInput;
215
+ /**
216
+ * The tool response format.
217
+ *
218
+ * If "content" then the output of the tool is interpreted as the contents of a
219
+ * ToolMessage. If "content_and_artifact" then the output is expected to be a
220
+ * two-tuple corresponding to the (content, artifact) of a ToolMessage.
221
+ *
222
+ * @default "content"
223
+ */
224
+ responseFormat?: ResponseFormat;
197
225
  }
198
226
  /**
199
227
  * Creates a new StructuredTool instance with the provided function, name, description, and schema.
228
+ *
200
229
  * @function
201
- * @template {ZodAny} RunInput The input schema for the tool.
230
+ * @template {ZodObjectAny | z.ZodString = ZodObjectAny} T The input schema for the tool. Either any Zod object, or a Zod string.
202
231
  *
203
- * @param {RunnableFunc<RunInput, string>} func - The function to invoke when the tool is called.
204
- * @param fields - An object containing the following properties:
232
+ * @param {RunnableFunc<z.output<T>, ToolReturnType>} func - The function to invoke when the tool is called.
233
+ * @param {ToolWrapperParams<T>} fields - An object containing the following properties:
205
234
  * @param {string} fields.name The name of the tool.
206
235
  * @param {string | undefined} fields.description The description of the tool. Defaults to either the description on the Zod schema, or `${fields.name} tool`.
207
- * @param {z.ZodObject<any, any, any, any>} fields.schema The Zod schema defining the input for the tool.
236
+ * @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.
208
237
  *
209
- * @returns {StructuredTool<RunInput, string>} A new StructuredTool instance.
238
+ * @returns {DynamicStructuredTool<T>} A new StructuredTool instance.
210
239
  */
211
- export declare function tool<RunInput extends ZodAny = ZodAny>(func: RunnableFunc<z.infer<RunInput>, string>, fields: ToolWrapperParams<RunInput>): DynamicStructuredTool<RunInput>;
212
- export {};
240
+ export declare function tool<T extends z.ZodString = z.ZodString>(func: RunnableFunc<z.output<T>, ToolReturnType>, fields: ToolWrapperParams<T>): DynamicTool;
241
+ export declare function tool<T extends ZodObjectAny = ZodObjectAny>(func: RunnableFunc<z.output<T>, ToolReturnType>, fields: ToolWrapperParams<T>): DynamicStructuredTool<T>;
@@ -1,24 +1,11 @@
1
1
  import { z } from "zod";
2
- import { CallbackManager, parseCallbackConfigArg, } from "./callbacks/manager.js";
3
- import { BaseLangChain, } from "./language_models/base.js";
4
- import { ensureConfig } from "./runnables/config.js";
5
- /**
6
- * Custom error class used to handle exceptions related to tool input parsing.
7
- * It extends the built-in `Error` class and adds an optional `output`
8
- * property that can hold the output that caused the exception.
9
- */
10
- export class ToolInputParsingException extends Error {
11
- constructor(message, output) {
12
- super(message);
13
- Object.defineProperty(this, "output", {
14
- enumerable: true,
15
- configurable: true,
16
- writable: true,
17
- value: void 0
18
- });
19
- this.output = output;
20
- }
21
- }
2
+ import { CallbackManager, parseCallbackConfigArg, } from "../callbacks/manager.js";
3
+ import { BaseLangChain, } from "../language_models/base.js";
4
+ import { ensureConfig, patchConfig, } from "../runnables/config.js";
5
+ import { ToolMessage } from "../messages/tool.js";
6
+ import { AsyncLocalStorageProviderSingleton } from "../singletons/index.js";
7
+ import { _isToolCall, ToolInputParsingException } from "./utils.js";
8
+ export { ToolInputParsingException };
22
9
  /**
23
10
  * Base class for Tools that accept input of any shape defined by a Zod schema.
24
11
  */
@@ -34,6 +21,22 @@ export class StructuredTool extends BaseLangChain {
34
21
  writable: true,
35
22
  value: false
36
23
  });
24
+ /**
25
+ * The tool response format.
26
+ *
27
+ * If "content" then the output of the tool is interpreted as the contents of a
28
+ * ToolMessage. If "content_and_artifact" then the output is expected to be a
29
+ * two-tuple corresponding to the (content, artifact) of a ToolMessage.
30
+ *
31
+ * @default "content"
32
+ */
33
+ Object.defineProperty(this, "responseFormat", {
34
+ enumerable: true,
35
+ configurable: true,
36
+ writable: true,
37
+ value: "content"
38
+ });
39
+ this.responseFormat = fields?.responseFormat ?? this.responseFormat;
37
40
  }
38
41
  /**
39
42
  * Invokes the tool with the provided input and configuration.
@@ -42,7 +45,23 @@ export class StructuredTool extends BaseLangChain {
42
45
  * @returns A Promise that resolves with a string.
43
46
  */
44
47
  async invoke(input, config) {
45
- return this.call(input, ensureConfig(config));
48
+ let tool_call_id;
49
+ let toolInput;
50
+ if (_isToolCall(input)) {
51
+ tool_call_id = input.id;
52
+ toolInput = input.args;
53
+ }
54
+ else {
55
+ toolInput = input;
56
+ }
57
+ const ensuredConfig = ensureConfig(config);
58
+ return this.call(toolInput, {
59
+ ...ensuredConfig,
60
+ configurable: {
61
+ ...ensuredConfig.configurable,
62
+ tool_call_id,
63
+ },
64
+ });
46
65
  }
47
66
  /**
48
67
  * @deprecated Use .invoke() instead. Will be removed in 0.3.0.
@@ -77,8 +96,32 @@ export class StructuredTool extends BaseLangChain {
77
96
  await runManager?.handleToolError(e);
78
97
  throw e;
79
98
  }
80
- await runManager?.handleToolEnd(result);
81
- return result;
99
+ let content;
100
+ let artifact;
101
+ if (this.responseFormat === "content_and_artifact") {
102
+ if (Array.isArray(result) && result.length === 2) {
103
+ [content, artifact] = result;
104
+ }
105
+ else {
106
+ throw new Error(`Tool response format is "content_and_artifact" but the output was not a two-tuple.\nResult: ${JSON.stringify(result)}`);
107
+ }
108
+ }
109
+ else {
110
+ content = result;
111
+ }
112
+ let toolCallId;
113
+ if (config && "configurable" in config) {
114
+ toolCallId = config.configurable
115
+ .tool_call_id;
116
+ }
117
+ const formattedOutput = _formatToolOutput({
118
+ content,
119
+ artifact,
120
+ toolCallId,
121
+ name: this.name,
122
+ });
123
+ await runManager?.handleToolEnd(formattedOutput);
124
+ return formattedOutput;
82
125
  }
83
126
  }
84
127
  /**
@@ -152,8 +195,8 @@ export class DynamicTool extends Tool {
152
195
  return super.call(arg, config);
153
196
  }
154
197
  /** @ignore */
155
- async _call(input, runManager, config) {
156
- return this.func(input, runManager, config);
198
+ async _call(input, runManager, parentConfig) {
199
+ return this.func(input, runManager, parentConfig);
157
200
  }
158
201
  }
159
202
  /**
@@ -210,8 +253,8 @@ export class DynamicStructuredTool extends StructuredTool {
210
253
  }
211
254
  return super.call(arg, config, tags);
212
255
  }
213
- _call(arg, runManager, config) {
214
- return this.func(arg, runManager, config);
256
+ _call(arg, runManager, parentConfig) {
257
+ return this.func(arg, runManager, parentConfig);
215
258
  }
216
259
  }
217
260
  /**
@@ -224,27 +267,73 @@ export class BaseToolkit {
224
267
  return this.tools;
225
268
  }
226
269
  }
227
- /**
228
- * Creates a new StructuredTool instance with the provided function, name, description, and schema.
229
- * @function
230
- * @template {ZodAny} RunInput The input schema for the tool.
231
- *
232
- * @param {RunnableFunc<RunInput, string>} func - The function to invoke when the tool is called.
233
- * @param fields - An object containing the following properties:
234
- * @param {string} fields.name The name of the tool.
235
- * @param {string | undefined} fields.description The description of the tool. Defaults to either the description on the Zod schema, or `${fields.name} tool`.
236
- * @param {z.ZodObject<any, any, any, any>} fields.schema The Zod schema defining the input for the tool.
237
- *
238
- * @returns {StructuredTool<RunInput, string>} A new StructuredTool instance.
239
- */
240
270
  export function tool(func, fields) {
241
- const schema = fields.schema ??
242
- z.object({ input: z.string().optional() }).transform((obj) => obj.input);
243
- const description = fields.description ?? schema.description ?? `${fields.name} tool`;
271
+ // If the schema is not provided, or it's a string schema, create a DynamicTool
272
+ if (!fields.schema || !("shape" in fields.schema) || !fields.schema.shape) {
273
+ return new DynamicTool({
274
+ name: fields.name,
275
+ description: fields.description ??
276
+ fields.schema?.description ??
277
+ `${fields.name} tool`,
278
+ responseFormat: fields.responseFormat,
279
+ func,
280
+ });
281
+ }
282
+ const description = fields.description ?? fields.schema.description ?? `${fields.name} tool`;
244
283
  return new DynamicStructuredTool({
245
284
  name: fields.name,
246
285
  description,
247
- schema: schema,
248
- func: async (input, _runManager, config) => func(input, config),
286
+ schema: fields.schema,
287
+ // TODO: Consider moving into DynamicStructuredTool constructor
288
+ func: async (input, runManager, config) => {
289
+ return new Promise((resolve, reject) => {
290
+ const childConfig = patchConfig(config, {
291
+ callbacks: runManager?.getChild(),
292
+ });
293
+ void AsyncLocalStorageProviderSingleton.getInstance().run(childConfig, async () => {
294
+ try {
295
+ resolve(func(input, childConfig));
296
+ }
297
+ catch (e) {
298
+ reject(e);
299
+ }
300
+ });
301
+ });
302
+ },
303
+ responseFormat: fields.responseFormat,
249
304
  });
250
305
  }
306
+ function _formatToolOutput(params) {
307
+ const { content, artifact, toolCallId } = params;
308
+ if (toolCallId) {
309
+ if (typeof content === "string" ||
310
+ (Array.isArray(content) &&
311
+ content.every((item) => typeof item === "object"))) {
312
+ return new ToolMessage({
313
+ content,
314
+ artifact,
315
+ tool_call_id: toolCallId,
316
+ name: params.name,
317
+ });
318
+ }
319
+ else {
320
+ return new ToolMessage({
321
+ content: _stringify(content),
322
+ artifact,
323
+ tool_call_id: toolCallId,
324
+ name: params.name,
325
+ });
326
+ }
327
+ }
328
+ else {
329
+ return content;
330
+ }
331
+ }
332
+ function _stringify(content) {
333
+ try {
334
+ return JSON.stringify(content, null, 2);
335
+ }
336
+ catch (_noOp) {
337
+ return `${content}`;
338
+ }
339
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,85 @@
1
+ import { test, expect } from "@jest/globals";
2
+ import { z } from "zod";
3
+ import { tool } from "../index.js";
4
+ import { ToolMessage } from "../../messages/tool.js";
5
+ test("Tool should error if responseFormat is content_and_artifact but the function doesn't return a tuple", async () => {
6
+ const weatherSchema = z.object({
7
+ location: z.string(),
8
+ });
9
+ const weatherTool = tool((_) => {
10
+ return "str";
11
+ }, {
12
+ name: "weather",
13
+ schema: weatherSchema,
14
+ responseFormat: "content_and_artifact",
15
+ });
16
+ await expect(async () => {
17
+ await weatherTool.invoke({ location: "San Francisco" });
18
+ }).rejects.toThrow();
19
+ });
20
+ test("Tool works if responseFormat is content_and_artifact and returns a tuple", async () => {
21
+ const weatherSchema = z.object({
22
+ location: z.string(),
23
+ });
24
+ const weatherTool = tool((input) => {
25
+ return ["msg_content", input];
26
+ }, {
27
+ name: "weather",
28
+ schema: weatherSchema,
29
+ responseFormat: "content_and_artifact",
30
+ });
31
+ const toolResult = await weatherTool.invoke({ location: "San Francisco" });
32
+ expect(toolResult).not.toBeInstanceOf(ToolMessage);
33
+ expect(toolResult).toBe("msg_content");
34
+ });
35
+ test("Does not return tool message if responseFormat is content_and_artifact and returns a tuple and a tool call with no id is passed in", async () => {
36
+ const weatherSchema = z.object({
37
+ location: z.string(),
38
+ });
39
+ const weatherTool = tool((input) => {
40
+ return ["msg_content", input];
41
+ }, {
42
+ name: "weather",
43
+ schema: weatherSchema,
44
+ responseFormat: "content_and_artifact",
45
+ });
46
+ const toolResult = await weatherTool.invoke({
47
+ args: { location: "San Francisco" },
48
+ name: "weather",
49
+ type: "tool_call",
50
+ });
51
+ expect(toolResult).toBe("msg_content");
52
+ });
53
+ test("Returns tool message if responseFormat is content_and_artifact and returns a tuple and a tool call with id is passed in", async () => {
54
+ const weatherSchema = z.object({
55
+ location: z.string(),
56
+ });
57
+ const weatherTool = tool((input) => {
58
+ return ["msg_content", input];
59
+ }, {
60
+ name: "weather",
61
+ schema: weatherSchema,
62
+ responseFormat: "content_and_artifact",
63
+ });
64
+ const toolResult = await weatherTool.invoke({
65
+ id: "testid",
66
+ args: { location: "San Francisco" },
67
+ name: "weather",
68
+ type: "tool_call",
69
+ });
70
+ expect(toolResult).toBeInstanceOf(ToolMessage);
71
+ expect(toolResult.content).toBe("msg_content");
72
+ expect(toolResult.artifact).toEqual({ location: "San Francisco" });
73
+ expect(toolResult.name).toBe("weather");
74
+ });
75
+ test("Tool can accept single string input", async () => {
76
+ const stringTool = tool((input) => {
77
+ return `${input}a`;
78
+ }, {
79
+ name: "string_tool",
80
+ description: "A tool that appends 'a' to the input string",
81
+ schema: z.string(),
82
+ });
83
+ const result = await stringTool.invoke("b");
84
+ expect(result).toBe("ba");
85
+ });
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ToolInputParsingException = exports._isToolCall = void 0;
4
+ function _isToolCall(toolCall) {
5
+ return !!(toolCall &&
6
+ typeof toolCall === "object" &&
7
+ "type" in toolCall &&
8
+ toolCall.type === "tool_call");
9
+ }
10
+ exports._isToolCall = _isToolCall;
11
+ /**
12
+ * Custom error class used to handle exceptions related to tool input parsing.
13
+ * It extends the built-in `Error` class and adds an optional `output`
14
+ * property that can hold the output that caused the exception.
15
+ */
16
+ class ToolInputParsingException extends Error {
17
+ constructor(message, output) {
18
+ super(message);
19
+ Object.defineProperty(this, "output", {
20
+ enumerable: true,
21
+ configurable: true,
22
+ writable: true,
23
+ value: void 0
24
+ });
25
+ this.output = output;
26
+ }
27
+ }
28
+ exports.ToolInputParsingException = ToolInputParsingException;
@@ -0,0 +1,11 @@
1
+ import { ToolCall } from "../messages/tool.js";
2
+ export declare function _isToolCall(toolCall?: unknown): toolCall is ToolCall;
3
+ /**
4
+ * Custom error class used to handle exceptions related to tool input parsing.
5
+ * It extends the built-in `Error` class and adds an optional `output`
6
+ * property that can hold the output that caused the exception.
7
+ */
8
+ export declare class ToolInputParsingException extends Error {
9
+ output?: string;
10
+ constructor(message: string, output?: string);
11
+ }
@@ -0,0 +1,23 @@
1
+ export function _isToolCall(toolCall) {
2
+ return !!(toolCall &&
3
+ typeof toolCall === "object" &&
4
+ "type" in toolCall &&
5
+ toolCall.type === "tool_call");
6
+ }
7
+ /**
8
+ * Custom error class used to handle exceptions related to tool input parsing.
9
+ * It extends the built-in `Error` class and adds an optional `output`
10
+ * property that can hold the output that caused the exception.
11
+ */
12
+ export class ToolInputParsingException extends Error {
13
+ constructor(message, output) {
14
+ super(message);
15
+ Object.defineProperty(this, "output", {
16
+ enumerable: true,
17
+ configurable: true,
18
+ writable: true,
19
+ value: void 0
20
+ });
21
+ this.output = output;
22
+ }
23
+ }
@@ -274,6 +274,7 @@ class BaseTracer extends base_js_1.BaseCallbackHandler {
274
274
  await this.onToolStart?.(run);
275
275
  return run;
276
276
  }
277
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
277
278
  async handleToolEnd(output, runId) {
278
279
  const run = this.runMap.get(runId);
279
280
  if (!run || run?.run_type !== "tool") {
@@ -46,7 +46,7 @@ export declare abstract class BaseTracer extends BaseCallbackHandler {
46
46
  inputs?: Record<string, unknown>;
47
47
  }): Promise<Run>;
48
48
  handleToolStart(tool: Serialized, input: string, runId: string, parentRunId?: string, tags?: string[], metadata?: KVMap, name?: string): Promise<Run>;
49
- handleToolEnd(output: string, runId: string): Promise<Run>;
49
+ handleToolEnd(output: any, runId: string): Promise<Run>;
50
50
  handleToolError(error: unknown, runId: string): Promise<Run>;
51
51
  handleAgentAction(action: AgentAction, runId: string): Promise<void>;
52
52
  handleAgentEnd(action: AgentFinish, runId: string): Promise<void>;
@@ -271,6 +271,7 @@ export class BaseTracer extends BaseCallbackHandler {
271
271
  await this.onToolStart?.(run);
272
272
  return run;
273
273
  }
274
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
274
275
  async handleToolEnd(output, runId) {
275
276
  const run = this.runMap.get(runId);
276
277
  if (!run || run?.run_type !== "tool") {
@@ -489,6 +489,21 @@ class EventStreamCallbackHandler extends base_js_1.BaseTracer {
489
489
  metadata: runInfo.metadata,
490
490
  }, runInfo);
491
491
  }
492
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
493
+ async handleCustomEvent(eventName, data, runId) {
494
+ const runInfo = this.runInfoMap.get(runId);
495
+ if (runInfo === undefined) {
496
+ throw new Error(`handleCustomEvent: Run ID ${runId} not found in run map.`);
497
+ }
498
+ await this.send({
499
+ event: "on_custom_event",
500
+ run_id: runId,
501
+ name: eventName,
502
+ tags: runInfo.tags,
503
+ metadata: runInfo.metadata,
504
+ data,
505
+ }, runInfo);
506
+ }
492
507
  async finish() {
493
508
  const pendingPromises = [...this.tappedPromises.values()];
494
509
  void Promise.all(pendingPromises).finally(() => {