@langchain/langgraph
Version:
LangGraph
172 lines (170 loc) • 8.86 kB
TypeScript
import { BaseChatModel } from "@langchain/core/language_models/chat_models";
import { LanguageModelLike } from "@langchain/core/language_models/base";
import { BaseMessage, BaseMessageLike, SystemMessage } from "@langchain/core/messages";
import { Runnable, RunnableToolLike, type RunnableLike } from "@langchain/core/runnables";
import { DynamicTool, StructuredToolInterface } from "@langchain/core/tools";
import { All, BaseCheckpointSaver, BaseStore } from "@langchain/langgraph-checkpoint";
import { z } from "zod";
import { type CompiledStateGraph, AnnotationRoot } from "../graph/index.js";
import { MessagesAnnotation } from "../graph/messages_annotation.js";
import { ToolNode } from "./tool_node.js";
import { LangGraphRunnableConfig } from "../pregel/runnable_types.js";
import { Messages } from "../graph/message.js";
import { START } from "../constants.js";
export interface AgentState<StructuredResponseType extends Record<string, any> = Record<string, any>> {
messages: BaseMessage[];
structuredResponse: StructuredResponseType;
}
export type N = typeof START | "agent" | "tools";
export type StructuredResponseSchemaAndPrompt<StructuredResponseType> = {
prompt: string;
schema: z.ZodType<StructuredResponseType> | Record<string, any>;
};
type ServerTool = Record<string, unknown>;
type ClientTool = StructuredToolInterface | DynamicTool | RunnableToolLike;
interface ConfigurableModelInterface {
_queuedMethodOperations: Record<string, any>;
_model: () => Promise<BaseChatModel>;
}
export declare function _shouldBindTools(llm: LanguageModelLike, tools: (ClientTool | ServerTool)[]): Promise<boolean>;
export declare function _getModel(llm: LanguageModelLike | ConfigurableModelInterface): Promise<BaseChatModel>;
export type Prompt = SystemMessage | string | ((state: typeof MessagesAnnotation.State, config: LangGraphRunnableConfig) => BaseMessageLike[]) | ((state: typeof MessagesAnnotation.State, config: LangGraphRunnableConfig) => Promise<BaseMessageLike[]>) | Runnable;
/** @deprecated Use Prompt instead. */
export type StateModifier = Prompt;
/** @deprecated Use Prompt instead. */
export type MessageModifier = SystemMessage | string | ((messages: BaseMessage[]) => BaseMessage[]) | ((messages: BaseMessage[]) => Promise<BaseMessage[]>) | Runnable;
export declare const createReactAgentAnnotation: <T extends Record<string, any> = Record<string, any>>() => AnnotationRoot<{
messages: import("../web.js").BinaryOperatorAggregate<BaseMessage[], Messages>;
structuredResponse: {
(): import("../web.js").LastValue<T>;
(annotation: import("../web.js").SingleReducer<T, T>): import("../web.js").BinaryOperatorAggregate<T, T>;
Root: <S extends import("../web.js").StateDefinition>(sd: S) => AnnotationRoot<S>;
};
}>;
declare const PreHookAnnotation: AnnotationRoot<{
llmInputMessages: import("../web.js").BinaryOperatorAggregate<BaseMessage[], Messages>;
}>;
type PreHookAnnotation = typeof PreHookAnnotation;
export type CreateReactAgentParams<A extends AnnotationRoot<any> = AnnotationRoot<any>, StructuredResponseType = Record<string, any>> = {
/** The chat model that can utilize OpenAI-style tool calling. */
llm: LanguageModelLike;
/** A list of tools or a ToolNode. */
tools: ToolNode | (ServerTool | ClientTool)[];
/**
* @deprecated Use prompt instead.
*/
messageModifier?: MessageModifier;
/**
* @deprecated Use prompt instead.
*/
stateModifier?: StateModifier;
/**
* An optional prompt for the LLM. This takes full graph state BEFORE the LLM is called and prepares the input to LLM.
*
* Can take a few different forms:
*
* - str: This is converted to a SystemMessage and added to the beginning of the list of messages in state["messages"].
* - SystemMessage: this is added to the beginning of the list of messages in state["messages"].
* - Function: This function should take in full graph state and the output is then passed to the language model.
* - Runnable: This runnable should take in full graph state and the output is then passed to the language model.
*
* Note:
* Prior to `v0.2.46`, the prompt was set using `stateModifier` / `messagesModifier` parameters.
* This is now deprecated and will be removed in a future release.
*/
prompt?: Prompt;
stateSchema?: A;
/** An optional checkpoint saver to persist the agent's state. */
checkpointSaver?: BaseCheckpointSaver;
/** An optional checkpoint saver to persist the agent's state. Alias of "checkpointSaver". */
checkpointer?: BaseCheckpointSaver;
/** An optional list of node names to interrupt before running. */
interruptBefore?: N[] | All;
/** An optional list of node names to interrupt after running. */
interruptAfter?: N[] | All;
store?: BaseStore;
/**
* An optional schema for the final agent output.
*
* If provided, output will be formatted to match the given schema and returned in the 'structuredResponse' state key.
* If not provided, `structuredResponse` will not be present in the output state.
*
* Can be passed in as:
* - Zod schema
* - JSON schema
* - { prompt, schema }, where schema is one of the above.
* The prompt will be used together with the model that is being used to generate the structured response.
*
* @remarks
* **Important**: `responseFormat` requires the model to support `.withStructuredOutput()`.
*
* **Note**: The graph will make a separate call to the LLM to generate the structured response after the agent loop is finished.
* This is not the only strategy to get structured responses, see more options in [this guide](https://langchain-ai.github.io/langgraph/how-tos/react-agent-structured-output/).
*/
responseFormat?: z.ZodType<StructuredResponseType> | StructuredResponseSchemaAndPrompt<StructuredResponseType> | Record<string, any>;
/**
* An optional name for the agent.
*/
name?: string;
/**
* Use to specify how to expose the agent name to the underlying supervisor LLM.
- undefined: Relies on the LLM provider {@link AIMessage#name}. Currently, only OpenAI supports this.
- `"inline"`: Add the agent name directly into the content field of the {@link AIMessage} using XML-style tags.
Example: `"How can I help you"` -> `"<name>agent_name</name><content>How can I help you?</content>"`
*/
includeAgentName?: "inline" | undefined;
/**
* An optional node to add before the `agent` node (i.e., the node that calls the LLM).
* Useful for managing long message histories (e.g., message trimming, summarization, etc.).
*/
preModelHook?: RunnableLike<A["State"] & PreHookAnnotation["State"], A["Update"] & PreHookAnnotation["Update"], LangGraphRunnableConfig>;
/**
* An optional node to add after the `agent` node (i.e., the node that calls the LLM).
* Useful for implementing human-in-the-loop, guardrails, validation, or other post-processing.
*/
postModelHook?: RunnableLike<A["State"], A["Update"], LangGraphRunnableConfig>;
};
/**
* Creates a StateGraph agent that relies on a chat model utilizing tool calling.
*
* @example
* ```ts
* import { ChatOpenAI } from "@langchain/openai";
* import { tool } from "@langchain/core/tools";
* import { z } from "zod";
* import { createReactAgent } from "@langchain/langgraph/prebuilt";
*
* const model = new ChatOpenAI({
* model: "gpt-4o",
* });
*
* const getWeather = tool((input) => {
* if (["sf", "san francisco"].includes(input.location.toLowerCase())) {
* return "It's 60 degrees and foggy.";
* } else {
* return "It's 90 degrees and sunny.";
* }
* }, {
* name: "get_weather",
* description: "Call to get the current weather.",
* schema: z.object({
* location: z.string().describe("Location to get the weather for."),
* })
* })
*
* const agent = createReactAgent({ llm: model, tools: [getWeather] });
*
* const inputs = {
* messages: [{ role: "user", content: "what is the weather in SF?" }],
* };
*
* const stream = await agent.stream(inputs, { streamMode: "values" });
*
* for await (const { messages } of stream) {
* console.log(messages);
* }
* // Returns the messages in the state at each step of execution
* ```
*/
export declare function createReactAgent<A extends AnnotationRoot<any> = typeof MessagesAnnotation, StructuredResponseFormat extends Record<string, any> = Record<string, any>>(params: CreateReactAgentParams<A, StructuredResponseFormat>): CompiledStateGraph<A["State"], A["Update"], any, typeof MessagesAnnotation.spec & A["spec"], ReturnType<typeof createReactAgentAnnotation<StructuredResponseFormat>>["spec"] & A["spec"]>;
export {};