@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
@@ -7,10 +7,12 @@ import { RunnableLambda, RunnableMap, RunnablePassthrough, RunnablePick, } from
7
7
  import { ChatPromptTemplate } from "../../prompts/chat.js";
8
8
  import { FakeChatModel, FakeLLM, FakeListChatModel, FakeRetriever, FakeStreamingLLM, } from "../../utils/testing/index.js";
9
9
  import { AIMessage, AIMessageChunk, HumanMessage, SystemMessage, } from "../../messages/index.js";
10
- import { DynamicStructuredTool, DynamicTool, tool } from "../../tools.js";
10
+ import { DynamicStructuredTool, DynamicTool, tool } from "../../tools/index.js";
11
11
  import { Document } from "../../documents/document.js";
12
12
  import { PromptTemplate } from "../../prompts/prompt.js";
13
13
  import { GenerationChunk } from "../../outputs.js";
14
+ // Import from web to avoid side-effects from AsyncLocalStorage
15
+ import { dispatchCustomEvent } from "../../callbacks/dispatch/web.js";
14
16
  function reverse(s) {
15
17
  // Reverse a string.
16
18
  return s.split("").reverse().join("");
@@ -1748,6 +1750,109 @@ test("Runnable streamEvents method with simple tools", async () => {
1748
1750
  },
1749
1751
  ]);
1750
1752
  });
1753
+ test("Runnable streamEvents method with a custom event", async () => {
1754
+ const lambda = RunnableLambda.from(async (params, config) => {
1755
+ await dispatchCustomEvent("testEvent", { someval: "test" }, config);
1756
+ await dispatchCustomEvent("testEvent", { someval: "test2" }, config);
1757
+ return JSON.stringify({ x: params.x, y: params.y });
1758
+ });
1759
+ const events = [];
1760
+ const eventStream = await lambda.streamEvents({ x: 1, y: "2" }, { version: "v2" });
1761
+ for await (const event of eventStream) {
1762
+ events.push(event);
1763
+ }
1764
+ expect(events).toEqual([
1765
+ {
1766
+ event: "on_chain_start",
1767
+ data: { input: { x: 1, y: "2" } },
1768
+ name: "RunnableLambda",
1769
+ tags: [],
1770
+ run_id: expect.any(String),
1771
+ metadata: {},
1772
+ },
1773
+ {
1774
+ event: "on_custom_event",
1775
+ run_id: expect.any(String),
1776
+ name: "testEvent",
1777
+ tags: [],
1778
+ metadata: {},
1779
+ data: { someval: "test" },
1780
+ },
1781
+ {
1782
+ event: "on_custom_event",
1783
+ run_id: expect.any(String),
1784
+ name: "testEvent",
1785
+ tags: [],
1786
+ metadata: {},
1787
+ data: { someval: "test2" },
1788
+ },
1789
+ {
1790
+ event: "on_chain_stream",
1791
+ run_id: expect.any(String),
1792
+ name: "RunnableLambda",
1793
+ tags: [],
1794
+ metadata: {},
1795
+ data: { chunk: '{"x":1,"y":"2"}' },
1796
+ },
1797
+ {
1798
+ event: "on_chain_end",
1799
+ data: { output: '{"x":1,"y":"2"}' },
1800
+ run_id: expect.any(String),
1801
+ name: "RunnableLambda",
1802
+ tags: [],
1803
+ metadata: {},
1804
+ },
1805
+ ]);
1806
+ });
1807
+ test("Custom event inside a custom tool", async () => {
1808
+ const customTool = tool(async (params, config) => {
1809
+ await dispatchCustomEvent("testEvent", { someval: "test" }, config);
1810
+ await dispatchCustomEvent("testEvent", { someval: "test2" }, config);
1811
+ return JSON.stringify({ x: params.x, y: params.y });
1812
+ }, {
1813
+ schema: z.object({ x: z.number(), y: z.string() }),
1814
+ name: "testtool",
1815
+ });
1816
+ const events = [];
1817
+ const eventStream = await customTool.streamEvents({ x: 1, y: "2" }, { version: "v2" });
1818
+ for await (const event of eventStream) {
1819
+ events.push(event);
1820
+ }
1821
+ expect(events).toEqual([
1822
+ {
1823
+ event: "on_tool_start",
1824
+ data: { input: { x: 1, y: "2" } },
1825
+ name: "testtool",
1826
+ tags: [],
1827
+ run_id: expect.any(String),
1828
+ metadata: {},
1829
+ },
1830
+ {
1831
+ event: "on_custom_event",
1832
+ run_id: expect.any(String),
1833
+ name: "testEvent",
1834
+ tags: [],
1835
+ metadata: {},
1836
+ data: { someval: "test" },
1837
+ },
1838
+ {
1839
+ event: "on_custom_event",
1840
+ run_id: expect.any(String),
1841
+ name: "testEvent",
1842
+ tags: [],
1843
+ metadata: {},
1844
+ data: { someval: "test2" },
1845
+ },
1846
+ {
1847
+ event: "on_tool_end",
1848
+ data: { output: '{"x":1,"y":"2"}' },
1849
+ run_id: expect.any(String),
1850
+ name: "testtool",
1851
+ tags: [],
1852
+ metadata: {},
1853
+ },
1854
+ ]);
1855
+ });
1751
1856
  test("Runnable streamEvents method with tools that return objects", async () => {
1752
1857
  const adderFunc = (_params) => {
1753
1858
  return JSON.stringify({ sum: 3 });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,149 @@
1
+ import { z } from "zod";
2
+ import { RunnableLambda, RunnableToolLike } from "../base.js";
3
+ import { FakeRetriever } from "../../utils/testing/index.js";
4
+ import { Document } from "../../documents/document.js";
5
+ test("Runnable asTool works", async () => {
6
+ const schema = z.object({
7
+ foo: z.string(),
8
+ });
9
+ const runnable = RunnableLambda.from((input, config) => {
10
+ return `${input.foo}${config?.configurable.foo}`;
11
+ });
12
+ const tool = runnable.asTool({
13
+ schema,
14
+ });
15
+ expect(tool).toBeInstanceOf(RunnableToolLike);
16
+ expect(tool.schema).toBe(schema);
17
+ expect(tool.name).toBe(runnable.getName());
18
+ });
19
+ test("Runnable asTool works with all populated fields", async () => {
20
+ const schema = z.object({
21
+ foo: z.string(),
22
+ });
23
+ const runnable = RunnableLambda.from((input, config) => {
24
+ return `${input.foo}${config?.configurable.foo}`;
25
+ });
26
+ const tool = runnable.asTool({
27
+ schema,
28
+ name: "test",
29
+ description: "test",
30
+ });
31
+ expect(tool).toBeInstanceOf(RunnableToolLike);
32
+ expect(tool.schema).toBe(schema);
33
+ expect(tool.description).toBe("test");
34
+ expect(tool.name).toBe("test");
35
+ });
36
+ test("Runnable asTool can invoke", async () => {
37
+ const schema = z.object({
38
+ foo: z.string(),
39
+ });
40
+ const runnable = RunnableLambda.from((input, config) => {
41
+ return `${input.foo}${config?.configurable.foo}`;
42
+ });
43
+ const tool = runnable.asTool({
44
+ schema,
45
+ });
46
+ const toolResponse = await tool.invoke({
47
+ foo: "bar",
48
+ }, {
49
+ configurable: {
50
+ foo: "bar",
51
+ },
52
+ });
53
+ expect(toolResponse).toBe("barbar");
54
+ });
55
+ test("asTool should type error with mismatched schema", async () => {
56
+ // asTool infers the type of the Zod schema from the existing runnable's RunInput generic.
57
+ // If the Zod schema does not match the RunInput, it should throw a type error.
58
+ const schema = z.object({
59
+ foo: z.string(),
60
+ });
61
+ const runnable = RunnableLambda.from((input, config) => {
62
+ return `${input.bar}${config?.configurable.foo}`;
63
+ });
64
+ runnable.asTool({
65
+ // @ts-expect-error - Should error. If this does not give a type error, the generics/typing of `asTool` is broken.
66
+ schema,
67
+ });
68
+ });
69
+ test("Create a runnable tool directly from RunnableToolLike", async () => {
70
+ const schema = z.object({
71
+ foo: z.string(),
72
+ });
73
+ const adderFunc = (_) => {
74
+ return Promise.resolve(true);
75
+ };
76
+ const tool = new RunnableToolLike({
77
+ schema,
78
+ name: "test",
79
+ description: "test",
80
+ bound: RunnableLambda.from(adderFunc),
81
+ });
82
+ const result = await tool.invoke({ foo: "bar" });
83
+ expect(result).toBe(true);
84
+ });
85
+ test("asTool can take a single string input", async () => {
86
+ const firstRunnable = RunnableLambda.from((input) => {
87
+ return `${input}a`;
88
+ });
89
+ const secondRunnable = RunnableLambda.from((input) => {
90
+ return `${input}z`;
91
+ });
92
+ const runnable = firstRunnable.pipe(secondRunnable);
93
+ const asTool = runnable.asTool({
94
+ schema: z.string(),
95
+ });
96
+ const result = await asTool.invoke("b");
97
+ expect(result).toBe("baz");
98
+ });
99
+ test("Runnable asTool uses Zod schema description if not provided", async () => {
100
+ const description = "Test schema";
101
+ const schema = z
102
+ .object({
103
+ foo: z.string(),
104
+ })
105
+ .describe(description);
106
+ const runnable = RunnableLambda.from((input, config) => {
107
+ return `${input.foo}${config?.configurable.foo}`;
108
+ });
109
+ const tool = runnable.asTool({
110
+ schema,
111
+ });
112
+ expect(tool.description).toBe(description);
113
+ });
114
+ test("Runnable asTool can accept a string zod schema", async () => {
115
+ const lambda = RunnableLambda.from((input) => {
116
+ return `${input}a`;
117
+ }).asTool({
118
+ name: "string_tool",
119
+ description: "A tool that appends 'a' to the input string",
120
+ schema: z.string(),
121
+ });
122
+ const result = await lambda.invoke("b");
123
+ expect(result).toBe("ba");
124
+ });
125
+ test("Runnables which dont accept ToolCalls as inputs can accept ToolCalls", async () => {
126
+ const pageContent = "Dogs are pretty cool, man!";
127
+ const retriever = new FakeRetriever({
128
+ output: [
129
+ new Document({
130
+ pageContent,
131
+ }),
132
+ ],
133
+ });
134
+ const tool = retriever.asTool({
135
+ name: "pet_info_retriever",
136
+ description: "Get information about pets.",
137
+ schema: z.string(),
138
+ });
139
+ const result = await tool.invoke({
140
+ type: "tool_call",
141
+ name: "pet_info_retriever",
142
+ args: {
143
+ input: "dogs",
144
+ },
145
+ id: "string",
146
+ });
147
+ expect(result).toHaveLength(1);
148
+ expect(result[0].pageContent).toBe(pageContent);
149
+ });
@@ -2,27 +2,13 @@
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 manager_js_1 = require("./callbacks/manager.cjs");
6
- const base_js_1 = require("./language_models/base.cjs");
7
- const config_js_1 = require("./runnables/config.cjs");
8
- /**
9
- * Custom error class used to handle exceptions related to tool input parsing.
10
- * It extends the built-in `Error` class and adds an optional `output`
11
- * property that can hold the output that caused the exception.
12
- */
13
- class ToolInputParsingException extends Error {
14
- constructor(message, output) {
15
- super(message);
16
- Object.defineProperty(this, "output", {
17
- enumerable: true,
18
- configurable: true,
19
- writable: true,
20
- value: void 0
21
- });
22
- this.output = output;
23
- }
24
- }
25
- exports.ToolInputParsingException = ToolInputParsingException;
5
+ const manager_js_1 = require("../callbacks/manager.cjs");
6
+ const base_js_1 = require("../language_models/base.cjs");
7
+ const config_js_1 = require("../runnables/config.cjs");
8
+ const tool_js_1 = require("../messages/tool.cjs");
9
+ const index_js_1 = require("../singletons/index.cjs");
10
+ const utils_js_1 = require("./utils.cjs");
11
+ Object.defineProperty(exports, "ToolInputParsingException", { enumerable: true, get: function () { return utils_js_1.ToolInputParsingException; } });
26
12
  /**
27
13
  * Base class for Tools that accept input of any shape defined by a Zod schema.
28
14
  */
@@ -38,6 +24,22 @@ class StructuredTool extends base_js_1.BaseLangChain {
38
24
  writable: true,
39
25
  value: false
40
26
  });
27
+ /**
28
+ * The tool response format.
29
+ *
30
+ * If "content" then the output of the tool is interpreted as the contents of a
31
+ * ToolMessage. If "content_and_artifact" then the output is expected to be a
32
+ * two-tuple corresponding to the (content, artifact) of a ToolMessage.
33
+ *
34
+ * @default "content"
35
+ */
36
+ Object.defineProperty(this, "responseFormat", {
37
+ enumerable: true,
38
+ configurable: true,
39
+ writable: true,
40
+ value: "content"
41
+ });
42
+ this.responseFormat = fields?.responseFormat ?? this.responseFormat;
41
43
  }
42
44
  /**
43
45
  * Invokes the tool with the provided input and configuration.
@@ -46,7 +48,23 @@ class StructuredTool extends base_js_1.BaseLangChain {
46
48
  * @returns A Promise that resolves with a string.
47
49
  */
48
50
  async invoke(input, config) {
49
- return this.call(input, (0, config_js_1.ensureConfig)(config));
51
+ let tool_call_id;
52
+ let toolInput;
53
+ if ((0, utils_js_1._isToolCall)(input)) {
54
+ tool_call_id = input.id;
55
+ toolInput = input.args;
56
+ }
57
+ else {
58
+ toolInput = input;
59
+ }
60
+ const ensuredConfig = (0, config_js_1.ensureConfig)(config);
61
+ return this.call(toolInput, {
62
+ ...ensuredConfig,
63
+ configurable: {
64
+ ...ensuredConfig.configurable,
65
+ tool_call_id,
66
+ },
67
+ });
50
68
  }
51
69
  /**
52
70
  * @deprecated Use .invoke() instead. Will be removed in 0.3.0.
@@ -67,7 +85,7 @@ class StructuredTool extends base_js_1.BaseLangChain {
67
85
  parsed = await this.schema.parseAsync(arg);
68
86
  }
69
87
  catch (e) {
70
- throw new ToolInputParsingException(`Received tool input did not match expected schema`, JSON.stringify(arg));
88
+ throw new utils_js_1.ToolInputParsingException(`Received tool input did not match expected schema`, JSON.stringify(arg));
71
89
  }
72
90
  const config = (0, manager_js_1.parseCallbackConfigArg)(configArg);
73
91
  const callbackManager_ = await manager_js_1.CallbackManager.configure(config.callbacks, this.callbacks, config.tags || tags, this.tags, config.metadata, this.metadata, { verbose: this.verbose });
@@ -81,8 +99,32 @@ class StructuredTool extends base_js_1.BaseLangChain {
81
99
  await runManager?.handleToolError(e);
82
100
  throw e;
83
101
  }
84
- await runManager?.handleToolEnd(result);
85
- return result;
102
+ let content;
103
+ let artifact;
104
+ if (this.responseFormat === "content_and_artifact") {
105
+ if (Array.isArray(result) && result.length === 2) {
106
+ [content, artifact] = result;
107
+ }
108
+ else {
109
+ throw new Error(`Tool response format is "content_and_artifact" but the output was not a two-tuple.\nResult: ${JSON.stringify(result)}`);
110
+ }
111
+ }
112
+ else {
113
+ content = result;
114
+ }
115
+ let toolCallId;
116
+ if (config && "configurable" in config) {
117
+ toolCallId = config.configurable
118
+ .tool_call_id;
119
+ }
120
+ const formattedOutput = _formatToolOutput({
121
+ content,
122
+ artifact,
123
+ toolCallId,
124
+ name: this.name,
125
+ });
126
+ await runManager?.handleToolEnd(formattedOutput);
127
+ return formattedOutput;
86
128
  }
87
129
  }
88
130
  exports.StructuredTool = StructuredTool;
@@ -158,8 +200,8 @@ class DynamicTool extends Tool {
158
200
  return super.call(arg, config);
159
201
  }
160
202
  /** @ignore */
161
- async _call(input, runManager, config) {
162
- return this.func(input, runManager, config);
203
+ async _call(input, runManager, parentConfig) {
204
+ return this.func(input, runManager, parentConfig);
163
205
  }
164
206
  }
165
207
  exports.DynamicTool = DynamicTool;
@@ -217,8 +259,8 @@ class DynamicStructuredTool extends StructuredTool {
217
259
  }
218
260
  return super.call(arg, config, tags);
219
261
  }
220
- _call(arg, runManager, config) {
221
- return this.func(arg, runManager, config);
262
+ _call(arg, runManager, parentConfig) {
263
+ return this.func(arg, runManager, parentConfig);
222
264
  }
223
265
  }
224
266
  exports.DynamicStructuredTool = DynamicStructuredTool;
@@ -233,28 +275,74 @@ class BaseToolkit {
233
275
  }
234
276
  }
235
277
  exports.BaseToolkit = BaseToolkit;
236
- /**
237
- * Creates a new StructuredTool instance with the provided function, name, description, and schema.
238
- * @function
239
- * @template {ZodAny} RunInput The input schema for the tool.
240
- *
241
- * @param {RunnableFunc<RunInput, string>} func - The function to invoke when the tool is called.
242
- * @param fields - An object containing the following properties:
243
- * @param {string} fields.name The name of the tool.
244
- * @param {string | undefined} fields.description The description of the tool. Defaults to either the description on the Zod schema, or `${fields.name} tool`.
245
- * @param {z.ZodObject<any, any, any, any>} fields.schema The Zod schema defining the input for the tool.
246
- *
247
- * @returns {StructuredTool<RunInput, string>} A new StructuredTool instance.
248
- */
249
278
  function tool(func, fields) {
250
- const schema = fields.schema ??
251
- zod_1.z.object({ input: zod_1.z.string().optional() }).transform((obj) => obj.input);
252
- const description = fields.description ?? schema.description ?? `${fields.name} tool`;
279
+ // If the schema is not provided, or it's a string schema, create a DynamicTool
280
+ if (!fields.schema || !("shape" in fields.schema) || !fields.schema.shape) {
281
+ return new DynamicTool({
282
+ name: fields.name,
283
+ description: fields.description ??
284
+ fields.schema?.description ??
285
+ `${fields.name} tool`,
286
+ responseFormat: fields.responseFormat,
287
+ func,
288
+ });
289
+ }
290
+ const description = fields.description ?? fields.schema.description ?? `${fields.name} tool`;
253
291
  return new DynamicStructuredTool({
254
292
  name: fields.name,
255
293
  description,
256
- schema: schema,
257
- func: async (input, _runManager, config) => func(input, config),
294
+ schema: fields.schema,
295
+ // TODO: Consider moving into DynamicStructuredTool constructor
296
+ func: async (input, runManager, config) => {
297
+ return new Promise((resolve, reject) => {
298
+ const childConfig = (0, config_js_1.patchConfig)(config, {
299
+ callbacks: runManager?.getChild(),
300
+ });
301
+ void index_js_1.AsyncLocalStorageProviderSingleton.getInstance().run(childConfig, async () => {
302
+ try {
303
+ resolve(func(input, childConfig));
304
+ }
305
+ catch (e) {
306
+ reject(e);
307
+ }
308
+ });
309
+ });
310
+ },
311
+ responseFormat: fields.responseFormat,
258
312
  });
259
313
  }
260
314
  exports.tool = tool;
315
+ function _formatToolOutput(params) {
316
+ const { content, artifact, toolCallId } = params;
317
+ if (toolCallId) {
318
+ if (typeof content === "string" ||
319
+ (Array.isArray(content) &&
320
+ content.every((item) => typeof item === "object"))) {
321
+ return new tool_js_1.ToolMessage({
322
+ content,
323
+ artifact,
324
+ tool_call_id: toolCallId,
325
+ name: params.name,
326
+ });
327
+ }
328
+ else {
329
+ return new tool_js_1.ToolMessage({
330
+ content: _stringify(content),
331
+ artifact,
332
+ tool_call_id: toolCallId,
333
+ name: params.name,
334
+ });
335
+ }
336
+ }
337
+ else {
338
+ return content;
339
+ }
340
+ }
341
+ function _stringify(content) {
342
+ try {
343
+ return JSON.stringify(content, null, 2);
344
+ }
345
+ catch (_noOp) {
346
+ return `${content}`;
347
+ }
348
+ }