@langchain/core 0.2.6 → 0.2.7

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.
@@ -66,7 +66,9 @@ const mustacheTemplateToNodes = (template) => template.map((temp) => {
66
66
  const name = temp[1].includes(".") ? temp[1].split(".")[0] : temp[1];
67
67
  return { type: "variable", name };
68
68
  }
69
- else if (temp[0] === "#") {
69
+ else if (["#", "&"].includes(temp[0])) {
70
+ // # represents a section, "&" represents an unescaped variable.
71
+ // These should both be considered variables.
70
72
  return { type: "variable", name: temp[1] };
71
73
  }
72
74
  else {
@@ -59,7 +59,9 @@ const mustacheTemplateToNodes = (template) => template.map((temp) => {
59
59
  const name = temp[1].includes(".") ? temp[1].split(".")[0] : temp[1];
60
60
  return { type: "variable", name };
61
61
  }
62
- else if (temp[0] === "#") {
62
+ else if (["#", "&"].includes(temp[0])) {
63
+ // # represents a section, "&" represents an unescaped variable.
64
+ // These should both be considered variables.
63
65
  return { type: "variable", name: temp[1] };
64
66
  }
65
67
  else {
@@ -1,5 +1,6 @@
1
1
  import { test, expect } from "@jest/globals";
2
2
  import { PromptTemplate } from "../prompt.js";
3
+ import { parseTemplate } from "../template.js";
3
4
  test("Single input variable.", async () => {
4
5
  const template = "This is a {{foo}} test.";
5
6
  const prompt = PromptTemplate.fromTemplate(template, {
@@ -83,3 +84,22 @@ hello
83
84
  is a test.`);
84
85
  expect(promptWithRepeats.inputVariables).toEqual(["foo"]);
85
86
  });
87
+ test("Escaped variables", async () => {
88
+ const template = `test: {{{text}}}`;
89
+ const parsed = parseTemplate(template, "mustache");
90
+ expect(parsed[0]).toStrictEqual({
91
+ type: "literal",
92
+ text: "test: ",
93
+ });
94
+ expect(parsed[1]).toStrictEqual({
95
+ type: "variable",
96
+ name: "text",
97
+ });
98
+ const promptTemplate = PromptTemplate.fromTemplate(template, {
99
+ templateFormat: "mustache",
100
+ });
101
+ const result = await promptTemplate.invoke({
102
+ text: `hello i have a "quote`,
103
+ });
104
+ expect(result.value).toBe(`test: hello i have a "quote`);
105
+ });
@@ -7,7 +7,7 @@ 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 } from "../../tools.js";
10
+ import { DynamicStructuredTool, DynamicTool, tool } from "../../tools.js";
11
11
  import { Document } from "../../documents/document.js";
12
12
  import { PromptTemplate } from "../../prompts/prompt.js";
13
13
  import { GenerationChunk } from "../../outputs.js";
@@ -1748,6 +1748,70 @@ test("Runnable streamEvents method with simple tools", async () => {
1748
1748
  },
1749
1749
  ]);
1750
1750
  });
1751
+ test("Runnable streamEvents method with tools that return objects", async () => {
1752
+ const adderFunc = (_params) => {
1753
+ return JSON.stringify({ sum: 3 });
1754
+ };
1755
+ const parameterlessTool = tool(adderFunc, {
1756
+ name: "parameterless",
1757
+ });
1758
+ const events = [];
1759
+ const eventStream = parameterlessTool.streamEvents({}, { version: "v2" });
1760
+ for await (const event of eventStream) {
1761
+ events.push(event);
1762
+ }
1763
+ expect(events).toEqual([
1764
+ {
1765
+ data: { input: {} },
1766
+ event: "on_tool_start",
1767
+ metadata: {},
1768
+ name: "parameterless",
1769
+ run_id: expect.any(String),
1770
+ tags: [],
1771
+ },
1772
+ {
1773
+ data: {
1774
+ output: JSON.stringify({ sum: 3 }),
1775
+ },
1776
+ event: "on_tool_end",
1777
+ metadata: {},
1778
+ name: "parameterless",
1779
+ run_id: expect.any(String),
1780
+ tags: [],
1781
+ },
1782
+ ]);
1783
+ const adderTool = tool(adderFunc, {
1784
+ name: "with_parameters",
1785
+ description: "A tool that does nothing",
1786
+ schema: z.object({
1787
+ x: z.number(),
1788
+ y: z.number(),
1789
+ }),
1790
+ });
1791
+ const events2 = [];
1792
+ const eventStream2 = adderTool.streamEvents({ x: 1, y: 2 }, { version: "v2" });
1793
+ for await (const event of eventStream2) {
1794
+ events2.push(event);
1795
+ }
1796
+ expect(events2).toEqual([
1797
+ {
1798
+ data: { input: { x: 1, y: 2 } },
1799
+ event: "on_tool_start",
1800
+ metadata: {},
1801
+ name: "with_parameters",
1802
+ run_id: expect.any(String),
1803
+ tags: [],
1804
+ },
1805
+ {
1806
+ data: { output: JSON.stringify({ sum: 3 }) },
1807
+ event: "on_tool_end",
1808
+ metadata: {},
1809
+ name: "with_parameters",
1810
+ run_id: expect.any(String),
1811
+ tags: [],
1812
+ },
1813
+ ]);
1814
+ });
1751
1815
  test("Runnable streamEvents method with a retriever", async () => {
1752
1816
  const retriever = new FakeRetriever({
1753
1817
  output: [
package/dist/tools.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BaseToolkit = exports.DynamicStructuredTool = exports.DynamicTool = exports.Tool = exports.StructuredTool = exports.ToolInputParsingException = void 0;
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
5
  const manager_js_1 = require("./callbacks/manager.cjs");
6
6
  const base_js_1 = require("./language_models/base.cjs");
@@ -233,3 +233,28 @@ class BaseToolkit {
233
233
  }
234
234
  }
235
235
  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
+ 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`;
253
+ return new DynamicStructuredTool({
254
+ name: fields.name,
255
+ description,
256
+ schema: schema,
257
+ func: async (input, _runManager, config) => func(input, config),
258
+ });
259
+ }
260
+ exports.tool = tool;
package/dist/tools.d.ts CHANGED
@@ -2,7 +2,8 @@ import { z } from "zod";
2
2
  import { CallbackManagerForToolRun, Callbacks } from "./callbacks/manager.js";
3
3
  import { BaseLangChain, type BaseLangChainParams } from "./language_models/base.js";
4
4
  import { type RunnableConfig } from "./runnables/config.js";
5
- import type { RunnableInterface } from "./runnables/base.js";
5
+ import type { RunnableFunc, RunnableInterface } from "./runnables/base.js";
6
+ type ZodAny = z.ZodObject<any, any, any, any>;
6
7
  /**
7
8
  * Parameters for the Tool classes.
8
9
  */
@@ -17,7 +18,7 @@ export declare class ToolInputParsingException extends Error {
17
18
  output?: string;
18
19
  constructor(message: string, output?: string);
19
20
  }
20
- export interface StructuredToolInterface<T extends z.ZodObject<any, any, any, any> = z.ZodObject<any, any, any, any>> extends RunnableInterface<(z.output<T> extends string ? string : never) | z.input<T>, string> {
21
+ export interface StructuredToolInterface<T extends ZodAny = ZodAny> extends RunnableInterface<(z.output<T> extends string ? string : never) | z.input<T>, string> {
21
22
  lc_namespace: string[];
22
23
  schema: T | z.ZodEffects<T>;
23
24
  /**
@@ -41,7 +42,7 @@ export interface StructuredToolInterface<T extends z.ZodObject<any, any, any, an
41
42
  /**
42
43
  * Base class for Tools that accept input of any shape defined by a Zod schema.
43
44
  */
44
- export declare abstract class StructuredTool<T extends z.ZodObject<any, any, any, any> = z.ZodObject<any, any, any, any>> extends BaseLangChain<(z.output<T> extends string ? string : never) | z.input<T>, string> {
45
+ export declare abstract class StructuredTool<T extends ZodAny = ZodAny> extends BaseLangChain<(z.output<T> extends string ? string : never) | z.input<T>, string> {
45
46
  abstract schema: T | z.ZodEffects<T>;
46
47
  get lc_namespace(): string[];
47
48
  constructor(fields?: ToolParams);
@@ -122,7 +123,7 @@ export interface DynamicToolInput extends BaseDynamicToolInput {
122
123
  /**
123
124
  * Interface for the input parameters of the DynamicStructuredTool class.
124
125
  */
125
- export interface DynamicStructuredToolInput<T extends z.ZodObject<any, any, any, any> = z.ZodObject<any, any, any, any>> extends BaseDynamicToolInput {
126
+ export interface DynamicStructuredToolInput<T extends ZodAny = ZodAny> extends BaseDynamicToolInput {
126
127
  func: (input: z.infer<T>, runManager?: CallbackManagerForToolRun, config?: RunnableConfig) => Promise<string>;
127
128
  schema: T;
128
129
  }
@@ -148,11 +149,11 @@ export declare class DynamicTool extends Tool {
148
149
  * StructuredTool class and overrides the _call method to execute the
149
150
  * provided function when the tool is called.
150
151
  */
151
- export declare class DynamicStructuredTool<T extends z.ZodObject<any, any, any, any> = z.ZodObject<any, any, any, any>> extends StructuredTool {
152
+ export declare class DynamicStructuredTool<T extends ZodAny = ZodAny> extends StructuredTool<T> {
152
153
  static lc_name(): string;
153
154
  name: string;
154
155
  description: string;
155
- func: DynamicStructuredToolInput["func"];
156
+ func: DynamicStructuredToolInput<T>["func"];
156
157
  schema: T;
157
158
  constructor(fields: DynamicStructuredToolInput<T>);
158
159
  /**
@@ -172,3 +173,40 @@ export declare abstract class BaseToolkit {
172
173
  abstract tools: StructuredToolInterface[];
173
174
  getTools(): StructuredToolInterface[];
174
175
  }
176
+ /**
177
+ * Parameters for the tool function.
178
+ * @template {ZodAny} RunInput The input schema for the tool.
179
+ */
180
+ interface ToolWrapperParams<RunInput extends ZodAny = ZodAny> extends ToolParams {
181
+ /**
182
+ * The name of the tool. If using with an LLM, this
183
+ * will be passed as the tool name.
184
+ */
185
+ name: string;
186
+ /**
187
+ * The description of the tool.
188
+ * @default `${fields.name} tool`
189
+ */
190
+ description?: string;
191
+ /**
192
+ * The input schema for the tool. If using an LLM, this
193
+ * will be passed as the tool schema to generate arguments
194
+ * for.
195
+ */
196
+ schema?: RunInput;
197
+ }
198
+ /**
199
+ * Creates a new StructuredTool instance with the provided function, name, description, and schema.
200
+ * @function
201
+ * @template {ZodAny} RunInput The input schema for the tool.
202
+ *
203
+ * @param {RunnableFunc<RunInput, string>} func - The function to invoke when the tool is called.
204
+ * @param fields - An object containing the following properties:
205
+ * @param {string} fields.name The name of the tool.
206
+ * @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.
208
+ *
209
+ * @returns {StructuredTool<RunInput, string>} A new StructuredTool instance.
210
+ */
211
+ export declare function tool<RunInput extends ZodAny = ZodAny>(func: RunnableFunc<z.infer<RunInput>, string>, fields: ToolWrapperParams<RunInput>): DynamicStructuredTool<RunInput>;
212
+ export {};
package/dist/tools.js CHANGED
@@ -224,3 +224,27 @@ export class BaseToolkit {
224
224
  return this.tools;
225
225
  }
226
226
  }
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
+ 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`;
244
+ return new DynamicStructuredTool({
245
+ name: fields.name,
246
+ description,
247
+ schema: schema,
248
+ func: async (input, _runManager, config) => func(input, config),
249
+ });
250
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/core",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "Core LangChain.js abstractions and schemas",
5
5
  "type": "module",
6
6
  "engines": {