@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.
- package/caches.cjs +1 -1
- package/caches.d.cts +1 -1
- package/caches.d.ts +1 -1
- package/caches.js +1 -1
- package/callbacks/dispatch/web.cjs +1 -0
- package/callbacks/dispatch/web.d.cts +1 -0
- package/callbacks/dispatch/web.d.ts +1 -0
- package/callbacks/dispatch/web.js +1 -0
- package/callbacks/dispatch.cjs +1 -0
- package/callbacks/dispatch.d.cts +1 -0
- package/callbacks/dispatch.d.ts +1 -0
- package/callbacks/dispatch.js +1 -0
- package/dist/{caches.cjs → caches/base.cjs} +6 -6
- package/dist/{caches.d.ts → caches/base.d.ts} +7 -7
- package/dist/{caches.js → caches/base.js} +6 -6
- package/dist/caches/tests/in_memory_cache.test.d.ts +1 -0
- package/dist/caches/tests/in_memory_cache.test.js +33 -0
- package/dist/callbacks/base.cjs +8 -0
- package/dist/callbacks/base.d.ts +16 -10
- package/dist/callbacks/base.js +8 -0
- package/dist/callbacks/dispatch/index.cjs +49 -0
- package/dist/callbacks/dispatch/index.d.ts +35 -0
- package/dist/callbacks/dispatch/index.js +45 -0
- package/dist/callbacks/dispatch/web.cjs +61 -0
- package/dist/callbacks/dispatch/web.d.ts +32 -0
- package/dist/callbacks/dispatch/web.js +57 -0
- package/dist/callbacks/manager.cjs +20 -0
- package/dist/callbacks/manager.d.ts +2 -1
- package/dist/callbacks/manager.js +20 -0
- package/dist/language_models/base.cjs +4 -4
- package/dist/language_models/base.d.ts +2 -2
- package/dist/language_models/base.js +1 -1
- package/dist/language_models/chat_models.d.ts +22 -5
- package/dist/language_models/llms.d.ts +1 -1
- package/dist/language_models/tests/chat_models.test.js +33 -0
- package/dist/load/import_map.cjs +2 -2
- package/dist/load/import_map.d.ts +2 -2
- package/dist/load/import_map.js +2 -2
- package/dist/messages/ai.cjs +19 -0
- package/dist/messages/ai.d.ts +2 -0
- package/dist/messages/ai.js +19 -0
- package/dist/messages/base.cjs +95 -5
- package/dist/messages/base.d.ts +5 -1
- package/dist/messages/base.js +93 -4
- package/dist/messages/chat.cjs +12 -0
- package/dist/messages/chat.d.ts +2 -0
- package/dist/messages/chat.js +12 -0
- package/dist/messages/index.cjs +1 -0
- package/dist/messages/index.d.ts +2 -1
- package/dist/messages/index.js +1 -0
- package/dist/messages/modifier.cjs +35 -0
- package/dist/messages/modifier.d.ts +19 -0
- package/dist/messages/modifier.js +31 -0
- package/dist/messages/tests/base_message.test.js +134 -2
- package/dist/messages/tests/message_utils.test.js +54 -2
- package/dist/messages/tool.cjs +45 -0
- package/dist/messages/tool.d.ts +29 -0
- package/dist/messages/tool.js +46 -1
- package/dist/messages/transformers.cjs +6 -0
- package/dist/messages/transformers.d.ts +3 -2
- package/dist/messages/transformers.js +6 -0
- package/dist/messages/utils.cjs +5 -1
- package/dist/messages/utils.js +5 -1
- package/dist/output_parsers/openai_tools/json_output_tools_parsers.cjs +2 -0
- package/dist/output_parsers/openai_tools/json_output_tools_parsers.js +2 -0
- package/dist/runnables/base.cjs +104 -1
- package/dist/runnables/base.d.ts +50 -0
- package/dist/runnables/base.js +101 -0
- package/dist/runnables/index.cjs +2 -1
- package/dist/runnables/index.d.ts +1 -1
- package/dist/runnables/index.js +1 -1
- package/dist/runnables/tests/runnable_stream_events.test.js +1 -1
- package/dist/runnables/tests/runnable_stream_events_v2.test.js +106 -1
- package/dist/runnables/tests/runnable_tools.test.d.ts +1 -0
- package/dist/runnables/tests/runnable_tools.test.js +149 -0
- package/dist/{tools.cjs → tools/index.cjs} +135 -47
- package/dist/{tools.d.ts → tools/index.d.ts} +76 -47
- package/dist/{tools.js → tools/index.js} +134 -45
- package/dist/tools/tests/tools.test.d.ts +1 -0
- package/dist/tools/tests/tools.test.js +85 -0
- package/dist/tools/utils.cjs +28 -0
- package/dist/tools/utils.d.ts +11 -0
- package/dist/tools/utils.js +23 -0
- package/dist/tracers/base.cjs +1 -0
- package/dist/tracers/base.d.ts +1 -1
- package/dist/tracers/base.js +1 -0
- package/dist/tracers/event_stream.cjs +15 -0
- package/dist/tracers/event_stream.d.ts +1 -0
- package/dist/tracers/event_stream.js +15 -0
- package/dist/types/zod.cjs +2 -0
- package/dist/types/zod.d.ts +2 -0
- package/dist/types/zod.js +1 -0
- package/dist/utils/function_calling.cjs +38 -10
- package/dist/utils/function_calling.d.ts +32 -11
- package/dist/utils/function_calling.js +36 -9
- package/dist/utils/testing/index.cjs +10 -3
- package/dist/utils/testing/index.d.ts +1 -1
- package/dist/utils/testing/index.js +9 -2
- package/package.json +28 -1
- package/tools.cjs +1 -1
- package/tools.d.cts +1 -1
- package/tools.d.ts +1 -1
- 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("
|
|
6
|
-
const base_js_1 = require("
|
|
7
|
-
const config_js_1 = require("
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
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
|
-
|
|
85
|
-
|
|
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,
|
|
162
|
-
return this.func(input, runManager,
|
|
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,
|
|
221
|
-
return this.func(arg, runManager,
|
|
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
|
-
|
|
251
|
-
|
|
252
|
-
|
|
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
|
-
|
|
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
|
+
}
|