UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

61 lines (60 loc) • 3.66 kB
import { tierAliasVia } from "./roles.js"; export function contextOverlayFor(settings, ref, catalog) { if (settings === undefined || typeof ref !== "string") return undefined; for (const word of [ref, ...tierAliasVia(ref, catalog?.models)]) if (Object.hasOwn(settings, word)) return settings[word]; return undefined; } export function assertContextSettingsWords(settings, models, where) { const unknown = Object.keys(settings ?? {}).filter((w) => models === undefined || !Object.hasOwn(models, w)); if (unknown.length === 0) return settings; const e = new Error(`${where}: contextSettings declares ${unknown.map((w) => JSON.stringify(w)).join(", ")}, which ${unknown.length === 1 ? "is" : "are"} not a word of the model catalog (its keys, and the tier words and aliases \`tiers\` expanded) — an overlay no leg can be keyed by governs nothing; the current settings stay in force`); e.code = "config.context_settings_unknown_word"; throw e; } export function assertContextSettingsValue(v, where) { if (v === undefined) return undefined; if (v === null || typeof v !== "object" || Array.isArray(v)) { throw new Error(`${where}: contextSettings must be a plain Record<string, {contextTokens?, autoCompactTokens?, enabled?}> (got ${v === null ? "null" : Array.isArray(v) ? "array" : typeof v})`); } const out = {}; for (const [word, raw] of Object.entries(v)) { if (raw === null || typeof raw !== "object" || Array.isArray(raw)) { throw new Error(`${where}: contextSettings[${JSON.stringify(word)}] must be a plain object (got ${raw === null ? "null" : Array.isArray(raw) ? "array" : typeof raw})`); } const o = raw; const unknown = Object.keys(o).filter((k) => k !== "contextTokens" && k !== "autoCompactTokens" && k !== "enabled"); if (unknown.length > 0) { throw new Error(`${where}: contextSettings[${JSON.stringify(word)}] carries ${unknown.map((k) => JSON.stringify(k)).join(", ")} — this seat declares window geometry only (contextTokens | autoCompactTokens | enabled); routing, pricing and fencing stay on the model card`); } for (const k of ["contextTokens", "autoCompactTokens"]) { const n = o[k]; if (n !== undefined && (typeof n !== "number" || !Number.isFinite(n) || n <= 0)) { throw new Error(`${where}: contextSettings[${JSON.stringify(word)}].${k} must be a positive finite number (got ${JSON.stringify(n)}) — an unusable window is a configuration defect, not a request to fall back to the model's own`); } } if (o.enabled !== undefined && typeof o.enabled !== "boolean") { throw new Error(`${where}: contextSettings[${JSON.stringify(word)}].enabled must be a boolean (got ${JSON.stringify(o.enabled)})`); } out[word] = Object.freeze({ ...(o.contextTokens !== undefined ? { contextTokens: o.contextTokens } : {}), ...(o.autoCompactTokens !== undefined ? { autoCompactTokens: o.autoCompactTokens } : {}), ...(o.enabled !== undefined ? { enabled: o.enabled } : {}), }); } return Object.freeze(out); } export function compactionEnabled(specEnabled, overlay) { return specEnabled ?? overlay?.enabled ?? true; } export function physicalWindowOf(model, overlay) { const card = model.contextTokens ?? model.contextWindow; const declared = overlay?.contextTokens; if (declared === undefined) return card; return Number.isFinite(card) && card > 0 ? Math.min(declared, card) : declared; }