UNPKG

langchain

Version:
476 lines (475 loc) 25.4 kB
import { JumpToTarget } from "../constants.cjs"; import { AgentBuiltInState, Runtime } from "../runtime.cjs"; import { ModelRequest } from "../nodes/types.cjs"; import { AIMessage, SystemMessage, ToolMessage } from "@langchain/core/messages"; import { ClientTool, ServerTool } from "@langchain/core/tools"; import { InferInteropZodInput, InferInteropZodOutput, InteropZodDefault, InteropZodObject, InteropZodOptional } from "@langchain/core/utils/types"; import { ToolCall as ToolCall$1 } from "@langchain/core/messages/tool"; import { AnnotationRoot, Command } from "@langchain/langgraph"; import { InteropZodToStateDefinition } from "@langchain/langgraph/zod"; //#region src/agents/middleware/types.d.ts type PromiseOrValue<T> = T | Promise<T>; type AnyAnnotationRoot = AnnotationRoot<any>; /** * Type bag that encapsulates all middleware type parameters. * * This interface bundles all the generic type parameters used throughout the middleware system * into a single configuration object. This pattern simplifies type signatures and makes * it easier to add new type parameters without changing multiple function signatures. * * @typeParam TSchema - The middleware state schema type. Can be an `InteropZodObject` or `undefined`. * * @typeParam TContextSchema - The middleware context schema type. Can be an `InteropZodObject`, * `InteropZodDefault`, `InteropZodOptional`, or `undefined`. * * @typeParam TFullContext - The full context type available to middleware hooks. * * @typeParam TTools - The tools array type registered by the middleware. * * @example * ```typescript * // Define a type configuration * type MyMiddlewareTypes = MiddlewareTypeConfig< * typeof myStateSchema, * typeof myContextSchema, * MyContextType, * typeof myTools * >; * ``` */ interface MiddlewareTypeConfig<TSchema$1 extends InteropZodObject | undefined = InteropZodObject | undefined, TContextSchema$1 extends InteropZodObject | InteropZodDefault<InteropZodObject> | InteropZodOptional<InteropZodObject> | undefined = InteropZodObject | InteropZodDefault<InteropZodObject> | InteropZodOptional<InteropZodObject> | undefined, TFullContext = any, TTools extends readonly (ClientTool | ServerTool)[] = readonly (ClientTool | ServerTool)[]> { /** The middleware state schema type */ Schema: TSchema$1; /** The middleware context schema type */ ContextSchema: TContextSchema$1; /** The full context type */ FullContext: TFullContext; /** The tools array type */ Tools: TTools; } /** * Default type configuration for middleware. * Used when no explicit type parameters are provided. */ type DefaultMiddlewareTypeConfig = MiddlewareTypeConfig; type NormalizedSchemaInput<TSchema$1 extends InteropZodObject | undefined | never = any> = [TSchema$1] extends [never] ? AgentBuiltInState : TSchema$1 extends InteropZodObject ? InferInteropZodOutput<TSchema$1> & AgentBuiltInState : TSchema$1 extends Record<string, unknown> ? TSchema$1 & AgentBuiltInState : AgentBuiltInState; /** * Result type for middleware functions. */ type MiddlewareResult<TState> = (TState & { jumpTo?: JumpToTarget; }) | void; /** * Represents a tool call request for the wrapToolCall hook. * Contains the tool call information along with the agent's current state and runtime. */ interface ToolCallRequest<TState extends Record<string, unknown> = Record<string, unknown>, TContext = unknown> { /** * The tool call to be executed */ toolCall: ToolCall$1; /** * The BaseTool instance being invoked. * Provides access to tool metadata like name, description, schema, etc. */ tool: ClientTool | ServerTool; /** * The current agent state (includes both middleware state and built-in state). */ state: TState & AgentBuiltInState; /** * The runtime context containing metadata, signal, writer, interrupt, etc. */ runtime: Runtime<TContext>; } /** * Handler function type for wrapping tool calls. * Takes a tool call request and returns the tool result or a command. */ type ToolCallHandler<TSchema$1 extends Record<string, unknown> = AgentBuiltInState, TContext = unknown> = (request: ToolCallRequest<TSchema$1, TContext>) => PromiseOrValue<ToolMessage | Command>; /** * Wrapper function type for the wrapToolCall hook. * Allows middleware to intercept and modify tool execution. */ type WrapToolCallHook<TSchema$1 extends InteropZodObject | undefined = undefined, TContext = unknown> = (request: ToolCallRequest<NormalizedSchemaInput<TSchema$1>, TContext>, handler: ToolCallHandler<NormalizedSchemaInput<TSchema$1>, TContext>) => PromiseOrValue<ToolMessage | Command>; /** * Handler function type for wrapping model calls. * Takes a model request and returns the AI message response. * * @param request - The model request containing model, messages, systemPrompt, tools, state, and runtime * @returns The AI message response from the model */ type WrapModelCallHandler<TSchema$1 extends InteropZodObject | undefined = undefined, TContext = unknown> = (request: Omit<ModelRequest<NormalizedSchemaInput<TSchema$1>, TContext>, /** * allow to reset the system prompt or system message */ "systemPrompt" | "systemMessage"> & { systemPrompt?: string; systemMessage?: SystemMessage; }) => PromiseOrValue<AIMessage>; /** * Wrapper function type for the wrapModelCall hook. * Allows middleware to intercept and modify model execution. * This enables you to: * - Modify the request before calling the model (e.g., change system prompt, add/remove tools) * - Handle errors and retry with different parameters * - Post-process the response * - Implement custom caching, logging, or other cross-cutting concerns * * @param request - The model request containing all parameters needed for the model call * @param handler - The function that invokes the model. Call this with a ModelRequest to get the response * @returns The AI message response from the model (or a modified version) */ type WrapModelCallHook<TSchema$1 extends InteropZodObject | undefined = undefined, TContext = unknown> = (request: ModelRequest<NormalizedSchemaInput<TSchema$1>, TContext>, handler: WrapModelCallHandler<TSchema$1, TContext>) => PromiseOrValue<AIMessage>; /** * Handler function type for the beforeAgent hook. * Called once at the start of agent invocation before any model calls or tool executions. * * @param state - The current agent state (includes both middleware state and built-in state) * @param runtime - The runtime context containing metadata, signal, writer, interrupt, etc. * @returns A middleware result containing partial state updates or undefined to pass through */ type BeforeAgentHandler<TSchema$1, TContext> = (state: TSchema$1, runtime: Runtime<TContext>) => PromiseOrValue<MiddlewareResult<Partial<TSchema$1>>>; /** * Hook type for the beforeAgent lifecycle event. * Can be either a handler function or an object with a handler and optional jump targets. * This hook is called once at the start of the agent invocation. */ type BeforeAgentHook<TSchema$1 extends InteropZodObject | undefined = undefined, TContext = unknown> = BeforeAgentHandler<NormalizedSchemaInput<TSchema$1>, TContext> | { hook: BeforeAgentHandler<NormalizedSchemaInput<TSchema$1>, TContext>; canJumpTo?: JumpToTarget[]; }; /** * Handler function type for the beforeModel hook. * Called before the model is invoked and before the wrapModelCall hook. * * @param state - The current agent state (includes both middleware state and built-in state) * @param runtime - The runtime context containing metadata, signal, writer, interrupt, etc. * @returns A middleware result containing partial state updates or undefined to pass through */ type BeforeModelHandler<TSchema$1, TContext> = (state: TSchema$1, runtime: Runtime<TContext>) => PromiseOrValue<MiddlewareResult<Partial<TSchema$1>>>; /** * Hook type for the beforeModel lifecycle event. * Can be either a handler function or an object with a handler and optional jump targets. * This hook is called before each model invocation. */ type BeforeModelHook<TSchema$1 extends InteropZodObject | undefined = undefined, TContext = unknown> = BeforeModelHandler<NormalizedSchemaInput<TSchema$1>, TContext> | { hook: BeforeModelHandler<NormalizedSchemaInput<TSchema$1>, TContext>; canJumpTo?: JumpToTarget[]; }; /** * Handler function type for the afterModel hook. * Called after the model is invoked and before any tools are called. * Allows modifying the agent state after model invocation, e.g., to update tool call parameters. * * @param state - The current agent state (includes both middleware state and built-in state) * @param runtime - The runtime context containing metadata, signal, writer, interrupt, etc. * @returns A middleware result containing partial state updates or undefined to pass through */ type AfterModelHandler<TSchema$1, TContext> = (state: TSchema$1, runtime: Runtime<TContext>) => PromiseOrValue<MiddlewareResult<Partial<TSchema$1>>>; /** * Hook type for the afterModel lifecycle event. * Can be either a handler function or an object with a handler and optional jump targets. * This hook is called after each model invocation. */ type AfterModelHook<TSchema$1 extends InteropZodObject | undefined = undefined, TContext = unknown> = AfterModelHandler<NormalizedSchemaInput<TSchema$1>, TContext> | { hook: AfterModelHandler<NormalizedSchemaInput<TSchema$1>, TContext>; canJumpTo?: JumpToTarget[]; }; /** * Handler function type for the afterAgent hook. * Called once at the end of agent invocation after all model calls and tool executions are complete. * * @param state - The current agent state (includes both middleware state and built-in state) * @param runtime - The runtime context containing metadata, signal, writer, interrupt, etc. * @returns A middleware result containing partial state updates or undefined to pass through */ type AfterAgentHandler<TSchema$1, TContext> = (state: TSchema$1, runtime: Runtime<TContext>) => PromiseOrValue<MiddlewareResult<Partial<TSchema$1>>>; /** * Hook type for the afterAgent lifecycle event. * Can be either a handler function or an object with a handler and optional jump targets. * This hook is called once at the end of the agent invocation. */ type AfterAgentHook<TSchema$1 extends InteropZodObject | undefined = undefined, TContext = unknown> = AfterAgentHandler<NormalizedSchemaInput<TSchema$1>, TContext> | { hook: AfterAgentHandler<NormalizedSchemaInput<TSchema$1>, TContext>; canJumpTo?: JumpToTarget[]; }; /** * Unique symbol used to brand middleware instances. * This prevents functions from being accidentally assignable to AgentMiddleware * since functions have a 'name' property that would otherwise make them structurally compatible. */ declare const MIDDLEWARE_BRAND: unique symbol; /** * Base middleware interface. * * @typeParam TSchema - The middleware state schema type * @typeParam TContextSchema - The middleware context schema type * @typeParam TFullContext - The full context type available to hooks * @typeParam TTools - The tools array type registered by the middleware * * @example * ```typescript * const middleware = createMiddleware({ * name: "myMiddleware", * stateSchema: z.object({ count: z.number() }), * tools: [myTool], * }); * ``` */ interface AgentMiddleware<TSchema$1 extends InteropZodObject | undefined = any, TContextSchema$1 extends InteropZodObject | InteropZodDefault<InteropZodObject> | InteropZodOptional<InteropZodObject> | undefined = any, TFullContext = any, TTools extends readonly (ClientTool | ServerTool)[] = readonly (ClientTool | ServerTool)[]> { /** * Brand property to distinguish middleware instances from plain objects or functions. * This is required and prevents accidental assignment of functions to middleware arrays. */ readonly [MIDDLEWARE_BRAND]: true; /** * Type marker for extracting the MiddlewareTypeConfig from a middleware instance. * This is a phantom property used only for type inference. * @internal */ readonly "~middlewareTypes"?: MiddlewareTypeConfig<TSchema$1, TContextSchema$1, TFullContext, TTools>; /** * The name of the middleware. */ name: string; /** * The schema of the middleware state. Middleware state is persisted between multiple invocations. It can be either: * - A Zod object * - A Zod optional object * - A Zod default object * - Undefined */ stateSchema?: TSchema$1; /** * The schema of the middleware context. Middleware context is read-only and not persisted between multiple invocations. It can be either: * - A Zod object * - A Zod optional object * - A Zod default object * - Undefined */ contextSchema?: TContextSchema$1; /** * Additional tools registered by the middleware. */ tools?: TTools; /** * Wraps tool execution with custom logic. This allows you to: * - Modify tool call parameters before execution * - Handle errors and retry with different parameters * - Post-process tool results * - Implement caching, logging, authentication, or other cross-cutting concerns * - Return Command objects for advanced control flow * * The handler receives a ToolCallRequest containing the tool call, state, and runtime, * along with a handler function to execute the actual tool. * * @param request - The tool call request containing toolCall, state, and runtime. * @param handler - The function that executes the tool. Call this with a ToolCallRequest to get the result. * @returns The tool result as a ToolMessage or a Command for advanced control flow. * * @example * ```ts * wrapToolCall: async (request, handler) => { * console.log(`Calling tool: ${request.tool.name}`); * console.log(`Tool description: ${request.tool.description}`); * * try { * // Execute the tool * const result = await handler(request); * console.log(`Tool ${request.tool.name} succeeded`); * return result; * } catch (error) { * console.error(`Tool ${request.tool.name} failed:`, error); * // Could return a custom error message or retry * throw error; * } * } * ``` * * @example Authentication * ```ts * wrapToolCall: async (request, handler) => { * // Check if user is authorized for this tool * if (!request.runtime.context.isAuthorized(request.tool.name)) { * return new ToolMessage({ * content: "Unauthorized to call this tool", * tool_call_id: request.toolCall.id, * }); * } * return handler(request); * } * ``` * * @example Caching * ```ts * const cache = new Map(); * wrapToolCall: async (request, handler) => { * const cacheKey = `${request.tool.name}:${JSON.stringify(request.toolCall.args)}`; * if (cache.has(cacheKey)) { * return cache.get(cacheKey); * } * const result = await handler(request); * cache.set(cacheKey, result); * return result; * } * ``` */ wrapToolCall?: WrapToolCallHook<TSchema$1, TFullContext>; /** * Wraps the model invocation with custom logic. This allows you to: * - Modify the request before calling the model * - Handle errors and retry with different parameters * - Post-process the response * - Implement custom caching, logging, or other cross-cutting concerns * * @param request - The model request containing model, messages, systemPrompt, tools, state, and runtime. * @param handler - The function that invokes the model. Call this with a ModelRequest to get the response. * @returns The response from the model (or a modified version). * * @example * ```ts * wrapModelCall: async (request, handler) => { * // Modify request before calling * const modifiedRequest = { ...request, systemPrompt: "You are helpful" }; * * try { * // Call the model * return await handler(modifiedRequest); * } catch (error) { * // Handle errors and retry with fallback * const fallbackRequest = { ...request, model: fallbackModel }; * return await handler(fallbackRequest); * } * } * ``` */ wrapModelCall?: WrapModelCallHook<TSchema$1, TFullContext>; /** * The function to run before the agent execution starts. This function is called once at the start of the agent invocation. * It allows to modify the state of the agent before any model calls or tool executions. * * @param state - The middleware state * @param runtime - The middleware runtime * @returns The modified middleware state or undefined to pass through */ beforeAgent?: BeforeAgentHook<TSchema$1, TFullContext>; /** * The function to run before the model call. This function is called before the model is invoked and before the `wrapModelCall` hook. * It allows to modify the state of the agent. * * @param state - The middleware state * @param runtime - The middleware runtime * @returns The modified middleware state or undefined to pass through */ beforeModel?: BeforeModelHook<TSchema$1, TFullContext>; /** * The function to run after the model call. This function is called after the model is invoked and before any tools are called. * It allows to modify the state of the agent after the model is invoked, e.g. to update tool call parameters. * * @param state - The middleware state * @param runtime - The middleware runtime * @returns The modified middleware state or undefined to pass through */ afterModel?: AfterModelHook<TSchema$1, TFullContext>; /** * The function to run after the agent execution completes. This function is called once at the end of the agent invocation. * It allows to modify the final state of the agent after all model calls and tool executions are complete. * * @param state - The middleware state * @param runtime - The middleware runtime * @returns The modified middleware state or undefined to pass through */ afterAgent?: AfterAgentHook<TSchema$1, TFullContext>; } /** * Helper type to filter out properties that start with underscore (private properties) */ type FilterPrivateProps<T> = { [K in keyof T as K extends `_${string}` ? never : K]: T[K] }; /** * Helper type to resolve a MiddlewareTypeConfig from either: * - A MiddlewareTypeConfig directly * - An AgentMiddleware instance (using `typeof middleware`) */ type ResolveMiddlewareTypeConfig<T> = T extends { "~middlewareTypes"?: infer Types; } ? Types extends MiddlewareTypeConfig ? Types : never : T extends MiddlewareTypeConfig ? T : never; /** * Helper type to extract any property from a MiddlewareTypeConfig or AgentMiddleware. * * @typeParam T - The MiddlewareTypeConfig or AgentMiddleware to extract from * @typeParam K - The property key to extract ("Schema" | "ContextSchema" | "FullContext" | "Tools") */ type InferMiddlewareType<T, K$1 extends keyof MiddlewareTypeConfig> = ResolveMiddlewareTypeConfig<T>[K$1]; /** * Shorthand helper to extract the Schema type from a MiddlewareTypeConfig or AgentMiddleware. */ type InferMiddlewareSchema<T> = InferMiddlewareType<T, "Schema">; /** * Shorthand helper to extract the ContextSchema type from a MiddlewareTypeConfig or AgentMiddleware. */ type InferMiddlewareContextSchema<T> = InferMiddlewareType<T, "ContextSchema">; /** * Shorthand helper to extract the FullContext type from a MiddlewareTypeConfig or AgentMiddleware. */ type InferMiddlewareFullContext<T> = InferMiddlewareType<T, "FullContext">; /** * Shorthand helper to extract the Tools type from a MiddlewareTypeConfig or AgentMiddleware. */ type InferMiddlewareToolsFromConfig<T> = InferMiddlewareType<T, "Tools">; type InferChannelType<T extends AnyAnnotationRoot | InteropZodObject> = T extends AnyAnnotationRoot ? ToAnnotationRoot<T>["State"] : T extends InteropZodObject ? InferInteropZodInput<T> : {}; /** * Helper type to infer the state schema type from a middleware * This filters out private properties (those starting with underscore) */ type InferMiddlewareState<T extends AgentMiddleware> = T extends AgentMiddleware<infer TSchema, any, any, any> ? TSchema extends InteropZodObject ? FilterPrivateProps<InferInteropZodOutput<TSchema>> : {} : {}; /** * Helper type to infer the input state schema type from a middleware (all properties optional) * This filters out private properties (those starting with underscore) */ type InferMiddlewareInputState<T extends AgentMiddleware> = T extends AgentMiddleware<infer TSchema, any, any, any> ? TSchema extends InteropZodObject ? FilterPrivateProps<InferInteropZodInput<TSchema>> : {} : {}; /** * Helper type to infer merged state from an array of middleware (just the middleware states) */ type InferMiddlewareStates<T = AgentMiddleware[]> = T extends readonly [] ? {} : T extends readonly [infer First, ...infer Rest] ? First extends AgentMiddleware ? Rest extends readonly AgentMiddleware[] ? InferMiddlewareState<First> & InferMiddlewareStates<Rest> : InferMiddlewareState<First> : {} : {}; /** * Helper type to infer merged input state from an array of middleware (with optional defaults) */ type InferMiddlewareInputStates<T extends readonly AgentMiddleware[]> = T extends readonly [] ? {} : T extends readonly [infer First, ...infer Rest] ? First extends AgentMiddleware ? Rest extends readonly AgentMiddleware[] ? InferMiddlewareInputState<First> & InferMiddlewareInputStates<Rest> : InferMiddlewareInputState<First> : {} : {}; /** * Helper type to infer merged state from an array of middleware (includes built-in state) */ type InferMergedState<T extends readonly AgentMiddleware[]> = InferMiddlewareStates<T> & AgentBuiltInState; /** * Helper type to infer merged input state from an array of middleware (includes built-in state) */ type InferMergedInputState<T extends readonly AgentMiddleware[]> = InferMiddlewareInputStates<T> & AgentBuiltInState; /** * Helper type to infer the context schema type from a middleware */ type InferMiddlewareContext<T extends AgentMiddleware> = T extends AgentMiddleware<any, infer TContextSchema, any, any> ? TContextSchema extends InteropZodObject ? InferInteropZodInput<TContextSchema> : {} : {}; /** * Helper type to infer the input context schema type from a middleware (with optional defaults) */ type InferMiddlewareContextInput<T extends AgentMiddleware> = T extends AgentMiddleware<any, infer TContextSchema, any, any> ? TContextSchema extends InteropZodOptional<infer Inner> ? InferInteropZodInput<Inner> | undefined : TContextSchema extends InteropZodObject ? InferInteropZodInput<TContextSchema> : {} : {}; /** * Helper type to infer merged context from an array of middleware */ type InferMiddlewareContexts<T extends readonly AgentMiddleware[]> = T extends readonly [] ? {} : T extends readonly [infer First, ...infer Rest] ? First extends AgentMiddleware ? Rest extends readonly AgentMiddleware[] ? InferMiddlewareContext<First> & InferMiddlewareContexts<Rest> : InferMiddlewareContext<First> : {} : {}; /** * Helper to merge two context types, preserving undefined unions */ type MergeContextTypes<A, B> = [A] extends [undefined] ? [B] extends [undefined] ? undefined : B | undefined : [B] extends [undefined] ? A | undefined : [A] extends [B] ? A : [B] extends [A] ? B : A & B; /** * Helper type to infer merged input context from an array of middleware (with optional defaults) */ type InferMiddlewareContextInputs<T extends readonly AgentMiddleware[]> = T extends readonly [] ? {} : T extends readonly [infer First, ...infer Rest] ? First extends AgentMiddleware ? Rest extends readonly AgentMiddleware[] ? MergeContextTypes<InferMiddlewareContextInput<First>, InferMiddlewareContextInputs<Rest>> : InferMiddlewareContextInput<First> : {} : {}; /** * Helper type to extract input type from context schema (with optional defaults) */ type InferContextInput<ContextSchema extends AnyAnnotationRoot | InteropZodObject> = ContextSchema extends InteropZodObject ? InferInteropZodInput<ContextSchema> : ContextSchema extends AnyAnnotationRoot ? ToAnnotationRoot<ContextSchema>["State"] : {}; type ToAnnotationRoot<A extends AnyAnnotationRoot | InteropZodObject> = A extends AnyAnnotationRoot ? A : A extends InteropZodObject ? AnnotationRoot<InteropZodToStateDefinition<A>> : never; type InferSchemaInput<A extends AnyAnnotationRoot | InteropZodObject | undefined> = A extends AnyAnnotationRoot | InteropZodObject ? ToAnnotationRoot<A>["State"] : {}; //#endregion export { AfterAgentHook, AfterModelHook, AgentMiddleware, AnyAnnotationRoot, BeforeAgentHook, BeforeModelHook, DefaultMiddlewareTypeConfig, InferChannelType, InferContextInput, InferMergedInputState, InferMergedState, InferMiddlewareContext, InferMiddlewareContextInput, InferMiddlewareContextInputs, InferMiddlewareContextSchema, InferMiddlewareContexts, InferMiddlewareFullContext, InferMiddlewareInputState, InferMiddlewareInputStates, InferMiddlewareSchema, InferMiddlewareState, InferMiddlewareStates, InferMiddlewareToolsFromConfig, InferMiddlewareType, InferSchemaInput, MIDDLEWARE_BRAND, MiddlewareResult, MiddlewareTypeConfig, NormalizedSchemaInput, ResolveMiddlewareTypeConfig, ToAnnotationRoot, ToolCallHandler, ToolCallRequest, WrapModelCallHandler, WrapModelCallHook, WrapToolCallHook }; //# sourceMappingURL=types.d.cts.map