feat(models): strong/cheap/vision model slots + multi-provider engine federation
Model slots wave (2026-09-20), chunk B:
- settings: new `models` section {strong, cheap, vision} slots (each
field independent, same shape as a role override); ROLE_SLOT maps all
nine roles to tiers (strong=prober+teacher, cheap=researcher/
demoBuilder/extractor/auditor/labeler, vision=visualMaker+pdfReader);
resolution chain per role: override → slot → factory pin.
- config: ModelSpec gains provider (all pins openrouter, the BYOK
default); MODEL_PINS in stores.ts now spans all nine roles (the strong
slot's factory rep IS the prober pin).
- engine: piModels() registers EVERY builtin provider catalog;
piEngineForSpec(resolved spec) is the new engine factory (pi-ai
resolves per-provider keys from env itself); piEngineFor stays as the
config-pin fallback. chat-handler resolves the conversation chain
(chat override → strong slot → pin) and injects engineFor into the job
runner, closing the old gap where per-role overrides never reached
job engines.
- /api/models: models federate ONLY keyed providers (providers surface
with keyPresent, env-wins, fresh per call); slots (resolved tier pins)
join rolePins; catalogDefaultsFor inherits the strong slot; the models
settings section gets the same catalog gate as chat.
- pricing: PRICES/CONTEXT_LIMITS uniformly keyed provider:id
(regenerated from ALL pi-ai catalogs, 1354 keys); usage stamps
(TurnUsage, JobUsage, extraction stages) switch to provider:id —
owner decision: no legacy compat, old stamps render unpriced.
This commit is contained in:
+13
-8
@@ -22,20 +22,25 @@ export const stores = {
|
||||
|
||||
export type Stores = typeof stores;
|
||||
|
||||
/** config.ts's MODELS narrowed to the background roles — the compiled
|
||||
* factory layer the resolution reads. core stays pure (it takes this as a
|
||||
* parameter, never imports config at runtime); the prober/teacher pins
|
||||
* are chat-settings-controlled and deliberately absent here. Tests pin
|
||||
* that the role set matches core's BACKGROUND_MODEL_ROLES. */
|
||||
const BACKGROUND_MODEL_PINS: ModelRoleSpecs = {
|
||||
/** config.ts's MODELS as the compiled factory layer the resolution reads —
|
||||
* ALL NINE roles since the model-slots wave (2026-09-20): the strong
|
||||
* slot's factory fallback IS the prober pin. core stays pure (it takes
|
||||
* this as a parameter, never imports config at runtime). Per-role
|
||||
* OVERRIDES stay background-only (the conversation pair is
|
||||
* chat-settings-controlled) — that split lives in core's
|
||||
* BACKGROUND_MODEL_ROLES, unchanged. */
|
||||
const MODEL_PINS: ModelRoleSpecs = {
|
||||
prober: MODELS.prober,
|
||||
teacher: MODELS.teacher,
|
||||
researcher: MODELS.researcher,
|
||||
demoBuilder: MODELS.demoBuilder,
|
||||
visualMaker: MODELS.visualMaker,
|
||||
pdfReader: MODELS.pdfReader,
|
||||
extractor: MODELS.extractor,
|
||||
auditor: MODELS.auditor,
|
||||
labeler: MODELS.labeler,
|
||||
};
|
||||
export { BACKGROUND_MODEL_PINS };
|
||||
export { MODEL_PINS };
|
||||
|
||||
/**
|
||||
* The resolved view of the settings record (core/settings-resolution.ts):
|
||||
@@ -44,5 +49,5 @@ export { BACKGROUND_MODEL_PINS };
|
||||
* no caching layer (stale toggles after a settings PUT would be worse).
|
||||
*/
|
||||
export function effectiveSettings(): EffectiveSettings {
|
||||
return resolveSettings(settingsStore.readSettings(), BACKGROUND_MODEL_PINS);
|
||||
return resolveSettings(settingsStore.readSettings(), MODEL_PINS);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user