@langchain/core 0.3.65 → 0.3.67

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.
@@ -144,10 +144,11 @@ class AIMessageChunk extends base_js_1.BaseMessageChunk {
144
144
  }
145
145
  else {
146
146
  const groupedToolCallChunk = fields.tool_call_chunks.reduce((acc, chunk) => {
147
- if (!chunk.id)
148
- return acc;
149
- acc[chunk.id] = acc[chunk.id] ?? [];
150
- acc[chunk.id].push(chunk);
147
+ // Assign a fallback ID if the chunk doesn't have one
148
+ // This can happen with tools that have empty schemas
149
+ const chunkId = chunk.id || `fallback-${chunk.index || 0}`;
150
+ acc[chunkId] = acc[chunkId] ?? [];
151
+ acc[chunkId].push(chunk);
151
152
  return acc;
152
153
  }, {});
153
154
  const toolCalls = [];
@@ -157,6 +158,8 @@ class AIMessageChunk extends base_js_1.BaseMessageChunk {
157
158
  const name = chunks[0]?.name ?? "";
158
159
  const joinedArgs = chunks.map((c) => c.args || "").join("");
159
160
  const argsStr = joinedArgs.length ? joinedArgs : "{}";
161
+ // Use the original ID from the first chunk if it exists, otherwise use the grouped ID
162
+ const originalId = chunks[0]?.id || id;
160
163
  try {
161
164
  parsedArgs = (0, json_js_1.parsePartialJson)(argsStr);
162
165
  if (parsedArgs === null ||
@@ -167,7 +170,7 @@ class AIMessageChunk extends base_js_1.BaseMessageChunk {
167
170
  toolCalls.push({
168
171
  name,
169
172
  args: parsedArgs,
170
- id,
173
+ id: originalId,
171
174
  type: "tool_call",
172
175
  });
173
176
  }
@@ -175,7 +178,7 @@ class AIMessageChunk extends base_js_1.BaseMessageChunk {
175
178
  invalidToolCalls.push({
176
179
  name,
177
180
  args: argsStr,
178
- id,
181
+ id: originalId,
179
182
  error: "Malformed args.",
180
183
  type: "invalid_tool_call",
181
184
  });
@@ -138,10 +138,11 @@ export class AIMessageChunk extends BaseMessageChunk {
138
138
  }
139
139
  else {
140
140
  const groupedToolCallChunk = fields.tool_call_chunks.reduce((acc, chunk) => {
141
- if (!chunk.id)
142
- return acc;
143
- acc[chunk.id] = acc[chunk.id] ?? [];
144
- acc[chunk.id].push(chunk);
141
+ // Assign a fallback ID if the chunk doesn't have one
142
+ // This can happen with tools that have empty schemas
143
+ const chunkId = chunk.id || `fallback-${chunk.index || 0}`;
144
+ acc[chunkId] = acc[chunkId] ?? [];
145
+ acc[chunkId].push(chunk);
145
146
  return acc;
146
147
  }, {});
147
148
  const toolCalls = [];
@@ -151,6 +152,8 @@ export class AIMessageChunk extends BaseMessageChunk {
151
152
  const name = chunks[0]?.name ?? "";
152
153
  const joinedArgs = chunks.map((c) => c.args || "").join("");
153
154
  const argsStr = joinedArgs.length ? joinedArgs : "{}";
155
+ // Use the original ID from the first chunk if it exists, otherwise use the grouped ID
156
+ const originalId = chunks[0]?.id || id;
154
157
  try {
155
158
  parsedArgs = parsePartialJson(argsStr);
156
159
  if (parsedArgs === null ||
@@ -161,7 +164,7 @@ export class AIMessageChunk extends BaseMessageChunk {
161
164
  toolCalls.push({
162
165
  name,
163
166
  args: parsedArgs,
164
- id,
167
+ id: originalId,
165
168
  type: "tool_call",
166
169
  });
167
170
  }
@@ -169,7 +172,7 @@ export class AIMessageChunk extends BaseMessageChunk {
169
172
  invalidToolCalls.push({
170
173
  name,
171
174
  args: argsStr,
172
- id,
175
+ id: originalId,
173
176
  error: "Malformed args.",
174
177
  type: "invalid_tool_call",
175
178
  });
@@ -67,20 +67,29 @@ exports.parseFString = parseFString;
67
67
  * @param {mustache.TemplateSpans} template The result of parsing a mustache template with the mustache.js library.
68
68
  * @returns {ParsedTemplateNode[]}
69
69
  */
70
- const mustacheTemplateToNodes = (template) => template.map((temp) => {
71
- if (temp[0] === "name") {
72
- const name = temp[1].includes(".") ? temp[1].split(".")[0] : temp[1];
73
- return { type: "variable", name };
74
- }
75
- else if (["#", "&", "^", ">"].includes(temp[0])) {
76
- // # represents a section, "&" represents an unescaped variable.
77
- // These should both be considered variables.
78
- return { type: "variable", name: temp[1] };
79
- }
80
- else {
81
- return { type: "literal", text: temp[1] };
70
+ const mustacheTemplateToNodes = (template) => {
71
+ const nodes = [];
72
+ for (const temp of template) {
73
+ if (temp[0] === "name") {
74
+ const name = temp[1].includes(".") ? temp[1].split(".")[0] : temp[1];
75
+ nodes.push({ type: "variable", name });
76
+ }
77
+ else if (["#", "&", "^", ">"].includes(temp[0])) {
78
+ // # represents a section, "&" represents an unescaped variable.
79
+ // These should both be considered variables.
80
+ nodes.push({ type: "variable", name: temp[1] });
81
+ // If this is a section with nested content, recursively process it
82
+ if (temp[0] === "#" && temp.length > 4 && Array.isArray(temp[4])) {
83
+ const nestedNodes = mustacheTemplateToNodes(temp[4]);
84
+ nodes.push(...nestedNodes);
85
+ }
86
+ }
87
+ else {
88
+ nodes.push({ type: "literal", text: temp[1] });
89
+ }
82
90
  }
83
- });
91
+ return nodes;
92
+ };
84
93
  const parseMustache = (template) => {
85
94
  configureMustache();
86
95
  const parsed = mustache_1.default.parse(template);
@@ -60,20 +60,29 @@ export const parseFString = (template) => {
60
60
  * @param {mustache.TemplateSpans} template The result of parsing a mustache template with the mustache.js library.
61
61
  * @returns {ParsedTemplateNode[]}
62
62
  */
63
- const mustacheTemplateToNodes = (template) => template.map((temp) => {
64
- if (temp[0] === "name") {
65
- const name = temp[1].includes(".") ? temp[1].split(".")[0] : temp[1];
66
- return { type: "variable", name };
67
- }
68
- else if (["#", "&", "^", ">"].includes(temp[0])) {
69
- // # represents a section, "&" represents an unescaped variable.
70
- // These should both be considered variables.
71
- return { type: "variable", name: temp[1] };
72
- }
73
- else {
74
- return { type: "literal", text: temp[1] };
63
+ const mustacheTemplateToNodes = (template) => {
64
+ const nodes = [];
65
+ for (const temp of template) {
66
+ if (temp[0] === "name") {
67
+ const name = temp[1].includes(".") ? temp[1].split(".")[0] : temp[1];
68
+ nodes.push({ type: "variable", name });
69
+ }
70
+ else if (["#", "&", "^", ">"].includes(temp[0])) {
71
+ // # represents a section, "&" represents an unescaped variable.
72
+ // These should both be considered variables.
73
+ nodes.push({ type: "variable", name: temp[1] });
74
+ // If this is a section with nested content, recursively process it
75
+ if (temp[0] === "#" && temp.length > 4 && Array.isArray(temp[4])) {
76
+ const nestedNodes = mustacheTemplateToNodes(temp[4]);
77
+ nodes.push(...nestedNodes);
78
+ }
79
+ }
80
+ else {
81
+ nodes.push({ type: "literal", text: temp[1] });
82
+ }
75
83
  }
76
- });
84
+ return nodes;
85
+ };
77
86
  export const parseMustache = (template) => {
78
87
  configureMustache();
79
88
  const parsed = mustache.parse(template);
@@ -1881,9 +1881,9 @@ exports.RunnableLambda = RunnableLambda;
1881
1881
  * );
1882
1882
  *
1883
1883
  * // Invoke the sequence with a single age input
1884
- * const res = sequence.invoke(25);
1884
+ * const res = await sequence.invoke(25);
1885
1885
  *
1886
- * // { years_to_fifty: 25, years_to_hundred: 75 }
1886
+ * // { years_to_fifty: 20, years_to_hundred: 70 }
1887
1887
  * ```
1888
1888
  */
1889
1889
  class RunnableParallel extends RunnableMap {
@@ -729,9 +729,9 @@ export declare class RunnableLambda<RunInput, RunOutput, CallOptions extends Run
729
729
  * );
730
730
  *
731
731
  * // Invoke the sequence with a single age input
732
- * const res = sequence.invoke(25);
732
+ * const res = await sequence.invoke(25);
733
733
  *
734
- * // { years_to_fifty: 25, years_to_hundred: 75 }
734
+ * // { years_to_fifty: 20, years_to_hundred: 70 }
735
735
  * ```
736
736
  */
737
737
  export declare class RunnableParallel<RunInput> extends RunnableMap<RunInput> {
@@ -1864,9 +1864,9 @@ export class RunnableLambda extends Runnable {
1864
1864
  * );
1865
1865
  *
1866
1866
  * // Invoke the sequence with a single age input
1867
- * const res = sequence.invoke(25);
1867
+ * const res = await sequence.invoke(25);
1868
1868
  *
1869
- * // { years_to_fifty: 25, years_to_hundred: 75 }
1869
+ * // { years_to_fifty: 20, years_to_hundred: 70 }
1870
1870
  * ```
1871
1871
  */
1872
1872
  export class RunnableParallel extends RunnableMap {
@@ -60,9 +60,19 @@ class StructuredTool extends base_js_1.BaseLangChain {
60
60
  writable: true,
61
61
  value: "content"
62
62
  });
63
+ /**
64
+ * Default config object for the tool runnable.
65
+ */
66
+ Object.defineProperty(this, "defaultConfig", {
67
+ enumerable: true,
68
+ configurable: true,
69
+ writable: true,
70
+ value: void 0
71
+ });
63
72
  this.verboseParsingErrors =
64
73
  fields?.verboseParsingErrors ?? this.verboseParsingErrors;
65
74
  this.responseFormat = fields?.responseFormat ?? this.responseFormat;
75
+ this.defaultConfig = fields?.defaultConfig ?? this.defaultConfig;
66
76
  }
67
77
  /**
68
78
  * Invokes the tool with the provided input and configuration.
@@ -72,7 +82,7 @@ class StructuredTool extends base_js_1.BaseLangChain {
72
82
  */
73
83
  async invoke(input, config) {
74
84
  let toolInput;
75
- let enrichedConfig = (0, config_js_1.ensureConfig)(config);
85
+ let enrichedConfig = (0, config_js_1.ensureConfig)((0, config_js_1.mergeConfigs)(this.defaultConfig, config));
76
86
  if ((0, utils_js_1._isToolCall)(input)) {
77
87
  toolInput = input.args;
78
88
  enrichedConfig = {
@@ -37,6 +37,10 @@ export declare abstract class StructuredTool<SchemaT = ToolInputSchemaBase, Sche
37
37
  * @default "content"
38
38
  */
39
39
  responseFormat?: ResponseFormat;
40
+ /**
41
+ * Default config object for the tool runnable.
42
+ */
43
+ defaultConfig?: ToolRunnableConfig;
40
44
  constructor(fields?: ToolParams);
41
45
  protected abstract _call(arg: SchemaOutputT, runManager?: CallbackManagerForToolRun, parentConfig?: ToolRunnableConfig): Promise<ToolOutputT>;
42
46
  /**
@@ -2,7 +2,7 @@ import { z } from "zod/v3";
2
2
  import { validate, } from "@cfworker/json-schema";
3
3
  import { CallbackManager, parseCallbackConfigArg, } from "../callbacks/manager.js";
4
4
  import { BaseLangChain } from "../language_models/base.js";
5
- import { ensureConfig, patchConfig, pickRunnableConfigKeys, } from "../runnables/config.js";
5
+ import { mergeConfigs, ensureConfig, patchConfig, pickRunnableConfigKeys, } from "../runnables/config.js";
6
6
  import { isDirectToolOutput, ToolMessage } from "../messages/tool.js";
7
7
  import { AsyncLocalStorageProviderSingleton } from "../singletons/index.js";
8
8
  import { _configHasToolCallId, _isToolCall, ToolInputParsingException, } from "./utils.js";
@@ -52,9 +52,19 @@ export class StructuredTool extends BaseLangChain {
52
52
  writable: true,
53
53
  value: "content"
54
54
  });
55
+ /**
56
+ * Default config object for the tool runnable.
57
+ */
58
+ Object.defineProperty(this, "defaultConfig", {
59
+ enumerable: true,
60
+ configurable: true,
61
+ writable: true,
62
+ value: void 0
63
+ });
55
64
  this.verboseParsingErrors =
56
65
  fields?.verboseParsingErrors ?? this.verboseParsingErrors;
57
66
  this.responseFormat = fields?.responseFormat ?? this.responseFormat;
67
+ this.defaultConfig = fields?.defaultConfig ?? this.defaultConfig;
58
68
  }
59
69
  /**
60
70
  * Invokes the tool with the provided input and configuration.
@@ -64,7 +74,7 @@ export class StructuredTool extends BaseLangChain {
64
74
  */
65
75
  async invoke(input, config) {
66
76
  let toolInput;
67
- let enrichedConfig = ensureConfig(config);
77
+ let enrichedConfig = ensureConfig(mergeConfigs(this.defaultConfig, config));
68
78
  if (_isToolCall(input)) {
69
79
  toolInput = input.args;
70
80
  enrichedConfig = {
@@ -48,6 +48,10 @@ export interface ToolParams extends BaseLangChainParams {
48
48
  * @default "content"
49
49
  */
50
50
  responseFormat?: ResponseFormat;
51
+ /**
52
+ * Default config object for the tool runnable.
53
+ */
54
+ defaultConfig?: ToolRunnableConfig;
51
55
  /**
52
56
  * Whether to show full details in the thrown parsing errors.
53
57
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/core",
3
- "version": "0.3.65",
3
+ "version": "0.3.67",
4
4
  "description": "Core LangChain.js abstractions and schemas",
5
5
  "type": "module",
6
6
  "engines": {