@langchain/langgraph 0.2.45 → 0.2.47

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.
@@ -12,11 +12,6 @@ const utils_js_1 = require("../utils.cjs");
12
12
  /**
13
13
  * Define a LangGraph task using the `task` function.
14
14
  *
15
- * !!! warning "Beta"
16
- * The Functional API is currently in beta and is subject to change.
17
- *
18
- * @beta
19
- *
20
15
  * Tasks can only be called from within an {@link entrypoint} or from within a StateGraph.
21
16
  * A task can be called like a regular function with the following differences:
22
17
  *
@@ -75,11 +70,6 @@ exports.task = task;
75
70
  /**
76
71
  * Define a LangGraph workflow using the `entrypoint` function.
77
72
  *
78
- * !!! warning "Beta"
79
- * The Functional API is currently in beta and is subject to change.
80
- *
81
- * @beta
82
- *
83
73
  * ### Function signature
84
74
  *
85
75
  * The wrapped function must accept at most **two parameters**. The first parameter
@@ -251,11 +241,6 @@ exports.entrypoint.final = function final({ value, save, }) {
251
241
  * This function allows workflows to access state that was saved in previous runs
252
242
  * using {@link entrypoint.final}.
253
243
  *
254
- * !!! warning "Beta"
255
- * The Functional API is currently in beta and is subject to change.
256
- *
257
- * @beta
258
- *
259
244
  * @typeParam StateT - The type of the state that was previously saved
260
245
  * @returns The previous saved state from the last invocation of the current thread
261
246
  *
@@ -8,35 +8,21 @@ import { LastValue } from "../channels/last_value.js";
8
8
  import { EntrypointFinal, EntrypointReturnT, EntrypointFinalSaveT, EntrypointFunc, TaskFunc } from "./types.js";
9
9
  /**
10
10
  * Options for the {@link task} function
11
- *
12
- * !!! warning "Beta"
13
- * The Functional API is currently in beta and is subject to change.
14
- *
15
- * @beta
16
11
  */
17
12
  export type TaskOptions = {
18
13
  /**
19
14
  * The name of the task, analogous to the node name in {@link StateGraph}.
20
- *
21
- * @beta
22
15
  */
23
16
  name: string;
24
17
  /**
25
18
  * The retry policy for the task. Configures how many times and under what conditions
26
19
  * the task should be retried if it fails.
27
- *
28
- * @beta
29
20
  */
30
21
  retry?: RetryPolicy;
31
22
  };
32
23
  /**
33
24
  * Define a LangGraph task using the `task` function.
34
25
  *
35
- * !!! warning "Beta"
36
- * The Functional API is currently in beta and is subject to change.
37
- *
38
- * @beta
39
- *
40
26
  * Tasks can only be called from within an {@link entrypoint} or from within a StateGraph.
41
27
  * A task can be called like a regular function with the following differences:
42
28
  *
@@ -83,31 +69,20 @@ export type TaskOptions = {
83
69
  export declare function task<ArgsT extends unknown[], OutputT>(optionsOrName: TaskOptions | string, func: TaskFunc<ArgsT, OutputT>): (...args: ArgsT) => Promise<OutputT>;
84
70
  /**
85
71
  * Options for the {@link entrypoint} function
86
- *
87
- * !!! warning "Beta"
88
- * The Functional API is currently in beta and is subject to change.
89
- *
90
- * @beta
91
72
  */
92
73
  export type EntrypointOptions = {
93
74
  /**
94
75
  * The name of the {@link entrypoint}, analogous to the node name in {@link StateGraph}.
95
76
  * This name is used for logging, debugging, and checkpoint identification.
96
- *
97
- * @beta
98
77
  */
99
78
  name: string;
100
79
  /**
101
80
  * The checkpointer for the {@link entrypoint}. Used to save and restore state between
102
81
  * invocations of the workflow.
103
- *
104
- * @beta
105
82
  */
106
83
  checkpointer?: BaseCheckpointSaver;
107
84
  /**
108
85
  * The store for the {@link entrypoint}. Used to persist data across workflow runs.
109
- *
110
- * @beta
111
86
  */
112
87
  store?: BaseStore;
113
88
  };
@@ -125,11 +100,6 @@ export interface EntrypointFunction {
125
100
  * as well as a separate state value to persist to the checkpoint. This allows workflows
126
101
  * to maintain state between runs while returning different values to the caller.
127
102
  *
128
- * !!! warning "Beta"
129
- * The Functional API is currently in beta and is subject to change.
130
- *
131
- * @beta
132
- *
133
103
  * @typeParam ValueT - The type of the value to return to the caller
134
104
  * @typeParam SaveT - The type of the state to save to the checkpoint
135
105
  * @param value - The value to return to the caller
@@ -152,11 +122,6 @@ export interface EntrypointFunction {
152
122
  /**
153
123
  * Define a LangGraph workflow using the `entrypoint` function.
154
124
  *
155
- * !!! warning "Beta"
156
- * The Functional API is currently in beta and is subject to change.
157
- *
158
- * @beta
159
- *
160
125
  * ### Function signature
161
126
  *
162
127
  * The wrapped function must accept at most **two parameters**. The first parameter
@@ -293,11 +258,6 @@ export declare const entrypoint: EntrypointFunction;
293
258
  * This function allows workflows to access state that was saved in previous runs
294
259
  * using {@link entrypoint.final}.
295
260
  *
296
- * !!! warning "Beta"
297
- * The Functional API is currently in beta and is subject to change.
298
- *
299
- * @beta
300
- *
301
261
  * @typeParam StateT - The type of the state that was previously saved
302
262
  * @returns The previous saved state from the last invocation of the current thread
303
263
  *
@@ -9,11 +9,6 @@ import { isAsyncGeneratorFunction, isGeneratorFunction } from "../utils.js";
9
9
  /**
10
10
  * Define a LangGraph task using the `task` function.
11
11
  *
12
- * !!! warning "Beta"
13
- * The Functional API is currently in beta and is subject to change.
14
- *
15
- * @beta
16
- *
17
12
  * Tasks can only be called from within an {@link entrypoint} or from within a StateGraph.
18
13
  * A task can be called like a regular function with the following differences:
19
14
  *
@@ -71,11 +66,6 @@ export function task(optionsOrName, func) {
71
66
  /**
72
67
  * Define a LangGraph workflow using the `entrypoint` function.
73
68
  *
74
- * !!! warning "Beta"
75
- * The Functional API is currently in beta and is subject to change.
76
- *
77
- * @beta
78
- *
79
69
  * ### Function signature
80
70
  *
81
71
  * The wrapped function must accept at most **two parameters**. The first parameter
@@ -247,11 +237,6 @@ entrypoint.final = function final({ value, save, }) {
247
237
  * This function allows workflows to access state that was saved in previous runs
248
238
  * using {@link entrypoint.final}.
249
239
  *
250
- * !!! warning "Beta"
251
- * The Functional API is currently in beta and is subject to change.
252
- *
253
- * @beta
254
- *
255
240
  * @typeParam StateT - The type of the state that was previously saved
256
241
  * @returns The previous saved state from the last invocation of the current thread
257
242
  *
@@ -6,7 +6,6 @@ const last_value_js_1 = require("../channels/last_value.cjs");
6
6
  const base_js_1 = require("../managed/base.cjs");
7
7
  /**
8
8
  * Should not be instantiated directly. See {@link Annotation}.
9
- * @internal
10
9
  */
11
10
  class AnnotationRoot {
12
11
  constructor(s) {
@@ -33,7 +33,6 @@ export interface AnnotationFunction {
33
33
  }
34
34
  /**
35
35
  * Should not be instantiated directly. See {@link Annotation}.
36
- * @internal
37
36
  */
38
37
  export declare class AnnotationRoot<SD extends StateDefinition> {
39
38
  lc_graph_name: string;
@@ -3,7 +3,6 @@ import { LastValue } from "../channels/last_value.js";
3
3
  import { isConfiguredManagedValue, } from "../managed/base.js";
4
4
  /**
5
5
  * Should not be instantiated directly. See {@link Annotation}.
6
- * @internal
7
6
  */
8
7
  export class AnnotationRoot {
9
8
  constructor(s) {
@@ -220,7 +220,7 @@ class Graph {
220
220
  this.warnIfCompiled("Setting a finish point of a graph that has already been compiled. This will not be reflected in the compiled graph.");
221
221
  return this.addEdge(key, constants_js_1.END);
222
222
  }
223
- compile({ checkpointer, interruptBefore, interruptAfter, } = {}) {
223
+ compile({ checkpointer, interruptBefore, interruptAfter, name, } = {}) {
224
224
  // validate the graph
225
225
  this.validate([
226
226
  ...(Array.isArray(interruptBefore) ? interruptBefore : []),
@@ -242,6 +242,7 @@ class Graph {
242
242
  outputChannels: constants_js_1.END,
243
243
  streamChannels: [],
244
244
  streamMode: "values",
245
+ name,
245
246
  });
246
247
  // attach nodes, edges and branches
247
248
  for (const [key, node] of Object.entries(this.nodes)) {
@@ -54,10 +54,11 @@ export declare class Graph<N extends string = typeof END, RunInput = any, RunOut
54
54
  * @deprecated use `addEdge(key, END)` instead
55
55
  */
56
56
  setFinishPoint(key: N): this;
57
- compile({ checkpointer, interruptBefore, interruptAfter, }?: {
57
+ compile({ checkpointer, interruptBefore, interruptAfter, name, }?: {
58
58
  checkpointer?: BaseCheckpointSaver | false;
59
59
  interruptBefore?: N[] | All;
60
60
  interruptAfter?: N[] | All;
61
+ name?: string;
61
62
  }): CompiledGraph<N>;
62
63
  validate(interrupt?: string[]): void;
63
64
  }
@@ -216,7 +216,7 @@ export class Graph {
216
216
  this.warnIfCompiled("Setting a finish point of a graph that has already been compiled. This will not be reflected in the compiled graph.");
217
217
  return this.addEdge(key, END);
218
218
  }
219
- compile({ checkpointer, interruptBefore, interruptAfter, } = {}) {
219
+ compile({ checkpointer, interruptBefore, interruptAfter, name, } = {}) {
220
220
  // validate the graph
221
221
  this.validate([
222
222
  ...(Array.isArray(interruptBefore) ? interruptBefore : []),
@@ -238,6 +238,7 @@ export class Graph {
238
238
  outputChannels: END,
239
239
  streamChannels: [],
240
240
  streamMode: "values",
241
+ name,
241
242
  });
242
243
  // attach nodes, edges and branches
243
244
  for (const [key, node] of Object.entries(this.nodes)) {
@@ -270,7 +270,7 @@ class StateGraph extends graph_js_1.Graph {
270
270
  this.waitingEdges.add([startKey, endKey]);
271
271
  return this;
272
272
  }
273
- compile({ checkpointer, store, interruptBefore, interruptAfter, } = {}) {
273
+ compile({ checkpointer, store, interruptBefore, interruptAfter, name, } = {}) {
274
274
  // validate the graph
275
275
  this.validate([
276
276
  ...(Array.isArray(interruptBefore) ? interruptBefore : []),
@@ -298,6 +298,7 @@ class StateGraph extends graph_js_1.Graph {
298
298
  streamChannels,
299
299
  streamMode: "updates",
300
300
  store,
301
+ name,
301
302
  });
302
303
  // attach nodes, edges and branches
303
304
  compiled.attachNode(constants_js_1.START);
@@ -117,11 +117,12 @@ export declare class StateGraph<SD extends StateDefinition | unknown, S = SD ext
117
117
  _addSchema(stateDefinition: StateDefinition): void;
118
118
  addNode<K extends string, NodeInput = S>(key: K, action: RunnableLike<NodeInput, U extends object ? U & Record<string, any> : U, LangGraphRunnableConfig<StateType<C>>>, options?: StateGraphAddNodeOptions): StateGraph<SD, S, U, N | K, I, O, C>;
119
119
  addEdge(startKey: typeof START | N | N[], endKey: N | typeof END): this;
120
- compile({ checkpointer, store, interruptBefore, interruptAfter, }?: {
120
+ compile({ checkpointer, store, interruptBefore, interruptAfter, name, }?: {
121
121
  checkpointer?: BaseCheckpointSaver | false;
122
122
  store?: BaseStore;
123
123
  interruptBefore?: N[] | All;
124
124
  interruptAfter?: N[] | All;
125
+ name?: string;
125
126
  }): CompiledStateGraph<S, U, N, I, O, C>;
126
127
  }
127
128
  /**
@@ -267,7 +267,7 @@ export class StateGraph extends Graph {
267
267
  this.waitingEdges.add([startKey, endKey]);
268
268
  return this;
269
269
  }
270
- compile({ checkpointer, store, interruptBefore, interruptAfter, } = {}) {
270
+ compile({ checkpointer, store, interruptBefore, interruptAfter, name, } = {}) {
271
271
  // validate the graph
272
272
  this.validate([
273
273
  ...(Array.isArray(interruptBefore) ? interruptBefore : []),
@@ -295,6 +295,7 @@ export class StateGraph extends Graph {
295
295
  streamChannels,
296
296
  streamMode: "updates",
297
297
  store,
298
+ name,
298
299
  });
299
300
  // attach nodes, edges and branches
300
301
  compiled.attachNode(START);
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toolsCondition = exports.ToolNode = exports.ToolExecutor = exports.createReactAgent = exports.createFunctionCallingExecutor = exports.createAgentExecutor = void 0;
3
+ exports.toolsCondition = exports.ToolNode = exports.ToolExecutor = exports.createReactAgentAnnotation = exports.createReactAgent = exports.createFunctionCallingExecutor = exports.createAgentExecutor = void 0;
4
4
  var agent_executor_js_1 = require("./agent_executor.cjs");
5
5
  Object.defineProperty(exports, "createAgentExecutor", { enumerable: true, get: function () { return agent_executor_js_1.createAgentExecutor; } });
6
6
  var chat_agent_executor_js_1 = require("./chat_agent_executor.cjs");
7
7
  Object.defineProperty(exports, "createFunctionCallingExecutor", { enumerable: true, get: function () { return chat_agent_executor_js_1.createFunctionCallingExecutor; } });
8
8
  var react_agent_executor_js_1 = require("./react_agent_executor.cjs");
9
9
  Object.defineProperty(exports, "createReactAgent", { enumerable: true, get: function () { return react_agent_executor_js_1.createReactAgent; } });
10
+ Object.defineProperty(exports, "createReactAgentAnnotation", { enumerable: true, get: function () { return react_agent_executor_js_1.createReactAgentAnnotation; } });
10
11
  var tool_executor_js_1 = require("./tool_executor.cjs");
11
12
  Object.defineProperty(exports, "ToolExecutor", { enumerable: true, get: function () { return tool_executor_js_1.ToolExecutor; } });
12
13
  var tool_node_js_1 = require("./tool_node.cjs");
@@ -1,6 +1,6 @@
1
1
  export { type AgentExecutorState, createAgentExecutor, } from "./agent_executor.js";
2
2
  export { type FunctionCallingExecutorState, createFunctionCallingExecutor, } from "./chat_agent_executor.js";
3
- export { type AgentState, type CreateReactAgentParams, createReactAgent, } from "./react_agent_executor.js";
3
+ export { type AgentState, type CreateReactAgentParams, createReactAgent, createReactAgentAnnotation, } from "./react_agent_executor.js";
4
4
  export { type ToolExecutorArgs, type ToolInvocationInterface, ToolExecutor, } from "./tool_executor.js";
5
5
  export { ToolNode, toolsCondition, type ToolNodeOptions } from "./tool_node.js";
6
6
  export type { HumanInterruptConfig, ActionRequest, HumanInterrupt, HumanResponse, } from "./interrupt.js";
@@ -1,5 +1,5 @@
1
1
  export { createAgentExecutor, } from "./agent_executor.js";
2
2
  export { createFunctionCallingExecutor, } from "./chat_agent_executor.js";
3
- export { createReactAgent, } from "./react_agent_executor.js";
3
+ export { createReactAgent, createReactAgentAnnotation, } from "./react_agent_executor.js";
4
4
  export { ToolExecutor, } from "./tool_executor.js";
5
5
  export { ToolNode, toolsCondition } from "./tool_node.js";
@@ -8,7 +8,7 @@ const tool_node_js_1 = require("./tool_node.cjs");
8
8
  const annotation_js_1 = require("../graph/annotation.cjs");
9
9
  const message_js_1 = require("../graph/message.cjs");
10
10
  const constants_js_1 = require("../constants.cjs");
11
- function _convertMessageModifierToStateModifier(messageModifier) {
11
+ function _convertMessageModifierToPrompt(messageModifier) {
12
12
  // Handle string or SystemMessage
13
13
  if (typeof messageModifier === "string" ||
14
14
  ((0, messages_1.isBaseMessage)(messageModifier) && messageModifier._getType() === "system")) {
@@ -24,48 +24,99 @@ function _convertMessageModifierToStateModifier(messageModifier) {
24
24
  }
25
25
  throw new Error(`Unexpected type for messageModifier: ${typeof messageModifier}`);
26
26
  }
27
- function _getStateModifierRunnable(stateModifier) {
28
- let stateModifierRunnable;
29
- if (stateModifier == null) {
30
- stateModifierRunnable = runnables_1.RunnableLambda.from((state) => state.messages).withConfig({ runName: "state_modifier" });
31
- }
32
- else if (typeof stateModifier === "string") {
33
- const systemMessage = new messages_1.SystemMessage(stateModifier);
34
- stateModifierRunnable = runnables_1.RunnableLambda.from((state) => {
27
+ const PROMPT_RUNNABLE_NAME = "prompt";
28
+ function _getPromptRunnable(prompt) {
29
+ let promptRunnable;
30
+ if (prompt == null) {
31
+ promptRunnable = runnables_1.RunnableLambda.from((state) => state.messages).withConfig({ runName: PROMPT_RUNNABLE_NAME });
32
+ }
33
+ else if (typeof prompt === "string") {
34
+ const systemMessage = new messages_1.SystemMessage(prompt);
35
+ promptRunnable = runnables_1.RunnableLambda.from((state) => {
35
36
  return [systemMessage, ...(state.messages ?? [])];
36
- }).withConfig({ runName: "state_modifier" });
37
- }
38
- else if ((0, messages_1.isBaseMessage)(stateModifier) &&
39
- stateModifier._getType() === "system") {
40
- stateModifierRunnable = runnables_1.RunnableLambda.from((state) => [
41
- stateModifier,
42
- ...state.messages,
43
- ]).withConfig({ runName: "state_modifier" });
44
- }
45
- else if (typeof stateModifier === "function") {
46
- stateModifierRunnable = runnables_1.RunnableLambda.from(stateModifier).withConfig({
47
- runName: "state_modifier",
37
+ }).withConfig({ runName: PROMPT_RUNNABLE_NAME });
38
+ }
39
+ else if ((0, messages_1.isBaseMessage)(prompt) && prompt._getType() === "system") {
40
+ promptRunnable = runnables_1.RunnableLambda.from((state) => [prompt, ...state.messages]).withConfig({ runName: PROMPT_RUNNABLE_NAME });
41
+ }
42
+ else if (typeof prompt === "function") {
43
+ promptRunnable = runnables_1.RunnableLambda.from(prompt).withConfig({
44
+ runName: PROMPT_RUNNABLE_NAME,
48
45
  });
49
46
  }
50
- else if (runnables_1.Runnable.isRunnable(stateModifier)) {
51
- stateModifierRunnable = stateModifier;
47
+ else if (runnables_1.Runnable.isRunnable(prompt)) {
48
+ promptRunnable = prompt;
52
49
  }
53
50
  else {
54
- throw new Error(`Got unexpected type for 'stateModifier': ${typeof stateModifier}`);
51
+ throw new Error(`Got unexpected type for 'prompt': ${typeof prompt}`);
52
+ }
53
+ return promptRunnable;
54
+ }
55
+ function _getPrompt(prompt, stateModifier, messageModifier) {
56
+ // Check if multiple modifiers exist
57
+ const definedCount = [prompt, stateModifier, messageModifier].filter((x) => x != null).length;
58
+ if (definedCount > 1) {
59
+ throw new Error("Expected only one of prompt, stateModifier, or messageModifier, got multiple values");
60
+ }
61
+ let finalPrompt = prompt;
62
+ if (stateModifier != null) {
63
+ finalPrompt = stateModifier;
64
+ }
65
+ else if (messageModifier != null) {
66
+ finalPrompt = _convertMessageModifierToPrompt(messageModifier);
67
+ }
68
+ return _getPromptRunnable(finalPrompt);
69
+ }
70
+ function _shouldBindTools(llm, tools) {
71
+ if (!runnables_1.Runnable.isRunnable(llm) || !("kwargs" in llm)) {
72
+ return true;
73
+ }
74
+ if (!llm.kwargs ||
75
+ typeof llm.kwargs !== "object" ||
76
+ !("tools" in llm.kwargs)) {
77
+ return true;
55
78
  }
56
- return stateModifierRunnable;
79
+ const boundTools = llm.kwargs.tools;
80
+ if (tools.length !== boundTools.length) {
81
+ throw new Error("Number of tools in the model.bindTools() and tools passed to createReactAgent must match");
82
+ }
83
+ const toolNames = new Set(tools.map((tool) => tool.name));
84
+ const boundToolNames = new Set();
85
+ for (const boundTool of boundTools) {
86
+ let boundToolName;
87
+ // OpenAI-style tool
88
+ if ("type" in boundTool && boundTool.type === "function") {
89
+ boundToolName = boundTool.function.name;
90
+ }
91
+ // Anthropic-style tool
92
+ else if ("name" in boundTool) {
93
+ boundToolName = boundTool.name;
94
+ }
95
+ // unknown tool type so we'll ignore it
96
+ else {
97
+ continue;
98
+ }
99
+ boundToolNames.add(boundToolName);
100
+ }
101
+ const missingTools = [...toolNames].filter((x) => !boundToolNames.has(x));
102
+ if (missingTools.length > 0) {
103
+ throw new Error(`Missing tools '${missingTools}' in the model.bindTools().` +
104
+ `Tools in the model.bindTools() must match the tools passed to createReactAgent.`);
105
+ }
106
+ return false;
57
107
  }
58
- function _getModelPreprocessingRunnable(stateModifier, messageModifier) {
59
- // Check if both modifiers exist
60
- if (stateModifier != null && messageModifier != null) {
61
- throw new Error("Expected value for either stateModifier or messageModifier, got values for both");
108
+ function _getModel(llm) {
109
+ // Get the underlying model from a RunnableBinding or return the model itself
110
+ let model = llm;
111
+ if (runnables_1.Runnable.isRunnable(llm) && "bound" in llm) {
112
+ model = llm.bound;
62
113
  }
63
- // Convert message modifier to state modifier if necessary
64
- if (stateModifier == null && messageModifier != null) {
65
- // eslint-disable-next-line no-param-reassign
66
- stateModifier = _convertMessageModifierToStateModifier(messageModifier);
114
+ if (!("invoke" in model &&
115
+ typeof model.invoke === "function" &&
116
+ "_modelType" in model)) {
117
+ throw new Error(`Expected \`llm\` to be a ChatModel or RunnableBinding (e.g. llm.bind_tools(...)) with invoke() and generate() methods, got ${model.constructor.name}`);
67
118
  }
68
- return _getStateModifierRunnable(stateModifier);
119
+ return model;
69
120
  }
70
121
  const createReactAgentAnnotation = () => annotation_js_1.Annotation.Root({
71
122
  messages: (0, annotation_js_1.Annotation)({
@@ -118,7 +169,7 @@ exports.createReactAgentAnnotation = createReactAgentAnnotation;
118
169
  * ```
119
170
  */
120
171
  function createReactAgent(params) {
121
- const { llm, tools, messageModifier, stateModifier, stateSchema, checkpointSaver, checkpointer, interruptBefore, interruptAfter, store, responseFormat, } = params;
172
+ const { llm, tools, messageModifier, stateModifier, prompt, stateSchema, checkpointSaver, checkpointer, interruptBefore, interruptAfter, store, responseFormat, name, } = params;
122
173
  let toolClasses;
123
174
  if (!Array.isArray(tools)) {
124
175
  toolClasses = tools.tools;
@@ -126,13 +177,17 @@ function createReactAgent(params) {
126
177
  else {
127
178
  toolClasses = tools;
128
179
  }
129
- if (!("bindTools" in llm) || typeof llm.bindTools !== "function") {
130
- throw new Error(`llm ${llm} must define bindTools method.`);
180
+ let modelWithTools;
181
+ if (_shouldBindTools(llm, toolClasses)) {
182
+ if (!("bindTools" in llm) || typeof llm.bindTools !== "function") {
183
+ throw new Error(`llm ${llm} must define bindTools method.`);
184
+ }
185
+ modelWithTools = llm.bindTools(toolClasses);
186
+ }
187
+ else {
188
+ modelWithTools = llm;
131
189
  }
132
- const modelWithTools = llm.bindTools(toolClasses);
133
- // we're passing store here for validation
134
- const preprocessor = _getModelPreprocessingRunnable(stateModifier, messageModifier);
135
- const modelRunnable = preprocessor.pipe(modelWithTools);
190
+ const modelRunnable = _getPrompt(prompt, stateModifier, messageModifier).pipe(modelWithTools);
136
191
  // If any of the tools are configured to return_directly after running,
137
192
  // our graph needs to check if these were called
138
193
  const shouldReturnDirect = new Set(toolClasses
@@ -161,18 +216,22 @@ function createReactAgent(params) {
161
216
  "prompt" in responseFormat &&
162
217
  "schema" in responseFormat) {
163
218
  const { prompt, schema } = responseFormat;
164
- modelWithStructuredOutput = llm.withStructuredOutput(schema);
219
+ modelWithStructuredOutput = _getModel(llm).withStructuredOutput(schema);
165
220
  messages.unshift(new messages_1.SystemMessage({ content: prompt }));
166
221
  }
167
222
  else {
168
- modelWithStructuredOutput = llm.withStructuredOutput(responseFormat);
223
+ modelWithStructuredOutput =
224
+ _getModel(llm).withStructuredOutput(responseFormat);
169
225
  }
170
226
  const response = await modelWithStructuredOutput.invoke(messages, config);
171
227
  return { structuredResponse: response };
172
228
  };
173
229
  const callModel = async (state, config) => {
174
230
  // TODO: Auto-promote streaming.
175
- return { messages: [await modelRunnable.invoke(state, config)] };
231
+ const response = (await modelRunnable.invoke(state, config));
232
+ // add agent name to the AIMessage
233
+ response.name = name;
234
+ return { messages: [response] };
176
235
  };
177
236
  const workflow = new index_js_1.StateGraph(stateSchema ?? (0, exports.createReactAgentAnnotation)())
178
237
  .addNode("agent", callModel)
@@ -219,6 +278,7 @@ function createReactAgent(params) {
219
278
  interruptBefore,
220
279
  interruptAfter,
221
280
  store,
281
+ name,
222
282
  });
223
283
  }
224
284
  exports.createReactAgent = createReactAgent;
@@ -1,7 +1,7 @@
1
- import { BaseChatModel } from "@langchain/core/language_models/chat_models";
1
+ import { LanguageModelLike } from "@langchain/core/language_models/base";
2
2
  import { BaseMessage, BaseMessageLike, SystemMessage } from "@langchain/core/messages";
3
3
  import { Runnable, RunnableToolLike } from "@langchain/core/runnables";
4
- import { StructuredToolInterface } from "@langchain/core/tools";
4
+ import { DynamicTool, StructuredToolInterface } from "@langchain/core/tools";
5
5
  import { All, BaseCheckpointSaver, BaseStore } from "@langchain/langgraph-checkpoint";
6
6
  import { z } from "zod";
7
7
  import { CompiledStateGraph, AnnotationRoot } from "../graph/index.js";
@@ -19,8 +19,10 @@ export type StructuredResponseSchemaAndPrompt<StructuredResponseType> = {
19
19
  prompt: string;
20
20
  schema: z.ZodType<StructuredResponseType> | Record<string, any>;
21
21
  };
22
- export type StateModifier = SystemMessage | string | ((state: typeof MessagesAnnotation.State, config: LangGraphRunnableConfig) => BaseMessageLike[]) | ((state: typeof MessagesAnnotation.State, config: LangGraphRunnableConfig) => Promise<BaseMessageLike[]>) | Runnable;
23
- /** @deprecated Use StateModifier instead. */
22
+ export type Prompt = SystemMessage | string | ((state: typeof MessagesAnnotation.State, config: LangGraphRunnableConfig) => BaseMessageLike[]) | ((state: typeof MessagesAnnotation.State, config: LangGraphRunnableConfig) => Promise<BaseMessageLike[]>) | Runnable;
23
+ /** @deprecated Use Prompt instead. */
24
+ export type StateModifier = Prompt;
25
+ /** @deprecated Use Prompt instead. */
24
26
  export type MessageModifier = SystemMessage | string | ((messages: BaseMessage[]) => BaseMessage[]) | ((messages: BaseMessage[]) => Promise<BaseMessage[]>) | Runnable;
25
27
  export declare const createReactAgentAnnotation: <T extends Record<string, any> = Record<string, any>>() => AnnotationRoot<{
26
28
  messages: import("../web.js").BinaryOperatorAggregate<BaseMessage[], Messages>;
@@ -32,63 +34,32 @@ export declare const createReactAgentAnnotation: <T extends Record<string, any>
32
34
  }>;
33
35
  export type CreateReactAgentParams<A extends AnnotationRoot<any> = AnnotationRoot<any>, StructuredResponseType = Record<string, any>> = {
34
36
  /** The chat model that can utilize OpenAI-style tool calling. */
35
- llm: BaseChatModel;
37
+ llm: LanguageModelLike;
36
38
  /** A list of tools or a ToolNode. */
37
- tools: ToolNode | (StructuredToolInterface | RunnableToolLike)[];
39
+ tools: ToolNode | (StructuredToolInterface | DynamicTool | RunnableToolLike)[];
38
40
  /**
39
- * @deprecated
40
- * Use stateModifier instead. stateModifier works the same as
41
- * messageModifier in that it runs right before calling the chat model,
42
- * but if passed as a function, it takes the full graph state as
43
- * input whenever a tool is called rather than a list of messages.
44
- *
45
- * If a function is passed, it should return a list of messages to
46
- * pass directly to the chat model.
47
- *
48
- * @example
49
- * ```ts
50
- * import { ChatOpenAI } from "@langchain/openai";
51
- * import { MessagesAnnotation } from "@langchain/langgraph";
52
- * import { createReactAgent } from "@langchain/langgraph/prebuilt";
53
- * import { type BaseMessage, SystemMessage } from "@langchain/core/messages";
54
- *
55
- * const model = new ChatOpenAI({
56
- * model: "gpt-4o-mini",
57
- * });
58
- *
59
- * const tools = [...];
60
- *
61
- * // Deprecated style with messageModifier
62
- * const deprecated = createReactAgent({
63
- * llm,
64
- * tools,
65
- * messageModifier: async (messages: BaseMessage[]) => {
66
- * return [new SystemMessage("You are a pirate")].concat(messages);
67
- * }
68
- * });
69
- *
70
- * // New style with stateModifier
71
- * const agent = createReactAgent({
72
- * llm,
73
- * tools,
74
- * stateModifier: async (state: typeof MessagesAnnotation.State) => {
75
- * return [new SystemMessage("You are a pirate.")].concat(messages);
76
- * }
77
- * });
78
- * ```
41
+ * @deprecated Use prompt instead.
79
42
  */
80
43
  messageModifier?: MessageModifier;
81
44
  /**
82
- * An optional state modifier. This takes full graph state BEFORE the LLM is called and prepares the input to LLM.
45
+ * @deprecated Use prompt instead.
46
+ */
47
+ stateModifier?: StateModifier;
48
+ /**
49
+ * An optional prompt for the LLM. This takes full graph state BEFORE the LLM is called and prepares the input to LLM.
83
50
  *
84
51
  * Can take a few different forms:
85
52
  *
86
- * - SystemMessage: this is added to the beginning of the list of messages in state["messages"].
87
53
  * - str: This is converted to a SystemMessage and added to the beginning of the list of messages in state["messages"].
54
+ * - SystemMessage: this is added to the beginning of the list of messages in state["messages"].
88
55
  * - Function: This function should take in full graph state and the output is then passed to the language model.
89
56
  * - Runnable: This runnable should take in full graph state and the output is then passed to the language model.
57
+ *
58
+ * Note:
59
+ * Prior to `v0.2.46`, the prompt was set using `stateModifier` / `messagesModifier` parameters.
60
+ * This is now deprecated and will be removed in a future release.
90
61
  */
91
- stateModifier?: StateModifier;
62
+ prompt?: Prompt;
92
63
  stateSchema?: A;
93
64
  /** An optional checkpoint saver to persist the agent's state. */
94
65
  checkpointSaver?: BaseCheckpointSaver;
@@ -112,6 +83,7 @@ export type CreateReactAgentParams<A extends AnnotationRoot<any> = AnnotationRoo
112
83
  * The prompt will be used together with the model that is being used to generate the structured response.
113
84
  */
114
85
  responseFormat?: z.ZodType<StructuredResponseType> | StructuredResponseSchemaAndPrompt<StructuredResponseType> | Record<string, any>;
86
+ name?: string;
115
87
  };
116
88
  /**
117
89
  * Creates a StateGraph agent that relies on a chat model utilizing tool calling.