{"version":3,"file":"middleware.cjs","names":["MIDDLEWARE_BRAND"],"sources":["../../src/agents/middleware.ts"],"sourcesContent":["import type {\n  InteropZodObject,\n  InferInteropZodOutput,\n} from \"@langchain/core/utils/types\";\nimport type {\n  StateDefinitionInit,\n  StreamTransformer,\n} from \"@langchain/langgraph\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\n\nimport {\n  MIDDLEWARE_BRAND,\n  type AgentMiddleware,\n  type WrapToolCallHook,\n  type WrapModelCallHook,\n  type BeforeAgentHook,\n  type BeforeModelHook,\n  type AfterModelHook,\n  type AfterAgentHook,\n} from \"./middleware/types.js\";\n\n/**\n * Creates a middleware instance with automatic schema inference.\n *\n * @param config - Middleware configuration\n * @param config.name - The name of the middleware\n * @param config.stateSchema - The schema of the middleware state\n * @param config.contextSchema - The schema of the middleware context\n * @param config.wrapModelCall - The function to wrap model invocation\n * @param config.wrapToolCall - The function to wrap tool invocation\n * @param config.beforeModel - The function to run before the model call\n * @param config.afterModel - The function to run after the model call\n * @param config.beforeAgent - The function to run before the agent execution starts\n * @param config.afterAgent - The function to run after the agent execution completes\n * @param config.tools - Additional tools registered by the middleware\n * @param config.streamTransformers - Stream transformer factories registered by the middleware\n * @returns A middleware instance\n *\n * @example Using Zod schema\n * ```ts\n * const authMiddleware = createMiddleware({\n *   name: \"AuthMiddleware\",\n *   stateSchema: z.object({\n *     isAuthenticated: z.boolean().default(false),\n *   }),\n *   contextSchema: z.object({\n *     userId: z.string(),\n *   }),\n *   beforeModel: async (state, runtime) => {\n *     if (!state.isAuthenticated) {\n *       throw new Error(\"Not authenticated\");\n *     }\n *   },\n * });\n * ```\n *\n * @example Using StateSchema\n * ```ts\n * import { StateSchema, ReducedValue } from \"@langchain/langgraph\";\n *\n * const historyMiddleware = createMiddleware({\n *   name: \"HistoryMiddleware\",\n *   stateSchema: new StateSchema({\n *     count: z.number().default(0),\n *     history: new ReducedValue(\n *       z.array(z.string()).default(() => []),\n *       { inputSchema: z.string(), reducer: (current, next) => [...current, next] }\n *     ),\n *   }),\n *   beforeModel: async (state, runtime) => {\n *     return { count: state.count + 1 };\n *   },\n * });\n * ```\n */\nexport function createMiddleware<\n  TSchema extends StateDefinitionInit | undefined = undefined,\n  TContextSchema extends InteropZodObject | undefined = undefined,\n  const TTools extends readonly (ClientTool | ServerTool)[] = readonly (\n    | ClientTool\n    | ServerTool\n  )[],\n  const TStreamTransformers extends ReadonlyArray<\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    () => StreamTransformer<any>\n  > = readonly [],\n>(config: {\n  /**\n   * The name of the middleware\n   */\n  name: string;\n  /**\n   * The schema of the middleware state. Middleware state is persisted between multiple invocations. It can be either:\n   * - A Zod object (InteropZodObject)\n   * - A StateSchema from LangGraph (supports ReducedValue, UntrackedValue)\n   * - An AnnotationRoot\n   * - Undefined\n   */\n  stateSchema?: TSchema;\n  /**\n   * The schema of the middleware context. Middleware context is read-only and not persisted between multiple invocations. It can be either:\n   * - A Zod object\n   * - A Zod optional object\n   * - A Zod default object\n   * - Undefined\n   */\n  contextSchema?: TContextSchema;\n  /**\n   * Additional tools registered by the middleware.\n   */\n  tools?: TTools;\n  /**\n   * Stream transformer factories registered by the middleware.\n   * Merged with `createAgent({ streamTransformers })` when the agent compiles.\n   */\n  streamTransformers?: TStreamTransformers;\n  /**\n   * Wraps tool execution with custom logic. This allows you to:\n   * - Modify tool call parameters before execution\n   * - Handle errors and retry with different parameters\n   * - Post-process tool results\n   * - Implement caching, logging, authentication, or other cross-cutting concerns\n   * - Return Command objects for advanced control flow\n   *\n   * The handler receives a ToolCallRequest containing the tool call, state, and runtime,\n   * along with a handler function to execute the actual tool.\n   *\n   * @param request - The tool call request containing toolCall, state, and runtime.\n   * @param handler - The function that executes the tool. Call this with a ToolCallRequest to get the result.\n   * @returns The tool result as a ToolMessage or a Command for advanced control flow.\n   *\n   * @example\n   * ```ts\n   * wrapToolCall: async (request, handler) => {\n   *   console.log(`Calling tool: ${request.tool.name}`);\n   *   console.log(`Tool description: ${request.tool.description}`);\n   *\n   *   try {\n   *     // Execute the tool\n   *     const result = await handler(request);\n   *     console.log(`Tool ${request.tool.name} succeeded`);\n   *     return result;\n   *   } catch (error) {\n   *     console.error(`Tool ${request.tool.name} failed:`, error);\n   *     // Could return a custom error message or retry\n   *     throw error;\n   *   }\n   * }\n   * ```\n   *\n   * @example Authentication\n   * ```ts\n   * wrapToolCall: async (request, handler) => {\n   *   // Check if user is authorized for this tool\n   *   if (!request.runtime.context.isAuthorized(request.tool.name)) {\n   *     return new ToolMessage({\n   *       content: \"Unauthorized to call this tool\",\n   *       tool_call_id: request.toolCall.id,\n   *     });\n   *   }\n   *   return handler(request);\n   * }\n   * ```\n   */\n  wrapToolCall?: WrapToolCallHook<\n    TSchema,\n    NormalizeContextSchema<TContextSchema>\n  >;\n\n  /**\n   * Wraps the model invocation with custom logic. This allows you to:\n   * - Modify the request before calling the model\n   * - Handle errors and retry with different parameters\n   * - Post-process the response\n   * - Implement custom caching, logging, or other cross-cutting concerns\n   *\n   * The request parameter contains: model, messages, systemPrompt, tools, state, and runtime.\n   *\n   * @param request - The model request containing all the parameters needed.\n   * @param handler - The function that invokes the model. Call this with a ModelRequest to get the response.\n   * @returns The response from the model (or a modified version).\n   *\n   * @example\n   * ```ts\n   * wrapModelCall: async (request, handler) => {\n   *   // Modify request before calling\n   *   const modifiedRequest = { ...request, systemPrompt: \"You are helpful\" };\n   *\n   *   try {\n   *     // Call the model\n   *     return await handler(modifiedRequest);\n   *   } catch (error) {\n   *     // Handle errors and retry with fallback\n   *     const fallbackRequest = { ...request, model: fallbackModel };\n   *     return await handler(fallbackRequest);\n   *   }\n   * }\n   * ```\n   */\n  wrapModelCall?: WrapModelCallHook<\n    TSchema,\n    NormalizeContextSchema<TContextSchema>\n  >;\n  /**\n   * The function to run before the agent execution starts. This function is called once at the start of the agent invocation.\n   * It allows to modify the state of the agent before any model calls or tool executions.\n   *\n   * @param state - The middleware state\n   * @param runtime - The middleware runtime\n   * @returns The modified middleware state or undefined to pass through\n   */\n  beforeAgent?: BeforeAgentHook<\n    TSchema,\n    NormalizeContextSchema<TContextSchema>\n  >;\n\n  /**\n   * The function to run before the model call. This function is called before the model is invoked and before the `wrapModelCall` hook.\n   * It allows to modify the state of the agent.\n   *\n   * @param state - The middleware state\n   * @param runtime - The middleware runtime\n   * @returns The modified middleware state or undefined to pass through\n   */\n  beforeModel?: BeforeModelHook<\n    TSchema,\n    NormalizeContextSchema<TContextSchema>\n  >;\n\n  /**\n   * The function to run after the model call. This function is called after the model is invoked and before any tools are called.\n   * It allows to modify the state of the agent after the model is invoked, e.g. to update tool call parameters.\n   *\n   * @param state - The middleware state\n   * @param runtime - The middleware runtime\n   * @returns The modified middleware state or undefined to pass through\n   */\n  afterModel?: AfterModelHook<TSchema, NormalizeContextSchema<TContextSchema>>;\n\n  /**\n   * The function to run after the agent execution completes. This function is called once at the end of the agent invocation.\n   * It allows to modify the final state of the agent after all model calls and tool executions are complete.\n   *\n   * @param state - The middleware state\n   * @param runtime - The middleware runtime\n   * @returns The modified middleware state or undefined to pass through\n   */\n  afterAgent?: AfterAgentHook<TSchema, NormalizeContextSchema<TContextSchema>>;\n}): AgentMiddleware<\n  TSchema,\n  TContextSchema,\n  NormalizeContextSchema<TContextSchema>,\n  TTools,\n  TStreamTransformers\n> {\n  const middleware: AgentMiddleware<\n    TSchema,\n    TContextSchema,\n    NormalizeContextSchema<TContextSchema>,\n    TTools,\n    TStreamTransformers\n  > = {\n    [MIDDLEWARE_BRAND]: true as const,\n    name: config.name,\n    stateSchema: config.stateSchema,\n    contextSchema: config.contextSchema,\n    wrapToolCall: config.wrapToolCall,\n    wrapModelCall: config.wrapModelCall,\n    beforeAgent: config.beforeAgent,\n    beforeModel: config.beforeModel,\n    afterModel: config.afterModel,\n    afterAgent: config.afterAgent,\n    tools: config.tools,\n    streamTransformers: config.streamTransformers,\n  };\n\n  return middleware;\n}\n\ntype NormalizeContextSchema<\n  TContextSchema extends InteropZodObject | undefined = undefined,\n> = TContextSchema extends InteropZodObject\n  ? InferInteropZodOutput<TContextSchema>\n  : unknown;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2EA,SAAgB,iBAWd,QAwKA;AAsBA,QAAO;GAdJA,cAAAA,mBAAmB;EACpB,MAAM,OAAO;EACb,aAAa,OAAO;EACpB,eAAe,OAAO;EACtB,cAAc,OAAO;EACrB,eAAe,OAAO;EACtB,aAAa,OAAO;EACpB,aAAa,OAAO;EACpB,YAAY,OAAO;EACnB,YAAY,OAAO;EACnB,OAAO,OAAO;EACd,oBAAoB,OAAO;EAGZ"}