UNPKG

langchain

Version:
71 lines (70 loc) • 3.05 kB
const require_middleware = require("../../../middleware.cjs"); const require_chat_models_universal = require("../../../../chat_models/universal.cjs"); const require_decisions = require("./decisions.cjs"); let _langchain_core_messages = require("@langchain/core/messages"); let zod_v4 = require("zod/v4"); // src/agents/middleware/provider/openai/modelRouter.ts const routeSchema = zod_v4.z.object({ choice: zod_v4.z.string(), confidence: zod_v4.z.number(), probabilities: zod_v4.z.array(zod_v4.z.object({ value: zod_v4.z.string(), probability: zod_v4.z.number() })) }); /** * Routes each agent run to one of several models with the OpenAI Decisions API * (beta). * * Classifies the latest human message once per run and stores the answer in * `modelRoute`, then uses the chosen model for every model call in that run. With * no human message, or a refusal, the agent's own model is used. */ function openAIModelRouterMiddleware(options) { const routes = Object.keys(options.choices); if (!routes.length) throw new Error("openAIModelRouterMiddleware requires at least one choice."); if (!options.instructions.trim()) throw new Error("openAIModelRouterMiddleware instructions must not be empty."); const decide = require_decisions.decider(options.model, { model_route: { type: "choice", instructions: options.instructions, choices: Object.fromEntries(routes.map((route) => [route, options.choices[route].criteria])) } }); const models = /* @__PURE__ */ new Map(); const modelFor = (route) => { if (!Object.hasOwn(options.choices, route)) throw new Error(`Unknown model route "${route}".`); if (!models.has(route)) { const choice = options.choices[route]; const pending = Promise.resolve(typeof choice.model === "string" ? require_chat_models_universal.initChatModel(choice.model) : choice.model); pending.catch(() => models.delete(route)); models.set(route, pending); } return models.get(route); }; return require_middleware.createMiddleware({ name: "OpenAIModelRouterMiddleware", stateSchema: zod_v4.z.object({ modelRoute: routeSchema.nullable().optional() }), async beforeAgent(state, runtime) { const message = [...state.messages].reverse().find((message) => _langchain_core_messages.HumanMessage.isInstance(message)); if (!message) return { modelRoute: null }; const answer = await decide(message, runtime.signal); if (answer?.type !== "choice") return { modelRoute: null }; if (!Object.hasOwn(options.choices, answer.choice)) throw new Error(`OpenAI Decisions selected unknown model route "${answer.choice}".`); const { choice, confidence, probabilities } = answer; return { modelRoute: { choice, confidence, probabilities } }; }, async wrapModelCall(request, handler) { const route = request.state.modelRoute; if (!route) return handler(request); return handler({ ...request, model: await modelFor(route.choice) }); } }); } exports.openAIModelRouterMiddleware = openAIModelRouterMiddleware; //# sourceMappingURL=modelRouter.cjs.map