{"version":3,"file":"middleware.cjs","names":["RunnableCallable","getHookConstraint","derivePrivateState"],"sources":["../../../src/agents/nodes/middleware.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { z } from \"zod/v4\";\nimport { LangGraphRunnableConfig, Command } from \"@langchain/langgraph\";\nimport { interopParse } from \"@langchain/core/utils/types\";\n\nimport { RunnableCallable, RunnableCallableArgs } from \"../RunnableCallable.js\";\nimport type { JumpToTarget } from \"../constants.js\";\nimport type { Runtime } from \"../runtime.js\";\nimport type { AgentMiddleware, MiddlewareResult } from \"../middleware/types.js\";\nimport { derivePrivateState } from \"./utils.js\";\nimport { getHookConstraint } from \"../middleware/utils.js\";\n\n/**\n * Named class for context objects to provide better error messages\n */\nclass AgentContext {}\nclass AgentRuntime {}\n\ntype NodeOutput<TStateSchema extends Record<string, any>> =\n  | TStateSchema\n  | Command<any, TStateSchema, string>\n  | { jumpTo?: JumpToTarget };\n\nexport abstract class MiddlewareNode<\n  TStateSchema extends Record<string, any>,\n  TContextSchema extends Record<string, any>,\n> extends RunnableCallable<TStateSchema, NodeOutput<TStateSchema>> {\n  abstract middleware: AgentMiddleware<\n    z.ZodObject<z.ZodRawShape>,\n    z.ZodObject<z.ZodRawShape>\n  >;\n\n  constructor(\n    fields: RunnableCallableArgs<TStateSchema, NodeOutput<TStateSchema>>\n  ) {\n    super(fields);\n  }\n\n  abstract runHook(\n    state: TStateSchema,\n    config?: Runtime<TContextSchema>\n  ): Promise<MiddlewareResult<TStateSchema>> | MiddlewareResult<TStateSchema>;\n\n  async invokeMiddleware(\n    invokeState: TStateSchema,\n    config?: LangGraphRunnableConfig\n  ): Promise<NodeOutput<TStateSchema>> {\n    /**\n     * Filter context based on middleware's contextSchema\n     */\n    let filteredContext = {} as TContextSchema;\n    /**\n     * Parse context using middleware's contextSchema to apply defaults and validation\n     */\n    if (this.middleware.contextSchema) {\n      /**\n       * Extract only the fields relevant to this middleware's schema\n       */\n      const schemaShape = this.middleware.contextSchema?.shape;\n      if (schemaShape) {\n        const relevantContext: Record<string, unknown> = {};\n        const invokeContext = config?.context || {};\n        for (const key of Object.keys(schemaShape)) {\n          if (key in invokeContext) {\n            relevantContext[key] = invokeContext[key];\n          }\n        }\n        /**\n         * Parse to apply defaults and validation, even if relevantContext is empty\n         * This will throw if required fields are missing and no defaults exist\n         */\n        filteredContext = interopParse(\n          this.middleware.contextSchema,\n          relevantContext\n        ) as TContextSchema;\n      }\n    }\n\n    const state: TStateSchema = {\n      ...invokeState,\n      /**\n       * don't overwrite possible outdated messages from other middleware nodes\n       */\n      messages: invokeState.messages,\n    };\n\n    const runtime: Runtime<TContextSchema> = {\n      context: filteredContext,\n      store: config?.store,\n      configurable: config?.configurable,\n      writer: config?.writer,\n      interrupt: config?.interrupt,\n      signal: config?.signal,\n    };\n\n    const result = await this.runHook(\n      state,\n      /**\n       * assign runtime and context values into empty named class\n       * instances to create a better error message.\n       */\n      Object.freeze(\n        Object.assign(new AgentRuntime(), {\n          ...runtime,\n          context: Object.freeze(\n            Object.assign(new AgentContext(), filteredContext)\n          ),\n        })\n      )\n    );\n\n    /**\n     * If result is undefined, the hook made no state changes — return\n     * only the jumpTo sentinel so we don't re-emit every input key as\n     * a state update.\n     */\n    if (!result) {\n      return { jumpTo: undefined };\n    }\n\n    /**\n     * Verify that the jump target is allowed for the middleware\n     */\n    let jumpToConstraint: JumpToTarget[] | undefined;\n    let constraint: string | undefined;\n\n    if (this.name?.startsWith(\"BeforeAgentNode_\")) {\n      jumpToConstraint = getHookConstraint(this.middleware.beforeAgent);\n      constraint = \"beforeAgent.canJumpTo\";\n    } else if (this.name?.startsWith(\"BeforeModelNode_\")) {\n      jumpToConstraint = getHookConstraint(this.middleware.beforeModel);\n      constraint = \"beforeModel.canJumpTo\";\n    } else if (this.name?.startsWith(\"AfterAgentNode_\")) {\n      jumpToConstraint = getHookConstraint(this.middleware.afterAgent);\n      constraint = \"afterAgent.canJumpTo\";\n    } else if (this.name?.startsWith(\"AfterModelNode_\")) {\n      jumpToConstraint = getHookConstraint(this.middleware.afterModel);\n      constraint = \"afterModel.canJumpTo\";\n    }\n\n    if (\n      typeof result.jumpTo === \"string\" &&\n      !jumpToConstraint?.includes(result.jumpTo as JumpToTarget)\n    ) {\n      const suggestion =\n        jumpToConstraint && jumpToConstraint.length > 0\n          ? `must be one of: ${jumpToConstraint?.join(\", \")}.`\n          : constraint\n            ? `no ${constraint} defined in middleware ${this.middleware.name}`\n            : \"\";\n      throw new Error(`Invalid jump target: ${result.jumpTo}, ${suggestion}.`);\n    }\n\n    /**\n     * If result is a control action, handle it\n     */\n    if (typeof result === \"object\" && \"type\" in result) {\n      // Handle control actions\n      if (result.type === \"terminate\") {\n        if (result.error) {\n          throw result.error;\n        }\n        return {\n          ...state,\n          ...(result.result || {}),\n          jumpTo: result.jumpTo,\n        };\n      }\n\n      throw new Error(`Invalid control action: ${JSON.stringify(result)}`);\n    }\n\n    /**\n     * If result is a state update, merge it with current state\n     */\n    return { ...state, ...result, jumpTo: result.jumpTo };\n  }\n\n  get nodeOptions() {\n    return {\n      input: derivePrivateState(this.middleware.stateSchema),\n    };\n  }\n}\n"],"mappings":";;;;;;;;;AAeA,IAAM,eAAN,MAAmB;AACnB,IAAM,eAAN,MAAmB;AAOnB,IAAsB,iBAAtB,cAGUA,yBAAAA,iBAAyD;CAMjE,YACE,QACA;AACA,QAAM,OAAO;;CAQf,MAAM,iBACJ,aACA,QACmC;;;;EAInC,IAAI,kBAAkB,EAAE;;;;AAIxB,MAAI,KAAK,WAAW,eAAe;;;;GAIjC,MAAM,cAAc,KAAK,WAAW,eAAe;AACnD,OAAI,aAAa;IACf,MAAM,kBAA2C,EAAE;IACnD,MAAM,gBAAgB,QAAQ,WAAW,EAAE;AAC3C,SAAK,MAAM,OAAO,OAAO,KAAK,YAAY,CACxC,KAAI,OAAO,cACT,iBAAgB,OAAO,cAAc;;;;;AAOzC,uBAAA,GAAA,4BAAA,cACE,KAAK,WAAW,eAChB,gBACD;;;EAIL,MAAM,QAAsB;GAC1B,GAAG;GAIH,UAAU,YAAY;GACvB;EAED,MAAM,UAAmC;GACvC,SAAS;GACT,OAAO,QAAQ;GACf,cAAc,QAAQ;GACtB,QAAQ,QAAQ;GAChB,WAAW,QAAQ;GACnB,QAAQ,QAAQ;GACjB;EAED,MAAM,SAAS,MAAM,KAAK;GACxB;;;;;GAKA,OAAO,OACL,OAAO,OAAO,IAAI,cAAc,EAAE;IAChC,GAAG;IACH,SAAS,OAAO,OACd,OAAO,OAAO,IAAI,cAAc,EAAE,gBAAgB,CACnD;IACF,CAAC,CACH;GACF;;;;;;AAOD,MAAI,CAAC,OACH,QAAO,EAAE,QAAQ,KAAA,GAAW;;;;EAM9B,IAAI;EACJ,IAAI;AAEJ,MAAI,KAAK,MAAM,WAAW,mBAAmB,EAAE;AAC7C,sBAAmBC,gBAAAA,kBAAkB,KAAK,WAAW,YAAY;AACjE,gBAAa;aACJ,KAAK,MAAM,WAAW,mBAAmB,EAAE;AACpD,sBAAmBA,gBAAAA,kBAAkB,KAAK,WAAW,YAAY;AACjE,gBAAa;aACJ,KAAK,MAAM,WAAW,kBAAkB,EAAE;AACnD,sBAAmBA,gBAAAA,kBAAkB,KAAK,WAAW,WAAW;AAChE,gBAAa;aACJ,KAAK,MAAM,WAAW,kBAAkB,EAAE;AACnD,sBAAmBA,gBAAAA,kBAAkB,KAAK,WAAW,WAAW;AAChE,gBAAa;;AAGf,MACE,OAAO,OAAO,WAAW,YACzB,CAAC,kBAAkB,SAAS,OAAO,OAAuB,EAC1D;GACA,MAAM,aACJ,oBAAoB,iBAAiB,SAAS,IAC1C,mBAAmB,kBAAkB,KAAK,KAAK,CAAC,KAChD,aACE,MAAM,WAAW,yBAAyB,KAAK,WAAW,SAC1D;AACR,SAAM,IAAI,MAAM,wBAAwB,OAAO,OAAO,IAAI,WAAW,GAAG;;;;;AAM1E,MAAI,OAAO,WAAW,YAAY,UAAU,QAAQ;AAElD,OAAI,OAAO,SAAS,aAAa;AAC/B,QAAI,OAAO,MACT,OAAM,OAAO;AAEf,WAAO;KACL,GAAG;KACH,GAAI,OAAO,UAAU,EAAE;KACvB,QAAQ,OAAO;KAChB;;AAGH,SAAM,IAAI,MAAM,2BAA2B,KAAK,UAAU,OAAO,GAAG;;;;;AAMtE,SAAO;GAAE,GAAG;GAAO,GAAG;GAAQ,QAAQ,OAAO;GAAQ;;CAGvD,IAAI,cAAc;AAChB,SAAO,EACL,OAAOC,cAAAA,mBAAmB,KAAK,WAAW,YAAY,EACvD"}