langchain
Version:
Typescript bindings for langchain
1 lines • 26.1 kB
Source Map (JSON)
{"version":3,"file":"utils.cjs","names":["StateSchema","AIMessage","AIMessageChunk","Runnable","isBaseChatModel","RunnableBinding","RunnableSequence","isConfigurableModel","MultipleToolsBoundError","SystemMessage","ToolMessage","MiddlewareError"],"sources":["../../src/agents/utils.ts"],"sourcesContent":["import {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n BaseMessageLike,\n SystemMessage,\n MessageContent,\n ToolMessage,\n} from \"@langchain/core/messages\";\nimport { isCommand, StateSchema } from \"@langchain/langgraph\";\nimport {\n type InteropZodObject,\n interopParse,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport {\n BaseChatModel,\n type BaseChatModelCallOptions,\n} from \"@langchain/core/language_models/chat_models\";\nimport { BaseLanguageModelInput } from \"@langchain/core/language_models/base\";\nimport {\n Runnable,\n RunnableLike,\n RunnableConfig,\n RunnableSequence,\n RunnableBinding,\n} from \"@langchain/core/runnables\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\n\nimport {\n isBaseChatModel,\n isConfigurableModel,\n type AgentLanguageModelLike as LanguageModelLike,\n} from \"./model.js\";\nimport { MultipleToolsBoundError, MiddlewareError } from \"./errors.js\";\nimport type { AgentBuiltInState } from \"./runtime.js\";\nimport type {\n ToolCallHandler,\n AnyAgentMiddleware,\n ToolCallRequest,\n WrapToolCallHook,\n} from \"./middleware/types.js\";\n\nconst NAME_PATTERN = /<name>(.*?)<\\/name>/s;\nconst CONTENT_PATTERN = /<content>(.*?)<\\/content>/s;\n\n/**\n * Parse middleware state from the full agent state based on the middleware's stateSchema.\n *\n * Handles two types of state schemas:\n * 1. Zod schemas (v3 or v4) - parsed using interopParse\n * 2. LangGraph StateSchema - extracts only the keys defined in `fields`\n *\n * @param stateSchema - The middleware's state schema (Zod or LangGraph StateSchema)\n * @param state - The full agent state to parse from\n * @returns Parsed state containing only the keys defined in the schema\n */\nfunction parseMiddlewareState(\n stateSchema: unknown,\n state: Record<string, unknown>\n): Record<string, unknown> {\n // Handle LangGraph StateSchema (has `fields` property)\n if (StateSchema.isInstance(stateSchema)) {\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(stateSchema.fields)) {\n if (key in state) {\n result[key] = state[key];\n }\n }\n return result;\n }\n\n // Handle Zod schemas using interopParse\n if (isInteropZodSchema(stateSchema)) {\n return interopParse(stateSchema as InteropZodObject, state);\n }\n\n throw new Error(`Invalid state schema type: ${typeof stateSchema}`);\n}\n\nexport type AgentNameMode = \"inline\";\n\n/**\n * Attach formatted agent names to the messages passed to and from a language model.\n *\n * This is useful for making a message history with multiple agents more coherent.\n *\n * NOTE: agent name is consumed from the message.name field.\n * If you're using an agent built with createAgent, name is automatically set.\n * If you're building a custom agent, make sure to set the name on the AI message returned by the LLM.\n *\n * @param message - Message to add agent name formatting to\n * @returns Message with agent name formatting\n *\n * @internal\n */\nexport function _addInlineAgentName<T extends BaseMessageLike>(\n message: T\n): T | AIMessage {\n if (!AIMessage.isInstance(message) || AIMessageChunk.isInstance(message)) {\n return message;\n }\n\n if (!message.name) {\n return message;\n }\n\n const { name } = message;\n\n if (typeof message.content === \"string\") {\n return new AIMessage({\n ...message.lc_kwargs,\n content: `<name>${name}</name><content>${message.content}</content>`,\n name: undefined,\n });\n }\n\n const updatedContent = [];\n let textBlockCount = 0;\n\n for (const contentBlock of message.content) {\n if (typeof contentBlock === \"string\") {\n textBlockCount += 1;\n updatedContent.push(\n `<name>${name}</name><content>${contentBlock}</content>`\n );\n } else if (\n typeof contentBlock === \"object\" &&\n \"type\" in contentBlock &&\n contentBlock.type === \"text\"\n ) {\n textBlockCount += 1;\n updatedContent.push({\n ...contentBlock,\n text: `<name>${name}</name><content>${contentBlock.text}</content>`,\n });\n } else {\n updatedContent.push(contentBlock);\n }\n }\n\n if (!textBlockCount) {\n updatedContent.unshift({\n type: \"text\",\n text: `<name>${name}</name><content></content>`,\n });\n }\n return new AIMessage({\n ...message.lc_kwargs,\n content: updatedContent as MessageContent,\n name: undefined,\n });\n}\n\n/**\n * Remove explicit name and content XML tags from the AI message content.\n *\n * Examples:\n *\n * @example\n * ```typescript\n * removeInlineAgentName(new AIMessage({ content: \"<name>assistant</name><content>Hello</content>\", name: \"assistant\" }))\n * // AIMessage with content: \"Hello\"\n *\n * removeInlineAgentName(new AIMessage({ content: [{type: \"text\", text: \"<name>assistant</name><content>Hello</content>\"}], name: \"assistant\" }))\n * // AIMessage with content: [{type: \"text\", text: \"Hello\"}]\n * ```\n *\n * @internal\n */\nexport function _removeInlineAgentName<T extends BaseMessage>(message: T): T {\n if (!AIMessage.isInstance(message) || !message.content) {\n return message;\n }\n\n let updatedContent: MessageContent = [];\n let updatedName: string | undefined;\n\n if (Array.isArray(message.content)) {\n updatedContent = message.content\n .filter((block) => {\n if (block.type === \"text\" && typeof block.text === \"string\") {\n const nameMatch = block.text.match(NAME_PATTERN);\n const contentMatch = block.text.match(CONTENT_PATTERN);\n // don't include empty content blocks that were added because there was no text block to modify\n if (nameMatch && (!contentMatch || contentMatch[1] === \"\")) {\n // capture name from text block\n updatedName = nameMatch[1];\n return false;\n }\n return true;\n }\n return true;\n })\n .map((block) => {\n if (block.type === \"text\" && typeof block.text === \"string\") {\n const nameMatch = block.text.match(NAME_PATTERN);\n const contentMatch = block.text.match(CONTENT_PATTERN);\n\n if (!nameMatch || !contentMatch) {\n return block;\n }\n\n // capture name from text block\n updatedName = nameMatch[1];\n\n return {\n ...block,\n text: contentMatch[1],\n };\n }\n return block;\n });\n } else {\n const content = message.content as string;\n const nameMatch = content.match(NAME_PATTERN);\n const contentMatch = content.match(CONTENT_PATTERN);\n\n if (!nameMatch || !contentMatch) {\n return message;\n }\n\n updatedName = nameMatch[1];\n updatedContent = contentMatch[1];\n }\n\n return new AIMessage({\n ...(Object.keys(message.lc_kwargs ?? {}).length > 0\n ? message.lc_kwargs\n : message),\n content: updatedContent,\n name: updatedName,\n }) as T;\n}\n\nexport function isClientTool(\n tool: ClientTool | ServerTool\n): tool is ClientTool {\n return Runnable.isRunnable(tool);\n}\n\n/**\n * Helper function to check if a language model has a bindTools method.\n * @param llm - The language model to check if it has a bindTools method.\n * @returns True if the language model has a bindTools method, false otherwise.\n */\nfunction _isChatModelWithBindTools(\n llm: LanguageModelLike\n): llm is BaseChatModel & Required<Pick<BaseChatModel, \"bindTools\">> {\n if (!isBaseChatModel(llm)) return false;\n return \"bindTools\" in llm && typeof llm.bindTools === \"function\";\n}\n\n/**\n * Helper function to bind tools to a language model.\n * @param llm - The language model to bind tools to.\n * @param toolClasses - The tools to bind to the language model.\n * @param options - The options to pass to the language model.\n * @returns The language model with the tools bound to it.\n */\nconst _simpleBindTools = (\n llm: LanguageModelLike,\n toolClasses: (ClientTool | ServerTool)[],\n options: Partial<BaseChatModelCallOptions> = {}\n) => {\n if (_isChatModelWithBindTools(llm)) {\n return llm.bindTools(toolClasses, options);\n }\n\n if (\n RunnableBinding.isRunnableBinding(llm) &&\n _isChatModelWithBindTools(llm.bound)\n ) {\n const newBound = llm.bound.bindTools(toolClasses, options);\n\n if (RunnableBinding.isRunnableBinding(newBound)) {\n return new RunnableBinding({\n bound: newBound.bound,\n config: { ...llm.config, ...newBound.config },\n kwargs: { ...llm.kwargs, ...newBound.kwargs },\n configFactories: newBound.configFactories ?? llm.configFactories,\n });\n }\n\n return new RunnableBinding({\n bound: newBound,\n config: llm.config,\n kwargs: llm.kwargs,\n configFactories: llm.configFactories,\n });\n }\n\n return null;\n};\n\n/**\n * Check if the LLM already has bound tools and throw if it does.\n *\n * @param llm - The LLM to check.\n * @returns void\n */\nexport function validateLLMHasNoBoundTools(llm: LanguageModelLike): void {\n /**\n * If llm is a function, we can't validate until runtime, so skip\n */\n if (typeof llm === \"function\") {\n return;\n }\n\n let model = llm;\n\n /**\n * If model is a RunnableSequence, find a RunnableBinding in its steps\n */\n if (RunnableSequence.isRunnableSequence(model)) {\n model =\n model.steps.find((step: RunnableLike) =>\n RunnableBinding.isRunnableBinding(step)\n ) || model;\n }\n\n /**\n * If model is configurable, get the underlying model\n */\n if (isConfigurableModel(model)) {\n /**\n * Can't validate async model retrieval in constructor\n */\n return;\n }\n\n /**\n * Check if model is a RunnableBinding with bound tools\n */\n if (RunnableBinding.isRunnableBinding(model)) {\n const hasToolsInKwargs =\n model.kwargs != null &&\n typeof model.kwargs === \"object\" &&\n \"tools\" in model.kwargs &&\n Array.isArray(model.kwargs.tools) &&\n model.kwargs.tools.length > 0;\n\n const hasToolsInConfig =\n model.config != null &&\n typeof model.config === \"object\" &&\n \"tools\" in model.config &&\n Array.isArray(model.config.tools) &&\n model.config.tools.length > 0;\n\n if (hasToolsInKwargs || hasToolsInConfig) {\n throw new MultipleToolsBoundError();\n }\n }\n\n /**\n * Also check if model has tools property directly (e.g., FakeToolCallingModel)\n */\n if (\n \"tools\" in model &&\n model.tools !== undefined &&\n Array.isArray(model.tools) &&\n model.tools.length > 0\n ) {\n throw new MultipleToolsBoundError();\n }\n}\n\n/**\n * Check if the last message in the messages array has tool calls.\n *\n * @param messages - The messages to check.\n * @returns True if the last message has tool calls, false otherwise.\n */\nexport function hasToolCalls(message?: BaseMessage): boolean {\n return Boolean(\n AIMessage.isInstance(message) &&\n message.tool_calls &&\n message.tool_calls.length > 0\n );\n}\n\n/**\n * Normalizes a system prompt to a SystemMessage object.\n * If it's already a SystemMessage, returns it as-is.\n * If it's a string, converts it to a SystemMessage.\n * If it's undefined, creates an empty system message so it is easier to append to it later.\n */\nexport function normalizeSystemPrompt(\n systemPrompt?: string | SystemMessage\n): SystemMessage {\n if (systemPrompt == null) {\n return new SystemMessage(\"\");\n }\n if (SystemMessage.isInstance(systemPrompt)) {\n return systemPrompt;\n }\n if (typeof systemPrompt === \"string\") {\n return new SystemMessage({\n content: [{ type: \"text\", text: systemPrompt }],\n });\n }\n throw new Error(\n `Invalid systemPrompt type: expected string or SystemMessage, got ${typeof systemPrompt}`\n );\n}\n\n/**\n * Helper function to bind tools to a language model.\n * @param llm - The language model to bind tools to.\n * @param toolClasses - The tools to bind to the language model.\n * @param options - The options to pass to the language model.\n * @returns The language model with the tools bound to it.\n */\nexport async function bindTools(\n llm: LanguageModelLike,\n toolClasses: (ClientTool | ServerTool)[],\n options: Partial<BaseChatModelCallOptions> = {}\n): Promise<\n | RunnableSequence<unknown, unknown>\n | RunnableBinding<unknown, unknown, RunnableConfig<Record<string, unknown>>>\n | Runnable<BaseLanguageModelInput, AIMessageChunk, BaseChatModelCallOptions>\n> {\n const model = _simpleBindTools(llm, toolClasses, options);\n if (model) return model;\n\n if (isConfigurableModel(llm)) {\n const model = _simpleBindTools(\n await llm._getModelInstance(),\n toolClasses,\n options\n );\n if (model) return model;\n }\n\n if (RunnableSequence.isRunnableSequence(llm)) {\n const modelStep = llm.steps.findIndex(\n (step) =>\n RunnableBinding.isRunnableBinding(step) ||\n isBaseChatModel(step) ||\n isConfigurableModel(step)\n );\n\n if (modelStep >= 0) {\n const model = _simpleBindTools(\n llm.steps[modelStep],\n toolClasses,\n options\n );\n if (model) {\n const nextSteps: unknown[] = llm.steps.slice();\n nextSteps.splice(modelStep, 1, model);\n\n return RunnableSequence.from(\n nextSteps as [RunnableLike, ...RunnableLike[], RunnableLike]\n );\n }\n }\n }\n\n throw new Error(`llm ${llm} must define bindTools method.`);\n}\n\n/**\n * Compose multiple wrapToolCall handlers into a single middleware stack.\n *\n * Composes handlers so the first in the list becomes the outermost layer.\n * Each handler receives a handler callback to execute inner layers.\n *\n * @param handlers - List of handlers. First handler wraps all others.\n * @returns Composed handler, or undefined if handlers array is empty.\n *\n * @example\n * ```typescript\n * // handlers=[auth, retry] means: auth wraps retry\n * // Flow: auth calls retry, retry calls base handler\n * const auth: ToolCallWrapper = async (request, handler) => {\n * try {\n * return await handler(request);\n * } catch (error) {\n * if (error.message === \"Unauthorized\") {\n * await refreshToken();\n * return await handler(request);\n * }\n * throw error;\n * }\n * };\n *\n * const retry: ToolCallWrapper = async (request, handler) => {\n * for (let attempt = 0; attempt < 3; attempt++) {\n * try {\n * return await handler(request);\n * } catch (error) {\n * if (attempt === 2) throw error;\n * }\n * }\n * throw new Error(\"Unreachable\");\n * };\n *\n * const composedHandler = chainToolCallHandlers([auth, retry]);\n * ```\n */\nfunction chainToolCallHandlers(\n handlers: WrapToolCallHook[]\n): WrapToolCallHook | undefined {\n if (handlers.length === 0) {\n return undefined;\n }\n\n if (handlers.length === 1) {\n return handlers[0];\n }\n\n // Compose two handlers where outer wraps inner\n // The key is to properly propagate request modifications through the chain\n function composeTwo(\n outer: WrapToolCallHook,\n inner: WrapToolCallHook\n ): WrapToolCallHook {\n return async (request, handler) => {\n // Create a wrapper that calls inner with the base handler\n // The innerHandler receives the (possibly modified) request from outer\n // and passes it to inner, which then calls the base handler\n const innerHandler: ToolCallHandler = async (passedRequest) => {\n // inner receives the request passed by outer (which may be modified)\n return inner(passedRequest, handler);\n };\n\n // Call outer with the wrapped inner as its handler\n return outer(request, innerHandler);\n };\n }\n\n // Compose right-to-left: outer(inner(innermost(handler)))\n let result = handlers[handlers.length - 1];\n for (let i = handlers.length - 2; i >= 0; i--) {\n result = composeTwo(handlers[i], result);\n }\n\n return result;\n}\n\n/**\n * Wrapping `wrapToolCall` invocation so we can inject middleware name into\n * the error message.\n *\n * @param middleware list of middleware passed to the agent\n * @param state state of the agent\n * @returns single wrap function\n */\nexport function wrapToolCall(middleware: readonly AnyAgentMiddleware[]) {\n const middlewareWithWrapToolCall = middleware.filter((m) => m.wrapToolCall);\n\n if (middlewareWithWrapToolCall.length === 0) {\n return;\n }\n\n return chainToolCallHandlers(\n middlewareWithWrapToolCall.map((m) => {\n const originalHandler = m.wrapToolCall!;\n /**\n * Wrap with error handling and validation\n */\n const wrappedHandler: WrapToolCallHook = async (request, handler) => {\n /**\n * Capture the original state for this middleware's schema parsing.\n * This is important because the request may be modified (via override)\n * as it passes through the middleware chain, but each middleware\n * should always see the full original state for its schema parsing.\n */\n const originalState = request.state;\n\n /**\n * Create a handler that preserves state parsing for this middleware\n * while allowing tool/toolCall/state modifications from inner middleware\n */\n const wrappedInnerHandler: ToolCallHandler = async (passedRequest) => {\n /**\n * Merge the passed request with the original state for parsing.\n * This ensures middleware can override tool/toolCall while\n * maintaining proper state parsing for each middleware in the chain.\n */\n const mergedState = {\n ...originalState,\n ...passedRequest.state,\n };\n return handler({\n ...passedRequest,\n state: mergedState,\n });\n };\n\n try {\n const result = await originalHandler(\n {\n ...request,\n /**\n * override state with the state from the specific middleware\n */\n state: {\n messages: originalState.messages,\n ...(m.stateSchema\n ? parseMiddlewareState(m.stateSchema, { ...originalState })\n : {}),\n },\n } as ToolCallRequest<AgentBuiltInState, unknown>,\n wrappedInnerHandler\n );\n\n /**\n * Validate return type\n */\n if (!ToolMessage.isInstance(result) && !isCommand(result)) {\n throw new Error(\n `Invalid response from \"wrapToolCall\" in middleware \"${m.name}\": ` +\n `expected ToolMessage or Command, got ${typeof result}`\n );\n }\n\n return result;\n } catch (error) {\n throw MiddlewareError.wrap(error, m.name);\n }\n };\n return wrappedHandler;\n })\n );\n}\n\n/**\n * Static LangGraph config keys propagated from ReactAgent defaults onto the\n * compiled inner graph. This ensures values set via `withConfig()` survive\n * LangGraph API loading, which unwraps ReactAgent to `.graph` before execution.\n */\nconst GRAPH_DEFAULT_CONFIG_KEYS = [\n \"tags\",\n \"metadata\",\n \"runName\",\n \"maxConcurrency\",\n \"recursionLimit\",\n \"configurable\",\n] as const satisfies readonly (keyof RunnableConfig)[];\n\nexport function toGraphDefaultConfig(\n config: RunnableConfig\n): Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\"> {\n const result: Record<string, unknown> = {};\n for (const key of GRAPH_DEFAULT_CONFIG_KEYS) {\n const value = config[key];\n if (value !== undefined) {\n result[key] = value;\n }\n }\n return result as Omit<RunnableConfig, \"store\" | \"writer\" | \"interrupt\">;\n}\n"],"mappings":"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"}