UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

42 lines (41 loc) • 2.74 kB
import type { Brain } from "../core/types.js"; export interface RoutingBrainOptions { /** Which field of the Model selects the route. Default "provider". */ by?: "provider" | "api"; /** Brain used when no route matches. If omitted, an unmatched model yields an error. */ fallback?: Brain; } /** The two `Model` fields a route can be named by — a catalog entry that carries only a provider word is as good a subject as a whole `Model`. */ type RouteWords = { readonly provider?: string | undefined; readonly api?: string | undefined; }; /** * THE judge of which line serves a model: the model's route word (`provider`, or `api` when `by` says so) IF the route table * has an OWN route under that word, else `undefined` — the fallback (the deployment's gateway) serves it. A word the model * carries without a route, and a model with no string word at all, both answer `undefined`: a route that is not mounted is * not a line, whatever the model says. * * `routes` is the route TABLE itself — the very object a host hands {@link createRoutingBrain}, which asks this function for * every request — so the judge and the router answer from one reading of one table, whatever its shape. The question is * `Object.hasOwn(routes, word)`: it evaluates no entry and lists no keys, so a non-enumerable own route is a route, a lazily * keyed table is asked about the one name it is asked about, and a name the table only inherits (`constructor`, `__proto__`) * is not a route. The judge never reads a route's value: a route mounted under the word IS the line, and when its value is not * a brain the router fails that request on that line (an error terminal naming the route) rather than moving it to the * fallback — so the line this answers is the line the request was sent to, either way. A table that cannot answer the question * (it is not an object, or its trap throws) throws here, and the router fails the request with an error terminal. */ export declare function brainLaneOf(model: RouteWords, routes: Readonly<Record<string, unknown>>, by?: NonNullable<RoutingBrainOptions["by"]>): string | undefined; /** * Route to different brains by a Model field (default `model.provider`). Lets one Runner serve * multiple providers/gateways; compose with `createFailoverBrain` for per-route failover. Which route serves a * model is {@link brainLaneOf}'s answer. * * @example * createRoutingBrain({ * "vllm": createOpenAIBrain({ baseUrl: VLLM }), * "openai": createOpenAIBrain({ baseUrl: OPENAI, apiKey }), * }, { fallback: createOpenAIBrain({ baseUrl: VLLM }) }); */ export declare function createRoutingBrain(routes: Record<string, Brain>, opts?: RoutingBrainOptions): Brain; export {};