import { discoverFreeModels } from "./free-profile.js"; import { assertModelAllowed } from "./roster.js"; import type { Topology, UltraConfig } from "../types.js"; export { assertModelAllowed }; export function effectiveFreeMapping(availableModels: readonly string[]) { return discoverFreeModels(availableModels); } /** * The model a role uses for one particular lens, falling back to the role's own model. The lens * is the angle the work is being done from — `flow`, `tests`, `analogues` for a scout; the * writer's envelope lens, which is its topology or `first-proven-result`, for a writer. An * override is checked against the declared roster like any other model, so a per-lens entry * cannot smuggle in a model the profile does not allow. */ function modelForLens(config: UltraConfig, role: { model: string; modelByLens?: Record }, lens: string | undefined): string { const selected = lens ? role.modelByLens?.[lens] : undefined; if (!selected) return role.model; assertModelAllowed(config, selected); return selected; } export function scoutModelForLens(config: UltraConfig, lens: string | undefined): string { return modelForLens(config, config.scout, lens); } export function writerModelForLens(config: UltraConfig, lens: string | undefined, fallback = config.boundedWriter.model): string { const selected = lens ? config.boundedWriter.modelByLens?.[lens] : undefined; if (!selected) return fallback; assertModelAllowed(config, selected, true); return selected; } export function modelForRole(config: UltraConfig, topology: Topology): string { if (topology === "deep" || topology === "warroom") return config.deep.model; if (topology === "scout" || topology === "swarm") return config.scout.model; return config.root.model; }