/** * Shift tier scorer (OK-9.1, Switchyard stage-router pattern, arXiv lineage * in research/2026-08-18-switchyard-routing-fusion-deep-dive.md §2). * * Pure and deterministic: windowed behavioural signals over the last few tool * results decide the tier (efficient vs capable) for the current stage. No * model call on the hot path. Decision order (first match wins): * 1. critical severity OR compaction → capable (override) * 2. tests passed + recent production + 0 severity → efficient (settled) * 3. corroborative tanh scorer past threshold → route by sign * 4. fall-through → stage default (fall_open) * * Every decision carries a `source` label (override | tests_passed | * dimensions | fall_open) — Switchyard's observability discipline, and the * calibration-loop input. */ export type Tier = "efficient" | "capable"; export type TierDecisionSource = "override" | "tests_passed" | "dimensions" | "fall_open"; export interface TierDecision { tier: Tier; source: TierDecisionSource; /** Corroborative score in [-1, 1]; positive = toward capable. */ score: number; /** |score| — how confident the dimensions step is. */ confidence: number; reason: string; } /** One observed tool result in the window. */ export interface ToolSignal { /** The tool name (bash, write_file, edit_file, read_file, …). */ tool: string; /** First ~500 chars of the tool result text (for pattern matching). */ resultText: string; /** The command text for bash calls (enables write-bucketing, K3). */ command?: string; /** Non-zero exit / isError flag when known. */ isError?: boolean; } export interface TierInput { /** Last N tool results (caller passes ≤ window; we take the last 3). */ signals: ToolSignal[]; /** Current turn depth (tool calls so far this turn/session). */ turnDepth: number; /** True when the session context was auto-compacted (self-latching). */ compacted: boolean; } /** Severity levels (Switchyard's curated table). */ export declare const SEVERITY: { readonly SOFT: 0.3; readonly HARD: 0.7; readonly CRITICAL: 1; }; /** Corroborative threshold (Switchyard ships 0.5; one maxed signal ≈0.4621). */ export declare const TIER_THRESHOLD = 0.5; /** Max severity over the window (0 when clean). */ export declare function windowSeverity(signals: ToolSignal[]): number; /** Recent production intensity: (writes+edits) / ops in the window. */ export declare function productionIntensity(signals: ToolSignal[]): number; /** True when the window shows a settled run: tests passed, production, no severity. */ export declare function testsPassed(signals: ToolSignal[]): boolean; /** * The tier decision. Pure: same input → same decision. */ export declare function decideTier(input: TierInput, defaultTier?: Tier): TierDecision; /** Input modalities the pi-ai catalogue records per model. */ export type ModelModality = "text" | "image"; /** * True when the model accepts every required modality (K3 #2). The catalogue * records text/image today; audio/video/STT/TTS/embedding/ranking arrive with * the provider substrate — the filter is modality-generic so they slot in. * Tokens are a closed lowercase vocabulary; caller input is normalised (K3: * 'Image' used to silently defeat the filter). */ export declare function supportsModalities(modelInput: readonly ModelModality[], required: readonly ModelModality[]): boolean; /** Vision-capable shorthand (image tasks must never route to a text-only model). */ export declare function isVisionCapable(modelInput: readonly ModelModality[]): boolean; /** * Filter candidate models by required input modalities. If the filter would * empty the pool, return the original pool with `fellBack: true` (fail-open to * text-only rather than refuse the task) — the caller can label the routing * event instead of silently handing an image task to a text model (K3). * Pure and deterministic. */ export declare function filterByModality(models: readonly T[], required: readonly ModelModality[]): { models: T[]; fellBack: boolean; }; //# sourceMappingURL=tier.d.ts.map