langchain
Version:
Typescript bindings for langchain
1 lines • 8.4 kB
Source Map (JSON)
{"version":3,"file":"middleware.cjs","names":["RunnableCallable","isInteropZodObject","getInteropZodObjectShape","interopParse","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 tracePolicy: this.middleware.tracePolicy,\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,GAChBC,4BAAAA,mBAAAA,CAAmB,KAAK,WAAW,aAAa,GAChD;;;;GAIA,MAAM,eAAA,GAAcC,4BAAAA,yBAAAA,CAClB,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,GAAkBC,4BAAAA,aAAAA,CAChB,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;GACL,OAAOC,cAAAA,mBAAmB,KAAK,WAAW,WAAW;GACrD,aAAa,KAAK,WAAW;EAC/B;CACF;AACF"}