@bastani/atomic 0.9.28 → 0.9.29-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +6 -0
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +6 -0
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +2 -2
- package/dist/builtin/workflows/src/index.js +2 -2
- package/dist/core/execution-model-router.d.ts +1 -1
- package/dist/core/execution-model-router.d.ts.map +1 -1
- package/dist/core/execution-model-router.js +37 -15
- package/dist/core/execution-model-router.js.map +1 -1
- package/dist/core/model-routing-constraints.d.ts +2 -0
- package/dist/core/model-routing-constraints.d.ts.map +1 -1
- package/dist/core/model-routing-constraints.js.map +1 -1
- package/dist/core/service-tier-warnings.d.ts +4 -0
- package/dist/core/service-tier-warnings.d.ts.map +1 -0
- package/dist/core/service-tier-warnings.js +7 -0
- package/dist/core/service-tier-warnings.js.map +1 -0
- package/dist/core/settings-manager-basic-accessors.js +8 -4
- package/dist/core/settings-manager-basic-accessors.js.map +1 -1
- package/dist/core/settings-types.d.ts +5 -1
- package/dist/core/settings-types.d.ts.map +1 -1
- package/dist/core/settings-types.js.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.js +10 -0
- package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +5 -0
- package/dist/modes/print-mode.js.map +1 -1
- package/docs/codemode.md +1 -1
- package/docs/models/model-selection.md +1 -1
- package/docs/models/reference.md +2 -2
- package/docs/providers.md +6 -4
- package/docs/settings.md +18 -6
- package/docs/subagents/reference.md +4 -4
- package/docs/workflows/api-reference.md +4 -4
- package/docs/workflows/authoring.md +4 -0
- package/docs/workflows/operations.md +1 -1
- package/npm-shrinkwrap.json +32 -32
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.9.29-alpha.1] - 2026-10-08
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added `gpt-6.1-sol-ultrafast` and `gpt-5.6-sol-ultrafast` model variants for `openai` and `openai-api`, and `gpt-6.1-sol-ultrafast` for `openai-codex`. GPT-6.1 Sol Ultrafast is priced at OpenAI's published $12 input and $60 output per million tokens; GPT-5.6 Sol Ultrafast is a limited preview without published rates, priced at six times Standard. Ultrafast access depends on your OpenAI account ([#3529](https://github.com/bastani-inc/atomic/issues/3529)).
|
|
10
|
+
- Added OpenAI's GPT Image models (`gpt-image-2.5-flare`, `gpt-image-2.5-sunburst`, `gpt-image-2`, `gpt-image-1.5`, `gpt-image-1`, `gpt-image-1-mini`) as `openai-images` image models for codemode's `models.generateImages()`, extensions, and workflow `generateImages()` calls. They reuse your OpenAI API key, saved for `openai-api` or `openai` or set in `OPENAI_API_KEY`, and have no separate login; a ChatGPT sign-in cannot use them. See [Subscription and API key at the same time](docs/providers.md#subscription-and-api-key-at-the-same-time) ([#3527](https://github.com/bastani-inc/atomic/issues/3527)).
|
|
11
|
+
- Added the `modelRouting.allowedModels` and `modelRouting.excludedModels` settings, which keep workflow stages and subagents with `model: "auto"` from routing to models you did not allow, including through fallbacks. They take full model IDs or glob patterns, matched like `enabledModels` and `--models`. If they leave no eligible model, the stage or subagent fails before launch with an error naming the setting. `routerSelection` now also lists the `candidates` the router could choose from after filtering. See [modelRouting](docs/settings.md#modelrouting) ([#3528](https://github.com/bastani-inc/atomic/issues/3528)).
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- When the OpenAI API or the ChatGPT Codex backend rejects a Fast or Ultrafast tier, Atomic retries the request once at the default tier instead of failing the turn and shows a warning, for example `ultrafast isn't available for gpt-5.6-sol on this account; ran at default`. With an OpenAI API key, Atomic shows the same warning when the server reports a slower tier than the model you selected. Interactive sessions show it under the response, print mode writes it to stderr, and JSON mode includes it in the message's `diagnostics`. With ChatGPT sign-in (`openai` or `openai-codex`) there is no such warning, because the ChatGPT backend reports `default` for every tier it applies ([#3529](https://github.com/bastani-inc/atomic/issues/3529)).
|
|
16
|
+
|
|
5
17
|
## [0.9.28] - 2026-10-08
|
|
6
18
|
|
|
7
19
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/intercom",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.29-alpha.1",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension providing a private coordination channel between parent and child agent sessions. Fork of: https://github.com/nicobailon/pi-intercom",
|
|
6
6
|
"contributors": [
|
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.9.29-alpha.1] - 2026-10-08
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Subagents with `model: "auto"` honor the new `modelRouting.allowedModels` and `modelRouting.excludedModels` settings for the routed model, its fallbacks, and the current chat model used when routing fails, and the launch fails with an error naming the setting when no allowed model remains. A subagent result's `routerSelection` now lists the `candidates` the router could choose from ([#3528](https://github.com/bastani-inc/atomic/issues/3528)).
|
|
10
|
+
|
|
5
11
|
## [0.9.28] - 2026-10-08
|
|
6
12
|
|
|
7
13
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/subagents",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.29-alpha.1",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension for delegating tasks to subagents with parallel execution. Fork of: https://github.com/nicobailon/pi-subagents",
|
|
6
6
|
"contributors": [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/web-access",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.29-alpha.1",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension for web search, URL fetching, GitHub repo cloning, PDF/video extraction. Fork of: https://github.com/nicobailon/pi-web-access",
|
|
6
6
|
"contributors": [
|
|
@@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.9.29-alpha.1] - 2026-10-08
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Stages with `model: "auto"`, including builtin workflow stages that do not name a model, honor the new `modelRouting.allowedModels` and `modelRouting.excludedModels` settings for the routed model and every fallback, and fail before launch with an error naming the setting when no allowed model remains. A stage's `routerSelection` in `workflow` status now lists the `candidates` the router could choose from ([#3528](https://github.com/bastani-inc/atomic/issues/3528)).
|
|
14
|
+
|
|
9
15
|
## [0.9.28] - 2026-10-08
|
|
10
16
|
|
|
11
17
|
### Added
|
|
@@ -712,10 +712,10 @@ function isRouterSelection(value2) {
|
|
|
712
712
|
const fields = pair;
|
|
713
713
|
return Object.keys(pair).length === 2 && typeof fields.model === "string" && (fields.effort === null || isReasoningLevel(fields.effort));
|
|
714
714
|
};
|
|
715
|
-
return Object.keys(record).every((key) => ["model", "effort", "fallbacks"].includes(key)) && typeof record.model === "string" && (record.effort === null || isReasoningLevel(record.effort)) && (record.fallbacks === undefined || Array.isArray(record.fallbacks) && record.fallbacks.length <= 2 && record.fallbacks.every(isPair) && new Set([
|
|
715
|
+
return Object.keys(record).every((key) => ["model", "effort", "fallbacks", "candidates"].includes(key)) && typeof record.model === "string" && (record.effort === null || isReasoningLevel(record.effort)) && (record.fallbacks === undefined || Array.isArray(record.fallbacks) && record.fallbacks.length <= 2 && record.fallbacks.every(isPair) && new Set([
|
|
716
716
|
record.model,
|
|
717
717
|
...record.fallbacks.map((pair) => pair.model)
|
|
718
|
-
]).size === record.fallbacks.length + 1);
|
|
718
|
+
]).size === record.fallbacks.length + 1) && (record.candidates === undefined || Array.isArray(record.candidates) && record.candidates.every((id) => typeof id === "string"));
|
|
719
719
|
}
|
|
720
720
|
function isModelAttempts(value2) {
|
|
721
721
|
return Array.isArray(value2) && value2.every((attempt) => {
|
|
@@ -710,10 +710,10 @@ function isRouterSelection(value) {
|
|
|
710
710
|
const fields = pair;
|
|
711
711
|
return Object.keys(pair).length === 2 && typeof fields.model === "string" && (fields.effort === null || isReasoningLevel(fields.effort));
|
|
712
712
|
};
|
|
713
|
-
return Object.keys(record).every((key) => ["model", "effort", "fallbacks"].includes(key)) && typeof record.model === "string" && (record.effort === null || isReasoningLevel(record.effort)) && (record.fallbacks === undefined || Array.isArray(record.fallbacks) && record.fallbacks.length <= 2 && record.fallbacks.every(isPair) && new Set([
|
|
713
|
+
return Object.keys(record).every((key) => ["model", "effort", "fallbacks", "candidates"].includes(key)) && typeof record.model === "string" && (record.effort === null || isReasoningLevel(record.effort)) && (record.fallbacks === undefined || Array.isArray(record.fallbacks) && record.fallbacks.length <= 2 && record.fallbacks.every(isPair) && new Set([
|
|
714
714
|
record.model,
|
|
715
715
|
...record.fallbacks.map((pair) => pair.model)
|
|
716
|
-
]).size === record.fallbacks.length + 1);
|
|
716
|
+
]).size === record.fallbacks.length + 1) && (record.candidates === undefined || Array.isArray(record.candidates) && record.candidates.every((id) => typeof id === "string"));
|
|
717
717
|
}
|
|
718
718
|
function isModelAttempts(value) {
|
|
719
719
|
return Array.isArray(value) && value.every((attempt) => {
|
|
@@ -7,7 +7,7 @@ export interface ModelRoutingContext {
|
|
|
7
7
|
readonly modelRegistry: Pick<ModelRegistry, "getAll" | "getAvailable" | "streamSimple" | "containsConfiguredCredential"> & Partial<Pick<ModelRegistry, "getProviderAuthStatus" | "getProviderAuth" | "getClassifierModel" | "classify">>;
|
|
8
8
|
readonly model?: Model<Api>;
|
|
9
9
|
getRouterModel(): string;
|
|
10
|
-
/** Provider filters from settings.json `modelRouting`; absent means every
|
|
10
|
+
/** Provider and model filters from settings.json `modelRouting`; absent means every model is a candidate. */
|
|
11
11
|
getModelRouting?(): ModelRoutingSettings;
|
|
12
12
|
}
|
|
13
13
|
export interface ModelRoute {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-model-router.d.ts","sourceRoot":"","sources":["../../src/core/execution-model-router.ts"],"names":[],"mappings":"AAEA,OAAO,EACN,KAAK,GAAG,EAKR,KAAK,KAAK,EACV,MAAM,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"execution-model-router.d.ts","sourceRoot":"","sources":["../../src/core/execution-model-router.ts"],"names":[],"mappings":"AAEA,OAAO,EACN,KAAK,GAAG,EAKR,KAAK,KAAK,EACV,MAAM,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAUzD,OAAO,EAEN,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EAEtB,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EAMN,KAAK,SAAS,EACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGhE,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,aAAa,EAAE,IAAI,CAC3B,aAAa,EACb,QAAQ,GAAG,cAAc,GAAG,cAAc,GAAG,8BAA8B,CAC3E,GACA,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,uBAAuB,GAAG,iBAAiB,GAAG,oBAAoB,GAAG,UAAU,CAAC,CAAC,CAAC;IAC/G,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5B,cAAc,IAAI,MAAM,CAAC;IACzB,6GAA6G;IAC7G,eAAe,CAAC,IAAI,oBAAoB,CAAC;CACzC;AACD,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,eAAe,EAAE,iBAAiB,CAAC;IAC5C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,aAAa,IAAI,IAAI,CAAC;IACtB,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACzD;AAED;;;;GAIG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;IACnD;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,UAAU,CAAC;IAExC,YAAY,OAAO,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,UAAU,EAI1D;CACD;AA6CD,wBAAsB,mBAAmB,CAAC,KAAK,EAAE;IAChD,GAAG,EAAE,mBAAmB,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,WAAW,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC1C,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,kEAAkE;IAClE,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,+FAA+F;IAC/F,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;OAKG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACnC,GAAG,OAAO,CAAC,UAAU,CAAC,CA4YtB"}
|
|
@@ -3,6 +3,7 @@ import { join } from "node:path";
|
|
|
3
3
|
import { containsKnownEnvCredential, getServiceTierCost, getSupportedThinkingLevels, isModelType, } from "@bastani/pi-ai";
|
|
4
4
|
import { Type } from "typebox";
|
|
5
5
|
import { getDocsPath } from "../config.js";
|
|
6
|
+
import { resolveModelScopeFromModels } from "./model-resolver-scope.js";
|
|
6
7
|
import { ROUTING_REQUEST_BYTES } from "./model-routing-bytes.js";
|
|
7
8
|
import { describeOption, distinctTop, rankCandidates, } from "./model-routing-candidates.js";
|
|
8
9
|
import { eligiblePair, parseModelConstraints, } from "./model-routing-constraints.js";
|
|
@@ -74,13 +75,25 @@ export async function routeExecutionModel(input) {
|
|
|
74
75
|
const statedNeeds = parseTaskNeeds(input.taskNeeds);
|
|
75
76
|
// settings.json provider lists are defaults that only the call itself may
|
|
76
77
|
// replace; every constraint's own provider lists are enforced by eligiblePair.
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
const routing = ctx.getModelRouting?.() ?? {};
|
|
79
|
+
const { allowedProviders = [], excludedProviders = [] } = input.overrideProviderSettings ? {} : routing;
|
|
80
|
+
// The model lists are the operator's gate and apply to every call (#3528).
|
|
81
|
+
const { allowedModels = [], excludedModels = [] } = routing;
|
|
80
82
|
const providerPermitted = (provider) => (allowedProviders.length === 0 || allowedProviders.includes(provider)) && !excludedProviders.includes(provider);
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
const matching = (patterns, models) => new Set(resolveModelScopeFromModels([...patterns], models).scopedModels.map(({ model }) => `${model.provider}/${model.id}`));
|
|
84
|
+
const permittedModels = () => {
|
|
85
|
+
const models = ctx.modelRegistry.getAvailable();
|
|
86
|
+
const allowed = allowedModels.length ? matching(allowedModels, models) : undefined;
|
|
87
|
+
const excluded = matching(excludedModels, models);
|
|
88
|
+
return models.filter((model) => {
|
|
89
|
+
const id = `${model.provider}/${model.id}`;
|
|
90
|
+
return (isModelType(model, "chat") &&
|
|
91
|
+
providerPermitted(model.provider) &&
|
|
92
|
+
(allowed === undefined || allowed.has(id)) &&
|
|
93
|
+
!excluded.has(id));
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
const catalog = () => permittedModels()
|
|
84
97
|
// Ultrafast is billed above Standard and gated by account access. It is selectable
|
|
85
98
|
// manually, but auto must receive an exact caller allowance or restore an explicit decision.
|
|
86
99
|
.filter((model) => model.fastRoute?.serviceTier !== "ultrafast" ||
|
|
@@ -95,10 +108,20 @@ export async function routeExecutionModel(input) {
|
|
|
95
108
|
.filter((entry) => entry.pairs.length > 0);
|
|
96
109
|
const available = catalog();
|
|
97
110
|
const pairs = available.flatMap((entry) => entry.pairs);
|
|
98
|
-
if (!pairs.length)
|
|
99
|
-
|
|
100
|
-
|
|
111
|
+
if (!pairs.length) {
|
|
112
|
+
const providerSettings = allowedProviders.length > 0 || excludedProviders.length > 0;
|
|
113
|
+
const gateSettings = [
|
|
114
|
+
...(providerSettings ? ["modelRouting allowedProviders/excludedProviders"] : []),
|
|
115
|
+
...(allowedModels.length ? ["modelRouting.allowedModels"] : []),
|
|
116
|
+
...(excludedModels.length ? ["modelRouting.excludedModels"] : []),
|
|
117
|
+
];
|
|
118
|
+
const noun = gateSettings.length === 1 && !providerSettings ? "setting" : "settings";
|
|
119
|
+
throw new Error(gateSettings.length
|
|
120
|
+
? `Auto routing has no eligible model/effort pairs. Check configured providers, modelConstraints, and the ${new Intl.ListFormat("en", { type: "conjunction" }).format(gateSettings)} ${noun}.`
|
|
101
121
|
: "Auto routing has no eligible model/effort pairs. Check configured providers and modelConstraints.");
|
|
122
|
+
}
|
|
123
|
+
// The effective post-filter pool, echoed in routerSelection for audit (#3528).
|
|
124
|
+
const candidates = [...new Set(available.map((entry) => `${entry.model.provider}/${entry.model.id}`))];
|
|
102
125
|
let selection = input.selection;
|
|
103
126
|
if (selection === undefined) {
|
|
104
127
|
const settings = { getRouterModel: () => ctx.getRouterModel() };
|
|
@@ -129,7 +152,7 @@ export async function routeExecutionModel(input) {
|
|
|
129
152
|
const pair = CURRENT_MODEL_EFFORT_PREFERENCE.map((effort) => entry?.pairs.find((candidate) => candidate.effort === effort)).find((candidate) => candidate !== undefined);
|
|
130
153
|
if (pair === undefined)
|
|
131
154
|
return undefined;
|
|
132
|
-
return routeExecutionModel({ ...input, selection: { model: pair.model, effort: pair.effort } });
|
|
155
|
+
return routeExecutionModel({ ...input, selection: { model: pair.model, effort: pair.effort, candidates } });
|
|
133
156
|
};
|
|
134
157
|
// Any failure before a model is chosen is a total inference failure: the
|
|
135
158
|
// router and its chat structured-output fallback both failed (#3206).
|
|
@@ -234,6 +257,7 @@ export async function routeExecutionModel(input) {
|
|
|
234
257
|
: seeing;
|
|
235
258
|
const usable = roomy.length ? roomy : seeing;
|
|
236
259
|
const pairsFor = new Map(usable.map((entry) => [`${entry.model.provider}/${entry.model.id}`, entry.pairs]));
|
|
260
|
+
const routedCandidates = [...pairsFor.keys()];
|
|
237
261
|
const toCandidate = (model) => {
|
|
238
262
|
const routeCost = model.fastRoute?.serviceTier
|
|
239
263
|
? getServiceTierCost(model, model.fastRoute.serviceTier)
|
|
@@ -256,11 +280,7 @@ export async function routeExecutionModel(input) {
|
|
|
256
280
|
// but price and recency still compare them with every model the user could route to.
|
|
257
281
|
const callerListed = constraints.some((constraint) => (constraint.allowedModels?.length ?? 0) > 0);
|
|
258
282
|
const reference = callerListed
|
|
259
|
-
?
|
|
260
|
-
.getAvailable()
|
|
261
|
-
.filter((model) => isModelType(model, "chat") &&
|
|
262
|
-
providerPermitted(model.provider) &&
|
|
263
|
-
(!needs.needsImages || model.input.includes("image")))
|
|
283
|
+
? permittedModels().filter((model) => !needs.needsImages || model.input.includes("image"))
|
|
264
284
|
: usable.map((entry) => entry.model);
|
|
265
285
|
const standings = rankCandidates(catalogEvals, reference.map(toCandidate), needs);
|
|
266
286
|
const ranked = standings.filter((candidate) => pairsFor.has(candidate.model));
|
|
@@ -332,6 +352,7 @@ export async function routeExecutionModel(input) {
|
|
|
332
352
|
})),
|
|
333
353
|
}
|
|
334
354
|
: {}),
|
|
355
|
+
candidates: routedCandidates,
|
|
335
356
|
};
|
|
336
357
|
}
|
|
337
358
|
const fallbacks = selection.fallbacks?.map((pair) => Object.freeze({ model: pair.model, effort: pair.effort }));
|
|
@@ -343,6 +364,7 @@ export async function routeExecutionModel(input) {
|
|
|
343
364
|
model: selection.model,
|
|
344
365
|
effort: selection.effort,
|
|
345
366
|
...(fallbacks?.length ? { fallbacks: Object.freeze(fallbacks) } : {}),
|
|
367
|
+
...(selection.candidates ? { candidates: Object.freeze([...selection.candidates]) } : {}),
|
|
346
368
|
});
|
|
347
369
|
const hasPair = (pair) => catalog().some((entry) => entry.pairs.some((p) => p.model === pair.model && p.effort === pair.effort));
|
|
348
370
|
const allowsModel = (model, effort) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-model-router.js","sourceRoot":"","sources":["../../src/core/execution-model-router.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n\ttype Api,\n\tcontainsKnownEnvCredential,\n\tgetServiceTierCost,\n\tgetSupportedThinkingLevels,\n\tisModelType,\n\ttype Model,\n} from \"@bastani/pi-ai\";\nimport { Type } from \"typebox\";\nimport { getDocsPath } from \"../config.js\";\nimport type { ModelRegistry } from \"./model-registry.ts\";\nimport { ROUTING_REQUEST_BYTES } from \"./model-routing-bytes.js\";\nimport {\n\ttype CandidateModel,\n\tdescribeOption,\n\tdistinctTop,\n\ttype RankedCandidate,\n\trankCandidates,\n} from \"./model-routing-candidates.js\";\nimport {\n\teligiblePair,\n\ttype ModelConstraints,\n\ttype ModelRouterOutput,\n\tparseModelConstraints,\n} from \"./model-routing-constraints.js\";\nimport { reportModelRoutingDebug } from \"./model-routing-debug.js\";\nimport { parseEvalsCatalog } from \"./model-routing-evals.js\";\nimport {\n\teffortForDifficulty,\n\tmissingNeedsQuestions,\n\tparseTaskNeeds,\n\ttype ResolvedTaskNeeds,\n\tresolveTaskNeeds,\n\ttype TaskNeeds,\n} from \"./model-routing-needs.js\";\nimport type { ModelRoutingSettings } from \"./settings-types.ts\";\nimport { resolveRouterModel, routeModel } from \"./structured-output/index.js\";\n\nexport interface ModelRoutingContext {\n\treadonly modelRegistry: Pick<\n\t\tModelRegistry,\n\t\t\"getAll\" | \"getAvailable\" | \"streamSimple\" | \"containsConfiguredCredential\"\n\t> &\n\t\tPartial<Pick<ModelRegistry, \"getProviderAuthStatus\" | \"getProviderAuth\" | \"getClassifierModel\" | \"classify\">>;\n\treadonly model?: Model<Api>;\n\tgetRouterModel(): string;\n\t/** Provider filters from settings.json `modelRouting`; absent means every provider is a candidate. */\n\tgetModelRouting?(): ModelRoutingSettings;\n}\nexport interface ModelRoute {\n\treadonly routerSelection: ModelRouterOutput;\n\treadonly modelOverride: string;\n\treadonly fallbackModels?: readonly string[];\n\tassertCurrent(): void;\n\tallowsModel(model: Model<Api>, effort?: string): boolean;\n}\n\n/**\n * Total auto-routing inference failure: Jev and the chat structured-output\n * fallback both failed before any model was selected (#3206). Validation,\n * eligibility, and credential-screening errors are never marked.\n */\nexport class AutoRoutingInferenceError extends Error {\n\t/**\n\t * Route pinned to the current chat model, present only when that model is\n\t * available and satisfies every routing constraint. Consumers may degrade\n\t * to it; when it is absent the failure stays fatal.\n\t */\n\treadonly currentModelRoute?: ModelRoute;\n\n\tconstructor(message: string, currentModelRoute?: ModelRoute) {\n\t\tsuper(message);\n\t\tthis.name = \"AutoRoutingInferenceError\";\n\t\tif (currentModelRoute !== undefined) this.currentModelRoute = currentModelRoute;\n\t}\n}\n\n/** Degraded routes keep a balanced effort when the constraints leave a choice. */\nconst CURRENT_MODEL_EFFORT_PREFERENCE: readonly (string | null)[] = [\n\tnull,\n\t\"medium\",\n\t\"high\",\n\t\"low\",\n\t\"xhigh\",\n\t\"minimal\",\n\t\"max\",\n\t\"off\",\n];\n/** Most options the router compares when it builds the shortlist itself. */\nconst SHORTLIST_SIZE = 6;\n/** Conservative bytes per token when checking that a task fits a reader's context window. */\nconst BYTES_PER_TOKEN = 3;\n/** Room in the reader's window for the questions, instructions and its answer. */\nconst READER_OVERHEAD_TOKENS = 4_000;\n/** Jev accepts at most this many options in one Choice question. */\nconst MAX_CHOICE_OPTIONS = 255;\n\n/** A task that must hold this much in context prefers models whose window is at least this large. */\nconst LONG_CONTEXT_TOKENS = 400_000;\n\nconst NEEDS_INSTRUCTIONS =\n\t\"Read `task`, which `agent` will perform, and answer each field: what kind of work it is, how hard it is, how costly a mistake would be, whether it needs screenshots or images, whether it must hold a very large amount of material in context, and whether speed matters more than extra reasoning. Each field's description lists its options. Judge the task as written; `caller_says` lists answers the caller already gave.\";\nconst CHOICE_INSTRUCTIONS =\n\t\"Pick the model that should do the task `agent` will perform. The task's needs are in `needs`; the task itself is not shown. Each option lists the model's release date, price tier and prices, whether it reads images, and its results for this kind of work and overall; standings compare it with every eligible model. For demanding or high-stakes tasks prefer the best-proven model; for easy, low-stakes tasks prefer an adequate cheaper one. Prefer newer models over older ones with similar results. Missing results are unknown, not weak.\";\n\nconst EVALS_BUDGET_ERROR =\n\t\"Auto routing requires a nonempty evals.md document. Repair the Atomic installation or select a concrete execution model.\";\n\nasync function readModelSelectionEvals(signal?: AbortSignal): Promise<string> {\n\ttry {\n\t\tconst evals = await readFile(join(getDocsPath(), \"models\", \"evals.md\"), { encoding: \"utf8\", signal });\n\t\tif (!evals.trim()) throw new Error(EVALS_BUDGET_ERROR);\n\t\treturn evals;\n\t} catch (error) {\n\t\tsignal?.throwIfAborted();\n\t\tif (error instanceof Error && error.message === EVALS_BUDGET_ERROR) throw error;\n\t\tthrow new Error(EVALS_BUDGET_ERROR);\n\t}\n}\n\nexport async function routeExecutionModel(input: {\n\tctx: ModelRoutingContext;\n\ttask: string;\n\tagent: { name: string; description: string };\n\tconstraints?: readonly ModelConstraints[];\n\tsignal?: AbortSignal;\n\t/** Restore a recorded decision without another inference call. */\n\tselection?: ModelRouterOutput;\n\t/** What the caller already knows about the task; routing asks the router only for the rest. */\n\ttaskNeeds?: TaskNeeds;\n\t/**\n\t * True when this call's own constraints set a provider list because the user\n\t * asked. Only then are the settings.json provider lists replaced; provider\n\t * lists from agent definitions or inherited workflow constraints restrict\n\t * candidates on top of the settings and never lift a user's exclusion.\n\t */\n\toverrideProviderSettings?: boolean;\n}): Promise<ModelRoute> {\n\tconst { ctx, signal } = input;\n\tsignal?.throwIfAborted();\n\tconst constraints = structuredClone((input.constraints ?? []).map((c) => parseModelConstraints(c)!));\n\tconst statedNeeds = parseTaskNeeds(input.taskNeeds);\n\t// settings.json provider lists are defaults that only the call itself may\n\t// replace; every constraint's own provider lists are enforced by eligiblePair.\n\tconst { allowedProviders = [], excludedProviders = [] } = input.overrideProviderSettings\n\t\t? {}\n\t\t: (ctx.getModelRouting?.() ?? {});\n\tconst providerPermitted = (provider: string) =>\n\t\t(allowedProviders.length === 0 || allowedProviders.includes(provider)) && !excludedProviders.includes(provider);\n\tconst catalog = () =>\n\t\tctx.modelRegistry\n\t\t\t.getAvailable()\n\t\t\t.filter((model) => isModelType(model, \"chat\") && providerPermitted(model.provider))\n\t\t\t// Ultrafast is billed above Standard and gated by account access. It is selectable\n\t\t\t// manually, but auto must receive an exact caller allowance or restore an explicit decision.\n\t\t\t.filter(\n\t\t\t\t(model) =>\n\t\t\t\t\tmodel.fastRoute?.serviceTier !== \"ultrafast\" ||\n\t\t\t\t\tconstraints.some((constraint) => constraint.allowedModels?.includes(`${model.provider}/${model.id}`)) ||\n\t\t\t\t\tinput.selection?.model === `${model.provider}/${model.id}`,\n\t\t\t)\n\t\t\t.map((model) => ({\n\t\t\t\tmodel,\n\t\t\t\tpairs: (model.reasoning ? getSupportedThinkingLevels(model) : [null])\n\t\t\t\t\t.map((effort) => ({ model: `${model.provider}/${model.id}`, effort }))\n\t\t\t\t\t.filter((pair) => eligiblePair(model, pair, constraints)),\n\t\t\t}))\n\t\t\t.filter((entry) => entry.pairs.length > 0);\n\tconst available = catalog();\n\tconst pairs = available.flatMap((entry) => entry.pairs);\n\tif (!pairs.length)\n\t\tthrow new Error(\n\t\t\tallowedProviders.length || excludedProviders.length\n\t\t\t\t? \"Auto routing has no eligible model/effort pairs. Check configured providers, modelConstraints, and the modelRouting allowedProviders/excludedProviders settings.\"\n\t\t\t\t: \"Auto routing has no eligible model/effort pairs. Check configured providers and modelConstraints.\",\n\t\t);\n\tlet selection = input.selection;\n\tif (selection === undefined) {\n\t\tconst settings = { getRouterModel: () => ctx.getRouterModel() };\n\t\tconst router = resolveRouterModel({ settings, currentModel: ctx.model, modelRegistry: ctx.modelRegistry });\n\t\tif (!input.task.trim()) throw new Error(\"Auto routing requires task instructions.\");\n\t\tconst stated = statedNeeds;\n\t\tconst agent = { name: input.agent.name, description: input.agent.description };\n\t\t// Screen the task before any model reads it.\n\t\tconst serialized = JSON.stringify({ task: input.task, agent, stated, constraints });\n\t\tlet configuredCredential: boolean;\n\t\ttry {\n\t\t\tconfiguredCredential = await ctx.modelRegistry.containsConfiguredCredential(serialized);\n\t\t} catch {\n\t\t\tthrow new Error(\"Auto routing could not screen configured credentials. No inference was performed.\");\n\t\t}\n\t\tif (\n\t\t\tcontainsKnownEnvCredential(serialized) ||\n\t\t\tconfiguredCredential ||\n\t\t\t/\\bBearer\\s+[A-Za-z0-9._~+/-]{8,}|-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----|\\b(?:sk|ghp|github_pat)[-_][A-Za-z0-9_-]{16,}/i.test(\n\t\t\t\tserialized,\n\t\t\t)\n\t\t)\n\t\t\tthrow new Error(\"Auto routing context contains credential material. Remove secrets before retrying.\");\n\t\tconst task = input.task;\n\t\t// Degrade only to a current chat model that is available and eligible under\n\t\t// the same constraints, restored through the normal selection path (#3206).\n\t\tconst currentModelRoute = async (): Promise<ModelRoute | undefined> => {\n\t\t\tconst current = ctx.model;\n\t\t\tconst entry = available.find(\n\t\t\t\t(candidate) => candidate.model.provider === current?.provider && candidate.model.id === current?.id,\n\t\t\t);\n\t\t\tconst pair = CURRENT_MODEL_EFFORT_PREFERENCE.map((effort) =>\n\t\t\t\tentry?.pairs.find((candidate) => candidate.effort === effort),\n\t\t\t).find((candidate) => candidate !== undefined);\n\t\t\tif (pair === undefined) return undefined;\n\t\t\treturn routeExecutionModel({ ...input, selection: { model: pair.model, effort: pair.effort } });\n\t\t};\n\t\t// Any failure before a model is chosen is a total inference failure: the\n\t\t// router and its chat structured-output fallback both failed (#3206).\n\t\tconst infer = async <T>(decide: () => Promise<T>): Promise<T> => {\n\t\t\ttry {\n\t\t\t\treturn await decide();\n\t\t\t} catch (error) {\n\t\t\t\tsignal?.throwIfAborted();\n\t\t\t\tthrow new AutoRoutingInferenceError(\n\t\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t\t\tawait currentModelRoute().catch(() => undefined),\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\t\t// Where code cannot pick a model either, the current chat model takes over\n\t\t// the same way.\n\t\tconst fallBackToCurrentModel = async (message: string): Promise<never> => {\n\t\t\tthrow new AutoRoutingInferenceError(message, await currentModelRoute().catch(() => undefined));\n\t\t};\n\t\tconst catalogEvals = await readModelSelectionEvals(signal)\n\t\t\t.then(parseEvalsCatalog)\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tsignal?.throwIfAborted();\n\t\t\t\treturn fallBackToCurrentModel(error instanceof Error ? error.message : String(error));\n\t\t\t});\n\n\t\t// Step 1: a chat model reads the task and answers only what the caller did\n\t\t// not state. A classifier router such as Jev never receives the task.\n\t\tconst questions = missingNeedsQuestions(stated);\n\t\tlet answers: Record<string, string> = {};\n\t\tif (questions.length) {\n\t\t\tconst current = ctx.model;\n\t\t\tconst preferred =\n\t\t\t\trouter.kind === \"chat\"\n\t\t\t\t\t? router.model\n\t\t\t\t\t: current && current.id !== \"auto\" && isModelType(current, \"chat\")\n\t\t\t\t\t\t? current\n\t\t\t\t\t\t: undefined;\n\t\t\t// The reader gets the complete task. When the task is larger than the\n\t\t\t// preferred reader's window, the cheapest eligible model that holds it\n\t\t\t// reads instead; eligible models are the ones allowed to receive the task.\n\t\t\tconst taskTokens = Math.ceil(Buffer.byteLength(task, \"utf8\") / BYTES_PER_TOKEN) + READER_OVERHEAD_TOKENS;\n\t\t\tconst holdsTask = (model: Model<Api>) => model.contextWindow >= taskTokens;\n\t\t\tconst readerModel =\n\t\t\t\tpreferred && holdsTask(preferred)\n\t\t\t\t\t? preferred\n\t\t\t\t\t: (available\n\t\t\t\t\t\t\t.map((entry) => entry.model)\n\t\t\t\t\t\t\t.filter(holdsTask)\n\t\t\t\t\t\t\t.sort(\n\t\t\t\t\t\t\t\t(a, b) =>\n\t\t\t\t\t\t\t\t\ta.cost.input - b.cost.input ||\n\t\t\t\t\t\t\t\t\t`${a.provider}/${a.id}`.localeCompare(`${b.provider}/${b.id}`),\n\t\t\t\t\t\t\t)[0] ?? preferred);\n\t\t\tconst reader = readerModel ? `${readerModel.provider}/${readerModel.id}` : undefined;\n\t\t\tif (reader === undefined)\n\t\t\t\tawait fallBackToCurrentModel(\n\t\t\t\t\t\"Auto routing needs a chat model to read the task. Select a chat model or state every taskNeeds field.\",\n\t\t\t\t);\n\t\t\tconst schema = Type.Object(\n\t\t\t\tObject.fromEntries(\n\t\t\t\t\tquestions.map((question) => [\n\t\t\t\t\t\tquestion.id,\n\t\t\t\t\t\tType.String({\n\t\t\t\t\t\t\tenum: Object.keys(question.criteria),\n\t\t\t\t\t\t\tdescription: `${question.instructions} ${Object.entries(question.criteria)\n\t\t\t\t\t\t\t\t.map(([key, meaning]) => `${key}: ${meaning}`)\n\t\t\t\t\t\t\t\t.join(\"; \")}.`,\n\t\t\t\t\t\t}),\n\t\t\t\t\t]),\n\t\t\t\t),\n\t\t\t\t{ additionalProperties: false },\n\t\t\t);\n\t\t\tconst callerSays = stated\n\t\t\t\t? {\n\t\t\t\t\t\t...(stated.work ? { work: stated.work } : {}),\n\t\t\t\t\t\t...(stated.difficulty ? { difficulty: stated.difficulty } : {}),\n\t\t\t\t\t\t...(stated.mistakeCost ? { mistake_cost: stated.mistakeCost } : {}),\n\t\t\t\t\t\t...(stated.needsImages !== undefined ? { needs_images: stated.needsImages ? \"yes\" : \"no\" } : {}),\n\t\t\t\t\t\t...(stated.longContext !== undefined ? { long_context: stated.longContext ? \"yes\" : \"no\" } : {}),\n\t\t\t\t\t\t...(stated.latencySensitive !== undefined\n\t\t\t\t\t\t\t? { latency_sensitive: stated.latencySensitive ? \"yes\" : \"no\" }\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t}\n\t\t\t\t: undefined;\n\t\t\tconst result = await infer(() =>\n\t\t\t\trouteModel(\n\t\t\t\t\t{\n\t\t\t\t\t\tsettings: { getRouterModel: () => reader! },\n\t\t\t\t\t\tmodelRegistry: ctx.modelRegistry,\n\t\t\t\t\t\tcurrentModel: ctx.model,\n\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\ttask,\n\t\t\t\t\t\t\tagent,\n\t\t\t\t\t\t\t...(callerSays && Object.keys(callerSays).length ? { caller_says: callerSays } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tinstructions: NEEDS_INSTRUCTIONS,\n\t\t\t\t\t\tschema,\n\t\t\t\t\t\t// Unused: the reader always resolves to a chat model.\n\t\t\t\t\t\tclassifier: {\n\t\t\t\t\t\t\tquestions: Object.fromEntries(\n\t\t\t\t\t\t\t\tquestions.map((question) => [\n\t\t\t\t\t\t\t\t\tquestion.id,\n\t\t\t\t\t\t\t\t\t{ instructions: question.instructions, criteria: question.criteria },\n\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tdecode: (choices) =>\n\t\t\t\t\t\t\t\tObject.fromEntries(questions.map((question) => [question.id, choices[question.id]!])),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t},\n\t\t\t\t\t(value) => questions.every((question) => Object.hasOwn(question.criteria, String(value[question.id]))),\n\t\t\t\t),\n\t\t\t);\n\t\t\tanswers = result.value;\n\t\t}\n\t\tconst needs: ResolvedTaskNeeds = resolveTaskNeeds(stated, answers);\n\n\t\t// Step 2: narrow in code. A task that needs images only goes to models that read them.\n\t\tconst seeing = needs.needsImages ? available.filter((entry) => entry.model.input.includes(\"image\")) : available;\n\t\tif (seeing.length === 0)\n\t\t\tawait fallBackToCurrentModel(\n\t\t\t\t\"Auto routing: this task needs a model that can read images, and no eligible model can. Allow an image-capable model or select a concrete execution model.\",\n\t\t\t);\n\t\t// A large context window is preferred, not required: context size is a matter of degree.\n\t\tconst roomy = needs.longContext\n\t\t\t? seeing.filter((entry) => entry.model.contextWindow >= LONG_CONTEXT_TOKENS)\n\t\t\t: seeing;\n\t\tconst usable = roomy.length ? roomy : seeing;\n\t\tconst pairsFor = new Map(usable.map((entry) => [`${entry.model.provider}/${entry.model.id}`, entry.pairs]));\n\t\tconst toCandidate = (model: Model<Api>): CandidateModel => {\n\t\t\tconst routeCost = model.fastRoute?.serviceTier\n\t\t\t\t? getServiceTierCost(model, model.fastRoute.serviceTier)\n\t\t\t\t: undefined;\n\t\t\treturn {\n\t\t\t\tmodel: `${model.provider}/${model.id}`,\n\t\t\t\tname: model.name,\n\t\t\t\tcost: routeCost ?? model.cost,\n\t\t\t\tinput: model.input,\n\t\t\t\t...(model.fastRoute\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tfastRouteOf: `${model.provider}/${model.fastRoute.baseModelId}`,\n\t\t\t\t\t\t\tfastRouteServiceTier: model.fastRoute.serviceTier,\n\t\t\t\t\t\t\tfastRoutePriced: routeCost !== undefined,\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t};\n\t\t};\n\t\t// A caller that lists models (`allowedModels`) chooses the contenders itself,\n\t\t// but price and recency still compare them with every model the user could route to.\n\t\tconst callerListed = constraints.some((constraint) => (constraint.allowedModels?.length ?? 0) > 0);\n\t\tconst reference = callerListed\n\t\t\t? ctx.modelRegistry\n\t\t\t\t\t.getAvailable()\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(model) =>\n\t\t\t\t\t\t\tisModelType(model, \"chat\") &&\n\t\t\t\t\t\t\tproviderPermitted(model.provider) &&\n\t\t\t\t\t\t\t(!needs.needsImages || model.input.includes(\"image\")),\n\t\t\t\t\t)\n\t\t\t: usable.map((entry) => entry.model);\n\t\tconst standings = rankCandidates(catalogEvals, reference.map(toCandidate), needs);\n\t\tconst ranked = standings.filter((candidate) => pairsFor.has(candidate.model));\n\t\tconst choiceState = {\n\t\t\tagent,\n\t\t\tneeds: {\n\t\t\t\twork: needs.work,\n\t\t\t\tdifficulty: needs.difficulty,\n\t\t\t\tmistake_cost: needs.mistakeCost,\n\t\t\t\tneeds_images: needs.needsImages,\n\t\t\t\tlong_context: needs.longContext,\n\t\t\t\tlatency_sensitive: needs.latencySensitive,\n\t\t\t},\n\t\t};\n\t\tconst describeAll = (options: readonly RankedCandidate[]) =>\n\t\t\tObject.fromEntries(options.map((option, index) => [`m${index}`, describeOption(option, needs, standings)]));\n\t\tconst fitsOneChoice = (options: readonly RankedCandidate[]) =>\n\t\t\toptions.length <= MAX_CHOICE_OPTIONS &&\n\t\t\tBuffer.byteLength(\n\t\t\t\tJSON.stringify({ state: choiceState, instructions: CHOICE_INSTRUCTIONS, criteria: describeAll(options) }),\n\t\t\t\t\"utf8\",\n\t\t\t) <= ROUTING_REQUEST_BYTES;\n\t\t// A caller's list is offered whole when it fits one choice request; otherwise\n\t\t// duplicate routes of one model share a slot, and a list that still does not\n\t\t// fit falls back rather than silently dropping a contender.\n\t\tconst callerChoices = !callerListed || fitsOneChoice(ranked) ? ranked : distinctTop(ranked, ranked.length);\n\t\tif (callerListed && !fitsOneChoice(callerChoices))\n\t\t\tawait fallBackToCurrentModel(\n\t\t\t\t`Auto routing cannot compare ${callerChoices.length} different models from modelConstraints.allowedModels in one routing request. List fewer models.`,\n\t\t\t);\n\t\tconst shortlist = callerListed ? callerChoices : distinctTop(ranked, SHORTLIST_SIZE);\n\n\t\t// Step 3: the router picks one option; each carries its own evidence.\n\t\tlet chosen = shortlist[0]!;\n\t\tif (shortlist.length > 1) {\n\t\t\tconst keys = shortlist.map((_, index) => `m${index}`);\n\t\t\tconst schema = Type.Object(\n\t\t\t\t{ modelId: Type.String({ enum: shortlist.map((option) => option.model) }) },\n\t\t\t\t{ additionalProperties: false },\n\t\t\t);\n\t\t\tconst result = await infer(() =>\n\t\t\t\trouteModel(\n\t\t\t\t\t{\n\t\t\t\t\t\tsettings,\n\t\t\t\t\t\tmodelRegistry: ctx.modelRegistry,\n\t\t\t\t\t\tcurrentModel: ctx.model,\n\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t...choiceState,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tinstructions: CHOICE_INSTRUCTIONS,\n\t\t\t\t\t\tschema,\n\t\t\t\t\t\tclassifier: {\n\t\t\t\t\t\t\tquestions: {\n\t\t\t\t\t\t\t\tmodel: {\n\t\t\t\t\t\t\t\t\tinstructions: \"Which model should do this task?\",\n\t\t\t\t\t\t\t\t\tcriteria: describeAll(shortlist),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tdecode: (choices) => {\n\t\t\t\t\t\t\t\tconst option = shortlist[keys.indexOf(choices.model ?? \"\")];\n\t\t\t\t\t\t\t\tif (!option) throw new Error(\"Invalid execution model Choice.\");\n\t\t\t\t\t\t\t\treturn { modelId: option.model };\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t},\n\t\t\t\t\t(value) => shortlist.some((option) => option.model === value.modelId),\n\t\t\t\t),\n\t\t\t);\n\t\t\tchosen = shortlist.find((option) => option.model === result.value.modelId)!;\n\t\t}\n\n\t\t// Step 4: effort from difficulty; fallbacks are the next distinct models in code's ranking.\n\t\tconst effortOf = (model: string) =>\n\t\t\teffortForDifficulty(\n\t\t\t\t(pairsFor.get(model) ?? []).map((pair) => pair.effort),\n\t\t\t\tneeds.difficulty,\n\t\t\t\tneeds.latencySensitive,\n\t\t\t);\n\t\tconst fallbackModels = distinctTop(\n\t\t\tranked.filter((candidate) => candidate.baseKey !== chosen.baseKey),\n\t\t\t2,\n\t\t);\n\t\treportModelRoutingDebug(\n\t\t\t`Auto routing: ${needs.work}, ${needs.difficulty}, mistake cost ${needs.mistakeCost}, images ${needs.needsImages ? \"yes\" : \"no\"}, long context ${needs.longContext ? \"yes\" : \"no\"}, latency ${needs.latencySensitive ? \"sensitive\" : \"tolerant\"}; chose ${chosen.model} from ${shortlist.map((option) => option.model).join(\", \")}.`,\n\t\t);\n\t\tselection = {\n\t\t\tmodel: chosen.model,\n\t\t\teffort: effortOf(chosen.model),\n\t\t\t...(fallbackModels.length\n\t\t\t\t? {\n\t\t\t\t\t\tfallbacks: fallbackModels.map((candidate) => ({\n\t\t\t\t\t\t\tmodel: candidate.model,\n\t\t\t\t\t\t\teffort: effortOf(candidate.model),\n\t\t\t\t\t\t})),\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t};\n\t}\n\tconst fallbacks = selection.fallbacks?.map((pair) => Object.freeze({ model: pair.model, effort: pair.effort }));\n\tif (\n\t\tfallbacks &&\n\t\t(fallbacks.length > 2 ||\n\t\t\tnew Set([selection.model, ...fallbacks.map((pair) => pair.model)]).size !== fallbacks.length + 1)\n\t)\n\t\tthrow new Error(\"Invalid ranked auto selection: expected up to three distinct models.\");\n\tconst routerSelection = Object.freeze({\n\t\tmodel: selection.model,\n\t\teffort: selection.effort,\n\t\t...(fallbacks?.length ? { fallbacks: Object.freeze(fallbacks) } : {}),\n\t});\n\tconst hasPair = (pair: ModelRouterOutput) =>\n\t\tcatalog().some((entry) => entry.pairs.some((p) => p.model === pair.model && p.effort === pair.effort));\n\tconst allowsModel = (model: Model<Api>, effort?: string): boolean => {\n\t\tconst levels = model.reasoning ? getSupportedThinkingLevels(model) : [null];\n\t\treturn levels.some((level) => {\n\t\t\tif (model.reasoning && effort !== undefined && level !== effort) return false;\n\t\t\tconst pair = { model: `${model.provider}/${model.id}`, effort: level };\n\t\t\treturn eligiblePair(model, pair, constraints) && hasPair(pair);\n\t\t});\n\t};\n\tconst assertCurrent = () => {\n\t\tsignal?.throwIfAborted();\n\t\tif (![routerSelection, ...(routerSelection.fallbacks ?? [])].every(hasPair))\n\t\t\tthrow new Error(\"Auto selection is no longer eligible. Retry explicitly with the current catalog.\");\n\t};\n\tassertCurrent();\n\treturn {\n\t\trouterSelection,\n\t\tmodelOverride: routerSelection.model + (routerSelection.effort === null ? \"\" : `:${routerSelection.effort}`),\n\t\tfallbackModels: Object.freeze(\n\t\t\t(routerSelection.fallbacks ?? []).map((pair) => pair.model + (pair.effort === null ? \"\" : `:${pair.effort}`)),\n\t\t),\n\t\tassertCurrent,\n\t\tallowsModel,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"execution-model-router.js","sourceRoot":"","sources":["../../src/core/execution-model-router.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n\ttype Api,\n\tcontainsKnownEnvCredential,\n\tgetServiceTierCost,\n\tgetSupportedThinkingLevels,\n\tisModelType,\n\ttype Model,\n} from \"@bastani/pi-ai\";\nimport { Type } from \"typebox\";\nimport { getDocsPath } from \"../config.js\";\nimport type { ModelRegistry } from \"./model-registry.ts\";\nimport { resolveModelScopeFromModels } from \"./model-resolver-scope.ts\";\nimport { ROUTING_REQUEST_BYTES } from \"./model-routing-bytes.js\";\nimport {\n\ttype CandidateModel,\n\tdescribeOption,\n\tdistinctTop,\n\ttype RankedCandidate,\n\trankCandidates,\n} from \"./model-routing-candidates.js\";\nimport {\n\teligiblePair,\n\ttype ModelConstraints,\n\ttype ModelRouterOutput,\n\tparseModelConstraints,\n} from \"./model-routing-constraints.js\";\nimport { reportModelRoutingDebug } from \"./model-routing-debug.js\";\nimport { parseEvalsCatalog } from \"./model-routing-evals.js\";\nimport {\n\teffortForDifficulty,\n\tmissingNeedsQuestions,\n\tparseTaskNeeds,\n\ttype ResolvedTaskNeeds,\n\tresolveTaskNeeds,\n\ttype TaskNeeds,\n} from \"./model-routing-needs.js\";\nimport type { ModelRoutingSettings } from \"./settings-types.ts\";\nimport { resolveRouterModel, routeModel } from \"./structured-output/index.js\";\n\nexport interface ModelRoutingContext {\n\treadonly modelRegistry: Pick<\n\t\tModelRegistry,\n\t\t\"getAll\" | \"getAvailable\" | \"streamSimple\" | \"containsConfiguredCredential\"\n\t> &\n\t\tPartial<Pick<ModelRegistry, \"getProviderAuthStatus\" | \"getProviderAuth\" | \"getClassifierModel\" | \"classify\">>;\n\treadonly model?: Model<Api>;\n\tgetRouterModel(): string;\n\t/** Provider and model filters from settings.json `modelRouting`; absent means every model is a candidate. */\n\tgetModelRouting?(): ModelRoutingSettings;\n}\nexport interface ModelRoute {\n\treadonly routerSelection: ModelRouterOutput;\n\treadonly modelOverride: string;\n\treadonly fallbackModels?: readonly string[];\n\tassertCurrent(): void;\n\tallowsModel(model: Model<Api>, effort?: string): boolean;\n}\n\n/**\n * Total auto-routing inference failure: Jev and the chat structured-output\n * fallback both failed before any model was selected (#3206). Validation,\n * eligibility, and credential-screening errors are never marked.\n */\nexport class AutoRoutingInferenceError extends Error {\n\t/**\n\t * Route pinned to the current chat model, present only when that model is\n\t * available and satisfies every routing constraint. Consumers may degrade\n\t * to it; when it is absent the failure stays fatal.\n\t */\n\treadonly currentModelRoute?: ModelRoute;\n\n\tconstructor(message: string, currentModelRoute?: ModelRoute) {\n\t\tsuper(message);\n\t\tthis.name = \"AutoRoutingInferenceError\";\n\t\tif (currentModelRoute !== undefined) this.currentModelRoute = currentModelRoute;\n\t}\n}\n\n/** Degraded routes keep a balanced effort when the constraints leave a choice. */\nconst CURRENT_MODEL_EFFORT_PREFERENCE: readonly (string | null)[] = [\n\tnull,\n\t\"medium\",\n\t\"high\",\n\t\"low\",\n\t\"xhigh\",\n\t\"minimal\",\n\t\"max\",\n\t\"off\",\n];\n/** Most options the router compares when it builds the shortlist itself. */\nconst SHORTLIST_SIZE = 6;\n/** Conservative bytes per token when checking that a task fits a reader's context window. */\nconst BYTES_PER_TOKEN = 3;\n/** Room in the reader's window for the questions, instructions and its answer. */\nconst READER_OVERHEAD_TOKENS = 4_000;\n/** Jev accepts at most this many options in one Choice question. */\nconst MAX_CHOICE_OPTIONS = 255;\n\n/** A task that must hold this much in context prefers models whose window is at least this large. */\nconst LONG_CONTEXT_TOKENS = 400_000;\n\nconst NEEDS_INSTRUCTIONS =\n\t\"Read `task`, which `agent` will perform, and answer each field: what kind of work it is, how hard it is, how costly a mistake would be, whether it needs screenshots or images, whether it must hold a very large amount of material in context, and whether speed matters more than extra reasoning. Each field's description lists its options. Judge the task as written; `caller_says` lists answers the caller already gave.\";\nconst CHOICE_INSTRUCTIONS =\n\t\"Pick the model that should do the task `agent` will perform. The task's needs are in `needs`; the task itself is not shown. Each option lists the model's release date, price tier and prices, whether it reads images, and its results for this kind of work and overall; standings compare it with every eligible model. For demanding or high-stakes tasks prefer the best-proven model; for easy, low-stakes tasks prefer an adequate cheaper one. Prefer newer models over older ones with similar results. Missing results are unknown, not weak.\";\n\nconst EVALS_BUDGET_ERROR =\n\t\"Auto routing requires a nonempty evals.md document. Repair the Atomic installation or select a concrete execution model.\";\n\nasync function readModelSelectionEvals(signal?: AbortSignal): Promise<string> {\n\ttry {\n\t\tconst evals = await readFile(join(getDocsPath(), \"models\", \"evals.md\"), { encoding: \"utf8\", signal });\n\t\tif (!evals.trim()) throw new Error(EVALS_BUDGET_ERROR);\n\t\treturn evals;\n\t} catch (error) {\n\t\tsignal?.throwIfAborted();\n\t\tif (error instanceof Error && error.message === EVALS_BUDGET_ERROR) throw error;\n\t\tthrow new Error(EVALS_BUDGET_ERROR);\n\t}\n}\n\nexport async function routeExecutionModel(input: {\n\tctx: ModelRoutingContext;\n\ttask: string;\n\tagent: { name: string; description: string };\n\tconstraints?: readonly ModelConstraints[];\n\tsignal?: AbortSignal;\n\t/** Restore a recorded decision without another inference call. */\n\tselection?: ModelRouterOutput;\n\t/** What the caller already knows about the task; routing asks the router only for the rest. */\n\ttaskNeeds?: TaskNeeds;\n\t/**\n\t * True when this call's own constraints set a provider list because the user\n\t * asked. Only then are the settings.json provider lists replaced; provider\n\t * lists from agent definitions or inherited workflow constraints restrict\n\t * candidates on top of the settings and never lift a user's exclusion.\n\t */\n\toverrideProviderSettings?: boolean;\n}): Promise<ModelRoute> {\n\tconst { ctx, signal } = input;\n\tsignal?.throwIfAborted();\n\tconst constraints = structuredClone((input.constraints ?? []).map((c) => parseModelConstraints(c)!));\n\tconst statedNeeds = parseTaskNeeds(input.taskNeeds);\n\t// settings.json provider lists are defaults that only the call itself may\n\t// replace; every constraint's own provider lists are enforced by eligiblePair.\n\tconst routing = ctx.getModelRouting?.() ?? {};\n\tconst { allowedProviders = [], excludedProviders = [] } = input.overrideProviderSettings ? {} : routing;\n\t// The model lists are the operator's gate and apply to every call (#3528).\n\tconst { allowedModels = [], excludedModels = [] } = routing;\n\tconst providerPermitted = (provider: string) =>\n\t\t(allowedProviders.length === 0 || allowedProviders.includes(provider)) && !excludedProviders.includes(provider);\n\tconst matching = (patterns: readonly string[], models: readonly Model<Api>[]) =>\n\t\tnew Set(\n\t\t\tresolveModelScopeFromModels([...patterns], models).scopedModels.map(\n\t\t\t\t({ model }) => `${model.provider}/${model.id}`,\n\t\t\t),\n\t\t);\n\tconst permittedModels = () => {\n\t\tconst models = ctx.modelRegistry.getAvailable();\n\t\tconst allowed = allowedModels.length ? matching(allowedModels, models) : undefined;\n\t\tconst excluded = matching(excludedModels, models);\n\t\treturn models.filter((model) => {\n\t\t\tconst id = `${model.provider}/${model.id}`;\n\t\t\treturn (\n\t\t\t\tisModelType(model, \"chat\") &&\n\t\t\t\tproviderPermitted(model.provider) &&\n\t\t\t\t(allowed === undefined || allowed.has(id)) &&\n\t\t\t\t!excluded.has(id)\n\t\t\t);\n\t\t});\n\t};\n\tconst catalog = () =>\n\t\tpermittedModels()\n\t\t\t// Ultrafast is billed above Standard and gated by account access. It is selectable\n\t\t\t// manually, but auto must receive an exact caller allowance or restore an explicit decision.\n\t\t\t.filter(\n\t\t\t\t(model) =>\n\t\t\t\t\tmodel.fastRoute?.serviceTier !== \"ultrafast\" ||\n\t\t\t\t\tconstraints.some((constraint) => constraint.allowedModels?.includes(`${model.provider}/${model.id}`)) ||\n\t\t\t\t\tinput.selection?.model === `${model.provider}/${model.id}`,\n\t\t\t)\n\t\t\t.map((model) => ({\n\t\t\t\tmodel,\n\t\t\t\tpairs: (model.reasoning ? getSupportedThinkingLevels(model) : [null])\n\t\t\t\t\t.map((effort) => ({ model: `${model.provider}/${model.id}`, effort }))\n\t\t\t\t\t.filter((pair) => eligiblePair(model, pair, constraints)),\n\t\t\t}))\n\t\t\t.filter((entry) => entry.pairs.length > 0);\n\tconst available = catalog();\n\tconst pairs = available.flatMap((entry) => entry.pairs);\n\tif (!pairs.length) {\n\t\tconst providerSettings = allowedProviders.length > 0 || excludedProviders.length > 0;\n\t\tconst gateSettings = [\n\t\t\t...(providerSettings ? [\"modelRouting allowedProviders/excludedProviders\"] : []),\n\t\t\t...(allowedModels.length ? [\"modelRouting.allowedModels\"] : []),\n\t\t\t...(excludedModels.length ? [\"modelRouting.excludedModels\"] : []),\n\t\t];\n\t\tconst noun = gateSettings.length === 1 && !providerSettings ? \"setting\" : \"settings\";\n\t\tthrow new Error(\n\t\t\tgateSettings.length\n\t\t\t\t? `Auto routing has no eligible model/effort pairs. Check configured providers, modelConstraints, and the ${new Intl.ListFormat(\"en\", { type: \"conjunction\" }).format(gateSettings)} ${noun}.`\n\t\t\t\t: \"Auto routing has no eligible model/effort pairs. Check configured providers and modelConstraints.\",\n\t\t);\n\t}\n\t// The effective post-filter pool, echoed in routerSelection for audit (#3528).\n\tconst candidates = [...new Set(available.map((entry) => `${entry.model.provider}/${entry.model.id}`))];\n\tlet selection = input.selection;\n\tif (selection === undefined) {\n\t\tconst settings = { getRouterModel: () => ctx.getRouterModel() };\n\t\tconst router = resolveRouterModel({ settings, currentModel: ctx.model, modelRegistry: ctx.modelRegistry });\n\t\tif (!input.task.trim()) throw new Error(\"Auto routing requires task instructions.\");\n\t\tconst stated = statedNeeds;\n\t\tconst agent = { name: input.agent.name, description: input.agent.description };\n\t\t// Screen the task before any model reads it.\n\t\tconst serialized = JSON.stringify({ task: input.task, agent, stated, constraints });\n\t\tlet configuredCredential: boolean;\n\t\ttry {\n\t\t\tconfiguredCredential = await ctx.modelRegistry.containsConfiguredCredential(serialized);\n\t\t} catch {\n\t\t\tthrow new Error(\"Auto routing could not screen configured credentials. No inference was performed.\");\n\t\t}\n\t\tif (\n\t\t\tcontainsKnownEnvCredential(serialized) ||\n\t\t\tconfiguredCredential ||\n\t\t\t/\\bBearer\\s+[A-Za-z0-9._~+/-]{8,}|-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----|\\b(?:sk|ghp|github_pat)[-_][A-Za-z0-9_-]{16,}/i.test(\n\t\t\t\tserialized,\n\t\t\t)\n\t\t)\n\t\t\tthrow new Error(\"Auto routing context contains credential material. Remove secrets before retrying.\");\n\t\tconst task = input.task;\n\t\t// Degrade only to a current chat model that is available and eligible under\n\t\t// the same constraints, restored through the normal selection path (#3206).\n\t\tconst currentModelRoute = async (): Promise<ModelRoute | undefined> => {\n\t\t\tconst current = ctx.model;\n\t\t\tconst entry = available.find(\n\t\t\t\t(candidate) => candidate.model.provider === current?.provider && candidate.model.id === current?.id,\n\t\t\t);\n\t\t\tconst pair = CURRENT_MODEL_EFFORT_PREFERENCE.map((effort) =>\n\t\t\t\tentry?.pairs.find((candidate) => candidate.effort === effort),\n\t\t\t).find((candidate) => candidate !== undefined);\n\t\t\tif (pair === undefined) return undefined;\n\t\t\treturn routeExecutionModel({ ...input, selection: { model: pair.model, effort: pair.effort, candidates } });\n\t\t};\n\t\t// Any failure before a model is chosen is a total inference failure: the\n\t\t// router and its chat structured-output fallback both failed (#3206).\n\t\tconst infer = async <T>(decide: () => Promise<T>): Promise<T> => {\n\t\t\ttry {\n\t\t\t\treturn await decide();\n\t\t\t} catch (error) {\n\t\t\t\tsignal?.throwIfAborted();\n\t\t\t\tthrow new AutoRoutingInferenceError(\n\t\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t\t\tawait currentModelRoute().catch(() => undefined),\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\t\t// Where code cannot pick a model either, the current chat model takes over\n\t\t// the same way.\n\t\tconst fallBackToCurrentModel = async (message: string): Promise<never> => {\n\t\t\tthrow new AutoRoutingInferenceError(message, await currentModelRoute().catch(() => undefined));\n\t\t};\n\t\tconst catalogEvals = await readModelSelectionEvals(signal)\n\t\t\t.then(parseEvalsCatalog)\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tsignal?.throwIfAborted();\n\t\t\t\treturn fallBackToCurrentModel(error instanceof Error ? error.message : String(error));\n\t\t\t});\n\n\t\t// Step 1: a chat model reads the task and answers only what the caller did\n\t\t// not state. A classifier router such as Jev never receives the task.\n\t\tconst questions = missingNeedsQuestions(stated);\n\t\tlet answers: Record<string, string> = {};\n\t\tif (questions.length) {\n\t\t\tconst current = ctx.model;\n\t\t\tconst preferred =\n\t\t\t\trouter.kind === \"chat\"\n\t\t\t\t\t? router.model\n\t\t\t\t\t: current && current.id !== \"auto\" && isModelType(current, \"chat\")\n\t\t\t\t\t\t? current\n\t\t\t\t\t\t: undefined;\n\t\t\t// The reader gets the complete task. When the task is larger than the\n\t\t\t// preferred reader's window, the cheapest eligible model that holds it\n\t\t\t// reads instead; eligible models are the ones allowed to receive the task.\n\t\t\tconst taskTokens = Math.ceil(Buffer.byteLength(task, \"utf8\") / BYTES_PER_TOKEN) + READER_OVERHEAD_TOKENS;\n\t\t\tconst holdsTask = (model: Model<Api>) => model.contextWindow >= taskTokens;\n\t\t\tconst readerModel =\n\t\t\t\tpreferred && holdsTask(preferred)\n\t\t\t\t\t? preferred\n\t\t\t\t\t: (available\n\t\t\t\t\t\t\t.map((entry) => entry.model)\n\t\t\t\t\t\t\t.filter(holdsTask)\n\t\t\t\t\t\t\t.sort(\n\t\t\t\t\t\t\t\t(a, b) =>\n\t\t\t\t\t\t\t\t\ta.cost.input - b.cost.input ||\n\t\t\t\t\t\t\t\t\t`${a.provider}/${a.id}`.localeCompare(`${b.provider}/${b.id}`),\n\t\t\t\t\t\t\t)[0] ?? preferred);\n\t\t\tconst reader = readerModel ? `${readerModel.provider}/${readerModel.id}` : undefined;\n\t\t\tif (reader === undefined)\n\t\t\t\tawait fallBackToCurrentModel(\n\t\t\t\t\t\"Auto routing needs a chat model to read the task. Select a chat model or state every taskNeeds field.\",\n\t\t\t\t);\n\t\t\tconst schema = Type.Object(\n\t\t\t\tObject.fromEntries(\n\t\t\t\t\tquestions.map((question) => [\n\t\t\t\t\t\tquestion.id,\n\t\t\t\t\t\tType.String({\n\t\t\t\t\t\t\tenum: Object.keys(question.criteria),\n\t\t\t\t\t\t\tdescription: `${question.instructions} ${Object.entries(question.criteria)\n\t\t\t\t\t\t\t\t.map(([key, meaning]) => `${key}: ${meaning}`)\n\t\t\t\t\t\t\t\t.join(\"; \")}.`,\n\t\t\t\t\t\t}),\n\t\t\t\t\t]),\n\t\t\t\t),\n\t\t\t\t{ additionalProperties: false },\n\t\t\t);\n\t\t\tconst callerSays = stated\n\t\t\t\t? {\n\t\t\t\t\t\t...(stated.work ? { work: stated.work } : {}),\n\t\t\t\t\t\t...(stated.difficulty ? { difficulty: stated.difficulty } : {}),\n\t\t\t\t\t\t...(stated.mistakeCost ? { mistake_cost: stated.mistakeCost } : {}),\n\t\t\t\t\t\t...(stated.needsImages !== undefined ? { needs_images: stated.needsImages ? \"yes\" : \"no\" } : {}),\n\t\t\t\t\t\t...(stated.longContext !== undefined ? { long_context: stated.longContext ? \"yes\" : \"no\" } : {}),\n\t\t\t\t\t\t...(stated.latencySensitive !== undefined\n\t\t\t\t\t\t\t? { latency_sensitive: stated.latencySensitive ? \"yes\" : \"no\" }\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t}\n\t\t\t\t: undefined;\n\t\t\tconst result = await infer(() =>\n\t\t\t\trouteModel(\n\t\t\t\t\t{\n\t\t\t\t\t\tsettings: { getRouterModel: () => reader! },\n\t\t\t\t\t\tmodelRegistry: ctx.modelRegistry,\n\t\t\t\t\t\tcurrentModel: ctx.model,\n\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\ttask,\n\t\t\t\t\t\t\tagent,\n\t\t\t\t\t\t\t...(callerSays && Object.keys(callerSays).length ? { caller_says: callerSays } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tinstructions: NEEDS_INSTRUCTIONS,\n\t\t\t\t\t\tschema,\n\t\t\t\t\t\t// Unused: the reader always resolves to a chat model.\n\t\t\t\t\t\tclassifier: {\n\t\t\t\t\t\t\tquestions: Object.fromEntries(\n\t\t\t\t\t\t\t\tquestions.map((question) => [\n\t\t\t\t\t\t\t\t\tquestion.id,\n\t\t\t\t\t\t\t\t\t{ instructions: question.instructions, criteria: question.criteria },\n\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tdecode: (choices) =>\n\t\t\t\t\t\t\t\tObject.fromEntries(questions.map((question) => [question.id, choices[question.id]!])),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t},\n\t\t\t\t\t(value) => questions.every((question) => Object.hasOwn(question.criteria, String(value[question.id]))),\n\t\t\t\t),\n\t\t\t);\n\t\t\tanswers = result.value;\n\t\t}\n\t\tconst needs: ResolvedTaskNeeds = resolveTaskNeeds(stated, answers);\n\n\t\t// Step 2: narrow in code. A task that needs images only goes to models that read them.\n\t\tconst seeing = needs.needsImages ? available.filter((entry) => entry.model.input.includes(\"image\")) : available;\n\t\tif (seeing.length === 0)\n\t\t\tawait fallBackToCurrentModel(\n\t\t\t\t\"Auto routing: this task needs a model that can read images, and no eligible model can. Allow an image-capable model or select a concrete execution model.\",\n\t\t\t);\n\t\t// A large context window is preferred, not required: context size is a matter of degree.\n\t\tconst roomy = needs.longContext\n\t\t\t? seeing.filter((entry) => entry.model.contextWindow >= LONG_CONTEXT_TOKENS)\n\t\t\t: seeing;\n\t\tconst usable = roomy.length ? roomy : seeing;\n\t\tconst pairsFor = new Map(usable.map((entry) => [`${entry.model.provider}/${entry.model.id}`, entry.pairs]));\n\t\tconst routedCandidates = [...pairsFor.keys()];\n\t\tconst toCandidate = (model: Model<Api>): CandidateModel => {\n\t\t\tconst routeCost = model.fastRoute?.serviceTier\n\t\t\t\t? getServiceTierCost(model, model.fastRoute.serviceTier)\n\t\t\t\t: undefined;\n\t\t\treturn {\n\t\t\t\tmodel: `${model.provider}/${model.id}`,\n\t\t\t\tname: model.name,\n\t\t\t\tcost: routeCost ?? model.cost,\n\t\t\t\tinput: model.input,\n\t\t\t\t...(model.fastRoute\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tfastRouteOf: `${model.provider}/${model.fastRoute.baseModelId}`,\n\t\t\t\t\t\t\tfastRouteServiceTier: model.fastRoute.serviceTier,\n\t\t\t\t\t\t\tfastRoutePriced: routeCost !== undefined,\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t};\n\t\t};\n\t\t// A caller that lists models (`allowedModels`) chooses the contenders itself,\n\t\t// but price and recency still compare them with every model the user could route to.\n\t\tconst callerListed = constraints.some((constraint) => (constraint.allowedModels?.length ?? 0) > 0);\n\t\tconst reference = callerListed\n\t\t\t? permittedModels().filter((model) => !needs.needsImages || model.input.includes(\"image\"))\n\t\t\t: usable.map((entry) => entry.model);\n\t\tconst standings = rankCandidates(catalogEvals, reference.map(toCandidate), needs);\n\t\tconst ranked = standings.filter((candidate) => pairsFor.has(candidate.model));\n\t\tconst choiceState = {\n\t\t\tagent,\n\t\t\tneeds: {\n\t\t\t\twork: needs.work,\n\t\t\t\tdifficulty: needs.difficulty,\n\t\t\t\tmistake_cost: needs.mistakeCost,\n\t\t\t\tneeds_images: needs.needsImages,\n\t\t\t\tlong_context: needs.longContext,\n\t\t\t\tlatency_sensitive: needs.latencySensitive,\n\t\t\t},\n\t\t};\n\t\tconst describeAll = (options: readonly RankedCandidate[]) =>\n\t\t\tObject.fromEntries(options.map((option, index) => [`m${index}`, describeOption(option, needs, standings)]));\n\t\tconst fitsOneChoice = (options: readonly RankedCandidate[]) =>\n\t\t\toptions.length <= MAX_CHOICE_OPTIONS &&\n\t\t\tBuffer.byteLength(\n\t\t\t\tJSON.stringify({ state: choiceState, instructions: CHOICE_INSTRUCTIONS, criteria: describeAll(options) }),\n\t\t\t\t\"utf8\",\n\t\t\t) <= ROUTING_REQUEST_BYTES;\n\t\t// A caller's list is offered whole when it fits one choice request; otherwise\n\t\t// duplicate routes of one model share a slot, and a list that still does not\n\t\t// fit falls back rather than silently dropping a contender.\n\t\tconst callerChoices = !callerListed || fitsOneChoice(ranked) ? ranked : distinctTop(ranked, ranked.length);\n\t\tif (callerListed && !fitsOneChoice(callerChoices))\n\t\t\tawait fallBackToCurrentModel(\n\t\t\t\t`Auto routing cannot compare ${callerChoices.length} different models from modelConstraints.allowedModels in one routing request. List fewer models.`,\n\t\t\t);\n\t\tconst shortlist = callerListed ? callerChoices : distinctTop(ranked, SHORTLIST_SIZE);\n\n\t\t// Step 3: the router picks one option; each carries its own evidence.\n\t\tlet chosen = shortlist[0]!;\n\t\tif (shortlist.length > 1) {\n\t\t\tconst keys = shortlist.map((_, index) => `m${index}`);\n\t\t\tconst schema = Type.Object(\n\t\t\t\t{ modelId: Type.String({ enum: shortlist.map((option) => option.model) }) },\n\t\t\t\t{ additionalProperties: false },\n\t\t\t);\n\t\t\tconst result = await infer(() =>\n\t\t\t\trouteModel(\n\t\t\t\t\t{\n\t\t\t\t\t\tsettings,\n\t\t\t\t\t\tmodelRegistry: ctx.modelRegistry,\n\t\t\t\t\t\tcurrentModel: ctx.model,\n\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t...choiceState,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tinstructions: CHOICE_INSTRUCTIONS,\n\t\t\t\t\t\tschema,\n\t\t\t\t\t\tclassifier: {\n\t\t\t\t\t\t\tquestions: {\n\t\t\t\t\t\t\t\tmodel: {\n\t\t\t\t\t\t\t\t\tinstructions: \"Which model should do this task?\",\n\t\t\t\t\t\t\t\t\tcriteria: describeAll(shortlist),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tdecode: (choices) => {\n\t\t\t\t\t\t\t\tconst option = shortlist[keys.indexOf(choices.model ?? \"\")];\n\t\t\t\t\t\t\t\tif (!option) throw new Error(\"Invalid execution model Choice.\");\n\t\t\t\t\t\t\t\treturn { modelId: option.model };\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t},\n\t\t\t\t\t(value) => shortlist.some((option) => option.model === value.modelId),\n\t\t\t\t),\n\t\t\t);\n\t\t\tchosen = shortlist.find((option) => option.model === result.value.modelId)!;\n\t\t}\n\n\t\t// Step 4: effort from difficulty; fallbacks are the next distinct models in code's ranking.\n\t\tconst effortOf = (model: string) =>\n\t\t\teffortForDifficulty(\n\t\t\t\t(pairsFor.get(model) ?? []).map((pair) => pair.effort),\n\t\t\t\tneeds.difficulty,\n\t\t\t\tneeds.latencySensitive,\n\t\t\t);\n\t\tconst fallbackModels = distinctTop(\n\t\t\tranked.filter((candidate) => candidate.baseKey !== chosen.baseKey),\n\t\t\t2,\n\t\t);\n\t\treportModelRoutingDebug(\n\t\t\t`Auto routing: ${needs.work}, ${needs.difficulty}, mistake cost ${needs.mistakeCost}, images ${needs.needsImages ? \"yes\" : \"no\"}, long context ${needs.longContext ? \"yes\" : \"no\"}, latency ${needs.latencySensitive ? \"sensitive\" : \"tolerant\"}; chose ${chosen.model} from ${shortlist.map((option) => option.model).join(\", \")}.`,\n\t\t);\n\t\tselection = {\n\t\t\tmodel: chosen.model,\n\t\t\teffort: effortOf(chosen.model),\n\t\t\t...(fallbackModels.length\n\t\t\t\t? {\n\t\t\t\t\t\tfallbacks: fallbackModels.map((candidate) => ({\n\t\t\t\t\t\t\tmodel: candidate.model,\n\t\t\t\t\t\t\teffort: effortOf(candidate.model),\n\t\t\t\t\t\t})),\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t\tcandidates: routedCandidates,\n\t\t};\n\t}\n\tconst fallbacks = selection.fallbacks?.map((pair) => Object.freeze({ model: pair.model, effort: pair.effort }));\n\tif (\n\t\tfallbacks &&\n\t\t(fallbacks.length > 2 ||\n\t\t\tnew Set([selection.model, ...fallbacks.map((pair) => pair.model)]).size !== fallbacks.length + 1)\n\t)\n\t\tthrow new Error(\"Invalid ranked auto selection: expected up to three distinct models.\");\n\tconst routerSelection = Object.freeze({\n\t\tmodel: selection.model,\n\t\teffort: selection.effort,\n\t\t...(fallbacks?.length ? { fallbacks: Object.freeze(fallbacks) } : {}),\n\t\t...(selection.candidates ? { candidates: Object.freeze([...selection.candidates]) } : {}),\n\t});\n\tconst hasPair = (pair: ModelRouterOutput) =>\n\t\tcatalog().some((entry) => entry.pairs.some((p) => p.model === pair.model && p.effort === pair.effort));\n\tconst allowsModel = (model: Model<Api>, effort?: string): boolean => {\n\t\tconst levels = model.reasoning ? getSupportedThinkingLevels(model) : [null];\n\t\treturn levels.some((level) => {\n\t\t\tif (model.reasoning && effort !== undefined && level !== effort) return false;\n\t\t\tconst pair = { model: `${model.provider}/${model.id}`, effort: level };\n\t\t\treturn eligiblePair(model, pair, constraints) && hasPair(pair);\n\t\t});\n\t};\n\tconst assertCurrent = () => {\n\t\tsignal?.throwIfAborted();\n\t\tif (![routerSelection, ...(routerSelection.fallbacks ?? [])].every(hasPair))\n\t\t\tthrow new Error(\"Auto selection is no longer eligible. Retry explicitly with the current catalog.\");\n\t};\n\tassertCurrent();\n\treturn {\n\t\trouterSelection,\n\t\tmodelOverride: routerSelection.model + (routerSelection.effort === null ? \"\" : `:${routerSelection.effort}`),\n\t\tfallbackModels: Object.freeze(\n\t\t\t(routerSelection.fallbacks ?? []).map((pair) => pair.model + (pair.effort === null ? \"\" : `:${pair.effort}`)),\n\t\t),\n\t\tassertCurrent,\n\t\tallowsModel,\n\t};\n}\n"]}
|
|
@@ -20,6 +20,8 @@ export type ModelRouterOutput = {
|
|
|
20
20
|
readonly model: string;
|
|
21
21
|
readonly effort: string | null;
|
|
22
22
|
}[];
|
|
23
|
+
/** Full IDs of every model the router could choose from after all filters. Absent on legacy recorded selections. */
|
|
24
|
+
readonly candidates?: readonly string[];
|
|
23
25
|
};
|
|
24
26
|
/** Whether a constraint sets its own provider list. */
|
|
25
27
|
export declare function setsProviders(constraints: ModelConstraints | undefined): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-routing-constraints.d.ts","sourceRoot":"","sources":["../../src/core/model-routing-constraints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,eAAO,MAAM,sBAAsB;;;;;;;;;EAsDlC,CAAC;AACF,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAErE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,GAAG,SAAS,CAWlF;AACD,MAAM,MAAM,iBAAiB,GAAG;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,wFAAwF;IACxF,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"model-routing-constraints.d.ts","sourceRoot":"","sources":["../../src/core/model-routing-constraints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,eAAO,MAAM,sBAAsB;;;;;;;;;EAsDlC,CAAC;AACF,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAErE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,GAAG,SAAS,CAWlF;AACD,MAAM,MAAM,iBAAiB,GAAG;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,wFAAwF;IACxF,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,EAAE,CAAC;IAC3F,oHAAoH;IACpH,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC,CAAC;AACF,uDAAuD;AACvD,wBAAgB,aAAa,CAAC,WAAW,EAAE,gBAAgB,GAAG,SAAS,GAAG,OAAO,CAEhF;AAED,8FAA8F;AAC9F,wBAAgB,YAAY,CAC3B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,IAAI,EAAE,iBAAiB,EACvB,WAAW,EAAE,SAAS,gBAAgB,EAAE,GACtC,OAAO,CAcT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-routing-constraints.js","sourceRoot":"","sources":["../../src/core/model-routing-constraints.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC,MAAM,CAChD;IACC,aAAa,EAAE,IAAI,CAAC,QAAQ,CAC3B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE;QACzC,WAAW,EACV,4cAA4c;KAC7c,CAAC,CACF;IACD,gBAAgB,EAAE,IAAI,CAAC,QAAQ,CAC9B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE;QACzC,WAAW,EACV,qQAAqQ;KACtQ,CAAC,CACF;IACD,iBAAiB,EAAE,IAAI,CAAC,QAAQ,CAC/B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE;QACzC,WAAW,EACV,gNAAgN;KACjN,CAAC,CACF;IACD,YAAY,EAAE,IAAI,CAAC,QAAQ,CAC1B,IAAI,CAAC,MAAM,CAAC;QACX,OAAO,EAAE,CAAC;QACV,WAAW,EACV,yGAAyG;KAC1G,CAAC,CACF;IACD,aAAa,EAAE,IAAI,CAAC,QAAQ,CAC3B,IAAI,CAAC,MAAM,CAAC;QACX,OAAO,EAAE,CAAC;QACV,WAAW,EACV,0GAA0G;KAC3G,CAAC,CACF;IACD,gBAAgB,EAAE,IAAI,CAAC,QAAQ,CAC9B,IAAI,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,2CAA2C,EAAE,CAAC,CACrF;IACD,cAAc,EAAE,IAAI,CAAC,QAAQ,CAC5B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAmB,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CACnF;IACD,cAAc,EAAE,IAAI,CAAC,QAAQ,CAC5B,IAAI,CAAC,KAAK,CACT,IAAI,CAAC,KAAK,CAAC;QACV,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;QAClF,IAAI,CAAC,IAAI,EAAE;KACX,CAAC,CACF,CACD;CACD,EACD;IACC,oBAAoB,EAAE,KAAK;IAC3B,WAAW,EACV,oKAAoK;CACrK,CACD,CAAC;AAEF,MAAM,SAAS,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;AAClD,MAAM,UAAU,qBAAqB,CAAC,KAAc;IACnD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,IACC,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC;QACvB,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC,IAAI,CACrE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAC7C,EACA,CAAC;QACF,MAAM,IAAI,KAAK,CAAC,mFAAmF,CAAC,CAAC;IACtG,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;
|
|
1
|
+
{"version":3,"file":"model-routing-constraints.js","sourceRoot":"","sources":["../../src/core/model-routing-constraints.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, Model } from \"@bastani/pi-ai\";\nimport { type Static, Type } from \"typebox\";\nimport { Compile } from \"typebox/compile\";\n\nexport const ModelConstraintsSchema = Type.Object(\n\t{\n\t\tallowedModels: Type.Optional(\n\t\t\tType.Array(Type.String({ minLength: 1 }), {\n\t\t\t\tdescription:\n\t\t\t\t\t\"Exact provider/model IDs; omitted uses the full available catalog. With model 'auto', these are the candidates the router chooses between (as many as fit one routing request, roughly 100), so list the models that suit the task. Prefer the user's subscription models (for example ChatGPT/Codex, GitHub Copilot, a Claude subscription, or a coding or token plan) over pay-per-token API models, unless the user asked for API models or has no subscription models.\",\n\t\t\t}),\n\t\t),\n\t\tallowedProviders: Type.Optional(\n\t\t\tType.Array(Type.String({ minLength: 1 }), {\n\t\t\t\tdescription:\n\t\t\t\t\t'Provider IDs whose models may be used, for example [\"openai-codex\", \"github-copilot\"]. Setting this or excludedProviders replaces the user\\'s modelRouting provider settings for this call, so set them only when the user asks to use or avoid specific providers.',\n\t\t\t}),\n\t\t),\n\t\texcludedProviders: Type.Optional(\n\t\t\tType.Array(Type.String({ minLength: 1 }), {\n\t\t\t\tdescription:\n\t\t\t\t\t'Provider IDs whose models are never used, for example [\"openrouter\"]. Setting this or allowedProviders replaces the user\\'s modelRouting provider settings for this call, so set them only when the user asks.',\n\t\t\t}),\n\t\t),\n\t\tmaxInputCost: Type.Optional(\n\t\t\tType.Number({\n\t\t\t\tminimum: 0,\n\t\t\t\tdescription:\n\t\t\t\t\t\"Maximum catalog input rate in USD per million tokens, including pricing tiers; not total task spending.\",\n\t\t\t}),\n\t\t),\n\t\tmaxOutputCost: Type.Optional(\n\t\t\tType.Number({\n\t\t\t\tminimum: 0,\n\t\t\t\tdescription:\n\t\t\t\t\t\"Maximum catalog output rate in USD per million tokens, including pricing tiers; not total task spending.\",\n\t\t\t}),\n\t\t),\n\t\tminContextWindow: Type.Optional(\n\t\t\tType.Number({ minimum: 0, description: \"Minimum catalog context window in tokens.\" }),\n\t\t),\n\t\trequiredInputs: Type.Optional(\n\t\t\tType.Array(Type.Unsafe<\"text\" | \"image\">(Type.String({ enum: [\"text\", \"image\"] }))),\n\t\t),\n\t\tallowedEfforts: Type.Optional(\n\t\t\tType.Array(\n\t\t\t\tType.Union([\n\t\t\t\t\tType.String({ enum: [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"] }),\n\t\t\t\t\tType.Null(),\n\t\t\t\t]),\n\t\t\t),\n\t\t),\n\t},\n\t{\n\t\tadditionalProperties: false,\n\t\tdescription:\n\t\t\t\"Hard constraints for auto selection and execution fallback. Applicable definition and call constraints must all hold; concrete model calls keep existing behavior.\",\n\t},\n);\nexport type ModelConstraints = Static<typeof ModelConstraintsSchema>;\nconst validator = Compile(ModelConstraintsSchema);\nexport function parseModelConstraints(value: unknown): ModelConstraints | undefined {\n\tif (value === undefined) return undefined;\n\tif (\n\t\t!validator.Check(value) ||\n\t\t[value.maxInputCost, value.maxOutputCost, value.minContextWindow].some(\n\t\t\t(n) => n !== undefined && !Number.isFinite(n),\n\t\t)\n\t) {\n\t\tthrow new Error(\"Invalid modelConstraints: use known fields and finite nonnegative numeric limits.\");\n\t}\n\treturn value;\n}\nexport type ModelRouterOutput = {\n\treadonly model: string;\n\treadonly effort: string | null;\n\t/** Ranked alternatives, excluding the primary. Absent on legacy recorded selections. */\n\treadonly fallbacks?: readonly { readonly model: string; readonly effort: string | null }[];\n\t/** Full IDs of every model the router could choose from after all filters. Absent on legacy recorded selections. */\n\treadonly candidates?: readonly string[];\n};\n/** Whether a constraint sets its own provider list. */\nexport function setsProviders(constraints: ModelConstraints | undefined): boolean {\n\treturn constraints?.allowedProviders !== undefined || constraints?.excludedProviders !== undefined;\n}\n\n/** Every applicable declaration must hold; a caller never widens a definition restriction. */\nexport function eligiblePair(\n\tmodel: Model<Api>,\n\tpair: ModelRouterOutput,\n\tconstraints: readonly ModelConstraints[],\n): boolean {\n\treturn constraints.every(\n\t\t(c) =>\n\t\t\t(c.allowedModels === undefined || c.allowedModels.includes(pair.model)) &&\n\t\t\t(c.allowedProviders === undefined || c.allowedProviders.includes(model.provider)) &&\n\t\t\t!c.excludedProviders?.includes(model.provider) &&\n\t\t\t(c.allowedEfforts === undefined || c.allowedEfforts.some((e) => e === pair.effort)) &&\n\t\t\t(c.maxInputCost === undefined ||\n\t\t\t\t[model.cost, ...(model.cost.tiers ?? [])].every((rate) => rate.input <= c.maxInputCost!)) &&\n\t\t\t(c.maxOutputCost === undefined ||\n\t\t\t\t[model.cost, ...(model.cost.tiers ?? [])].every((rate) => rate.output <= c.maxOutputCost!)) &&\n\t\t\t(c.minContextWindow === undefined || model.contextWindow >= c.minContextWindow) &&\n\t\t\t(c.requiredInputs === undefined || c.requiredInputs.every((input) => model.input.includes(input))),\n\t);\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AssistantMessage } from "@bastani/pi-ai/compat";
|
|
2
|
+
/** Warnings a response carries because a requested Fast or Ultrafast tier did not apply. */
|
|
3
|
+
export declare function serviceTierWarnings(message: AssistantMessage): string[];
|
|
4
|
+
//# sourceMappingURL=service-tier-warnings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-tier-warnings.d.ts","sourceRoot":"","sources":["../../src/core/service-tier-warnings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,4FAA4F;AAC5F,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAMvE"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Warnings a response carries because a requested Fast or Ultrafast tier did not apply. */
|
|
2
|
+
export function serviceTierWarnings(message) {
|
|
3
|
+
return (message.diagnostics ?? []).flatMap((diagnostic) => diagnostic.type === "service_tier_unavailable" && typeof diagnostic.details?.message === "string"
|
|
4
|
+
? [diagnostic.details.message]
|
|
5
|
+
: []);
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=service-tier-warnings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-tier-warnings.js","sourceRoot":"","sources":["../../src/core/service-tier-warnings.ts"],"names":[],"mappings":"AAEA,4FAA4F;AAC5F,MAAM,UAAU,mBAAmB,CAAC,OAAyB;IAC5D,OAAO,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CACzD,UAAU,CAAC,IAAI,KAAK,0BAA0B,IAAI,OAAO,UAAU,CAAC,OAAO,EAAE,OAAO,KAAK,QAAQ;QAChG,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC;QAC9B,CAAC,CAAC,EAAE,CACL,CAAC;AACH,CAAC","sourcesContent":["import type { AssistantMessage } from \"@bastani/pi-ai/compat\";\n\n/** Warnings a response carries because a requested Fast or Ultrafast tier did not apply. */\nexport function serviceTierWarnings(message: AssistantMessage): string[] {\n\treturn (message.diagnostics ?? []).flatMap((diagnostic) =>\n\t\tdiagnostic.type === \"service_tier_unavailable\" && typeof diagnostic.details?.message === \"string\"\n\t\t\t? [diagnostic.details.message]\n\t\t\t: [],\n\t);\n}\n"]}
|
|
@@ -6,8 +6,8 @@ import { SettingsManager } from "./settings-manager-core.js";
|
|
|
6
6
|
import { settingsInternals } from "./settings-manager-internals.js";
|
|
7
7
|
import { resolveDefaultTools } from "./settings-merge.js";
|
|
8
8
|
import { CACHE_WARMING_MODES } from "./settings-types.js";
|
|
9
|
-
const MODEL_ROUTING_ERROR = 'Invalid modelRouting: allowedProviders and excludedProviders must be arrays of provider IDs, such as ["github-copilot"].';
|
|
10
|
-
function
|
|
9
|
+
const MODEL_ROUTING_ERROR = 'Invalid modelRouting: allowedProviders and excludedProviders must be arrays of provider IDs, such as ["github-copilot"], and allowedModels and excludedModels must be arrays of model IDs or glob patterns, such as ["anthropic/claude-*"].';
|
|
10
|
+
function routingList(value) {
|
|
11
11
|
if (value === undefined)
|
|
12
12
|
return undefined;
|
|
13
13
|
if (!Array.isArray(value) || value.some((item) => typeof item !== "string" || !item.trim() || item.trim() !== item))
|
|
@@ -122,11 +122,15 @@ const basicAccessors = {
|
|
|
122
122
|
return {};
|
|
123
123
|
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
124
124
|
throw new Error(MODEL_ROUTING_ERROR);
|
|
125
|
-
const allowedProviders =
|
|
126
|
-
const excludedProviders =
|
|
125
|
+
const allowedProviders = routingList(value.allowedProviders);
|
|
126
|
+
const excludedProviders = routingList(value.excludedProviders);
|
|
127
|
+
const allowedModels = routingList(value.allowedModels);
|
|
128
|
+
const excludedModels = routingList(value.excludedModels);
|
|
127
129
|
return {
|
|
128
130
|
...(allowedProviders ? { allowedProviders } : {}),
|
|
129
131
|
...(excludedProviders ? { excludedProviders } : {}),
|
|
132
|
+
...(allowedModels ? { allowedModels } : {}),
|
|
133
|
+
...(excludedModels ? { excludedModels } : {}),
|
|
130
134
|
};
|
|
131
135
|
},
|
|
132
136
|
setRouterModel(model, scope = "global") {
|