{"version":3,"file":"middleware.cjs","names":["RunnableCallable","getHookConstraint","derivePrivateState"],"sources":["../../../src/agents/nodes/middleware.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { LangGraphRunnableConfig, Command } from \"@langchain/langgraph\";\nimport {\n  getInteropZodObjectShape,\n  interopParse,\n  isInteropZodObject,\n} 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 {\n  AnyAgentMiddleware,\n  MiddlewareResult,\n} 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: AnyAgentMiddleware;\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 (\n      this.middleware.contextSchema &&\n      isInteropZodObject(this.middleware.contextSchema)\n    ) {\n      /**\n       * Extract only the fields relevant to this middleware's schema\n       */\n      const schemaShape = getInteropZodObjectShape(\n        this.middleware.contextSchema\n      );\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":";;;;;;;;AAqBA,IAAM,eAAN,MAAmB,CAAC;AACpB,IAAM,eAAN,MAAmB,CAAC;AAOpB,IAAsB,iBAAtB,cAGUA,yBAAAA,iBAAyD;CAGjE,YACE,QACA;EACA,MAAM,MAAM;CACd;CAOA,MAAM,iBACJ,aACA,QACmC;;;;EAInC,IAAI,kBAAkB,CAAC;;;;EAIvB,IACE,KAAK,WAAW,kBAAA,GAAA,4BAAA,mBAAA,CACG,KAAK,WAAW,aAAa,GAChD;;;;GAIA,MAAM,eAAA,GAAA,4BAAA,yBAAA,CACJ,KAAK,WAAW,aAClB;GACA,IAAI,aAAa;IACf,MAAM,kBAA2C,CAAC;IAClD,MAAM,gBAAgB,QAAQ,WAAW,CAAC;IAC1C,KAAK,MAAM,OAAO,OAAO,KAAK,WAAW,GACvC,IAAI,OAAO,eACT,gBAAgB,OAAO,cAAc;;;;;IAOzC,mBAAA,GAAA,4BAAA,aAAA,CACE,KAAK,WAAW,eAChB,eACF;GACF;EACF;EAEA,MAAM,QAAsB;GAC1B,GAAG;;;;GAIH,UAAU,YAAY;EACxB;EAEA,MAAM,UAAmC;GACvC,SAAS;GACT,OAAO,QAAQ;GACf,cAAc,QAAQ;GACtB,QAAQ,QAAQ;GAChB,WAAW,QAAQ;GACnB,QAAQ,QAAQ;EAClB;EAEA,MAAM,SAAS,MAAM,KAAK;GACxB;;;;;GAKA,OAAO,OACL,OAAO,OAAO,IAAI,aAAa,GAAG;IAChC,GAAG;IACH,SAAS,OAAO,OACd,OAAO,OAAO,IAAI,aAAa,GAAG,eAAe,CACnD;GACF,CAAC,CACH;EACF;;;;;;EAOA,IAAI,CAAC,QACH,OAAO,EAAE,QAAQ,KAAA,EAAU;;;;EAM7B,IAAI;EACJ,IAAI;EAEJ,IAAI,KAAK,MAAM,WAAW,kBAAkB,GAAG;GAC7C,mBAAmBC,gBAAAA,kBAAkB,KAAK,WAAW,WAAW;GAChE,aAAa;EACf,OAAO,IAAI,KAAK,MAAM,WAAW,kBAAkB,GAAG;GACpD,mBAAmBA,gBAAAA,kBAAkB,KAAK,WAAW,WAAW;GAChE,aAAa;EACf,OAAO,IAAI,KAAK,MAAM,WAAW,iBAAiB,GAAG;GACnD,mBAAmBA,gBAAAA,kBAAkB,KAAK,WAAW,UAAU;GAC/D,aAAa;EACf,OAAO,IAAI,KAAK,MAAM,WAAW,iBAAiB,GAAG;GACnD,mBAAmBA,gBAAAA,kBAAkB,KAAK,WAAW,UAAU;GAC/D,aAAa;EACf;EAEA,IACE,OAAO,OAAO,WAAW,YACzB,CAAC,kBAAkB,SAAS,OAAO,MAAsB,GACzD;GACA,MAAM,aACJ,oBAAoB,iBAAiB,SAAS,IAC1C,mBAAmB,kBAAkB,KAAK,IAAI,EAAE,KAChD,aACE,MAAM,WAAW,yBAAyB,KAAK,WAAW,SAC1D;GACR,MAAM,IAAI,MAAM,wBAAwB,OAAO,OAAO,IAAI,WAAW,EAAE;EACzE;;;;EAKA,IAAI,OAAO,WAAW,YAAY,UAAU,QAAQ;GAElD,IAAI,OAAO,SAAS,aAAa;IAC/B,IAAI,OAAO,OACT,MAAM,OAAO;IAEf,OAAO;KACL,GAAG;KACH,GAAI,OAAO,UAAU,CAAC;KACtB,QAAQ,OAAO;IACjB;GACF;GAEA,MAAM,IAAI,MAAM,2BAA2B,KAAK,UAAU,MAAM,GAAG;EACrE;;;;EAKA,OAAO;GAAE,GAAG;GAAO,GAAG;GAAQ,QAAQ,OAAO;EAAO;CACtD;CAEA,IAAI,cAAc;EAChB,OAAO,EACL,OAAOC,cAAAA,mBAAmB,KAAK,WAAW,WAAW,EACvD;CACF;AACF"}