@wrongstack/core 0.273.0 → 0.274.0

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.
Files changed (64) hide show
  1. package/dist/{agent-bridge-BZ2enORi.d.ts → agent-bridge-DFo21wmY.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-ehb4xGvd.d.ts → agent-subagent-runner-BwmkIDEd.d.ts} +7 -7
  3. package/dist/{brain-BxN2k2HP.d.ts → brain-gfZX3the.d.ts} +11 -5
  4. package/dist/{provider-model-resolve-DFd3IPpw.d.ts → codex-catalog-CooZ6mOl.d.ts} +47 -4
  5. package/dist/{compactor-72ug-ZRB.d.ts → compactor-riTOds0f.d.ts} +1 -1
  6. package/dist/{config-C8IYxlO8.d.ts → config-BxcrDzri.d.ts} +60 -4
  7. package/dist/{context-Dw55zZ_Q.d.ts → context-DERiLofu.d.ts} +60 -1
  8. package/dist/coordination/index.d.ts +27 -16
  9. package/dist/coordination/index.js +1641 -1398
  10. package/dist/coordination/index.js.map +1 -1
  11. package/dist/defaults/index.d.ts +26 -26
  12. package/dist/defaults/index.js +2154 -1466
  13. package/dist/defaults/index.js.map +1 -1
  14. package/dist/execution/index.d.ts +15 -15
  15. package/dist/execution/index.js +77 -9
  16. package/dist/execution/index.js.map +1 -1
  17. package/dist/execution/prompt-enhancer.d.ts +1 -1
  18. package/dist/extension/index.d.ts +6 -6
  19. package/dist/{global-mailbox-C9dsc9Y_.d.ts → global-mailbox-Cr8TW4t_.d.ts} +1 -1
  20. package/dist/{goal-preamble-NhflDjYb.d.ts → goal-preamble-CEhROp1e.d.ts} +9 -9
  21. package/dist/{goal-store-Cx363x7Z.d.ts → goal-store-xNSVxmpV.d.ts} +1 -1
  22. package/dist/hq/index.d.ts +5 -5
  23. package/dist/{index-B7fHDt0B.d.ts → index-00KPKAlm.d.ts} +5 -5
  24. package/dist/{index-BbVprU-9.d.ts → index-pDBSBE1r.d.ts} +2 -2
  25. package/dist/index.d.ts +72 -45
  26. package/dist/index.js +2840 -1769
  27. package/dist/index.js.map +1 -1
  28. package/dist/infrastructure/index.d.ts +6 -6
  29. package/dist/kernel/index.d.ts +11 -11
  30. package/dist/kernel/index.js.map +1 -1
  31. package/dist/{mcp-servers-B6fSRNC1.d.ts → mcp-servers-BIwRiOxe.d.ts} +3 -3
  32. package/dist/models/index.d.ts +5 -5
  33. package/dist/models/index.js +40 -2
  34. package/dist/models/index.js.map +1 -1
  35. package/dist/{models-registry-4C6Wr91w.d.ts → models-registry-8OorW51H.d.ts} +1 -1
  36. package/dist/{multi-agent-coordinator-q1skFeNP.d.ts → multi-agent-coordinator-CNx48Zoz.d.ts} +1 -1
  37. package/dist/{null-fleet-bus-C9rrgQwc.d.ts → null-fleet-bus-B4ZUJYL6.d.ts} +6 -6
  38. package/dist/observability/index.d.ts +2 -2
  39. package/dist/{parallel-eternal-engine-CtXly2Sf.d.ts → parallel-eternal-engine-rsIclDqO.d.ts} +9 -9
  40. package/dist/{path-resolver-Bim6G5Jz.d.ts → path-resolver-BqU-fwzD.d.ts} +3 -3
  41. package/dist/{permission-CC7XFYWG.d.ts → permission-Dgs3v-Xq.d.ts} +1 -1
  42. package/dist/{permission-policy-cYR4RJmw.d.ts → permission-policy-Dtht2k0e.d.ts} +2 -2
  43. package/dist/{pipeline-CNVKuQDQ.d.ts → pipeline-B-dpCFYS.d.ts} +2 -2
  44. package/dist/{plan-templates-C4wXMmiM.d.ts → plan-templates-B7MxyY2o.d.ts} +58 -5
  45. package/dist/{provider-runner-BpM0mdBE.d.ts → provider-runner-DrmpBE5l.d.ts} +3 -3
  46. package/dist/{retry-policy-BV7nzeAd.d.ts → retry-policy-hYxsm10a.d.ts} +1 -1
  47. package/dist/sdd/index.d.ts +12 -10
  48. package/dist/sdd/index.js +7 -0
  49. package/dist/sdd/index.js.map +1 -1
  50. package/dist/{secret-vault-eMBKfheR.d.ts → secret-vault-DnqIFhPF.d.ts} +1 -1
  51. package/dist/security/index.d.ts +5 -5
  52. package/dist/{selector-C4ORTOid.d.ts → selector-D21RjDIg.d.ts} +1 -1
  53. package/dist/{session-event-bridge-CeNpUL9w.d.ts → session-event-bridge-Dt54CTvq.d.ts} +1 -1
  54. package/dist/{session-reader-BepLSnGL.d.ts → session-reader-CceH13Kq.d.ts} +5 -4
  55. package/dist/storage/index.d.ts +46 -12
  56. package/dist/storage/index.js +2281 -1476
  57. package/dist/storage/index.js.map +1 -1
  58. package/dist/tools/index.d.ts +2 -2
  59. package/dist/types/index.d.ts +19 -19
  60. package/dist/types/index.js +162 -42
  61. package/dist/types/index.js.map +1 -1
  62. package/dist/utils/index.d.ts +2 -2
  63. package/dist/{worktree-manager-BDuXTaWL.d.ts → worktree-manager-DUfBbKzk.d.ts} +1 -1
  64. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/atomic-write.ts","../../src/utils/error.ts","../../src/utils/merge-models-payload.ts","../../src/models/models-registry.ts","../../src/types/mode.ts","../../src/models/mode-store.ts","../../src/utils/expect-defined.ts","../../src/utils/token-estimate.ts","../../src/types/blocks.ts","../../src/models/llm-selector.ts","../../src/models/provider-model-resolve.ts","../../src/models/model-intelligence.ts","../../src/models/model-router.ts"],"names":["path","stat","resolve","path2","fs2","fs3"],"mappings":"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","file":"index.js","sourcesContent":["import { randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\nexport interface AtomicWriteOptions {\n mode?: number | undefined;\n encoding?: BufferEncoding | undefined;\n}\n\nexport interface FileLockOptions {\n timeoutMs?: number | undefined;\n staleMs?: number | undefined;\n}\n\nexport async function atomicWrite(\n targetPath: string,\n content: string | Uint8Array,\n opts: AtomicWriteOptions = {},\n): Promise<void> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const tmp = path.join(dir, `.${path.basename(targetPath)}.${randomBytes(6).toString('hex')}.tmp`);\n\n // Write content to tmp first; 'wx' ensures exclusive creation (fails if\n // tmp already exists — extremely unlikely with 6-byte random suffix).\n try {\n if (typeof content === 'string') {\n await fs.writeFile(tmp, content, { flag: 'wx', encoding: opts.encoding ?? 'utf8' });\n } else {\n await fs.writeFile(tmp, content, { flag: 'wx' });\n }\n try {\n const fh = await fs.open(tmp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync best-effort\n }\n // Now safely read mode from target (if it exists) and apply to tmp before rename.\n // Prefer opts.mode for new files; for existing files preserve their mode.\n let mode: number | undefined;\n try {\n const stat = await fs.stat(targetPath);\n mode = stat.mode & 0o777;\n } catch {\n mode = opts.mode;\n }\n if (mode !== undefined) {\n await fs.chmod(tmp, mode);\n }\n await renameWithRetry(tmp, targetPath);\n } catch (err) {\n try {\n await fs.unlink(tmp);\n } catch {\n // ignore cleanup error\n }\n throw err;\n }\n}\n\nexport async function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\nexport async function withFileLock<T>(\n targetPath: string,\n fn: () => Promise<T>,\n opts: FileLockOptions = {},\n): Promise<T> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const lockPath = path.join(dir, `.${path.basename(targetPath)}.lock`);\n const timeoutMs = opts.timeoutMs ?? 5_000;\n const staleMs = opts.staleMs ?? 30_000;\n const started = Date.now();\n let handle: fs.FileHandle | undefined;\n\n for (;;) {\n try {\n handle = await fs.open(lockPath, 'wx');\n await handle.writeFile(`${process.pid}:${Date.now()}`);\n break;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n // ENOENT means the directory was deleted (e.g. by concurrent cleanup).\n // Recreate it and retry acquiring the lock.\n if (code === 'ENOENT') {\n await fs.mkdir(dir, { recursive: true });\n continue;\n }\n if (code !== 'EEXIST') throw err;\n try {\n const stat = await fs.stat(lockPath);\n if (Date.now() - stat.mtimeMs > staleMs) {\n await fs.unlink(lockPath);\n continue;\n }\n } catch {\n continue;\n }\n if (Date.now() - started >= timeoutMs) {\n throw new Error(`Timed out waiting for file lock: ${targetPath}`);\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n\n try {\n return await fn();\n } finally {\n try {\n await handle?.close();\n } catch {\n // ignore\n }\n try {\n await fs.unlink(lockPath);\n } catch {\n // ignore\n }\n }\n}\n\n// On Windows, fs.rename over an existing file can fail with EPERM/EBUSY/EACCES\n// when antivirus, file indexers, editor file watchers, or a concurrent writer\n// briefly hold a handle on the destination. These are transient — retry with a\n// short backoff before giving up. POSIX renames are atomic and won't hit this.\nconst TRANSIENT_RENAME_CODES = new Set(['EPERM', 'EBUSY', 'EACCES', 'ENOTEMPTY']);\n\nasync function renameWithRetry(from: string, to: string): Promise<void> {\n if (process.platform !== 'win32') {\n await fs.rename(from, to);\n return;\n }\n const delays = [10, 25, 60, 120, 250];\n let lastErr: unknown;\n for (let i = 0; i <= delays.length; i++) {\n try {\n await fs.rename(from, to);\n return;\n } catch (err) {\n lastErr = err;\n const code = (err as NodeJS.ErrnoException)?.code;\n if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {\n throw err;\n }\n await new Promise((resolve) => setTimeout(resolve, delays[i]));\n }\n }\n throw lastErr;\n}\n","/**\n * Converts an unknown error value to a human-readable string.\n * Used in 40+ files across the codebase to normalize error messaging.\n */\nexport function toErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","import type {\n ModelsDevModel,\n ModelsDevProvider,\n ModelsDevPayload,\n} from '../types/models-registry.js';\n\n/**\n * Deep-merge a curated `overlay` payload on top of a `base` payload (both in\n * the models.dev `api.json` shape). The overlay always wins: it can add\n * providers/models the base lacks and override fields the base gets wrong.\n *\n * Precedence rules:\n * - Provider present in both → scalar fields (`name`, `npm`, `api`, `env`,\n * `doc`) come from the overlay when set; `models` maps merge by model id.\n * - Provider only in the overlay → added wholesale.\n * - Model present in both → overlay model fields override base model fields\n * (`{ ...base, ...overlay }`), with the nested `limit` / `cost` /\n * `modalities` objects merged one level deeper so an overlay can fix just\n * `limit.context` without restating the rest of the model.\n * - Model only in the overlay → added.\n *\n * Pure: never mutates its inputs.\n */\nexport function mergeModelsPayload(\n base: ModelsDevPayload,\n overlay: ModelsDevPayload,\n): ModelsDevPayload {\n const out: ModelsDevPayload = {};\n for (const [id, provider] of Object.entries(base)) {\n out[id] = cloneProvider(provider);\n }\n for (const [id, ovProvider] of Object.entries(overlay)) {\n const existing = out[id];\n out[id] = existing ? mergeProvider(existing, ovProvider) : cloneProvider(ovProvider);\n }\n return out;\n}\n\nfunction mergeProvider(base: ModelsDevProvider, overlay: ModelsDevProvider): ModelsDevProvider {\n const models: Record<string, ModelsDevModel> = {};\n for (const [mid, m] of Object.entries(base.models ?? {})) {\n models[mid] = { ...m };\n }\n for (const [mid, ovModel] of Object.entries(overlay.models ?? {})) {\n const existing = models[mid];\n models[mid] = existing ? mergeModel(existing, ovModel) : { ...ovModel };\n }\n return {\n ...base,\n // Overlay scalar fields win when explicitly provided; otherwise keep base.\n ...stripUndefined({\n id: overlay.id,\n name: overlay.name,\n npm: overlay.npm,\n api: overlay.api,\n env: overlay.env,\n doc: overlay.doc,\n }),\n models,\n };\n}\n\nfunction mergeModel(base: ModelsDevModel, overlay: ModelsDevModel): ModelsDevModel {\n const merged: ModelsDevModel = { ...base, ...overlay };\n // One level deeper for the structured fields so a partial overlay (e.g. only\n // `limit.context`) doesn't blow away the base's other sub-fields.\n if (base.limit || overlay.limit) {\n merged.limit = { ...base.limit, ...overlay.limit };\n }\n if (base.cost || overlay.cost) {\n merged.cost = { ...base.cost, ...overlay.cost };\n }\n if (base.modalities || overlay.modalities) {\n merged.modalities = { ...base.modalities, ...overlay.modalities };\n }\n return merged;\n}\n\nfunction cloneProvider(p: ModelsDevProvider): ModelsDevProvider {\n const models: Record<string, ModelsDevModel> = {};\n for (const [mid, m] of Object.entries(p.models ?? {})) {\n models[mid] = { ...m };\n }\n return { ...p, models };\n}\n\n/** Drop keys whose value is `undefined` so they don't clobber base fields. */\nfunction stripUndefined<T extends Record<string, unknown>>(obj: T): Partial<T> {\n const out: Partial<T> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (v !== undefined) out[k as keyof T] = v as T[keyof T];\n }\n return out;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type {\n ModelsDevPayload,\n ModelsDevProvider,\n ModelsRegistry,\n ResolvedModel,\n ResolvedProvider,\n WireFamily,\n} from '../types/models-registry.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { mergeModelsPayload } from '../utils/merge-models-payload.js';\n\nconst DEFAULT_URL = 'https://models.dev/api.json';\n/** Env var to override the models.dev base URL (e.g. for self-hosted mirrors). */\nconst ENV_URL_KEY = 'WRONGSTACK_MODELS_DEV_URL';\nconst DEFAULT_TTL_SECONDS = 24 * 3600;\nconst DEFAULT_REFRESH_TIMEOUT_MS = 15_000;\n\ninterface CacheEnvelope {\n fetchedAt: string;\n url: string;\n payload: ModelsDevPayload;\n}\n\nexport interface DefaultModelsRegistryOptions {\n cacheFile: string;\n url?: string | undefined;\n ttlSeconds?: number | undefined;\n fetchImpl?: typeof fetch | undefined;\n /** Pre-seeded payload — useful for offline scenarios and tests. */\n seed?: ModelsDevPayload | undefined;\n /**\n * Maximum age in seconds for stale cache fallback when network fails.\n * Defaults to 7 days. Set to `Infinity` for full offline resilience\n * (risk: deprecated models, wrong pricing). Set to `0` to disable\n * stale fallback entirely.\n */\n maxStaleAgeSeconds?: number | undefined;\n /**\n * Timeout in milliseconds for the models.dev network fetch. When exceeded,\n * the fetch is aborted and cache/stale fallback is used instead.\n * Defaults to 15 seconds. Set to `0` to disable (infinite wait).\n */\n refreshTimeoutMs?: number | undefined;\n /**\n * Curated override payload deep-merged ON TOP of the models.dev base via\n * `mergeModelsPayload` — adds providers/models the base lacks and overrides\n * fields it gets wrong. Resolution order (first non-empty wins): this\n * in-memory `overlay` → `overlayUrl` (fetched, cached) → `overlayFile`\n * (bundled, read from disk). A missing/broken overlay degrades to `{}` and\n * never throws, so the base alone still works.\n */\n overlay?: ModelsDevPayload | undefined;\n /** GitHub-raw (or any) URL serving the curated overlay `providers.json`. */\n overlayUrl?: string | undefined;\n /** Path to the bundled overlay `providers.json` (offline floor). */\n overlayFile?: string | undefined;\n /** Cache file for the fetched `overlayUrl`. Defaults next to `cacheFile`. */\n overlayCacheFile?: string | undefined;\n}\n\n/**\n * The npm package each models.dev provider declares determines which wire\n * family WrongStack speaks. Anything not listed falls into `unsupported` and\n * can be enabled by registering a custom provider factory via a plugin.\n */\nconst FAMILY_BY_NPM: Record<string, WireFamily> = {\n '@ai-sdk/anthropic': 'anthropic',\n '@ai-sdk/google-vertex/anthropic': 'anthropic',\n '@ai-sdk/openai': 'openai',\n '@ai-sdk/openai-compatible': 'openai-compatible',\n '@ai-sdk/groq': 'openai-compatible',\n '@ai-sdk/xai': 'openai-compatible',\n '@ai-sdk/cerebras': 'openai-compatible',\n '@ai-sdk/togetherai': 'openai-compatible',\n '@ai-sdk/mistral': 'openai-compatible',\n '@ai-sdk/perplexity': 'openai-compatible',\n '@ai-sdk/deepinfra': 'openai-compatible',\n '@openrouter/ai-sdk-provider': 'openai-compatible',\n 'ai-gateway-provider': 'openai-compatible',\n '@ai-sdk/vercel': 'openai-compatible',\n '@ai-sdk/gateway': 'openai-compatible',\n '@aihubmix/ai-sdk-provider': 'openai-compatible',\n 'venice-ai-sdk-provider': 'openai-compatible',\n '@ai-sdk/google': 'google',\n};\n\nexport function classifyFamily(npm: string | undefined): WireFamily {\n if (!npm) return 'unsupported';\n return FAMILY_BY_NPM[npm] ?? 'unsupported';\n}\n\nexport class DefaultModelsRegistry implements ModelsRegistry {\n /** Merged (base + overlay) payload — what every reader sees. */\n private payload?: ModelsDevPayload | undefined;\n /** Memoised overlay payload (in-memory / fetched / file). */\n private overlayPayload?: ModelsDevPayload | undefined;\n private fetchedAt?: Date | undefined;\n private readonly cacheFile: string;\n private readonly url: string;\n private readonly ttlMs: number;\n private readonly fetchImpl: typeof fetch;\n private readonly seed?: ModelsDevPayload | undefined;\n private readonly maxStaleAgeMs: number;\n private readonly refreshTimeoutMs: number;\n private readonly overlay?: ModelsDevPayload | undefined;\n private readonly overlayUrl?: string | undefined;\n private readonly overlayFile?: string | undefined;\n private readonly overlayCacheFile?: string | undefined;\n\n constructor(opts: DefaultModelsRegistryOptions) {\n this.cacheFile = opts.cacheFile;\n this.url = opts.url ?? process.env[ENV_URL_KEY] ?? DEFAULT_URL;\n this.ttlMs = (opts.ttlSeconds ?? DEFAULT_TTL_SECONDS) * 1000;\n this.fetchImpl = opts.fetchImpl ?? fetch;\n this.seed = opts.seed;\n // Default max stale age: 7 days\n const maxStaleSeconds = opts.maxStaleAgeSeconds ?? 7 * 24 * 3600;\n this.maxStaleAgeMs = maxStaleSeconds * 1000;\n this.refreshTimeoutMs = opts.refreshTimeoutMs ?? DEFAULT_REFRESH_TIMEOUT_MS;\n this.overlay = opts.overlay;\n this.overlayUrl = opts.overlayUrl;\n this.overlayFile = opts.overlayFile;\n this.overlayCacheFile =\n opts.overlayCacheFile ??\n (opts.overlayUrl\n ? path.join(path.dirname(opts.cacheFile), 'models-overlay-cache.json')\n : undefined);\n }\n\n async load(opts: { force?: boolean | undefined } = {}): Promise<ModelsDevPayload> {\n if (this.payload && !opts.force) return this.payload;\n // A `seed` is treated as the complete, final payload — used for offline\n // scenarios and tests. It bypasses both the base fetch and the overlay.\n if (this.seed) {\n this.payload = this.seed;\n this.fetchedAt = new Date();\n return this.payload;\n }\n // Load the overlay first so base degradation can tell whether there is\n // actually curated data to serve when models.dev is unreachable.\n const overlay = await this.loadOverlay(opts);\n const base = await this.loadBase(opts, Object.keys(overlay).length > 0);\n this.payload = mergeModelsPayload(base, overlay);\n return this.payload;\n }\n\n /**\n * Load the models.dev base payload: fresh cache → network → stale cache.\n * On total failure, degrade to `{}` (so a non-empty overlay still drives\n * the catalog) rather than throwing — unless there's no curated overlay to\n * fall back on, in which case the original error propagates so pure-\n * models.dev setups still surface the problem.\n */\n private async loadBase(\n opts: { force?: boolean | undefined } = {},\n overlayAvailable = false,\n ): Promise<ModelsDevPayload> {\n if (!opts.force) {\n const cached = await this.readCacheAt(this.cacheFile);\n if (cached && this.isFresh(cached.fetchedAt)) {\n this.fetchedAt = new Date(cached.fetchedAt);\n return cached.payload;\n }\n }\n try {\n return await this.refreshBase();\n } catch (err) {\n // Network failed — fall back to stale cache if within maxStaleAgeMs.\n const cached = await this.readCacheAt(this.cacheFile);\n if (cached && this.isWithinMaxStaleAge(cached.fetchedAt)) {\n this.fetchedAt = new Date(cached.fetchedAt);\n const ageSeconds = Math.floor((Date.now() - this.fetchedAt.getTime()) / 1000);\n // eslint-disable-next-line no-console -- user-visible operator warning\n console.warn(\n `ModelsRegistry: models.dev unavailable (${toErrorMessage(err)}); ` +\n `using stale cache from ${formatAge(ageSeconds)} ago. Run \\`wstack models refresh\\` to retry.`,\n );\n return cached.payload;\n }\n if (overlayAvailable) {\n // eslint-disable-next-line no-console -- one-line operator warning\n console.warn(\n `ModelsRegistry: models.dev unavailable (${\n toErrorMessage(err)\n }); serving curated overlay only.`,\n );\n return {};\n }\n throw err;\n }\n }\n\n /** Fetch + cache the models.dev base. Throws on failure (used by `refresh`). */\n private async refreshBase(): Promise<ModelsDevPayload> {\n const controller = new AbortController();\n /* v8 ignore next -- timing: the abort callback only fires if the real fetch exceeds the timeout */\n const timeout = setTimeout(() => controller.abort(), this.refreshTimeoutMs);\n try {\n const res = await this.fetchImpl(this.url, {\n method: 'GET',\n headers: { accept: 'application/json' },\n signal: controller.signal,\n });\n clearTimeout(timeout);\n if (!res.ok) {\n throw new Error(`ModelsRegistry: HTTP ${res.status} fetching ${this.url}`);\n }\n const json = (await res.json()) as ModelsDevPayload;\n this.fetchedAt = new Date();\n const envelope: CacheEnvelope = {\n fetchedAt: this.fetchedAt.toISOString(),\n url: this.url,\n payload: json,\n };\n await atomicWrite(this.cacheFile, JSON.stringify(envelope));\n return json;\n } catch (err) {\n clearTimeout(timeout);\n if (err instanceof Error && err.name === 'AbortError') {\n throw new Error(`ModelsRegistry: fetch timed out after ${this.refreshTimeoutMs}ms`);\n }\n throw err;\n }\n }\n\n /**\n * Resolve the curated overlay, memoised. Order: in-memory `overlay` →\n * fetched `overlayUrl` (cached, same TTL/stale rules) → `overlayFile` on\n * disk. Never throws — a missing/broken overlay yields `{}`.\n */\n private async loadOverlay(opts: { force?: boolean | undefined } = {}): Promise<ModelsDevPayload> {\n /* v8 ignore next -- unreachable: load() caches `payload` and short-circuits before re-calling loadOverlay non-forced */\n if (this.overlayPayload && !opts.force) return this.overlayPayload;\n if (hasEntries(this.overlay)) {\n this.overlayPayload = this.overlay;\n return this.overlayPayload;\n }\n const fetched = await this.loadOverlayFromUrl(opts);\n if (hasEntries(fetched)) {\n this.overlayPayload = fetched;\n return fetched;\n }\n const fromFile = await this.readOverlayFile();\n this.overlayPayload = fromFile ?? {};\n return this.overlayPayload;\n }\n\n private async loadOverlayFromUrl(opts: { force?: boolean | undefined }): Promise<\n ModelsDevPayload | undefined\n > {\n if (!this.overlayUrl || !this.overlayCacheFile) return undefined;\n if (!opts.force) {\n const cached = await this.readCacheAt(this.overlayCacheFile);\n if (cached && this.isFresh(cached.fetchedAt)) return cached.payload;\n }\n try {\n const res = await this.fetchImpl(this.overlayUrl, {\n method: 'GET',\n headers: { accept: 'application/json' },\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const json = (await res.json()) as ModelsDevPayload;\n const envelope: CacheEnvelope = {\n fetchedAt: new Date().toISOString(),\n url: this.overlayUrl,\n payload: json,\n };\n /* v8 ignore next -- best-effort: overlay-cache write failure is intentionally ignored */\n await atomicWrite(this.overlayCacheFile, JSON.stringify(envelope)).catch(() => {});\n return json;\n } catch {\n // Network/parse failure — fall back to stale overlay cache, then the\n // bundled file (handled by the caller).\n const cached = await this.readCacheAt(this.overlayCacheFile);\n if (cached && this.isWithinMaxStaleAge(cached.fetchedAt)) {\n const ageSeconds = Math.floor((Date.now() - new Date(cached.fetchedAt).getTime()) / 1000);\n // eslint-disable-next-line no-console -- operator-visible warning\n console.warn(\n `ModelsRegistry: overlay unavailable; using stale overlay from ${formatAge(ageSeconds)} ago.`,\n );\n return cached.payload;\n }\n return undefined;\n }\n }\n\n private async readOverlayFile(): Promise<ModelsDevPayload | undefined> {\n if (!this.overlayFile) return undefined;\n try {\n const raw = await fs.readFile(this.overlayFile, 'utf8');\n return JSON.parse(raw) as ModelsDevPayload;\n } catch {\n return undefined;\n }\n }\n\n async refresh(): Promise<ModelsDevPayload> {\n // Refresh the models.dev base (throws on failure so `wstack models refresh`\n // can report it), then recompute the merged payload with a fresh overlay.\n const base = await this.refreshBase();\n const overlay = await this.loadOverlay({ force: true });\n this.payload = mergeModelsPayload(base, overlay);\n return this.payload;\n }\n\n async listProviders(): Promise<ResolvedProvider[]> {\n const payload = await this.load();\n return Object.values(payload).map((p) => this.resolveProvider(p));\n }\n\n async getProvider(id: string): Promise<ResolvedProvider | undefined> {\n const payload = await this.load();\n const p = payload[id];\n return p ? this.resolveProvider(p) : undefined;\n }\n\n async getModel(providerId: string, modelId: string): Promise<ResolvedModel | undefined> {\n const provider = await this.getProvider(providerId);\n if (!provider) return undefined;\n const model = provider.models.find((m) => m.id === modelId);\n if (!model) return undefined;\n return {\n providerId,\n modelId,\n capabilities: {\n tools: model.tool_call ?? false,\n vision: Boolean(model.modalities?.input?.includes('image')),\n reasoning: model.reasoning ?? model.reasoningConfig !== undefined,\n maxContext: model.limit?.context ?? 0,\n maxOutput: model.limit?.output,\n knowledge: model.knowledge,\n reasoningConfig: model.reasoningConfig,\n },\n cost: model.cost,\n };\n }\n\n async suggestModel(providerId: string): Promise<string | undefined> {\n const provider = await this.getProvider(providerId);\n if (!provider || provider.models.length === 0) return undefined;\n const ranked = [...provider.models].sort((a, b) => {\n const at = a.release_date ?? a.last_updated ?? '';\n const bt = b.release_date ?? b.last_updated ?? '';\n return bt.localeCompare(at);\n });\n return ranked[0]?.id;\n }\n\n async ageSeconds(): Promise<number> {\n if (!this.fetchedAt) {\n const cached = await this.readCacheAt(this.cacheFile);\n if (!cached) return Number.POSITIVE_INFINITY;\n return (Date.now() - new Date(cached.fetchedAt).getTime()) / 1000;\n }\n return (Date.now() - this.fetchedAt.getTime()) / 1000;\n }\n\n private resolveProvider(p: ModelsDevProvider): ResolvedProvider {\n return {\n id: p.id,\n name: p.name,\n family: classifyFamily(p.npm),\n apiBase: p.api,\n envVars: p.env ?? [],\n doc: p.doc,\n models: Object.values(p.models ?? {}),\n npm: p.npm,\n };\n }\n\n private isFresh(fetchedAtIso: string): boolean {\n return Date.now() - new Date(fetchedAtIso).getTime() < this.ttlMs;\n }\n\n private isWithinMaxStaleAge(fetchedAtIso: string): boolean {\n return Date.now() - new Date(fetchedAtIso).getTime() < this.maxStaleAgeMs;\n }\n\n private async readCacheAt(file: string): Promise<CacheEnvelope | undefined> {\n try {\n const raw = await fs.readFile(file, 'utf8');\n return JSON.parse(raw) as CacheEnvelope;\n } catch {\n return undefined;\n }\n }\n\n /** Used by `wstack models refresh` to expose where the cache lives. */\n cacheLocation(): string {\n return path.resolve(this.cacheFile);\n }\n}\n\n/** Render a seconds-duration as a human-friendly \"Xh Ym\" or \"Xd\" string. */\nfunction formatAge(seconds: number): string {\n if (seconds < 60) return '<1m';\n if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;\n if (seconds < 86400) {\n const h = Math.floor(seconds / 3600);\n const m = Math.floor((seconds % 3600) / 60);\n return m > 0 ? `${h}h ${m}m` : `${h}h`;\n }\n return `${Math.floor(seconds / 86400)}d`;\n}\n\nfunction hasEntries(payload: ModelsDevPayload | undefined): payload is ModelsDevPayload {\n return payload !== undefined && Object.keys(payload).length > 0;\n}\n","export interface Mode {\n id: string;\n name: string;\n description: string;\n /** Additional prompt text injected into system prompt when mode is active */\n prompt: string;\n /** Tags for tool_search filtering */\n tags?: string[] | undefined;\n /** Tools that should be prioritized/highlighted when this mode is active */\n toolPreferences?: string[] | undefined;\n /**\n * Skill names that are particularly relevant to this mode. The system\n * prompt builder appends a \"Suggested skills\" note so the model knows\n * which domain knowledge to leverage first. Skill must exist in the\n * loaded skill set to appear.\n */\n suggestedSkills?: string[] | undefined;\n}\n\nexport interface ModeManifest {\n modes: Mode[];\n defaultMode?: string | undefined;\n}\n\nexport interface ModeStore {\n getActiveMode(): Promise<Mode | null>;\n setActiveMode(modeId: string | null): Promise<void>;\n listModes(): Promise<Mode[]>;\n getMode(modeId: string): Promise<Mode | null>;\n}\n\nexport interface ModeConfig {\n directory: string;\n}\n\nexport const DEFAULT_MODES: Mode[] = [\n {\n id: 'default',\n name: 'Default',\n description: 'General-purpose coding assistant',\n prompt: '',\n tags: ['general'],\n },\n {\n id: 'code-reviewer',\n name: 'Code Reviewer',\n description: 'Focus on code quality, best practices, and potential bugs',\n prompt: `## Code Reviewer Mode\n\nWhen reviewing code:\n- Look for potential bugs, race conditions, and edge cases\n- Check for security vulnerabilities (SQL injection, XSS, CSRF, etc.)\n- Evaluate error handling completeness\n- Assess code readability and maintainability\n- Check for performance anti-patterns\n- Verify test coverage for critical paths\n- Ensure naming conventions are followed`,\n tags: ['review', 'quality', 'security'],\n toolPreferences: ['read', 'grep', 'git', 'diff', 'test'],\n suggestedSkills: ['bug-hunter', 'security-scanner', 'typescript-strict', 'testing'],\n },\n {\n id: 'code-auditor',\n name: 'Code Auditor',\n description: 'Security-focused code analysis',\n prompt: `## Code Auditor Mode\n\nWhen auditing code for security:\n- Identify injection vulnerabilities (SQL, Command, XSS, LDAP)\n- Check authentication and authorization patterns\n- Look for sensitive data exposure (secrets, PII in logs)\n- Verify cryptographic implementations\n- Check for insecure dependencies or configurations\n- Assess input validation and output encoding\n- Look for timing attacks and information leakage`,\n tags: ['security', 'audit', 'compliance'],\n toolPreferences: ['grep', 'read', 'audit', 'bash'],\n suggestedSkills: ['security-scanner', 'bug-hunter', 'audit-log'],\n },\n {\n id: 'architect',\n name: 'Software Architect',\n description: 'Design patterns, scalability, and system design',\n prompt: `## Architect Mode\n\nWhen designing or reviewing architecture:\n- Evaluate scalability and future growth\n- Check for appropriate design patterns\n- Assess coupling and cohesion\n- Look for SOLID principle violations\n- Evaluate data modeling decisions\n- Check for eventual consistency issues\n- Assess API design and contract stability\n- Consider operational aspects (monitoring, logging, deployment)`,\n tags: ['architecture', 'design', 'scalability'],\n toolPreferences: ['read', 'glob', 'tree', 'diff'],\n suggestedSkills: ['api-design', 'refactor-planner', 'node-modern', 'docker-deploy'],\n },\n {\n id: 'debugger',\n name: 'Debugger',\n description: 'Root cause analysis and error investigation',\n prompt: `## Debugger Mode\n\nWhen investigating bugs:\n- Reproduce the issue with minimal steps\n- Check error messages and stack traces thoroughly\n- Look for related logs and historical context\n- Verify assumptions about data flow\n- Check for race conditions in async code\n- Validate environment and configuration\n- Use binary search to isolate the root cause\n- Verify fixes with tests before considering done`,\n tags: ['debug', 'investigation', 'error-resolution'],\n toolPreferences: ['read', 'grep', 'bash', 'logs', 'test'],\n suggestedSkills: ['bug-hunter', 'audit-log', 'observability'],\n },\n {\n id: 'tester',\n name: 'QA Engineer',\n description: 'Test coverage, edge cases, and quality assurance',\n prompt: `## Tester Mode\n\nWhen testing or writing tests:\n- Cover happy path and error paths equally\n- Think about edge cases and boundary conditions\n- Check for missing null/undefined handling tests\n- Verify error messages are tested\n- Look for race condition tests in async code\n- Assess mutation testing opportunities\n- Check for integration test gaps\n- Verify test isolation and cleanup`,\n tags: ['testing', 'qa', 'quality'],\n toolPreferences: ['read', 'grep', 'test', 'bash'],\n suggestedSkills: ['testing', 'bug-hunter', 'typescript-strict'],\n },\n {\n id: 'devops',\n name: 'DevOps Engineer',\n description: 'Infrastructure, deployment, and operations',\n prompt: `## DevOps Mode\n\nWhen working on infrastructure:\n- Check for containerization and deployment readiness\n- Verify CI/CD pipeline configurations\n- Assess monitoring and alerting setup\n- Look for health check endpoints\n- Check for graceful shutdown handling\n- Verify backup and disaster recovery plans\n- Assess secrets management\n- Check for resource limits and quotas`,\n tags: ['devops', 'infrastructure', 'operations'],\n toolPreferences: ['read', 'bash', 'grep', 'logs', 'git'],\n suggestedSkills: ['docker-deploy', 'observability', 'security-scanner'],\n },\n {\n id: 'refactorer',\n name: 'Refactorer',\n description: 'Code improvement and modernization',\n prompt: `## Refactorer Mode\n\nWhen refactoring code:\n- Maintain existing behavior — tests must pass before and after\n- Make one change at a time, verify after each\n- Prefer small, focused commits\n- Preserve API contracts unless explicitly changing\n- Remove dead code and comments\n- Improve naming as you go\n- Don't mix formatting changes with logic changes\n- Keep performance in mind — don't regress`,\n tags: ['refactor', 'modernization', 'improvement'],\n toolPreferences: ['read', 'edit', 'test', 'git', 'grep'],\n suggestedSkills: ['refactor-planner', 'typescript-strict', 'node-modern', 'testing'],\n },\n {\n id: 'brief',\n name: 'Brief',\n description: 'Fast, no-nonsense — get to the point',\n prompt: `## Brief Mode\n\nYou are WrongStack, a fast, no-nonsense AI coding agent.\nGet to the point — read files, run commands, make changes.\n\n### Operating rules\n1. **Read first.** Inspect relevant files before touching anything.\n2. **Edit surgically.** Use edit tool for existing files, write only for new ones.\n3. **One sentence before action.** State what you're doing, then do it.\n4. **Say what happened.** After tool calls, one line: success, failure, or what's next.\n5. **Be honest.** Admit when you don't know or something failed. No filler.\n6. **Keep moving.** Task done? Stop. More work needed? State it and continue.\n\n### Decision rules\n- **Ambiguous task?** Ask. One question, get clarity, proceed.\n- **Clear task, unknown approach?** Pick one reasonable path, execute, report.\n- **Tool fails?** Retry once with adjusted params, then report.\n\n### Output style\n- Prose paragraphs (no bullet points unless unavoidable)\n- Code blocks for code, backticks for paths/commands\n- One-liner sufficient? One liner.\n- Max 3 sentences per paragraph.`,\n tags: ['fast', 'concise', 'direct'],\n toolPreferences: ['read', 'edit', 'bash'],\n suggestedSkills: [],\n },\n {\n id: 'teach',\n name: 'Teach',\n description: 'Mentor mode — explains why, not just what',\n prompt: `## Teach Mode\n\nYou are WrongStack, an expert AI coding mentor.\n\nYou operate inside the user's terminal with full access to their codebase. You help developers learn and understand — not just execute tasks, but build mental models.\n\n### Teaching philosophy\n\n1. **Explain the why.** When you make a change, explain why it works that way — not just what you did.\n2. **Build mental models.** Use analogies, highlight patterns, connect new concepts to things the user already knows.\n3. **Read before teaching.** Always inspect relevant files so your explanations are accurate and specific to the actual code.\n4. **Surgical edits with context.** When editing code, explain the approach before doing it, and what trade-offs were considered.\n5. **Be thorough but not verbose.** A 2-paragraph explanation beats a 5-paragraph one. Depth without padding.\n6. **Admit knowledge gaps.** If you're unsure, say so. Speculating teaches bad patterns.\n\n### Teaching style\n\n- **Before action:** Briefly explain what you're going to do and why.\n- **After action:** Summarize what happened and what the user should take away from this.\n- **With code:** Show concrete examples, explain syntax choices, point out gotchas.\n- **With errors:** Explain why the error occurred, what it's actually complaining about, and how to avoid it in the future.\n- **General principles:** Offer them when the user's question suggests a deeper concept they'd benefit from understanding.\n\n### Decision heuristics\n\n- **Task is ambiguous?** Ask — but frame the question as \"what would you like to learn from this?\"\n- **Task is clear, approach is unknown?** Execute, then teach the approach as you go.\n- **Tool fails?** Explain what failed, why it failed, and how to avoid the failure.\n- **User asks \"how do I...?\"** Don't just give the answer — explain the underlying mechanism.\n- **Context window filling up?** Compact, but summarize what was lost so the teaching continuity isn't broken.\n\n### Output format\n\n- Use headings to structure multi-concept explanations.\n- Code blocks with brief annotations for code examples.\n- **Bold** key terms and concepts worth remembering.\n- Callouts like \"Key takeaway:\" or \"Pattern:\" to anchor learning.\n- Max 3 sentences per paragraph — readability over completeness.\n\n### Don'ts\n\n- Don't lecture condescendingly — the user is a developer, not a beginner.\n- Don't pad explanations with obvious things.\n- Don't skip the \"why\" — even quick tasks deserve one sentence of context.\n- Don't just say \"do X\" — say \"do X because Y.\"\n- Don't leave the user hanging after a complex operation — explain what just happened.\n\n### Core principles\n\nYou follow these principles, but always with explanation:\n- Read before write\n- Surgical edits over rewrites\n- Show your work (explain your reasoning, not just mechanical steps)\n- Be honest about limits\n- Format for scanability\n- Recover explicitly from failures\n\nRemember: your job is to make the user a better developer, not just to complete tasks faster.`,\n tags: ['teaching', 'mentor', 'learning'],\n toolPreferences: ['read', 'edit', 'explain'],\n suggestedSkills: ['prompt-engineering', 'skill-creator', 'node-modern', 'typescript-strict'],\n },\n {\n id: 'research-web',\n name: 'Research Web',\n description: 'Current-data research — search web, verify, inject findings into context',\n prompt: `## Research Web Mode\n\nYou are in research mode. Your role: find, verify, and incorporate\ncurrent web data. Your training data is stale — every factual claim\nabout version numbers, API surfaces, package status, or ecosystem\nchanges must be verified against live sources.\n\n### When to research\n- The user asks \"is this still the case?\", \"what's current?\", \"latest version?\"\n- You're about to claim a version number, deprecation, or API change\n- You're comparing tools, packages, or approaches released in the last 12 months\n- You realize your knowledge may be >6 months old on a fast-moving topic\n\n### Research methodology\n1. **Search first, fetch selectively.** Use web_search with 5-8 results for\n broad queries. Then web_fetch the 1-2 most authoritative results for detail.\n Don't fetch every result — you'll burn tokens on noise.\n2. **Cross-reference.** One source is a data point. Two sources that agree\n is a signal. Three is confirmation. Flag single-source claims as tentative.\n3. **Cite sources.** Every factual claim from web data must include where it\n came from: domain name, and date if visible on the page.\n4. **Know when to stop.** 2-3 searches + 1-2 fetches is usually sufficient.\n If you're on your 5th search without a clear answer, pause and tell the user\n what you've found and what's still unclear — let them decide to dig deeper.\n5. **Inject findings for reuse.** After gathering current data, use\n context_manager with add_note to inject a structured \"Research Findings\"\n block into the conversation. Future turns see this and don't re-search.\n\n### Self-injection pattern\nWhen you discover current data mid-research, inject it so subsequent turns\nbenefit without re-searching:\n\nweb_search(\"Next.js middleware breaking changes 2025\")\n → Surfaced: Next.js 15.2 changed middleware runtime from edge to node\nweb_fetch(\"https://nextjs.org/docs/messages/middleware-upgrade-guide\")\n → Confirmed: middleware now runs on Node.js runtime by default\ncontext_manager: add_note(\n \"## Research: Next.js middleware\n - Next.js 15.2: middleware defaults to Node.js runtime (was edge)\n - Breaking: edge-only APIs (crypto.subtle, WebSocket) no longer available\n - Migration: use node:* equivalents or set runtime: 'edge' explicitly\n - Source: nextjs.org/docs/messages/middleware-upgrade-guide\"\n)\n\nThe add_note persists in conversation — you won't re-search on the next turn.\n\n### Anti-patterns\n- Don't research things already in the conversation context (including\n earlier add_note blocks you injected)\n- Don't treat a single web search result as ground truth — cross-reference\n- Don't inject raw JSON or search result dumps via add_note — summarize\n- Don't research while the user is waiting for a quick code edit — toggle\n research-web mode only during analysis/discussion phases\n- Don't research-loop: 5+ searches on one topic → stop and ask the user\n\n### Exiting research mode\nWhen the user no longer needs current-data research, suggest switching back\nto the previous mode. You stay in research mode until explicitly told to\nswitch — but don't force web searches on every turn. The methodology rules\nabove already gate when to actually search.\n\nWhen you're done with research: suggest the user run \\`/mode default\\` or\ntheir previous mode.`,\n tags: ['research', 'web', 'current-data', 'up-to-date'],\n toolPreferences: ['web_search', 'web_fetch', 'search', 'fetch', 'context_manager'],\n suggestedSkills: ['research-web', 'tech-stack', 'node-modern', 'security-scanner', 'react-modern'],\n },\n];\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport type { Mode, ModeConfig, ModeManifest, ModeStore } from '../types/mode.js';\nimport { DEFAULT_MODES } from '../types/mode.js';\n\nexport class DefaultModeStore implements ModeStore {\n private activeModeId: string | null = null;\n private modes: Mode[];\n private configDir: string;\n\n constructor(config: ModeConfig) {\n this.configDir = config.directory;\n this.modes = [...DEFAULT_MODES];\n }\n\n async getActiveMode(): Promise<Mode | null> {\n if (!this.activeModeId) {\n await this.loadActiveMode();\n }\n if (!this.activeModeId) return null;\n return this.modes.find((m) => m.id === this.activeModeId) ?? null;\n }\n\n async setActiveMode(modeId: string | null): Promise<void> {\n this.activeModeId = modeId;\n await this.saveActiveMode();\n }\n\n async listModes(): Promise<Mode[]> {\n return [...this.modes];\n }\n\n async getMode(modeId: string): Promise<Mode | null> {\n return this.modes.find((m) => m.id === modeId) ?? null;\n }\n\n async addMode(mode: Mode): Promise<void> {\n const idx = this.modes.findIndex((m) => m.id === mode.id);\n if (idx >= 0) {\n this.modes[idx] = mode;\n } else {\n this.modes.push(mode);\n }\n }\n\n async removeMode(modeId: string): Promise<void> {\n const builtIn = DEFAULT_MODES.find((m) => m.id === modeId);\n if (builtIn) {\n throw new Error(`Cannot remove built-in mode \"${modeId}\"`);\n }\n this.modes = this.modes.filter((m) => m.id !== modeId);\n if (this.activeModeId === modeId) {\n this.activeModeId = null;\n await this.saveActiveMode();\n }\n }\n\n private async loadActiveMode(): Promise<void> {\n try {\n const configPath = path.join(this.configDir, 'mode.json');\n const content = await fs.readFile(configPath, 'utf8');\n const data = JSON.parse(content);\n this.activeModeId = data.activeMode ?? null;\n } catch {\n this.activeModeId = 'default';\n }\n }\n\n private async saveActiveMode(): Promise<void> {\n try {\n await fs.mkdir(this.configDir, { recursive: true });\n const configPath = path.join(this.configDir, 'mode.json');\n // atomicWrite: torn write would leave mode.json malformed and the\n // next load would silently reset to \"default\".\n await atomicWrite(\n configPath,\n JSON.stringify({ activeMode: this.activeModeId }, null, 2),\n );\n } catch {\n // ignore save errors\n }\n }\n}\n\nexport interface ModeLoaderOptions {\n projectModesDir?: string | undefined;\n userModesDir?: string | undefined;\n}\n\nexport async function loadProjectModes(modesDir: string): Promise<Mode[]> {\n const modes: Mode[] = [];\n try {\n const entries = await fs.readdir(modesDir);\n for (const entry of entries) {\n if (!entry.endsWith('.md') && !entry.endsWith('.txt')) continue;\n const filePath = path.join(modesDir, entry);\n const stat = await fs.stat(filePath);\n if (!stat.isFile()) continue;\n const content = await fs.readFile(filePath, 'utf8');\n const id = path.basename(entry, path.extname(entry));\n modes.push({\n id,\n name: id.replace(/[-_]/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase()),\n description: content.split('\\n')[0] ?? id,\n prompt: content,\n tags: ['project'],\n });\n }\n } catch {\n // no project modes\n }\n return modes;\n}\n\nexport async function loadUserModes(modesDir: string): Promise<Mode[]> {\n const modes: Mode[] = [];\n try {\n const manifestPath = path.join(modesDir, 'modes.json');\n const content = await fs.readFile(manifestPath, 'utf8');\n const manifest: ModeManifest = JSON.parse(content);\n for (const mode of manifest.modes) {\n modes.push(mode);\n }\n } catch {\n // no user modes\n }\n return modes;\n}\n","/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n","import type { Message } from '../types/messages.js';\nimport { compactToolDefinitionForWire } from './tool-wire-compact.js';\n\n/**\n * Shared token estimation with JSON.stringify caching.\n * Avoids repeated stringification of tool input objects.\n *\n * ## Calibration\n *\n * `estimateRequestTokens` uses a fixed 3.5 chars/token heuristic — a\n * conservative overestimate that prevents underestimation but reduces\n * accuracy. After each API call, call `recordActualUsage()` with the\n * real `usage.input` from the provider response. The module maintains a\n * rolling average of `actual / estimated` ratio (EWM, α=0.3) and\n * applies it to subsequent calls via `estimateRequestTokensCalibrated`.\n *\n * Calibration is per-module (shared across all callers), which is\n * sufficient: the chars/token ratio is a property of the tokenizer,\n * not the model. Uncalibrated calls (before any samples, or when\n * `recordActualUsage` is not called) fall back to the uncalibrated\n * estimate so nothing breaks.\n */\n\nconst RoughTokenEstimate = (text: string, charsPerToken = 3.5): number =>\n Math.max(1, Math.ceil(text.length / charsPerToken));\n\n/** Calibration state: actual/estimated ratio via exponential weighted moving average. */\ninterface CalState {\n ratio: number; // current calibration multiplier (actual / estimated)\n count: number; // number of samples recorded\n prevEst: number; // estimated tokens from the most recent estimateRequestTokens call\n}\n\n/** EWM α — higher = faster adaptation, more volatile. */\nconst CAL_ALPHA = 0.3;\n\n/**\n * Calibration is keyed so that, in a multi-agent / model-switching process,\n * each (provider, model) tokenizer gets its own ratio instead of all of them\n * collapsing onto one shared number. Callers that don't pass a key use the\n * shared `__global__` bucket — that preserves the original single-session\n * behavior and keeps all existing call sites working unchanged.\n */\nconst CALIBRATION_GLOBAL_KEY = '__global__';\nconst _cals = new Map<string, CalState>();\n\nfunction calState(key: string): CalState {\n let state = _cals.get(key);\n if (!state) {\n state = { ratio: 1.0, count: 0, prevEst: 0 };\n _cals.set(key, state);\n }\n return state;\n}\n\nconst MIN_SAMPLES_FOR_CALIBRATION = 3;\n\n/**\n * Fallback chars/token ratios per model family for providers that don't return\n * usage data. Used when `recordActualUsage` receives zero/negative tokens and\n * we have enough samples to trust the fallback. Keys are lowercase prefixes.\n */\nconst MODEL_FAMILY_RATIO: Record<string, number> = {\n // Anthropic: ~3.8-4.0 chars/token depending on model\n claude: 3.8,\n // OpenAI: ~4.0 chars/token\n 'gpt-4': 4.0,\n 'gpt-3.5': 4.0,\n // Google: ~3.5 chars/token\n gemini: 3.5,\n // DeepSeek: ~3.5 chars/token\n deepseek: 3.5,\n};\n\n/**\n * Cache of computed estimates keyed by the stringified input — not the\n * input object itself. Previously the cache was keyed by the input object\n * via WeakMap, but JSON.stringify() produces a new object reference each\n * call so the cache never hit. Now we use a Map with string keys so that\n * repeated stringifications of the same structure share a single entry.\n */\nconst ESTIMATE_CACHE = new Map<string, number>();\n/** Insertion-order queue for O(1) LRU eviction: shift from front on overcapacity. */\nconst _estimateCacheOrder: string[] = [];\n\nconst ESTIMATE_CACHE_MAX_SIZE = 50_000;\n\nfunction getCachedEstimate(key: string, compute: (key: string) => number): number {\n const existing = ESTIMATE_CACHE.get(key);\n if (existing !== undefined) return existing;\n if (ESTIMATE_CACHE.size >= ESTIMATE_CACHE_MAX_SIZE) {\n // Evict oldest half — O(1) per eviction (array shift + Map.delete) instead\n // of O(n) iteration over all 50 000 keys in the Map.\n while (ESTIMATE_CACHE.size > Math.floor(ESTIMATE_CACHE_MAX_SIZE / 2)) {\n const oldest = _estimateCacheOrder.shift();\n if (oldest !== undefined) ESTIMATE_CACHE.delete(oldest);\n }\n }\n const estimate = compute(key);\n ESTIMATE_CACHE.set(key, estimate);\n _estimateCacheOrder.push(key);\n return estimate;\n}\n\n/**\n * Estimate tokens for a tool_use block input.\n * Caches the stringified result keyed by the stable string representation\n * to avoid repeated JSON.stringify calls during context window checks.\n */\nexport function estimateToolInputTokens(input: unknown): number {\n if (typeof input === 'string') return RoughTokenEstimate(input);\n if (input === null || typeof input !== 'object') {\n return RoughTokenEstimate(String(input));\n }\n // JSON.stringify is called once to form the cache key; RoughTokenEstimate\n // is deferred only on cache miss (compute callback), not wrapped unnecessarily.\n return getCachedEstimate(JSON.stringify(input), (key) => RoughTokenEstimate(key));\n}\n\n/**\n * Estimate tokens for a tool_result content.\n */\nexport function estimateToolResultTokens(content: string | unknown): number {\n if (typeof content === 'string') return RoughTokenEstimate(content);\n return getCachedEstimate(JSON.stringify(content), (key) => RoughTokenEstimate(key));\n}\n\n/**\n * Estimate tokens for a text block.\n */\nexport function estimateTextTokens(text: string): number {\n return RoughTokenEstimate(text);\n}\n\n/**\n * Compute and cache the token estimate for a single message. This is the\n * canonical per-message estimator — called once by ConversationState on\n * append/replace so the O(n·m) content-block walk happens at mutation time,\n * not on every context-pressure check.\n */\nexport function computeMessageTokens(msg: Message): number {\n if (typeof msg.content === 'string') return estimateTextTokens(msg.content);\n let total = 0;\n for (const b of msg.content) {\n if (b.type === 'text') total += estimateTextTokens(b.text);\n else if (b.type === 'tool_use') total += estimateToolInputTokens(b.input);\n else if (b.type === 'tool_result') total += estimateToolResultTokens(b.content);\n else total += RoughTokenEstimate(JSON.stringify(b));\n }\n return total;\n}\n\n/**\n * Estimate tokens for an array of messages (text + tool I/O), using the shared\n * 3.5 chars/token basis. This is the single canonical message-array estimator —\n * compactors, the context_manager tool, and the `/context` display all route\n * through it so the number a user sees matches the number compaction decides on.\n *\n * When a message carries a pre-computed `_estTokens` field (set by\n * ConversationState on append/replace), it is used directly instead of\n * re-walking the content blocks — turning the O(n·m) scan into an O(n)\n * sum for fully-cached arrays.\n */\nexport function estimateMessageTokens(messages: readonly Message[]): number {\n let total = 0;\n for (const m of messages) {\n if (typeof m._estTokens === 'number' && m._estTokens > 0) {\n total += m._estTokens;\n continue;\n }\n total += computeMessageTokens(m);\n }\n return total;\n}\n\n/**\n * Rough estimate of tokens in a tool definition (name + description + schema).\n * Accounts for the JSON-serialized inputSchema which is sent to the API\n * but NOT included in roughEstimate(content).\n */\nexport function estimateToolDefTokens(tool: {\n name: string;\n description?: string | undefined;\n inputSchema: unknown;\n}): number {\n // Fast path: pre-computed by ToolRegistry at registration time.\n const cached = (tool as { _estDefTokens?: number | undefined })._estDefTokens;\n if (typeof cached === 'number' && cached > 0) return cached;\n\n const compact = compactToolDefinitionForWire(tool);\n return (\n RoughTokenEstimate(tool.name) +\n RoughTokenEstimate(compact.description) +\n RoughTokenEstimate(JSON.stringify(compact.inputSchema))\n );\n}\n\n/**\n * Estimate the total API request token count: system prompt + tool definitions\n * + conversation messages. Use this for context-window bar calculations\n * instead of roughEstimate (which only counts messages).\n *\n * The overhead ratio (overhead / messages) varies by conversation length:\n * - Short conversations (< 10 messages): ~30-50% overhead (large system+tools)\n * - Medium (10-50 messages): ~15-30%\n * - Long (> 50 messages): ~5-15%\n *\n * Returns { messages, systemPrompt, tools, total } for debugging display.\n */\nexport interface RequestTokenBreakdown {\n messages: number;\n systemPrompt: number;\n tools: number;\n total: number;\n}\n\nexport function estimateRequestTokens(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string | undefined; inputSchema: unknown }[],\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): RequestTokenBreakdown {\n // Messages: apply the same logic as roughEstimate\n let messagesTokens = 0;\n if (typeof messages === 'string') {\n messagesTokens = RoughTokenEstimate(messages);\n } else if (Array.isArray(messages)) {\n for (const m of messages) {\n if (typeof m === 'object' && m !== null && 'content' in m) {\n // Fast path: pre-computed per-message token estimate (set by\n // ConversationState on append/replace). Skips the O(m) content-block\n // walk entirely for cached messages.\n const cached = (m as { _estTokens?: number | undefined })._estTokens;\n if (typeof cached === 'number' && cached > 0) {\n messagesTokens += cached;\n continue;\n }\n const content = (m as { content: unknown }).content;\n if (typeof content === 'string') {\n messagesTokens += RoughTokenEstimate(content);\n } else if (Array.isArray(content)) {\n for (const b of content) {\n if (typeof b === 'object' && b !== null) {\n if ((b as { type?: string | undefined }).type === 'text') {\n messagesTokens += RoughTokenEstimate((b as { text: string }).text);\n } else {\n messagesTokens += RoughTokenEstimate(JSON.stringify(b));\n }\n }\n }\n }\n }\n }\n }\n\n // System prompt\n let systemTokens = 0;\n if (typeof systemPrompt === 'string') {\n systemTokens = RoughTokenEstimate(systemPrompt);\n } else if (Array.isArray(systemPrompt)) {\n for (const b of systemPrompt) {\n if (\n typeof b === 'object' &&\n b !== null &&\n (b as { type?: string | undefined }).type === 'text'\n ) {\n systemTokens += RoughTokenEstimate((b as { text: string }).text);\n }\n }\n }\n\n // Tool definitions\n let toolsTokens = 0;\n for (const t of tools) {\n toolsTokens += estimateToolDefTokens(t);\n }\n\n const total = messagesTokens + systemTokens + toolsTokens;\n\n // Record the raw estimate for calibration: the next recordActualUsage()\n // call will pair this against the actual API usage so the rolling ratio\n // stays in sync with the real chars/token ratio of the content.\n calState(calibrationKey).prevEst = total;\n\n return {\n messages: messagesTokens,\n systemPrompt: systemTokens,\n tools: toolsTokens,\n total,\n };\n}\n\n/**\n * Record the actual API input token count after a provider call so\n * `estimateRequestTokensCalibrated` can self-correct on subsequent calls.\n *\n * Prefer passing `estimatedInputTokens` explicitly (the calibrated pre-flight\n * estimate from the middleware) — this avoids race conditions when other code\n * also calls `estimateRequestTokens` between the pre-flight and this call\n * (e.g. audit logging in agent.ts).\n *\n * When `estimatedInputTokens` is omitted, falls back to the keyed bucket's\n * `prevEst` for backward compatibility with callers that don't have the\n * pre-flight value. `calibrationKey` selects the per-(provider,model) bucket\n * (defaults to the shared global bucket).\n */\nexport function recordActualUsage(\n actualInputTokens: number,\n estimatedInputTokens?: number,\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): void {\n if (actualInputTokens <= 0) return;\n const cal = calState(calibrationKey);\n const est = estimatedInputTokens ?? cal.prevEst;\n if (est <= 0) return;\n\n const sampleRatio = actualInputTokens / est;\n if (cal.count === 0) {\n cal.ratio = sampleRatio;\n } else {\n // EWM: new = α * sample + (1-α) * old → α=0.3 = fast initial converge\n cal.ratio = CAL_ALPHA * sampleRatio + (1 - CAL_ALPHA) * cal.ratio;\n }\n // Sanity bound: keep the rolling ratio within [0.5, 1.5] so a sequence\n // of bad samples can't blow up the calibration for everyone.\n cal.ratio = Math.min(1.5, Math.max(0.5, cal.ratio));\n cal.count++;\n}\n\n/**\n * Returns the current calibration state for a bucket. Exposed for debugging\n * and tests — not needed by normal callers.\n */\nexport function getCalibrationState(calibrationKey: string = CALIBRATION_GLOBAL_KEY): {\n ratio: number;\n count: number;\n calibrated: boolean;\n} {\n const cal = calState(calibrationKey);\n return {\n ratio: cal.ratio,\n count: cal.count,\n calibrated: cal.count >= MIN_SAMPLES_FOR_CALIBRATION,\n };\n}\n\n/**\n * Like `estimateRequestTokens` but applies the rolling calibration factor\n * so context pressure readings converge on reality within a few iterations.\n *\n * Before any `recordActualUsage` samples are collected, returns the same\n * result as `estimateRequestTokens` (ratio = 1.0, no distortion).\n * After `MIN_SAMPLES_FOR_CALIBRATION` samples, applies the calibrated\n * multiplier capped to the range [0.5, 1.5] as a sanity bound.\n */\nexport function estimateRequestTokensCalibrated(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string | undefined; inputSchema: unknown }[],\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): RequestTokenBreakdown {\n const result = estimateRequestTokens(messages, systemPrompt, tools, calibrationKey);\n const cal = calState(calibrationKey);\n\n if (cal.count >= MIN_SAMPLES_FOR_CALIBRATION) {\n const safeRatio = Math.min(1.5, Math.max(0.5, cal.ratio));\n return {\n messages: Math.round(result.messages * safeRatio),\n systemPrompt: Math.round(result.systemPrompt * safeRatio),\n tools: Math.round(result.tools * safeRatio),\n total: Math.round(result.total * safeRatio),\n };\n }\n\n // No calibration samples yet — fall back to model-family ratio if available,\n // otherwise use the uncalibrated estimate (ratio = 1.0).\n const fallbackRatio = getModelFamilyRatio(calibrationKey);\n if (fallbackRatio !== null) {\n return {\n messages: Math.round(result.messages * fallbackRatio),\n systemPrompt: Math.round(result.systemPrompt * fallbackRatio),\n tools: Math.round(result.tools * fallbackRatio),\n total: Math.round(result.total * fallbackRatio),\n };\n }\n\n return result;\n}\n\n/** Look up the fallback chars/token ratio for a calibration key (e.g. \"provider/model\"). */\nfunction getModelFamilyRatio(calibrationKey: string): number | null {\n const lower = calibrationKey.toLowerCase();\n for (const [family, ratio] of Object.entries(MODEL_FAMILY_RATIO)) {\n if (lower.includes(family)) return ratio / 3.5; // MODEL_FAMILY_RATIO is chars/token, we need multiplier\n }\n return null;\n}\n\n/**\n * Resets calibration state. Primarily for tests that run in the same\n * process and need a clean slate between suites. With no argument it clears\n * every bucket (including the global one); pass a key to reset just that bucket.\n */\nexport function resetCalibration(calibrationKey?: string): void {\n if (calibrationKey === undefined) {\n _cals.clear();\n return;\n }\n _cals.delete(calibrationKey);\n}\n","export interface TextBlock {\n type: 'text';\n text: string;\n cache_control?: { type: 'ephemeral' | undefined };\n}\n\nexport interface ToolUseBlock {\n type: 'tool_use';\n id: string;\n name: string;\n input: Record<string, unknown>;\n /**\n * Provider-specific opaque metadata captured from the wire response.\n * Echoed back verbatim in the next request so providers that bind\n * extra state to function calls keep working. Example: Gemini's\n * `thoughtSignature` — required for tool-use turns with thinking\n * models, otherwise the next request fails with 400 \"Function call\n * is missing a thought_signature in functionCall parts\".\n *\n * Keys are namespaced by intent so multiple wires can coexist:\n * - `google.thoughtSignature` — Gemini signed-thought blob\n * Other providers can add their own keys without colliding.\n */\n providerMeta?: Record<string, unknown>;\n}\n\nexport interface ToolResultBlock {\n type: 'tool_result';\n tool_use_id: string;\n /**\n * The original tool name. Useful for providers like Google Gemini that\n * need the tool name in `functionResponse.name` — the tool_use_id is\n * only a session-local identifier and is not stable across replays.\n * Always set by ToolExecutor; may be absent on manually-constructed blocks.\n */\n name?: string | undefined;\n content: string;\n is_error?: boolean | undefined;\n}\n\nexport interface ImageBlock {\n type: 'image';\n source: {\n type: 'base64' | 'url';\n media_type?: string | undefined;\n data?: string | undefined;\n url?: string | undefined;\n };\n}\n\n/**\n * Chain-of-thought / extended-thinking content emitted by the model.\n *\n * Both Anthropic extended thinking (`{type:'thinking', thinking, signature}`)\n * and DeepSeek reasoning mode (top-level `reasoning_content` on the assistant\n * message) require this content to be echoed back verbatim on the next\n * request, otherwise the provider returns 400:\n * - Anthropic: \"The `content[].thinking` in the thinking mode must be passed back\"\n * - DeepSeek: \"The `reasoning_content` in the thinking mode must be passed back\"\n *\n * `signature` is Anthropic-specific (an opaque integrity blob). DeepSeek\n * doesn't issue a signature — the field is absent for that provider.\n *\n * Per Anthropic, thinking blocks MUST appear before any text/tool_use blocks\n * in an assistant message. Stream builders preserve that order.\n */\nexport interface ThinkingBlock {\n type: 'thinking';\n thinking: string;\n signature?: string | undefined;\n providerMeta?: Record<string, unknown>;\n}\n\nexport type ContentBlock = TextBlock | ToolUseBlock | ToolResultBlock | ImageBlock | ThinkingBlock;\n\nexport function isTextBlock(b: ContentBlock): b is TextBlock {\n return b.type === 'text';\n}\nexport function isToolUseBlock(b: ContentBlock): b is ToolUseBlock {\n return b.type === 'tool_use';\n}\nexport function isToolResultBlock(b: ContentBlock): b is ToolResultBlock {\n return b.type === 'tool_result';\n}\nexport function isImageBlock(b: ContentBlock): b is ImageBlock {\n return b.type === 'image';\n}\nexport function isThinkingBlock(b: ContentBlock): b is ThinkingBlock {\n return b.type === 'thinking';\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport { estimateMessageTokens, estimateTextTokens } from '../utils/token-estimate.js';\nimport { isTextBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nimport type { Provider, Request } from '../types/provider.js';\nimport type { MessageSelector, SelectorResult } from '../types/selector.js';\nexport interface LLMSelectorOptions {\n /** Provider used for the selector LLM call. Required. */\n provider: Provider;\n /** Model for the selector. Defaults to the provider's default model. */\n model?: string | undefined;\n /**\n * Maximum tokens to keep in context (target budget).\n * Selector will aim to keep total content below this.\n */\n maxContextTokens?: number | undefined;\n /**\n * Prompt instructing the selector how to behave.\n * Should guide the LLM on importance tiers and output format.\n */\n systemPrompt?: string | undefined;\n /**\n * Maximum output tokens for the selector LLM call.\n * Controls both the JSON response budget and the token reservation for the\n * history text budget calculation (default: 1024).\n */\n maxOutputTokens?: number | undefined;\n}\n\nconst DEFAULT_SYSTEM_PROMPT = `You are a context pruning assistant. Given a conversation history and a token budget, decide which message ranges are worth keeping verbatim and which should be collapsed into summaries.\n\nOutput a JSON object with this structure:\n{\n \"kept\": [{\"from\": 0, \"to\": 5, \"importance\": \"critical\"}],\n \"collapsed\": [{\"from\": 6, \"to\": 20, \"summary\": \"optional summary\"}],\n \"reasoning\": \"brief explanation of decisions\"\n}\n\nImportance tiers:\n- \"critical\": decisions, file edits, tool results that affect state, final answers\n- \"high\": substantive tool use, complex reasoning, non-obvious observations\n- \"medium\": routine exchanges, confirmations, straightforward Q&A\n\nRules:\n- Always keep the most recent K pairs (preserve recency)\n- Never collapse the final 2 user/assistant pairs (working memory)\n- Preserve tool results that modified files or had external effects\n- Collapse old, low-information exchanges (greetings, acknowledgements, etc.)\n- If unsure, keep rather than collapse (errors are more costly than waste)\n\nReturn ONLY the JSON object, no markdown, no explanation outside the JSON.`;\n\n/**\n * Format messages as a compact text dump for the selector LLM.\n * Uses token estimation (not character count) to budget the output,\n * so long sessions don't silently truncate the selector's view of history.\n */\nfunction formatMessages(messages: Message[], maxTokens = 2048): string {\n const lines: string[] = [];\n let usedTokens = 0;\n for (let i = 0; i < messages.length; i++) {\n const m = expectDefined(messages[i]);\n const role = m.role.padEnd(10, ' ');\n let text: string;\n if (typeof m.content === 'string') {\n text = m.content.slice(0, 500);\n } else {\n const content = m.content as import('../types/blocks.js').ContentBlock[];\n text = content\n .filter(isTextBlock)\n .map((b) => b.text)\n .join(' ');\n // Also capture tool names for context\n const toolUses = content.filter((b) => b.type === 'tool_use');\n if (toolUses.length > 0) {\n text += ` [tools: ${toolUses.map((b) => (b as { name?: string }).name).filter(Boolean).join(', ')}]`;\n }\n }\n const line = `[${i}][${role}]: ${text}`;\n const lineTokens = estimateTextTokens(line);\n if (usedTokens + lineTokens > maxTokens) break;\n lines.push(line);\n usedTokens += lineTokens;\n }\n return lines.join('\\n');\n}\n\n/**\n * LLM-powered message selector. Calls a sub-LLM to analyze the\n * message history and produce a keep/collapse plan — more surgical\n * than fixed-window rules.\n */\nexport class LLMSelector implements MessageSelector {\n private readonly provider: Provider;\n private readonly model: string;\n private readonly maxContextTokens: number;\n private readonly systemPrompt: string;\n private readonly maxOutputTokens: number;\n\n constructor(opts: LLMSelectorOptions) {\n this.provider = opts.provider;\n this.model = opts.model ?? 'unknown';\n if (\n this.model === 'unknown' &&\n (process.env['NODE_ENV'] === 'development' || process.env['WRONGSTACK_DEBUG'] === '1')\n ) {\n console.warn(\n '[LLMSelector] model not set — selector will use the provider default. Set `model` explicitly in LLMSelectorOptions to silence this warning.',\n );\n }\n this.maxContextTokens = opts.maxContextTokens ?? 40_000;\n this.systemPrompt = opts.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;\n this.maxOutputTokens = opts.maxOutputTokens ?? 1024;\n }\n\n async select(messages: Message[], maxToKeep: number): Promise<SelectorResult> {\n const effectiveBudget = Math.min(maxToKeep, this.maxContextTokens);\n\n const totalTokens = estimateMessageTokens(messages);\n const systemText = `${this.systemPrompt}\\n\\nConversation (${messages.length} messages, ~${totalTokens} tokens, budget: ${effectiveBudget}):\\n`;\n // Reserve tokens for the system prefix and output (maxOutputTokens), then give the\n // rest to the formatted history so the selector sees the maximum possible context.\n const systemTokens = estimateTextTokens(systemText);\n const historyBudget = Math.max(512, effectiveBudget - systemTokens - this.maxOutputTokens);\n\n // Build a concise representation of the conversation within the token budget\n const historyText = formatMessages(messages, historyBudget);\n\n // Add instruction to stay within budget\n const budgetInstruction =\n totalTokens > effectiveBudget\n ? `\\n\\nIMPORTANT: Total conversation (${totalTokens} tokens) exceeds budget (${effectiveBudget}). You MUST collapse enough to fit. Prefer collapsing older/lower-importance ranges.`\n : '';\n\n const req: Request = {\n model: this.model,\n system: [{ type: 'text', text: systemText + budgetInstruction }],\n messages: [{ role: 'user', content: historyText }],\n maxTokens: this.maxOutputTokens,\n };\n\n let raw: string;\n const ac = new AbortController();\n try {\n // 30-second timeout so a stuck selector LLM call can't hang the compactor.\n const timeoutSignal = AbortSignal.timeout(30_000);\n const res = await this.provider.complete(req, {\n signal: AbortSignal.any([ac.signal, timeoutSignal]),\n });\n const textBlocks = res.content.filter(isTextBlock);\n raw = textBlocks\n .map((b) => b.text)\n .join('\\n')\n .trim();\n } catch (err) {\n if (err instanceof Error) {\n console.warn('[LLMSelector] selector call failed, using recency fallback:', err.message);\n }\n return this.fallbackSelect(messages, effectiveBudget);\n } finally {\n ac.abort();\n }\n\n return this.parseSelectorOutput(raw, messages);\n }\n\n private fallbackSelect(messages: Message[], budget: number): SelectorResult {\n // Simple fallback: keep from the end until we hit budget\n const toKeep: SelectorResult['kept'] = [];\n const toCollapse: SelectorResult['collapsed'] = [];\n\n let tokenCount = 0;\n let startIdx = 0;\n\n // Scan from the end backwards\n for (let i = messages.length - 1; i >= 0; i--) {\n const m = expectDefined(messages[i]);\n const cost = estimateMessageTokens([m]);\n\n if (tokenCount + cost <= budget) {\n tokenCount += cost;\n } else {\n startIdx = i + 1;\n break;\n }\n }\n\n if (startIdx > 0) {\n toCollapse.push({ from: 0, to: startIdx - 1 });\n }\n toKeep.push({ from: startIdx, to: messages.length - 1, importance: 'high' });\n\n return {\n kept: toKeep,\n collapsed: toCollapse,\n reasoning: `Fallback: kept last ${messages.length - startIdx} messages within ${budget} token budget`,\n };\n }\n\n /**\n * Parse and validate the raw LLM output into a SelectorResult.\n * Falls back to recency-based selection if the LLM output is malformed,\n * out-of-bounds, or internally inconsistent.\n */\n private parseSelectorOutput(raw: string, messages: Message[]): SelectorResult {\n const messageCount = messages.length;\n if (messageCount === 0) {\n return { kept: [], collapsed: [], reasoning: 'empty session' };\n }\n\n // Try to extract JSON from the response\n const jsonStart = raw.indexOf('{');\n const jsonEnd = raw.lastIndexOf('}');\n if (jsonStart === -1 || jsonEnd === -1) {\n return this.fallbackSelect(messages, this.maxContextTokens);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw.slice(jsonStart, jsonEnd + 1));\n } catch {\n return this.fallbackSelect(messages, this.maxContextTokens);\n }\n\n const obj = parsed as Record<string, unknown>;\n const keptRaw =\n (obj.kept as Array<{ from: number; to: number; importance: string }> | undefined) ?? [];\n const collapsedRaw =\n (obj.collapsed as Array<{ from: number; to: number; summary?: string | undefined }> | undefined) ?? [];\n\n // Validate kept ranges — must be within [0, messageCount), from <= to\n const kept: SelectorResult['kept'] = [];\n for (const k of keptRaw) {\n if (\n typeof k.from !== 'number' ||\n typeof k.to !== 'number' ||\n k.from < 0 ||\n k.to >= messageCount ||\n k.from > k.to\n ) {\n return this.fallbackSelect(messages, this.maxContextTokens);\n }\n kept.push({\n from: k.from,\n to: k.to,\n importance: (k.importance ?? 'medium') as 'critical' | 'high' | 'medium',\n });\n }\n\n // Validate collapsed ranges — same bounds check\n const collapsed: SelectorResult['collapsed'] = [];\n for (const c of collapsedRaw) {\n if (\n typeof c.from !== 'number' ||\n typeof c.to !== 'number' ||\n c.from < 0 ||\n c.to >= messageCount ||\n c.from > c.to\n ) {\n return this.fallbackSelect(messages, this.maxContextTokens);\n }\n collapsed.push({ from: c.from, to: c.to, summary: c.summary });\n }\n\n // Check for overlaps: kept ranges must not overlap with each other or with collapsed ranges\n const allRanges: Array<{ from: number; to: number }> = [...kept, ...collapsed];\n for (let i = 0; i < allRanges.length; i++) {\n const a = allRanges[i];\n if (!a) continue;\n for (let j = i + 1; j < allRanges.length; j++) {\n const b = allRanges[j];\n if (!b) continue;\n // Overlap: a starts before b ends AND a ends after b starts\n if (a.from <= b.to && a.to >= b.from) {\n return this.fallbackSelect(messages, this.maxContextTokens);\n }\n }\n }\n\n return {\n kept,\n collapsed,\n reasoning: typeof obj.reasoning === 'string' ? obj.reasoning : '',\n };\n }\n}\n","import type { ModelsDevModel, ResolvedProvider } from '../types/models-registry.js';\n\n/**\n * A model descriptor shaped for the WebUI `provider.models` message. All\n * metadata fields are optional because OAuth / subscription providers that\n * models.dev doesn't list contribute only a bare id.\n */\nexport interface ProviderModelDescriptor {\n id: string;\n name: string;\n releaseDate?: string | undefined;\n contextWindow?: number | undefined;\n inputCost?: number | undefined;\n outputCost?: number | undefined;\n capabilities: string[];\n}\n\n/** Map a models.dev catalog model to the WebUI descriptor shape. */\nexport function describeCatalogModel(m: ModelsDevModel): ProviderModelDescriptor {\n return {\n id: m.id,\n name: m.name,\n releaseDate: m.release_date,\n contextWindow: m.limit?.context,\n inputCost: m.cost?.input,\n outputCost: m.cost?.output,\n capabilities: [\n ...(m.tool_call ? ['tools'] : []),\n ...(m.reasoning ? ['reasoning'] : []),\n ...(m.modalities?.input?.includes('image') ? ['vision'] : []),\n ...(m.open_weights ? ['open_weights'] : []),\n ],\n };\n}\n\n/**\n * Resolve the model list to offer for a provider, merging a saved-config\n * allowlist with optional models.dev catalog metadata.\n *\n * Priority:\n * 1. The saved `models` allowlist is authoritative. This is the only source\n * for OAuth / subscription / custom providers that models.dev does not\n * list — `github-copilot`, `anthropic-oauth`, `openai-codex`,\n * `zai-coding-plan`, etc. Each id is enriched with catalog metadata when a\n * same-id catalog model exists, otherwise returned as a bare `{id, name}`.\n * 2. Otherwise the full catalog model list (standard API-key providers with no\n * saved allowlist).\n * 3. Otherwise an empty list — *never* an error. A provider the user saved\n * that is neither in the catalog nor carries an allowlist simply has no\n * suggestions yet; callers must not raise a toast for that case (doing so\n * produced the \"not found in catalog\" notification flood when the WebUI\n * model switcher lazy-loaded every saved provider).\n */\nexport function resolveProviderModelList(\n savedModels: string[] | undefined,\n catalog: ResolvedProvider | undefined,\n): ProviderModelDescriptor[] {\n if (savedModels && savedModels.length > 0) {\n const byId = new Map((catalog?.models ?? []).map((m) => [m.id, m]));\n return savedModels.map((id) => {\n const hit = byId.get(id);\n return hit ? describeCatalogModel(hit) : { id, name: id, capabilities: [] };\n });\n }\n if (catalog) return catalog.models.map(describeCatalogModel);\n return [];\n}\n","/**\n * Model Intelligence — knowledge base of model capabilities, strengths,\n * and task-type suitability. Powers automatic agent → model routing.\n *\n * Each entry records:\n * - Known strengths (what this model family excels at)\n * - Known weaknesses (what it struggles with)\n * - Best-for task types (coding, planning, security, docs, etc.)\n * - Cost tier (budget / standard / premium)\n *\n * This is a curated dataset updated as new models release. Falls back\n * gracefully for unknown models.\n */\n\nexport interface ModelProfile {\n /** Provider id (e.g. \"anthropic\", \"openai\"). */\n provider: string;\n /** Model id regex — matches partial ids (e.g. \"claude-sonnet\" matches \"claude-sonnet-4-20250514\"). */\n pattern: RegExp;\n /** Human-readable model family name. */\n family: string;\n /** What this model is particularly good at. */\n strengths: string[];\n /** Known limitations. */\n weaknesses?: string[];\n /** Task types this model is the best choice for. Ordered by preference. */\n bestFor: TaskType[];\n /** Task types to avoid with this model (use a different one). */\n avoidFor?: TaskType[];\n /** Approximate cost tier. */\n costTier: 'budget' | 'standard' | 'premium';\n /** Approximate speed tier (relative to other models). */\n speedTier: 'fast' | 'normal' | 'slow';\n /** Minimum recommended context window. */\n minContext?: number;\n}\n\n/** Task categories that map to agent roles. */\nexport type TaskType =\n | 'coding' // general software development\n | 'planning' // architecture, design, strategy\n | 'security' // vulnerability scanning, security review\n | 'docs' // documentation, writing, explanation\n | 'testing' // test writing, test review\n | 'refactoring' // code restructuring, cleanup\n | 'debugging' // bug hunting, error tracing\n | 'data' // data analysis, JSON, DB queries\n | 'frontend' // React, UI, CSS\n | 'backend' // API, server, infrastructure\n | 'review' // code review, PR review\n | 'lightweight' // simple tasks, quick answers\n | 'general'; // fallback — any task\n\n/** Known model profiles. Patterns are tried in order; first match wins. */\nexport const MODEL_PROFILES: ModelProfile[] = [\n // ── Anthropic ──\n {\n provider: 'anthropic',\n pattern: /claude-opus/i,\n family: 'Claude Opus',\n strengths: ['complex reasoning', 'multi-step planning', 'nuanced judgment', 'long-form analysis'],\n weaknesses: ['latency', 'cost'],\n bestFor: ['planning', 'security', 'debugging', 'review'],\n costTier: 'premium',\n speedTier: 'slow',\n },\n {\n provider: 'anthropic',\n pattern: /claude-sonnet/i,\n family: 'Claude Sonnet',\n strengths: ['coding', 'balanced reasoning', 'tool use', 'fast iteration'],\n bestFor: ['coding', 'refactoring', 'backend', 'general'],\n costTier: 'standard',\n speedTier: 'fast',\n },\n {\n provider: 'anthropic',\n pattern: /claude-haiku/i,\n family: 'Claude Haiku',\n strengths: ['speed', 'low cost', 'simple tasks'],\n weaknesses: ['complex reasoning', 'long context'],\n bestFor: ['lightweight', 'docs', 'frontend'],\n avoidFor: ['planning', 'security'],\n costTier: 'budget',\n speedTier: 'fast',\n },\n\n // ── OpenAI ──\n {\n provider: 'openai',\n pattern: /gpt-5|o3|o4/i,\n family: 'GPT-5 / o3 / o4',\n strengths: ['complex reasoning', 'coding', 'multi-modal'],\n bestFor: ['planning', 'coding', 'debugging', 'general'],\n costTier: 'premium',\n speedTier: 'normal',\n },\n {\n provider: 'openai',\n pattern: /gpt-4\\.1|gpt-4o/i,\n family: 'GPT-4.1 / 4o',\n strengths: ['coding', 'balanced reasoning', 'fast'],\n bestFor: ['coding', 'refactoring', 'backend', 'docs'],\n costTier: 'standard',\n speedTier: 'fast',\n },\n {\n provider: 'openai',\n pattern: /gpt-4o-mini/i,\n family: 'GPT-4o Mini',\n strengths: ['speed', 'low cost', 'simple tasks'],\n weaknesses: ['complex reasoning'],\n bestFor: ['lightweight', 'frontend', 'docs'],\n avoidFor: ['planning', 'security'],\n costTier: 'budget',\n speedTier: 'fast',\n },\n\n // ── Google ──\n {\n provider: 'google',\n pattern: /gemini-(?:2\\.5|3)/i,\n family: 'Gemini 2.5 / 3',\n strengths: ['long context', 'multi-modal', 'coding', 'reasoning'],\n bestFor: ['coding', 'planning', 'data', 'general'],\n costTier: 'standard',\n speedTier: 'normal',\n },\n {\n provider: 'google',\n pattern: /gemini-2\\.0-flash|gemini-flash/i,\n family: 'Gemini Flash',\n strengths: ['speed', 'low cost', 'long context'],\n weaknesses: ['deep reasoning'],\n bestFor: ['lightweight', 'docs', 'frontend', 'data'],\n avoidFor: ['planning', 'security'],\n costTier: 'budget',\n speedTier: 'fast',\n },\n\n // ── DeepSeek ──\n {\n provider: 'deepseek',\n pattern: /deepseek-v3|deepseek-r1/i,\n family: 'DeepSeek V3 / R1',\n strengths: ['coding', 'math', 'reasoning', 'cost-effective'],\n bestFor: ['coding', 'refactoring', 'debugging', 'general'],\n costTier: 'standard',\n speedTier: 'normal',\n },\n\n // ── OpenRouter / catch-all ──\n {\n provider: 'openrouter',\n pattern: /.*/,\n family: 'OpenRouter (routed)',\n strengths: ['model variety', 'fallback'],\n bestFor: ['general'],\n costTier: 'standard',\n speedTier: 'normal',\n },\n];\n\n/** Map task types to the agent roles that handle them. */\nexport const TASK_TO_ROLE: Record<TaskType, string[]> = {\n coding: ['executor', 'architect', 'bug-hunter'],\n planning: ['planner', 'architect', 'refactor-planner'],\n security: ['security-scanner', 'security-reviewer'],\n docs: ['document', 'simplifier'],\n testing: ['test', 'e2e'],\n refactoring: ['refactor-planner', 'refactor', 'simplifier'],\n debugging: ['debugger', 'bug-hunter', 'tracer'],\n data: ['analyst', 'data', 'database'],\n frontend: ['frontend', 'designer'],\n backend: ['backend', 'api', 'auth'],\n review: ['code-reviewer', 'critic'],\n lightweight: ['executor', 'simplifier'],\n general: ['executor', 'analyst'],\n};\n\n/**\n * Infer the most likely task type from a task description and target role.\n * Uses keyword matching; falls back to the role's primary task type.\n */\nexport function inferTaskType(description: string, role?: string): TaskType {\n const d = description.toLowerCase();\n\n // Keyword → task type mapping\n const keywords: [RegExp, TaskType][] = [\n [/plan|architect|design|strategy|blueprint|system\\s*design/i, 'planning'],\n [/security|vuln|exploit|injection|auth/i, 'security'],\n [/doc|readme|explain|write\\s*(a|the)\\s*doc|tutorial/i, 'docs'],\n [/test|spec|assert|mock|coverage/i, 'testing'],\n [/refactor|clean\\s*up|restructure|simplify/i, 'refactoring'],\n [/bug|fix|debug|trace|crash|error/i, 'debugging'],\n [/data|json|sql|query|analyze|parse/i, 'data'],\n [/frontend|react|ui|css|component|jsx/i, 'frontend'],\n [/backend|api|server|endpoint|route|middleware/i, 'backend'],\n [/review|audit|inspect|check/i, 'review'],\n [/simple|quick|one-liner|trivial/i, 'lightweight'],\n ];\n\n for (const [re, taskType] of keywords) {\n if (re.test(d)) return taskType;\n }\n\n // Fallback: map role to best task type\n if (role) {\n for (const [taskType, roles] of Object.entries(TASK_TO_ROLE)) {\n if (roles.includes(role)) return taskType as TaskType;\n }\n }\n\n return 'general';\n}\n\n/**\n * Find the best matching model profile for a given provider + model id.\n */\nexport function findModelProfile(provider: string, modelId: string): ModelProfile | undefined {\n const candidates = MODEL_PROFILES.filter((p) => p.provider === provider);\n // Try exact match first, then pattern match\n for (const p of candidates) {\n if (p.pattern.test(modelId)) return p;\n }\n return undefined;\n}\n\n/**\n * Score a model for a given task type. Higher = better fit.\n * Returns 0-100.\n */\nexport function scoreModelForTask(profile: ModelProfile | undefined, taskType: TaskType): number {\n if (!profile) return 50; // unknown model — neutral\n\n // Explicitly avoided → very low score\n if (profile.avoidFor?.includes(taskType)) return 10;\n\n // Best-for match → high score\n const bestIdx = profile.bestFor.indexOf(taskType);\n if (bestIdx >= 0) {\n // Earlier in the list = better fit\n return 90 - bestIdx * 10;\n }\n\n // Cost/speed adjustments\n let score = 50;\n if (taskType === 'lightweight') {\n score += profile.costTier === 'budget' ? 30 : profile.costTier === 'standard' ? 15 : 0;\n score += profile.speedTier === 'fast' ? 20 : 0;\n }\n if (taskType === 'planning' || taskType === 'security') {\n score += profile.costTier === 'premium' ? 20 : 0;\n score += profile.speedTier === 'slow' ? 10 : 0; // slow = thorough\n }\n\n return score;\n}\n","/**\n * ModelRouter — intelligent model selection for subagent delegation.\n *\n * Combines:\n * 1. User-configured model matrix (/setmodel overrides)\n * 2. Model intelligence profiles (strengths/weaknesses per model family)\n * 3. Provider availability (which models have API keys configured)\n * 4. Per-model cost tracking\n *\n * Usage:\n * const router = new ModelRouter({ matrix, config, profiles: MODEL_PROFILES });\n * const pick = router.pickForTask('security-scanner', 'Audit the auth module');\n * // → { provider: 'anthropic', model: 'claude-sonnet-...', reason: 'best-for security' }\n */\n\nimport type { ModelMatrixEntry, ProviderConfig } from '../types/config.js';\n\nexport interface ModelIntelligenceEntry {\n provider: string;\n pattern: RegExp;\n family: string;\n strengths: string[];\n weaknesses?: string[];\n bestFor: string[];\n avoidFor?: string[];\n costTier: 'budget' | 'standard' | 'premium';\n speedTier: 'fast' | 'normal' | 'slow';\n minContext?: number;\n}\n\nexport interface RouterConfig {\n /** User-configured model matrix (from /setmodel). */\n matrix?: Record<string, ModelMatrixEntry> | undefined;\n /** Provider configurations (to check API key availability). */\n config: {\n provider: string;\n model: string;\n providers?: Record<string, ProviderConfig>;\n };\n /** Known model intelligence profiles. */\n profiles?: ModelIntelligenceEntry[] | undefined;\n}\n\nexport interface ModelPick {\n provider: string;\n model: string;\n /** Why this model was chosen. */\n reason: string;\n /** Whether this came from the user's matrix (true) or auto-detected (false). */\n fromMatrix: boolean;\n}\n\nexport interface RouterCosts {\n /** Cumulative cost per provider/model key. */\n byModel: Record<string, { cost: number; tokens: { input: number; output: number }; calls: number }>;\n /** Grand total. */\n totalCost: number;\n}\n\n/**\n * Default profiles used when none are provided. Kept inline so the router\n * is self-contained — callers can override with richer data from model-intelligence.\n */\nconst DEFAULT_PROFILES: ModelIntelligenceEntry[] = [\n { provider: 'anthropic', pattern: /claude-opus/i, family: 'Claude Opus', strengths: ['reasoning', 'planning'], bestFor: ['planning', 'security', 'debugging'], costTier: 'premium', speedTier: 'slow' },\n { provider: 'anthropic', pattern: /claude-sonnet/i, family: 'Claude Sonnet', strengths: ['coding', 'balanced'], bestFor: ['coding', 'general'], costTier: 'standard', speedTier: 'fast' },\n { provider: 'anthropic', pattern: /claude-haiku/i, family: 'Claude Haiku', strengths: ['speed'], bestFor: ['lightweight', 'docs'], avoidFor: ['planning'], costTier: 'budget', speedTier: 'fast' },\n { provider: 'openai', pattern: /gpt-5|o3|o4/i, family: 'GPT-5/o3/o4', strengths: ['reasoning', 'coding'], bestFor: ['planning', 'coding', 'debugging'], costTier: 'premium', speedTier: 'normal' },\n { provider: 'openai', pattern: /gpt-4/i, family: 'GPT-4', strengths: ['coding'], bestFor: ['coding', 'docs'], costTier: 'standard', speedTier: 'fast' },\n { provider: 'openai', pattern: /gpt-4o-mini/i, family: 'GPT-4o Mini', strengths: ['speed'], bestFor: ['lightweight', 'docs'], avoidFor: ['planning'], costTier: 'budget', speedTier: 'fast' },\n { provider: 'google', pattern: /gemini-(?:2\\.5|3)/i, family: 'Gemini 2.5/3', strengths: ['context', 'coding'], bestFor: ['coding', 'data'], costTier: 'standard', speedTier: 'normal' },\n { provider: 'google', pattern: /gemini.*flash/i, family: 'Gemini Flash', strengths: ['speed'], bestFor: ['lightweight', 'docs'], avoidFor: ['planning'], costTier: 'budget', speedTier: 'fast' },\n { provider: 'deepseek', pattern: /deepseek/i, family: 'DeepSeek', strengths: ['coding', 'cost-effective'], bestFor: ['coding', 'general'], costTier: 'standard', speedTier: 'normal' },\n];\n\n/** Map common task keywords to categories for model matching. */\nconst TASK_CATEGORIES: Record<string, string> = {\n plan: 'planning', architect: 'planning', design: 'planning', strategy: 'planning',\n security: 'security', vuln: 'security', exploit: 'security', auth: 'security',\n doc: 'docs', readme: 'docs', explain: 'docs', write: 'docs',\n test: 'testing', spec: 'testing', assert: 'testing', coverage: 'testing',\n refactor: 'refactoring', cleanup: 'refactoring', restructure: 'refactoring',\n bug: 'debugging', fix: 'debugging', debug: 'debugging', trace: 'debugging', crash: 'debugging',\n data: 'data', json: 'data', sql: 'data', query: 'data', analyze: 'data', parse: 'data',\n frontend: 'frontend', react: 'frontend', ui: 'frontend', css: 'frontend', component: 'frontend',\n backend: 'backend', api: 'backend', server: 'backend', endpoint: 'backend',\n review: 'review', audit: 'review', inspect: 'review',\n simple: 'lightweight', quick: 'lightweight', trivial: 'lightweight',\n};\n\nexport class ModelRouter {\n private profiles: ModelIntelligenceEntry[];\n private matrix: Record<string, ModelMatrixEntry>;\n private config: RouterConfig['config'];\n private costs: RouterCosts = { byModel: {}, totalCost: 0 };\n\n constructor(opts: RouterConfig) {\n this.profiles = opts.profiles ?? DEFAULT_PROFILES;\n this.matrix = opts.matrix ?? {};\n this.config = opts.config;\n }\n\n /** Look up the model matrix resolution for a role (role → phase → * → leader). */\n private resolveMatrix(role: string): ModelMatrixEntry | undefined {\n // Exact role match\n if (this.matrix[role]) return this.matrix[role];\n // Phase match\n const phase = this.roleToPhase(role);\n if (phase && this.matrix[phase]) return this.matrix[phase];\n // Wildcard\n if (this.matrix['*']) return this.matrix['*'];\n return undefined;\n }\n\n /** Simplified phase lookup for common roles. */\n private roleToPhase(role: string): string | undefined {\n const phaseMap: Record<string, string> = {\n planner: 'plan', architect: 'plan', 'refactor-planner': 'plan',\n executor: 'code', refactor: 'code', simplifier: 'code', migration: 'code',\n 'bug-hunter': 'code', debugger: 'code', tracer: 'code',\n test: 'code', e2e: 'code', performance: 'code', chaos: 'code',\n 'security-scanner': 'review', 'security-reviewer': 'review', 'code-reviewer': 'review',\n critic: 'review', accessibility: 'review', compliance: 'review',\n analyst: 'code', data: 'code', database: 'code',\n frontend: 'code', backend: 'code', api: 'code', auth: 'code',\n designer: 'code', document: 'code',\n researcher: 'plan', explore: 'plan', search: 'plan',\n };\n return phaseMap[role];\n }\n\n /**\n * Pick the best model for a task.\n *\n * Priority:\n * 1. User's /setmodel matrix entry for this role (explicit override)\n * 2. Best-matching model from intelligence profiles\n * 3. Leader model (fallback)\n */\n pickForTask(role: string, description: string): ModelPick {\n // 1. Check user matrix\n const matrixEntry = this.resolveMatrix(role);\n if (matrixEntry) {\n const provider = matrixEntry.provider ?? this.config.provider;\n return {\n provider,\n model: matrixEntry.model,\n reason: `matrix override for role ${role}`,\n fromMatrix: true,\n };\n }\n\n // 2. Auto-detect from task description + role\n const category = this.inferCategory(description, role);\n const best = this.findBestModel(category);\n if (best) {\n return { ...best, reason: `best-for ${category} (auto-detected)`, fromMatrix: false };\n }\n\n // 3. Leader fallback\n return {\n provider: this.config.provider,\n model: this.config.model,\n reason: 'leader fallback',\n fromMatrix: false,\n };\n }\n\n /** Infer task category from description keywords + role. */\n private inferCategory(description: string, role: string): string {\n const d = description.toLowerCase();\n for (const [keyword, category] of Object.entries(TASK_CATEGORIES)) {\n if (d.includes(keyword)) return category;\n }\n // Map role to category\n const roleMap: Record<string, string> = {\n 'security-scanner': 'security', 'security-reviewer': 'security',\n 'bug-hunter': 'debugging', debugger: 'debugging',\n planner: 'planning', architect: 'planning',\n 'refactor-planner': 'refactoring', refactor: 'refactoring',\n test: 'testing', e2e: 'testing',\n document: 'docs', simplifier: 'docs',\n 'code-reviewer': 'review', critic: 'review',\n 'frontend': 'frontend', 'backend': 'backend',\n };\n return roleMap[role] ?? 'general';\n }\n\n /** Find the best available model for a task category. */\n private findBestModel(category: string): { provider: string; model: string } | undefined {\n // Score each profile for this category\n const scored = this.profiles\n .filter((p) => this.hasKey(p.provider))\n .map((p) => {\n let score = 50;\n if (p.bestFor.includes(category)) score += 40;\n if (p.avoidFor?.includes(category)) score -= 50;\n if (category === 'lightweight' && p.costTier === 'budget') score += 20;\n if (category === 'planning' && p.costTier === 'premium') score += 15;\n if (category === 'planning' && p.speedTier === 'slow') score += 10; // slow = thorough\n return { profile: p, score };\n })\n .filter((s) => s.score > 0)\n .sort((a, b) => b.score - a.score);\n\n if (scored.length === 0) return undefined;\n\n // Guarded by scored.length === 0 check above — but use optional\n // chaining instead of `!` to satisfy the non-null assertion lint rule.\n const best = scored[0]?.profile;\n if (!best) return undefined;\n // Find the actual model id from the provider's configured models\n const models = this.getProviderModels(best.provider);\n const match = models.find((m) => best.pattern.test(m)) ?? models[0];\n if (!match) return undefined;\n\n return { provider: best.provider, model: match };\n }\n\n /** Check if a provider has an API key configured. */\n private hasKey(providerId: string): boolean {\n const pc = this.config.providers?.[providerId];\n if (!pc) return providerId === this.config.provider;\n if (typeof pc.apiKey === 'string' && pc.apiKey.length > 0) return true;\n if (Array.isArray(pc.apiKeys) && pc.apiKeys.some((k) => k?.apiKey)) return true;\n return false;\n }\n\n /** Get the configured model list for a provider. */\n private getProviderModels(providerId: string): string[] {\n const pc = this.config.providers?.[providerId];\n return pc?.models ?? [];\n }\n\n /** Record cost for a model. */\n recordCost(provider: string, model: string, cost: number, tokens?: { input: number; output: number }): void {\n const key = `${provider}/${model}`;\n const entry = this.costs.byModel[key] ?? { cost: 0, tokens: { input: 0, output: 0 }, calls: 0 };\n entry.cost += cost;\n if (tokens) {\n entry.tokens.input += tokens.input;\n entry.tokens.output += tokens.output;\n }\n entry.calls += 1;\n this.costs.byModel[key] = entry;\n this.costs.totalCost += cost;\n }\n\n /** Get cumulative costs. */\n getCosts(): RouterCosts {\n return { ...this.costs, byModel: { ...this.costs.byModel } };\n }\n\n /** Reset cost tracking. */\n resetCosts(): void {\n this.costs = { byModel: {}, totalCost: 0 };\n }\n\n /** List all available providers with their best model for each task category. */\n suggestMatrix(): Record<string, ModelPick> {\n const matrix: Record<string, ModelPick> = {};\n const roles = [\n 'security-scanner', 'bug-hunter', 'planner', 'architect',\n 'refactor-planner', 'test', 'document', 'code-reviewer',\n 'executor', 'debugger', 'analyst',\n ];\n\n for (const role of roles) {\n // Don't override explicit user matrix entries\n if (this.matrix[role]) continue;\n\n const pick = this.pickForTask(role, role);\n if (!pick.fromMatrix) {\n matrix[role] = pick;\n }\n }\n\n return matrix;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/utils/atomic-write.ts","../../src/utils/error.ts","../../src/utils/merge-models-payload.ts","../../src/models/models-registry.ts","../../src/types/mode.ts","../../src/models/mode-store.ts","../../src/utils/expect-defined.ts","../../src/utils/token-estimate.ts","../../src/types/blocks.ts","../../src/models/llm-selector.ts","../../src/models/codex-catalog.ts","../../src/models/provider-model-resolve.ts","../../src/models/model-intelligence.ts","../../src/models/model-router.ts"],"names":["path","stat","resolve","path2","fs2","fs3"],"mappings":"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","file":"index.js","sourcesContent":["import { randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\nexport interface AtomicWriteOptions {\n mode?: number | undefined;\n encoding?: BufferEncoding | undefined;\n}\n\nexport interface FileLockOptions {\n timeoutMs?: number | undefined;\n staleMs?: number | undefined;\n}\n\nexport async function atomicWrite(\n targetPath: string,\n content: string | Uint8Array,\n opts: AtomicWriteOptions = {},\n): Promise<void> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const tmp = path.join(dir, `.${path.basename(targetPath)}.${randomBytes(6).toString('hex')}.tmp`);\n\n // Write content to tmp first; 'wx' ensures exclusive creation (fails if\n // tmp already exists — extremely unlikely with 6-byte random suffix).\n try {\n if (typeof content === 'string') {\n await fs.writeFile(tmp, content, { flag: 'wx', encoding: opts.encoding ?? 'utf8' });\n } else {\n await fs.writeFile(tmp, content, { flag: 'wx' });\n }\n try {\n const fh = await fs.open(tmp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync best-effort\n }\n // Now safely read mode from target (if it exists) and apply to tmp before rename.\n // Prefer opts.mode for new files; for existing files preserve their mode.\n let mode: number | undefined;\n try {\n const stat = await fs.stat(targetPath);\n mode = stat.mode & 0o777;\n } catch {\n mode = opts.mode;\n }\n if (mode !== undefined) {\n await fs.chmod(tmp, mode);\n }\n await renameWithRetry(tmp, targetPath);\n } catch (err) {\n try {\n await fs.unlink(tmp);\n } catch {\n // ignore cleanup error\n }\n throw err;\n }\n}\n\nexport async function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\nexport async function withFileLock<T>(\n targetPath: string,\n fn: () => Promise<T>,\n opts: FileLockOptions = {},\n): Promise<T> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const lockPath = path.join(dir, `.${path.basename(targetPath)}.lock`);\n const timeoutMs = opts.timeoutMs ?? 5_000;\n const staleMs = opts.staleMs ?? 30_000;\n const started = Date.now();\n let handle: fs.FileHandle | undefined;\n\n for (;;) {\n try {\n handle = await fs.open(lockPath, 'wx');\n await handle.writeFile(`${process.pid}:${Date.now()}`);\n break;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n // ENOENT means the directory was deleted (e.g. by concurrent cleanup).\n // Recreate it and retry acquiring the lock.\n if (code === 'ENOENT') {\n await fs.mkdir(dir, { recursive: true });\n continue;\n }\n if (code !== 'EEXIST') throw err;\n try {\n const stat = await fs.stat(lockPath);\n if (Date.now() - stat.mtimeMs > staleMs) {\n await fs.unlink(lockPath);\n continue;\n }\n } catch {\n continue;\n }\n if (Date.now() - started >= timeoutMs) {\n throw new Error(`Timed out waiting for file lock: ${targetPath}`);\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n\n try {\n return await fn();\n } finally {\n try {\n await handle?.close();\n } catch {\n // ignore\n }\n try {\n await fs.unlink(lockPath);\n } catch {\n // ignore\n }\n }\n}\n\n// On Windows, fs.rename over an existing file can fail with EPERM/EBUSY/EACCES\n// when antivirus, file indexers, editor file watchers, or a concurrent writer\n// briefly hold a handle on the destination. These are transient — retry with a\n// short backoff before giving up. POSIX renames are atomic and won't hit this.\nconst TRANSIENT_RENAME_CODES = new Set(['EPERM', 'EBUSY', 'EACCES', 'ENOTEMPTY']);\n\nasync function renameWithRetry(from: string, to: string): Promise<void> {\n if (process.platform !== 'win32') {\n await fs.rename(from, to);\n return;\n }\n const delays = [10, 25, 60, 120, 250];\n let lastErr: unknown;\n for (let i = 0; i <= delays.length; i++) {\n try {\n await fs.rename(from, to);\n return;\n } catch (err) {\n lastErr = err;\n const code = (err as NodeJS.ErrnoException)?.code;\n if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {\n throw err;\n }\n await new Promise((resolve) => setTimeout(resolve, delays[i]));\n }\n }\n throw lastErr;\n}\n","/**\n * Converts an unknown error value to a human-readable string.\n * Used in 40+ files across the codebase to normalize error messaging.\n */\nexport function toErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","import type {\n ModelsDevModel,\n ModelsDevProvider,\n ModelsDevPayload,\n} from '../types/models-registry.js';\n\n/**\n * Deep-merge a curated `overlay` payload on top of a `base` payload (both in\n * the models.dev `api.json` shape). The overlay always wins: it can add\n * providers/models the base lacks and override fields the base gets wrong.\n *\n * Precedence rules:\n * - Provider present in both → scalar fields (`name`, `npm`, `api`, `env`,\n * `doc`) come from the overlay when set; `models` maps merge by model id.\n * - Provider only in the overlay → added wholesale.\n * - Model present in both → overlay model fields override base model fields\n * (`{ ...base, ...overlay }`), with the nested `limit` / `cost` /\n * `modalities` objects merged one level deeper so an overlay can fix just\n * `limit.context` without restating the rest of the model.\n * - Model only in the overlay → added.\n *\n * Pure: never mutates its inputs.\n */\nexport function mergeModelsPayload(\n base: ModelsDevPayload,\n overlay: ModelsDevPayload,\n): ModelsDevPayload {\n const out: ModelsDevPayload = {};\n for (const [id, provider] of Object.entries(base)) {\n out[id] = cloneProvider(provider);\n }\n for (const [id, ovProvider] of Object.entries(overlay)) {\n const existing = out[id];\n out[id] = existing ? mergeProvider(existing, ovProvider) : cloneProvider(ovProvider);\n }\n return out;\n}\n\nfunction mergeProvider(base: ModelsDevProvider, overlay: ModelsDevProvider): ModelsDevProvider {\n const models: Record<string, ModelsDevModel> = {};\n for (const [mid, m] of Object.entries(base.models ?? {})) {\n models[mid] = { ...m };\n }\n for (const [mid, ovModel] of Object.entries(overlay.models ?? {})) {\n const existing = models[mid];\n models[mid] = existing ? mergeModel(existing, ovModel) : { ...ovModel };\n }\n return {\n ...base,\n // Overlay scalar fields win when explicitly provided; otherwise keep base.\n ...stripUndefined({\n id: overlay.id,\n name: overlay.name,\n npm: overlay.npm,\n api: overlay.api,\n env: overlay.env,\n doc: overlay.doc,\n }),\n models,\n };\n}\n\nfunction mergeModel(base: ModelsDevModel, overlay: ModelsDevModel): ModelsDevModel {\n const merged: ModelsDevModel = { ...base, ...overlay };\n // One level deeper for the structured fields so a partial overlay (e.g. only\n // `limit.context`) doesn't blow away the base's other sub-fields.\n if (base.limit || overlay.limit) {\n merged.limit = { ...base.limit, ...overlay.limit };\n }\n if (base.cost || overlay.cost) {\n merged.cost = { ...base.cost, ...overlay.cost };\n }\n if (base.modalities || overlay.modalities) {\n merged.modalities = { ...base.modalities, ...overlay.modalities };\n }\n return merged;\n}\n\nfunction cloneProvider(p: ModelsDevProvider): ModelsDevProvider {\n const models: Record<string, ModelsDevModel> = {};\n for (const [mid, m] of Object.entries(p.models ?? {})) {\n models[mid] = { ...m };\n }\n return { ...p, models };\n}\n\n/** Drop keys whose value is `undefined` so they don't clobber base fields. */\nfunction stripUndefined<T extends Record<string, unknown>>(obj: T): Partial<T> {\n const out: Partial<T> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (v !== undefined) out[k as keyof T] = v as T[keyof T];\n }\n return out;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type {\n ModelsDevPayload,\n ModelsDevProvider,\n ModelsRegistry,\n ResolvedModel,\n ResolvedProvider,\n WireFamily,\n} from '../types/models-registry.js';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { mergeModelsPayload } from '../utils/merge-models-payload.js';\n\nconst DEFAULT_URL = 'https://models.dev/api.json';\n/** Env var to override the models.dev base URL (e.g. for self-hosted mirrors). */\nconst ENV_URL_KEY = 'WRONGSTACK_MODELS_DEV_URL';\nconst DEFAULT_TTL_SECONDS = 24 * 3600;\nconst DEFAULT_REFRESH_TIMEOUT_MS = 15_000;\n\ninterface CacheEnvelope {\n fetchedAt: string;\n url: string;\n payload: ModelsDevPayload;\n}\n\nexport interface DefaultModelsRegistryOptions {\n cacheFile: string;\n url?: string | undefined;\n ttlSeconds?: number | undefined;\n fetchImpl?: typeof fetch | undefined;\n /** Pre-seeded payload — useful for offline scenarios and tests. */\n seed?: ModelsDevPayload | undefined;\n /**\n * Maximum age in seconds for stale cache fallback when network fails.\n * Defaults to 7 days. Set to `Infinity` for full offline resilience\n * (risk: deprecated models, wrong pricing). Set to `0` to disable\n * stale fallback entirely.\n */\n maxStaleAgeSeconds?: number | undefined;\n /**\n * Timeout in milliseconds for the models.dev network fetch. When exceeded,\n * the fetch is aborted and cache/stale fallback is used instead.\n * Defaults to 15 seconds. Set to `0` to disable (infinite wait).\n */\n refreshTimeoutMs?: number | undefined;\n /**\n * Curated override payload deep-merged ON TOP of the models.dev base via\n * `mergeModelsPayload` — adds providers/models the base lacks and overrides\n * fields it gets wrong. Resolution order (first non-empty wins): this\n * in-memory `overlay` → `overlayUrl` (fetched, cached) → `overlayFile`\n * (bundled, read from disk). A missing/broken overlay degrades to `{}` and\n * never throws, so the base alone still works.\n */\n overlay?: ModelsDevPayload | undefined;\n /** GitHub-raw (or any) URL serving the curated overlay `providers.json`. */\n overlayUrl?: string | undefined;\n /** Path to the bundled overlay `providers.json` (offline floor). */\n overlayFile?: string | undefined;\n /** Cache file for the fetched `overlayUrl`. Defaults next to `cacheFile`. */\n overlayCacheFile?: string | undefined;\n}\n\n/**\n * The npm package each models.dev provider declares determines which wire\n * family WrongStack speaks. Anything not listed falls into `unsupported` and\n * can be enabled by registering a custom provider factory via a plugin.\n */\nconst FAMILY_BY_NPM: Record<string, WireFamily> = {\n '@ai-sdk/anthropic': 'anthropic',\n '@ai-sdk/google-vertex/anthropic': 'anthropic',\n '@ai-sdk/openai': 'openai',\n '@ai-sdk/openai-compatible': 'openai-compatible',\n '@ai-sdk/groq': 'openai-compatible',\n '@ai-sdk/xai': 'openai-compatible',\n '@ai-sdk/cerebras': 'openai-compatible',\n '@ai-sdk/togetherai': 'openai-compatible',\n '@ai-sdk/mistral': 'openai-compatible',\n '@ai-sdk/perplexity': 'openai-compatible',\n '@ai-sdk/deepinfra': 'openai-compatible',\n '@openrouter/ai-sdk-provider': 'openai-compatible',\n 'ai-gateway-provider': 'openai-compatible',\n '@ai-sdk/vercel': 'openai-compatible',\n '@ai-sdk/gateway': 'openai-compatible',\n '@aihubmix/ai-sdk-provider': 'openai-compatible',\n 'venice-ai-sdk-provider': 'openai-compatible',\n '@ai-sdk/google': 'google',\n};\n\nexport function classifyFamily(npm: string | undefined): WireFamily {\n if (!npm) return 'unsupported';\n return FAMILY_BY_NPM[npm] ?? 'unsupported';\n}\n\nexport class DefaultModelsRegistry implements ModelsRegistry {\n /** Merged (base + overlay) payload — what every reader sees. */\n private payload?: ModelsDevPayload | undefined;\n /** Memoised overlay payload (in-memory / fetched / file). */\n private overlayPayload?: ModelsDevPayload | undefined;\n private fetchedAt?: Date | undefined;\n private readonly cacheFile: string;\n private readonly url: string;\n private readonly ttlMs: number;\n private readonly fetchImpl: typeof fetch;\n private readonly seed?: ModelsDevPayload | undefined;\n private readonly maxStaleAgeMs: number;\n private readonly refreshTimeoutMs: number;\n private readonly overlay?: ModelsDevPayload | undefined;\n private readonly overlayUrl?: string | undefined;\n private readonly overlayFile?: string | undefined;\n private readonly overlayCacheFile?: string | undefined;\n\n constructor(opts: DefaultModelsRegistryOptions) {\n this.cacheFile = opts.cacheFile;\n this.url = opts.url ?? process.env[ENV_URL_KEY] ?? DEFAULT_URL;\n this.ttlMs = (opts.ttlSeconds ?? DEFAULT_TTL_SECONDS) * 1000;\n this.fetchImpl = opts.fetchImpl ?? fetch;\n this.seed = opts.seed;\n // Default max stale age: 7 days\n const maxStaleSeconds = opts.maxStaleAgeSeconds ?? 7 * 24 * 3600;\n this.maxStaleAgeMs = maxStaleSeconds * 1000;\n this.refreshTimeoutMs = opts.refreshTimeoutMs ?? DEFAULT_REFRESH_TIMEOUT_MS;\n this.overlay = opts.overlay;\n this.overlayUrl = opts.overlayUrl;\n this.overlayFile = opts.overlayFile;\n this.overlayCacheFile =\n opts.overlayCacheFile ??\n (opts.overlayUrl\n ? path.join(path.dirname(opts.cacheFile), 'models-overlay-cache.json')\n : undefined);\n }\n\n async load(opts: { force?: boolean | undefined } = {}): Promise<ModelsDevPayload> {\n if (this.payload && !opts.force) return this.payload;\n // A `seed` is treated as the complete, final payload — used for offline\n // scenarios and tests. It bypasses both the base fetch and the overlay.\n if (this.seed) {\n this.payload = this.seed;\n this.fetchedAt = new Date();\n return this.payload;\n }\n // Load the overlay first so base degradation can tell whether there is\n // actually curated data to serve when models.dev is unreachable.\n const overlay = await this.loadOverlay(opts);\n const base = await this.loadBase(opts, Object.keys(overlay).length > 0);\n this.payload = mergeModelsPayload(base, overlay);\n return this.payload;\n }\n\n /**\n * Load the models.dev base payload: fresh cache → network → stale cache.\n * On total failure, degrade to `{}` (so a non-empty overlay still drives\n * the catalog) rather than throwing — unless there's no curated overlay to\n * fall back on, in which case the original error propagates so pure-\n * models.dev setups still surface the problem.\n */\n private async loadBase(\n opts: { force?: boolean | undefined } = {},\n overlayAvailable = false,\n ): Promise<ModelsDevPayload> {\n if (!opts.force) {\n const cached = await this.readCacheAt(this.cacheFile);\n if (cached && this.isFresh(cached.fetchedAt)) {\n this.fetchedAt = new Date(cached.fetchedAt);\n return cached.payload;\n }\n }\n try {\n return await this.refreshBase();\n } catch (err) {\n // Network failed — fall back to stale cache if within maxStaleAgeMs.\n const cached = await this.readCacheAt(this.cacheFile);\n if (cached && this.isWithinMaxStaleAge(cached.fetchedAt)) {\n this.fetchedAt = new Date(cached.fetchedAt);\n const ageSeconds = Math.floor((Date.now() - this.fetchedAt.getTime()) / 1000);\n // eslint-disable-next-line no-console -- user-visible operator warning\n console.warn(\n `ModelsRegistry: models.dev unavailable (${toErrorMessage(err)}); ` +\n `using stale cache from ${formatAge(ageSeconds)} ago. Run \\`wstack models refresh\\` to retry.`,\n );\n return cached.payload;\n }\n if (overlayAvailable) {\n // eslint-disable-next-line no-console -- one-line operator warning\n console.warn(\n `ModelsRegistry: models.dev unavailable (${\n toErrorMessage(err)\n }); serving curated overlay only.`,\n );\n return {};\n }\n throw err;\n }\n }\n\n /** Fetch + cache the models.dev base. Throws on failure (used by `refresh`). */\n private async refreshBase(): Promise<ModelsDevPayload> {\n const controller = new AbortController();\n /* v8 ignore next -- timing: the abort callback only fires if the real fetch exceeds the timeout */\n const timeout = setTimeout(() => controller.abort(), this.refreshTimeoutMs);\n try {\n const res = await this.fetchImpl(this.url, {\n method: 'GET',\n headers: { accept: 'application/json' },\n signal: controller.signal,\n });\n clearTimeout(timeout);\n if (!res.ok) {\n throw new Error(`ModelsRegistry: HTTP ${res.status} fetching ${this.url}`);\n }\n const json = (await res.json()) as ModelsDevPayload;\n this.fetchedAt = new Date();\n const envelope: CacheEnvelope = {\n fetchedAt: this.fetchedAt.toISOString(),\n url: this.url,\n payload: json,\n };\n await atomicWrite(this.cacheFile, JSON.stringify(envelope));\n return json;\n } catch (err) {\n clearTimeout(timeout);\n if (err instanceof Error && err.name === 'AbortError') {\n throw new Error(`ModelsRegistry: fetch timed out after ${this.refreshTimeoutMs}ms`);\n }\n throw err;\n }\n }\n\n /**\n * Resolve the curated overlay, memoised. Order: in-memory `overlay` →\n * fetched `overlayUrl` (cached, same TTL/stale rules) → `overlayFile` on\n * disk. Never throws — a missing/broken overlay yields `{}`.\n */\n private async loadOverlay(opts: { force?: boolean | undefined } = {}): Promise<ModelsDevPayload> {\n /* v8 ignore next -- unreachable: load() caches `payload` and short-circuits before re-calling loadOverlay non-forced */\n if (this.overlayPayload && !opts.force) return this.overlayPayload;\n if (hasEntries(this.overlay)) {\n this.overlayPayload = this.overlay;\n return this.overlayPayload;\n }\n const fetched = await this.loadOverlayFromUrl(opts);\n if (hasEntries(fetched)) {\n this.overlayPayload = fetched;\n return fetched;\n }\n const fromFile = await this.readOverlayFile();\n this.overlayPayload = fromFile ?? {};\n return this.overlayPayload;\n }\n\n private async loadOverlayFromUrl(opts: { force?: boolean | undefined }): Promise<\n ModelsDevPayload | undefined\n > {\n if (!this.overlayUrl || !this.overlayCacheFile) return undefined;\n if (!opts.force) {\n const cached = await this.readCacheAt(this.overlayCacheFile);\n if (cached && this.isFresh(cached.fetchedAt)) return cached.payload;\n }\n try {\n const res = await this.fetchImpl(this.overlayUrl, {\n method: 'GET',\n headers: { accept: 'application/json' },\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const json = (await res.json()) as ModelsDevPayload;\n const envelope: CacheEnvelope = {\n fetchedAt: new Date().toISOString(),\n url: this.overlayUrl,\n payload: json,\n };\n /* v8 ignore next -- best-effort: overlay-cache write failure is intentionally ignored */\n await atomicWrite(this.overlayCacheFile, JSON.stringify(envelope)).catch(() => {});\n return json;\n } catch {\n // Network/parse failure — fall back to stale overlay cache, then the\n // bundled file (handled by the caller).\n const cached = await this.readCacheAt(this.overlayCacheFile);\n if (cached && this.isWithinMaxStaleAge(cached.fetchedAt)) {\n const ageSeconds = Math.floor((Date.now() - new Date(cached.fetchedAt).getTime()) / 1000);\n // eslint-disable-next-line no-console -- operator-visible warning\n console.warn(\n `ModelsRegistry: overlay unavailable; using stale overlay from ${formatAge(ageSeconds)} ago.`,\n );\n return cached.payload;\n }\n return undefined;\n }\n }\n\n private async readOverlayFile(): Promise<ModelsDevPayload | undefined> {\n if (!this.overlayFile) return undefined;\n try {\n const raw = await fs.readFile(this.overlayFile, 'utf8');\n return JSON.parse(raw) as ModelsDevPayload;\n } catch {\n return undefined;\n }\n }\n\n async refresh(): Promise<ModelsDevPayload> {\n // Refresh the models.dev base (throws on failure so `wstack models refresh`\n // can report it), then recompute the merged payload with a fresh overlay.\n const base = await this.refreshBase();\n const overlay = await this.loadOverlay({ force: true });\n this.payload = mergeModelsPayload(base, overlay);\n return this.payload;\n }\n\n async listProviders(): Promise<ResolvedProvider[]> {\n const payload = await this.load();\n return Object.values(payload).map((p) => this.resolveProvider(p));\n }\n\n async getProvider(id: string): Promise<ResolvedProvider | undefined> {\n const payload = await this.load();\n const p = payload[id];\n return p ? this.resolveProvider(p) : undefined;\n }\n\n async getModel(providerId: string, modelId: string): Promise<ResolvedModel | undefined> {\n const provider = await this.getProvider(providerId);\n if (!provider) return undefined;\n const model = provider.models.find((m) => m.id === modelId);\n if (!model) return undefined;\n return {\n providerId,\n modelId,\n capabilities: {\n tools: model.tool_call ?? false,\n vision: Boolean(model.modalities?.input?.includes('image')),\n reasoning: model.reasoning ?? model.reasoningConfig !== undefined,\n maxContext: model.limit?.context ?? 0,\n maxOutput: model.limit?.output,\n knowledge: model.knowledge,\n reasoningConfig: model.reasoningConfig,\n },\n cost: model.cost,\n };\n }\n\n async suggestModel(providerId: string): Promise<string | undefined> {\n const provider = await this.getProvider(providerId);\n if (!provider || provider.models.length === 0) return undefined;\n const ranked = [...provider.models].sort((a, b) => {\n const at = a.release_date ?? a.last_updated ?? '';\n const bt = b.release_date ?? b.last_updated ?? '';\n return bt.localeCompare(at);\n });\n return ranked[0]?.id;\n }\n\n async ageSeconds(): Promise<number> {\n if (!this.fetchedAt) {\n const cached = await this.readCacheAt(this.cacheFile);\n if (!cached) return Number.POSITIVE_INFINITY;\n return (Date.now() - new Date(cached.fetchedAt).getTime()) / 1000;\n }\n return (Date.now() - this.fetchedAt.getTime()) / 1000;\n }\n\n private resolveProvider(p: ModelsDevProvider): ResolvedProvider {\n return {\n id: p.id,\n name: p.name,\n family: classifyFamily(p.npm),\n apiBase: p.api,\n envVars: p.env ?? [],\n doc: p.doc,\n models: Object.values(p.models ?? {}),\n npm: p.npm,\n };\n }\n\n private isFresh(fetchedAtIso: string): boolean {\n return Date.now() - new Date(fetchedAtIso).getTime() < this.ttlMs;\n }\n\n private isWithinMaxStaleAge(fetchedAtIso: string): boolean {\n return Date.now() - new Date(fetchedAtIso).getTime() < this.maxStaleAgeMs;\n }\n\n private async readCacheAt(file: string): Promise<CacheEnvelope | undefined> {\n try {\n const raw = await fs.readFile(file, 'utf8');\n return JSON.parse(raw) as CacheEnvelope;\n } catch {\n return undefined;\n }\n }\n\n /** Used by `wstack models refresh` to expose where the cache lives. */\n cacheLocation(): string {\n return path.resolve(this.cacheFile);\n }\n}\n\n/** Render a seconds-duration as a human-friendly \"Xh Ym\" or \"Xd\" string. */\nfunction formatAge(seconds: number): string {\n if (seconds < 60) return '<1m';\n if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;\n if (seconds < 86400) {\n const h = Math.floor(seconds / 3600);\n const m = Math.floor((seconds % 3600) / 60);\n return m > 0 ? `${h}h ${m}m` : `${h}h`;\n }\n return `${Math.floor(seconds / 86400)}d`;\n}\n\nfunction hasEntries(payload: ModelsDevPayload | undefined): payload is ModelsDevPayload {\n return payload !== undefined && Object.keys(payload).length > 0;\n}\n","export interface Mode {\n id: string;\n name: string;\n description: string;\n /** Additional prompt text injected into system prompt when mode is active */\n prompt: string;\n /** Tags for tool_search filtering */\n tags?: string[] | undefined;\n /** Tools that should be prioritized/highlighted when this mode is active */\n toolPreferences?: string[] | undefined;\n /**\n * Skill names that are particularly relevant to this mode. The system\n * prompt builder appends a \"Suggested skills\" note so the model knows\n * which domain knowledge to leverage first. Skill must exist in the\n * loaded skill set to appear.\n */\n suggestedSkills?: string[] | undefined;\n}\n\nexport interface ModeManifest {\n modes: Mode[];\n defaultMode?: string | undefined;\n}\n\nexport interface ModeStore {\n getActiveMode(): Promise<Mode | null>;\n setActiveMode(modeId: string | null): Promise<void>;\n listModes(): Promise<Mode[]>;\n getMode(modeId: string): Promise<Mode | null>;\n}\n\nexport interface ModeConfig {\n directory: string;\n}\n\nexport const DEFAULT_MODES: Mode[] = [\n {\n id: 'default',\n name: 'Default',\n description: 'General-purpose coding assistant',\n prompt: '',\n tags: ['general'],\n },\n {\n id: 'code-reviewer',\n name: 'Code Reviewer',\n description: 'Focus on code quality, best practices, and potential bugs',\n prompt: `## Code Reviewer Mode\n\nWhen reviewing code:\n- Look for potential bugs, race conditions, and edge cases\n- Check for security vulnerabilities (SQL injection, XSS, CSRF, etc.)\n- Evaluate error handling completeness\n- Assess code readability and maintainability\n- Check for performance anti-patterns\n- Verify test coverage for critical paths\n- Ensure naming conventions are followed`,\n tags: ['review', 'quality', 'security'],\n toolPreferences: ['read', 'grep', 'git', 'diff', 'test'],\n suggestedSkills: ['bug-hunter', 'security-scanner', 'typescript-strict', 'testing'],\n },\n {\n id: 'code-auditor',\n name: 'Code Auditor',\n description: 'Security-focused code analysis',\n prompt: `## Code Auditor Mode\n\nWhen auditing code for security:\n- Identify injection vulnerabilities (SQL, Command, XSS, LDAP)\n- Check authentication and authorization patterns\n- Look for sensitive data exposure (secrets, PII in logs)\n- Verify cryptographic implementations\n- Check for insecure dependencies or configurations\n- Assess input validation and output encoding\n- Look for timing attacks and information leakage`,\n tags: ['security', 'audit', 'compliance'],\n toolPreferences: ['grep', 'read', 'audit', 'bash'],\n suggestedSkills: ['security-scanner', 'bug-hunter', 'audit-log'],\n },\n {\n id: 'architect',\n name: 'Software Architect',\n description: 'Design patterns, scalability, and system design',\n prompt: `## Architect Mode\n\nWhen designing or reviewing architecture:\n- Evaluate scalability and future growth\n- Check for appropriate design patterns\n- Assess coupling and cohesion\n- Look for SOLID principle violations\n- Evaluate data modeling decisions\n- Check for eventual consistency issues\n- Assess API design and contract stability\n- Consider operational aspects (monitoring, logging, deployment)`,\n tags: ['architecture', 'design', 'scalability'],\n toolPreferences: ['read', 'glob', 'tree', 'diff'],\n suggestedSkills: ['api-design', 'refactor-planner', 'node-modern', 'docker-deploy'],\n },\n {\n id: 'debugger',\n name: 'Debugger',\n description: 'Root cause analysis and error investigation',\n prompt: `## Debugger Mode\n\nWhen investigating bugs:\n- Reproduce the issue with minimal steps\n- Check error messages and stack traces thoroughly\n- Look for related logs and historical context\n- Verify assumptions about data flow\n- Check for race conditions in async code\n- Validate environment and configuration\n- Use binary search to isolate the root cause\n- Verify fixes with tests before considering done`,\n tags: ['debug', 'investigation', 'error-resolution'],\n toolPreferences: ['read', 'grep', 'bash', 'logs', 'test'],\n suggestedSkills: ['bug-hunter', 'audit-log', 'observability'],\n },\n {\n id: 'tester',\n name: 'QA Engineer',\n description: 'Test coverage, edge cases, and quality assurance',\n prompt: `## Tester Mode\n\nWhen testing or writing tests:\n- Cover happy path and error paths equally\n- Think about edge cases and boundary conditions\n- Check for missing null/undefined handling tests\n- Verify error messages are tested\n- Look for race condition tests in async code\n- Assess mutation testing opportunities\n- Check for integration test gaps\n- Verify test isolation and cleanup`,\n tags: ['testing', 'qa', 'quality'],\n toolPreferences: ['read', 'grep', 'test', 'bash'],\n suggestedSkills: ['testing', 'bug-hunter', 'typescript-strict'],\n },\n {\n id: 'devops',\n name: 'DevOps Engineer',\n description: 'Infrastructure, deployment, and operations',\n prompt: `## DevOps Mode\n\nWhen working on infrastructure:\n- Check for containerization and deployment readiness\n- Verify CI/CD pipeline configurations\n- Assess monitoring and alerting setup\n- Look for health check endpoints\n- Check for graceful shutdown handling\n- Verify backup and disaster recovery plans\n- Assess secrets management\n- Check for resource limits and quotas`,\n tags: ['devops', 'infrastructure', 'operations'],\n toolPreferences: ['read', 'bash', 'grep', 'logs', 'git'],\n suggestedSkills: ['docker-deploy', 'observability', 'security-scanner'],\n },\n {\n id: 'refactorer',\n name: 'Refactorer',\n description: 'Code improvement and modernization',\n prompt: `## Refactorer Mode\n\nWhen refactoring code:\n- Maintain existing behavior — tests must pass before and after\n- Make one change at a time, verify after each\n- Prefer small, focused commits\n- Preserve API contracts unless explicitly changing\n- Remove dead code and comments\n- Improve naming as you go\n- Don't mix formatting changes with logic changes\n- Keep performance in mind — don't regress`,\n tags: ['refactor', 'modernization', 'improvement'],\n toolPreferences: ['read', 'edit', 'test', 'git', 'grep'],\n suggestedSkills: ['refactor-planner', 'typescript-strict', 'node-modern', 'testing'],\n },\n {\n id: 'brief',\n name: 'Brief',\n description: 'Fast, no-nonsense — get to the point',\n prompt: `## Brief Mode\n\nYou are WrongStack, a fast, no-nonsense AI coding agent.\nGet to the point — read files, run commands, make changes.\n\n### Operating rules\n1. **Read first.** Inspect relevant files before touching anything.\n2. **Edit surgically.** Use edit tool for existing files, write only for new ones.\n3. **One sentence before action.** State what you're doing, then do it.\n4. **Say what happened.** After tool calls, one line: success, failure, or what's next.\n5. **Be honest.** Admit when you don't know or something failed. No filler.\n6. **Keep moving.** Task done? Stop. More work needed? State it and continue.\n\n### Decision rules\n- **Ambiguous task?** Ask. One question, get clarity, proceed.\n- **Clear task, unknown approach?** Pick one reasonable path, execute, report.\n- **Tool fails?** Retry once with adjusted params, then report.\n\n### Output style\n- Prose paragraphs (no bullet points unless unavoidable)\n- Code blocks for code, backticks for paths/commands\n- One-liner sufficient? One liner.\n- Max 3 sentences per paragraph.`,\n tags: ['fast', 'concise', 'direct'],\n toolPreferences: ['read', 'edit', 'bash'],\n suggestedSkills: [],\n },\n {\n id: 'teach',\n name: 'Teach',\n description: 'Mentor mode — explains why, not just what',\n prompt: `## Teach Mode\n\nYou are WrongStack, an expert AI coding mentor.\n\nYou operate inside the user's terminal with full access to their codebase. You help developers learn and understand — not just execute tasks, but build mental models.\n\n### Teaching philosophy\n\n1. **Explain the why.** When you make a change, explain why it works that way — not just what you did.\n2. **Build mental models.** Use analogies, highlight patterns, connect new concepts to things the user already knows.\n3. **Read before teaching.** Always inspect relevant files so your explanations are accurate and specific to the actual code.\n4. **Surgical edits with context.** When editing code, explain the approach before doing it, and what trade-offs were considered.\n5. **Be thorough but not verbose.** A 2-paragraph explanation beats a 5-paragraph one. Depth without padding.\n6. **Admit knowledge gaps.** If you're unsure, say so. Speculating teaches bad patterns.\n\n### Teaching style\n\n- **Before action:** Briefly explain what you're going to do and why.\n- **After action:** Summarize what happened and what the user should take away from this.\n- **With code:** Show concrete examples, explain syntax choices, point out gotchas.\n- **With errors:** Explain why the error occurred, what it's actually complaining about, and how to avoid it in the future.\n- **General principles:** Offer them when the user's question suggests a deeper concept they'd benefit from understanding.\n\n### Decision heuristics\n\n- **Task is ambiguous?** Ask — but frame the question as \"what would you like to learn from this?\"\n- **Task is clear, approach is unknown?** Execute, then teach the approach as you go.\n- **Tool fails?** Explain what failed, why it failed, and how to avoid the failure.\n- **User asks \"how do I...?\"** Don't just give the answer — explain the underlying mechanism.\n- **Context window filling up?** Compact, but summarize what was lost so the teaching continuity isn't broken.\n\n### Output format\n\n- Use headings to structure multi-concept explanations.\n- Code blocks with brief annotations for code examples.\n- **Bold** key terms and concepts worth remembering.\n- Callouts like \"Key takeaway:\" or \"Pattern:\" to anchor learning.\n- Max 3 sentences per paragraph — readability over completeness.\n\n### Don'ts\n\n- Don't lecture condescendingly — the user is a developer, not a beginner.\n- Don't pad explanations with obvious things.\n- Don't skip the \"why\" — even quick tasks deserve one sentence of context.\n- Don't just say \"do X\" — say \"do X because Y.\"\n- Don't leave the user hanging after a complex operation — explain what just happened.\n\n### Core principles\n\nYou follow these principles, but always with explanation:\n- Read before write\n- Surgical edits over rewrites\n- Show your work (explain your reasoning, not just mechanical steps)\n- Be honest about limits\n- Format for scanability\n- Recover explicitly from failures\n\nRemember: your job is to make the user a better developer, not just to complete tasks faster.`,\n tags: ['teaching', 'mentor', 'learning'],\n toolPreferences: ['read', 'edit', 'explain'],\n suggestedSkills: ['prompt-engineering', 'skill-creator', 'node-modern', 'typescript-strict'],\n },\n {\n id: 'research-web',\n name: 'Research Web',\n description: 'Current-data research — search web, verify, inject findings into context',\n prompt: `## Research Web Mode\n\nYou are in research mode. Your role: find, verify, and incorporate\ncurrent web data. Your training data is stale — every factual claim\nabout version numbers, API surfaces, package status, or ecosystem\nchanges must be verified against live sources.\n\n### When to research\n- The user asks \"is this still the case?\", \"what's current?\", \"latest version?\"\n- You're about to claim a version number, deprecation, or API change\n- You're comparing tools, packages, or approaches released in the last 12 months\n- You realize your knowledge may be >6 months old on a fast-moving topic\n\n### Research methodology\n1. **Search first, fetch selectively.** Use web_search with 5-8 results for\n broad queries. Then web_fetch the 1-2 most authoritative results for detail.\n Don't fetch every result — you'll burn tokens on noise.\n2. **Cross-reference.** One source is a data point. Two sources that agree\n is a signal. Three is confirmation. Flag single-source claims as tentative.\n3. **Cite sources.** Every factual claim from web data must include where it\n came from: domain name, and date if visible on the page.\n4. **Know when to stop.** 2-3 searches + 1-2 fetches is usually sufficient.\n If you're on your 5th search without a clear answer, pause and tell the user\n what you've found and what's still unclear — let them decide to dig deeper.\n5. **Inject findings for reuse.** After gathering current data, use\n context_manager with add_note to inject a structured \"Research Findings\"\n block into the conversation. Future turns see this and don't re-search.\n\n### Self-injection pattern\nWhen you discover current data mid-research, inject it so subsequent turns\nbenefit without re-searching:\n\nweb_search(\"Next.js middleware breaking changes 2025\")\n → Surfaced: Next.js 15.2 changed middleware runtime from edge to node\nweb_fetch(\"https://nextjs.org/docs/messages/middleware-upgrade-guide\")\n → Confirmed: middleware now runs on Node.js runtime by default\ncontext_manager: add_note(\n \"## Research: Next.js middleware\n - Next.js 15.2: middleware defaults to Node.js runtime (was edge)\n - Breaking: edge-only APIs (crypto.subtle, WebSocket) no longer available\n - Migration: use node:* equivalents or set runtime: 'edge' explicitly\n - Source: nextjs.org/docs/messages/middleware-upgrade-guide\"\n)\n\nThe add_note persists in conversation — you won't re-search on the next turn.\n\n### Anti-patterns\n- Don't research things already in the conversation context (including\n earlier add_note blocks you injected)\n- Don't treat a single web search result as ground truth — cross-reference\n- Don't inject raw JSON or search result dumps via add_note — summarize\n- Don't research while the user is waiting for a quick code edit — toggle\n research-web mode only during analysis/discussion phases\n- Don't research-loop: 5+ searches on one topic → stop and ask the user\n\n### Exiting research mode\nWhen the user no longer needs current-data research, suggest switching back\nto the previous mode. You stay in research mode until explicitly told to\nswitch — but don't force web searches on every turn. The methodology rules\nabove already gate when to actually search.\n\nWhen you're done with research: suggest the user run \\`/mode default\\` or\ntheir previous mode.`,\n tags: ['research', 'web', 'current-data', 'up-to-date'],\n toolPreferences: ['web_search', 'web_fetch', 'search', 'fetch', 'context_manager'],\n suggestedSkills: ['research-web', 'tech-stack', 'node-modern', 'security-scanner', 'react-modern'],\n },\n];\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite } from '../utils/atomic-write.js';\nimport type { Mode, ModeConfig, ModeManifest, ModeStore } from '../types/mode.js';\nimport { DEFAULT_MODES } from '../types/mode.js';\n\nexport class DefaultModeStore implements ModeStore {\n private activeModeId: string | null = null;\n private modes: Mode[];\n private configDir: string;\n\n constructor(config: ModeConfig) {\n this.configDir = config.directory;\n this.modes = [...DEFAULT_MODES];\n }\n\n async getActiveMode(): Promise<Mode | null> {\n if (!this.activeModeId) {\n await this.loadActiveMode();\n }\n if (!this.activeModeId) return null;\n return this.modes.find((m) => m.id === this.activeModeId) ?? null;\n }\n\n async setActiveMode(modeId: string | null): Promise<void> {\n this.activeModeId = modeId;\n await this.saveActiveMode();\n }\n\n async listModes(): Promise<Mode[]> {\n return [...this.modes];\n }\n\n async getMode(modeId: string): Promise<Mode | null> {\n return this.modes.find((m) => m.id === modeId) ?? null;\n }\n\n async addMode(mode: Mode): Promise<void> {\n const idx = this.modes.findIndex((m) => m.id === mode.id);\n if (idx >= 0) {\n this.modes[idx] = mode;\n } else {\n this.modes.push(mode);\n }\n }\n\n async removeMode(modeId: string): Promise<void> {\n const builtIn = DEFAULT_MODES.find((m) => m.id === modeId);\n if (builtIn) {\n throw new Error(`Cannot remove built-in mode \"${modeId}\"`);\n }\n this.modes = this.modes.filter((m) => m.id !== modeId);\n if (this.activeModeId === modeId) {\n this.activeModeId = null;\n await this.saveActiveMode();\n }\n }\n\n private async loadActiveMode(): Promise<void> {\n try {\n const configPath = path.join(this.configDir, 'mode.json');\n const content = await fs.readFile(configPath, 'utf8');\n const data = JSON.parse(content);\n this.activeModeId = data.activeMode ?? null;\n } catch {\n this.activeModeId = 'default';\n }\n }\n\n private async saveActiveMode(): Promise<void> {\n try {\n await fs.mkdir(this.configDir, { recursive: true });\n const configPath = path.join(this.configDir, 'mode.json');\n // atomicWrite: torn write would leave mode.json malformed and the\n // next load would silently reset to \"default\".\n await atomicWrite(\n configPath,\n JSON.stringify({ activeMode: this.activeModeId }, null, 2),\n );\n } catch {\n // ignore save errors\n }\n }\n}\n\nexport interface ModeLoaderOptions {\n projectModesDir?: string | undefined;\n userModesDir?: string | undefined;\n}\n\nexport async function loadProjectModes(modesDir: string): Promise<Mode[]> {\n const modes: Mode[] = [];\n try {\n const entries = await fs.readdir(modesDir);\n for (const entry of entries) {\n if (!entry.endsWith('.md') && !entry.endsWith('.txt')) continue;\n const filePath = path.join(modesDir, entry);\n const stat = await fs.stat(filePath);\n if (!stat.isFile()) continue;\n const content = await fs.readFile(filePath, 'utf8');\n const id = path.basename(entry, path.extname(entry));\n modes.push({\n id,\n name: id.replace(/[-_]/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase()),\n description: content.split('\\n')[0] ?? id,\n prompt: content,\n tags: ['project'],\n });\n }\n } catch {\n // no project modes\n }\n return modes;\n}\n\nexport async function loadUserModes(modesDir: string): Promise<Mode[]> {\n const modes: Mode[] = [];\n try {\n const manifestPath = path.join(modesDir, 'modes.json');\n const content = await fs.readFile(manifestPath, 'utf8');\n const manifest: ModeManifest = JSON.parse(content);\n for (const mode of manifest.modes) {\n modes.push(mode);\n }\n } catch {\n // no user modes\n }\n return modes;\n}\n","/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n","import type { Message } from '../types/messages.js';\nimport { compactToolDefinitionForWire } from './tool-wire-compact.js';\n\n/**\n * Shared token estimation with JSON.stringify caching.\n * Avoids repeated stringification of tool input objects.\n *\n * ## Calibration\n *\n * `estimateRequestTokens` uses a fixed 3.5 chars/token heuristic — a\n * conservative overestimate that prevents underestimation but reduces\n * accuracy. After each API call, call `recordActualUsage()` with the\n * real `usage.input` from the provider response. The module maintains a\n * rolling average of `actual / estimated` ratio (EWM, α=0.3) and\n * applies it to subsequent calls via `estimateRequestTokensCalibrated`.\n *\n * Calibration is per-module (shared across all callers), which is\n * sufficient: the chars/token ratio is a property of the tokenizer,\n * not the model. Uncalibrated calls (before any samples, or when\n * `recordActualUsage` is not called) fall back to the uncalibrated\n * estimate so nothing breaks.\n */\n\nconst RoughTokenEstimate = (text: string, charsPerToken = 3.5): number =>\n Math.max(1, Math.ceil(text.length / charsPerToken));\n\n/** Calibration state: actual/estimated ratio via exponential weighted moving average. */\ninterface CalState {\n ratio: number; // current calibration multiplier (actual / estimated)\n count: number; // number of samples recorded\n prevEst: number; // estimated tokens from the most recent estimateRequestTokens call\n}\n\n/** EWM α — higher = faster adaptation, more volatile. */\nconst CAL_ALPHA = 0.3;\n\n/**\n * Calibration is keyed so that, in a multi-agent / model-switching process,\n * each (provider, model) tokenizer gets its own ratio instead of all of them\n * collapsing onto one shared number. Callers that don't pass a key use the\n * shared `__global__` bucket — that preserves the original single-session\n * behavior and keeps all existing call sites working unchanged.\n */\nconst CALIBRATION_GLOBAL_KEY = '__global__';\nconst _cals = new Map<string, CalState>();\n\nfunction calState(key: string): CalState {\n let state = _cals.get(key);\n if (!state) {\n state = { ratio: 1.0, count: 0, prevEst: 0 };\n _cals.set(key, state);\n }\n return state;\n}\n\nconst MIN_SAMPLES_FOR_CALIBRATION = 3;\n\n/**\n * Fallback chars/token ratios per model family for providers that don't return\n * usage data. Used when `recordActualUsage` receives zero/negative tokens and\n * we have enough samples to trust the fallback. Keys are lowercase prefixes.\n */\nconst MODEL_FAMILY_RATIO: Record<string, number> = {\n // Anthropic: ~3.8-4.0 chars/token depending on model\n claude: 3.8,\n // OpenAI: ~4.0 chars/token\n 'gpt-4': 4.0,\n 'gpt-3.5': 4.0,\n // Google: ~3.5 chars/token\n gemini: 3.5,\n // DeepSeek: ~3.5 chars/token\n deepseek: 3.5,\n};\n\n/**\n * Cache of computed estimates keyed by the stringified input — not the\n * input object itself. Previously the cache was keyed by the input object\n * via WeakMap, but JSON.stringify() produces a new object reference each\n * call so the cache never hit. Now we use a Map with string keys so that\n * repeated stringifications of the same structure share a single entry.\n */\nconst ESTIMATE_CACHE = new Map<string, number>();\n/** Insertion-order queue for O(1) LRU eviction: shift from front on overcapacity. */\nconst _estimateCacheOrder: string[] = [];\n\nconst ESTIMATE_CACHE_MAX_SIZE = 50_000;\n\nfunction getCachedEstimate(key: string, compute: (key: string) => number): number {\n const existing = ESTIMATE_CACHE.get(key);\n if (existing !== undefined) return existing;\n if (ESTIMATE_CACHE.size >= ESTIMATE_CACHE_MAX_SIZE) {\n // Evict oldest half — O(1) per eviction (array shift + Map.delete) instead\n // of O(n) iteration over all 50 000 keys in the Map.\n while (ESTIMATE_CACHE.size > Math.floor(ESTIMATE_CACHE_MAX_SIZE / 2)) {\n const oldest = _estimateCacheOrder.shift();\n if (oldest !== undefined) ESTIMATE_CACHE.delete(oldest);\n }\n }\n const estimate = compute(key);\n ESTIMATE_CACHE.set(key, estimate);\n _estimateCacheOrder.push(key);\n return estimate;\n}\n\n/**\n * Estimate tokens for a tool_use block input.\n * Caches the stringified result keyed by the stable string representation\n * to avoid repeated JSON.stringify calls during context window checks.\n */\nexport function estimateToolInputTokens(input: unknown): number {\n if (typeof input === 'string') return RoughTokenEstimate(input);\n if (input === null || typeof input !== 'object') {\n return RoughTokenEstimate(String(input));\n }\n // JSON.stringify is called once to form the cache key; RoughTokenEstimate\n // is deferred only on cache miss (compute callback), not wrapped unnecessarily.\n return getCachedEstimate(JSON.stringify(input), (key) => RoughTokenEstimate(key));\n}\n\n/**\n * Estimate tokens for a tool_result content.\n */\nexport function estimateToolResultTokens(content: string | unknown): number {\n if (typeof content === 'string') return RoughTokenEstimate(content);\n return getCachedEstimate(JSON.stringify(content), (key) => RoughTokenEstimate(key));\n}\n\n/**\n * Estimate tokens for a text block.\n */\nexport function estimateTextTokens(text: string): number {\n return RoughTokenEstimate(text);\n}\n\n/**\n * Compute and cache the token estimate for a single message. This is the\n * canonical per-message estimator — called once by ConversationState on\n * append/replace so the O(n·m) content-block walk happens at mutation time,\n * not on every context-pressure check.\n */\nexport function computeMessageTokens(msg: Message): number {\n if (typeof msg.content === 'string') return estimateTextTokens(msg.content);\n let total = 0;\n for (const b of msg.content) {\n if (b.type === 'text') total += estimateTextTokens(b.text);\n else if (b.type === 'tool_use') total += estimateToolInputTokens(b.input);\n else if (b.type === 'tool_result') total += estimateToolResultTokens(b.content);\n else total += RoughTokenEstimate(JSON.stringify(b));\n }\n return total;\n}\n\n/**\n * Estimate tokens for an array of messages (text + tool I/O), using the shared\n * 3.5 chars/token basis. This is the single canonical message-array estimator —\n * compactors, the context_manager tool, and the `/context` display all route\n * through it so the number a user sees matches the number compaction decides on.\n *\n * When a message carries a pre-computed `_estTokens` field (set by\n * ConversationState on append/replace), it is used directly instead of\n * re-walking the content blocks — turning the O(n·m) scan into an O(n)\n * sum for fully-cached arrays.\n */\nexport function estimateMessageTokens(messages: readonly Message[]): number {\n let total = 0;\n for (const m of messages) {\n if (typeof m._estTokens === 'number' && m._estTokens > 0) {\n total += m._estTokens;\n continue;\n }\n total += computeMessageTokens(m);\n }\n return total;\n}\n\n/**\n * Rough estimate of tokens in a tool definition (name + description + schema).\n * Accounts for the JSON-serialized inputSchema which is sent to the API\n * but NOT included in roughEstimate(content).\n */\nexport function estimateToolDefTokens(tool: {\n name: string;\n description?: string | undefined;\n inputSchema: unknown;\n}): number {\n // Fast path: pre-computed by ToolRegistry at registration time.\n const cached = (tool as { _estDefTokens?: number | undefined })._estDefTokens;\n if (typeof cached === 'number' && cached > 0) return cached;\n\n const compact = compactToolDefinitionForWire(tool);\n return (\n RoughTokenEstimate(tool.name) +\n RoughTokenEstimate(compact.description) +\n RoughTokenEstimate(JSON.stringify(compact.inputSchema))\n );\n}\n\n/**\n * Estimate the total API request token count: system prompt + tool definitions\n * + conversation messages. Use this for context-window bar calculations\n * instead of roughEstimate (which only counts messages).\n *\n * The overhead ratio (overhead / messages) varies by conversation length:\n * - Short conversations (< 10 messages): ~30-50% overhead (large system+tools)\n * - Medium (10-50 messages): ~15-30%\n * - Long (> 50 messages): ~5-15%\n *\n * Returns { messages, systemPrompt, tools, total } for debugging display.\n */\nexport interface RequestTokenBreakdown {\n messages: number;\n systemPrompt: number;\n tools: number;\n total: number;\n}\n\nexport function estimateRequestTokens(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string | undefined; inputSchema: unknown }[],\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): RequestTokenBreakdown {\n // Messages: apply the same logic as roughEstimate\n let messagesTokens = 0;\n if (typeof messages === 'string') {\n messagesTokens = RoughTokenEstimate(messages);\n } else if (Array.isArray(messages)) {\n for (const m of messages) {\n if (typeof m === 'object' && m !== null && 'content' in m) {\n // Fast path: pre-computed per-message token estimate (set by\n // ConversationState on append/replace). Skips the O(m) content-block\n // walk entirely for cached messages.\n const cached = (m as { _estTokens?: number | undefined })._estTokens;\n if (typeof cached === 'number' && cached > 0) {\n messagesTokens += cached;\n continue;\n }\n const content = (m as { content: unknown }).content;\n if (typeof content === 'string') {\n messagesTokens += RoughTokenEstimate(content);\n } else if (Array.isArray(content)) {\n for (const b of content) {\n if (typeof b === 'object' && b !== null) {\n if ((b as { type?: string | undefined }).type === 'text') {\n messagesTokens += RoughTokenEstimate((b as { text: string }).text);\n } else {\n messagesTokens += RoughTokenEstimate(JSON.stringify(b));\n }\n }\n }\n }\n }\n }\n }\n\n // System prompt\n let systemTokens = 0;\n if (typeof systemPrompt === 'string') {\n systemTokens = RoughTokenEstimate(systemPrompt);\n } else if (Array.isArray(systemPrompt)) {\n for (const b of systemPrompt) {\n if (\n typeof b === 'object' &&\n b !== null &&\n (b as { type?: string | undefined }).type === 'text'\n ) {\n systemTokens += RoughTokenEstimate((b as { text: string }).text);\n }\n }\n }\n\n // Tool definitions\n let toolsTokens = 0;\n for (const t of tools) {\n toolsTokens += estimateToolDefTokens(t);\n }\n\n const total = messagesTokens + systemTokens + toolsTokens;\n\n // Record the raw estimate for calibration: the next recordActualUsage()\n // call will pair this against the actual API usage so the rolling ratio\n // stays in sync with the real chars/token ratio of the content.\n calState(calibrationKey).prevEst = total;\n\n return {\n messages: messagesTokens,\n systemPrompt: systemTokens,\n tools: toolsTokens,\n total,\n };\n}\n\n/**\n * Record the actual API input token count after a provider call so\n * `estimateRequestTokensCalibrated` can self-correct on subsequent calls.\n *\n * Prefer passing `estimatedInputTokens` explicitly (the calibrated pre-flight\n * estimate from the middleware) — this avoids race conditions when other code\n * also calls `estimateRequestTokens` between the pre-flight and this call\n * (e.g. audit logging in agent.ts).\n *\n * When `estimatedInputTokens` is omitted, falls back to the keyed bucket's\n * `prevEst` for backward compatibility with callers that don't have the\n * pre-flight value. `calibrationKey` selects the per-(provider,model) bucket\n * (defaults to the shared global bucket).\n */\nexport function recordActualUsage(\n actualInputTokens: number,\n estimatedInputTokens?: number,\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): void {\n if (actualInputTokens <= 0) return;\n const cal = calState(calibrationKey);\n const est = estimatedInputTokens ?? cal.prevEst;\n if (est <= 0) return;\n\n const sampleRatio = actualInputTokens / est;\n if (cal.count === 0) {\n cal.ratio = sampleRatio;\n } else {\n // EWM: new = α * sample + (1-α) * old → α=0.3 = fast initial converge\n cal.ratio = CAL_ALPHA * sampleRatio + (1 - CAL_ALPHA) * cal.ratio;\n }\n // Sanity bound: keep the rolling ratio within [0.5, 1.5] so a sequence\n // of bad samples can't blow up the calibration for everyone.\n cal.ratio = Math.min(1.5, Math.max(0.5, cal.ratio));\n cal.count++;\n}\n\n/**\n * Returns the current calibration state for a bucket. Exposed for debugging\n * and tests — not needed by normal callers.\n */\nexport function getCalibrationState(calibrationKey: string = CALIBRATION_GLOBAL_KEY): {\n ratio: number;\n count: number;\n calibrated: boolean;\n} {\n const cal = calState(calibrationKey);\n return {\n ratio: cal.ratio,\n count: cal.count,\n calibrated: cal.count >= MIN_SAMPLES_FOR_CALIBRATION,\n };\n}\n\n/**\n * Like `estimateRequestTokens` but applies the rolling calibration factor\n * so context pressure readings converge on reality within a few iterations.\n *\n * Before any `recordActualUsage` samples are collected, returns the same\n * result as `estimateRequestTokens` (ratio = 1.0, no distortion).\n * After `MIN_SAMPLES_FOR_CALIBRATION` samples, applies the calibrated\n * multiplier capped to the range [0.5, 1.5] as a sanity bound.\n */\nexport function estimateRequestTokensCalibrated(\n messages: unknown,\n systemPrompt: unknown,\n tools: { name: string; description?: string | undefined; inputSchema: unknown }[],\n calibrationKey: string = CALIBRATION_GLOBAL_KEY,\n): RequestTokenBreakdown {\n const result = estimateRequestTokens(messages, systemPrompt, tools, calibrationKey);\n const cal = calState(calibrationKey);\n\n if (cal.count >= MIN_SAMPLES_FOR_CALIBRATION) {\n const safeRatio = Math.min(1.5, Math.max(0.5, cal.ratio));\n return {\n messages: Math.round(result.messages * safeRatio),\n systemPrompt: Math.round(result.systemPrompt * safeRatio),\n tools: Math.round(result.tools * safeRatio),\n total: Math.round(result.total * safeRatio),\n };\n }\n\n // No calibration samples yet — fall back to model-family ratio if available,\n // otherwise use the uncalibrated estimate (ratio = 1.0).\n const fallbackRatio = getModelFamilyRatio(calibrationKey);\n if (fallbackRatio !== null) {\n return {\n messages: Math.round(result.messages * fallbackRatio),\n systemPrompt: Math.round(result.systemPrompt * fallbackRatio),\n tools: Math.round(result.tools * fallbackRatio),\n total: Math.round(result.total * fallbackRatio),\n };\n }\n\n return result;\n}\n\n/** Look up the fallback chars/token ratio for a calibration key (e.g. \"provider/model\"). */\nfunction getModelFamilyRatio(calibrationKey: string): number | null {\n const lower = calibrationKey.toLowerCase();\n for (const [family, ratio] of Object.entries(MODEL_FAMILY_RATIO)) {\n if (lower.includes(family)) return ratio / 3.5; // MODEL_FAMILY_RATIO is chars/token, we need multiplier\n }\n return null;\n}\n\n/**\n * Resets calibration state. Primarily for tests that run in the same\n * process and need a clean slate between suites. With no argument it clears\n * every bucket (including the global one); pass a key to reset just that bucket.\n */\nexport function resetCalibration(calibrationKey?: string): void {\n if (calibrationKey === undefined) {\n _cals.clear();\n return;\n }\n _cals.delete(calibrationKey);\n}\n","export interface TextBlock {\n type: 'text';\n text: string;\n cache_control?: { type: 'ephemeral' | undefined };\n}\n\nexport interface ToolUseBlock {\n type: 'tool_use';\n id: string;\n name: string;\n input: Record<string, unknown>;\n /**\n * Provider-specific opaque metadata captured from the wire response.\n * Echoed back verbatim in the next request so providers that bind\n * extra state to function calls keep working. Example: Gemini's\n * `thoughtSignature` — required for tool-use turns with thinking\n * models, otherwise the next request fails with 400 \"Function call\n * is missing a thought_signature in functionCall parts\".\n *\n * Keys are namespaced by intent so multiple wires can coexist:\n * - `google.thoughtSignature` — Gemini signed-thought blob\n * Other providers can add their own keys without colliding.\n */\n providerMeta?: Record<string, unknown>;\n}\n\nexport interface ToolResultBlock {\n type: 'tool_result';\n tool_use_id: string;\n /**\n * The original tool name. Useful for providers like Google Gemini that\n * need the tool name in `functionResponse.name` — the tool_use_id is\n * only a session-local identifier and is not stable across replays.\n * Always set by ToolExecutor; may be absent on manually-constructed blocks.\n */\n name?: string | undefined;\n content: string;\n is_error?: boolean | undefined;\n}\n\nexport interface ImageBlock {\n type: 'image';\n source: {\n type: 'base64' | 'url';\n media_type?: string | undefined;\n data?: string | undefined;\n url?: string | undefined;\n };\n}\n\n/**\n * Chain-of-thought / extended-thinking content emitted by the model.\n *\n * Both Anthropic extended thinking (`{type:'thinking', thinking, signature}`)\n * and DeepSeek reasoning mode (top-level `reasoning_content` on the assistant\n * message) require this content to be echoed back verbatim on the next\n * request, otherwise the provider returns 400:\n * - Anthropic: \"The `content[].thinking` in the thinking mode must be passed back\"\n * - DeepSeek: \"The `reasoning_content` in the thinking mode must be passed back\"\n *\n * `signature` is Anthropic-specific (an opaque integrity blob). DeepSeek\n * doesn't issue a signature — the field is absent for that provider.\n *\n * Per Anthropic, thinking blocks MUST appear before any text/tool_use blocks\n * in an assistant message. Stream builders preserve that order.\n */\nexport interface ThinkingBlock {\n type: 'thinking';\n thinking: string;\n signature?: string | undefined;\n providerMeta?: Record<string, unknown>;\n}\n\nexport type ContentBlock = TextBlock | ToolUseBlock | ToolResultBlock | ImageBlock | ThinkingBlock;\n\nexport function isTextBlock(b: ContentBlock): b is TextBlock {\n return b.type === 'text';\n}\nexport function isToolUseBlock(b: ContentBlock): b is ToolUseBlock {\n return b.type === 'tool_use';\n}\nexport function isToolResultBlock(b: ContentBlock): b is ToolResultBlock {\n return b.type === 'tool_result';\n}\nexport function isImageBlock(b: ContentBlock): b is ImageBlock {\n return b.type === 'image';\n}\nexport function isThinkingBlock(b: ContentBlock): b is ThinkingBlock {\n return b.type === 'thinking';\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport { estimateMessageTokens, estimateTextTokens } from '../utils/token-estimate.js';\nimport { isTextBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nimport type { Provider, Request } from '../types/provider.js';\nimport type { MessageSelector, SelectorResult } from '../types/selector.js';\nexport interface LLMSelectorOptions {\n /** Provider used for the selector LLM call. Required. */\n provider: Provider;\n /** Model for the selector. Defaults to the provider's default model. */\n model?: string | undefined;\n /**\n * Maximum tokens to keep in context (target budget).\n * Selector will aim to keep total content below this.\n */\n maxContextTokens?: number | undefined;\n /**\n * Prompt instructing the selector how to behave.\n * Should guide the LLM on importance tiers and output format.\n */\n systemPrompt?: string | undefined;\n /**\n * Maximum output tokens for the selector LLM call.\n * Controls both the JSON response budget and the token reservation for the\n * history text budget calculation (default: 1024).\n */\n maxOutputTokens?: number | undefined;\n}\n\nconst DEFAULT_SYSTEM_PROMPT = `You are a context pruning assistant. Given a conversation history and a token budget, decide which message ranges are worth keeping verbatim and which should be collapsed into summaries.\n\nOutput a JSON object with this structure:\n{\n \"kept\": [{\"from\": 0, \"to\": 5, \"importance\": \"critical\"}],\n \"collapsed\": [{\"from\": 6, \"to\": 20, \"summary\": \"optional summary\"}],\n \"reasoning\": \"brief explanation of decisions\"\n}\n\nImportance tiers:\n- \"critical\": decisions, file edits, tool results that affect state, final answers\n- \"high\": substantive tool use, complex reasoning, non-obvious observations\n- \"medium\": routine exchanges, confirmations, straightforward Q&A\n\nRules:\n- Always keep the most recent K pairs (preserve recency)\n- Never collapse the final 2 user/assistant pairs (working memory)\n- Preserve tool results that modified files or had external effects\n- Collapse old, low-information exchanges (greetings, acknowledgements, etc.)\n- If unsure, keep rather than collapse (errors are more costly than waste)\n\nReturn ONLY the JSON object, no markdown, no explanation outside the JSON.`;\n\n/**\n * Format messages as a compact text dump for the selector LLM.\n * Uses token estimation (not character count) to budget the output,\n * so long sessions don't silently truncate the selector's view of history.\n */\nfunction formatMessages(messages: Message[], maxTokens = 2048): string {\n const lines: string[] = [];\n let usedTokens = 0;\n for (let i = 0; i < messages.length; i++) {\n const m = expectDefined(messages[i]);\n const role = m.role.padEnd(10, ' ');\n let text: string;\n if (typeof m.content === 'string') {\n text = m.content.slice(0, 500);\n } else {\n const content = m.content as import('../types/blocks.js').ContentBlock[];\n text = content\n .filter(isTextBlock)\n .map((b) => b.text)\n .join(' ');\n // Also capture tool names for context\n const toolUses = content.filter((b) => b.type === 'tool_use');\n if (toolUses.length > 0) {\n text += ` [tools: ${toolUses.map((b) => (b as { name?: string }).name).filter(Boolean).join(', ')}]`;\n }\n }\n const line = `[${i}][${role}]: ${text}`;\n const lineTokens = estimateTextTokens(line);\n if (usedTokens + lineTokens > maxTokens) break;\n lines.push(line);\n usedTokens += lineTokens;\n }\n return lines.join('\\n');\n}\n\n/**\n * LLM-powered message selector. Calls a sub-LLM to analyze the\n * message history and produce a keep/collapse plan — more surgical\n * than fixed-window rules.\n */\nexport class LLMSelector implements MessageSelector {\n private readonly provider: Provider;\n private readonly model: string;\n private readonly maxContextTokens: number;\n private readonly systemPrompt: string;\n private readonly maxOutputTokens: number;\n\n constructor(opts: LLMSelectorOptions) {\n this.provider = opts.provider;\n this.model = opts.model ?? 'unknown';\n if (\n this.model === 'unknown' &&\n (process.env['NODE_ENV'] === 'development' || process.env['WRONGSTACK_DEBUG'] === '1')\n ) {\n console.warn(\n '[LLMSelector] model not set — selector will use the provider default. Set `model` explicitly in LLMSelectorOptions to silence this warning.',\n );\n }\n this.maxContextTokens = opts.maxContextTokens ?? 40_000;\n this.systemPrompt = opts.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;\n this.maxOutputTokens = opts.maxOutputTokens ?? 1024;\n }\n\n async select(messages: Message[], maxToKeep: number): Promise<SelectorResult> {\n const effectiveBudget = Math.min(maxToKeep, this.maxContextTokens);\n\n const totalTokens = estimateMessageTokens(messages);\n const systemText = `${this.systemPrompt}\\n\\nConversation (${messages.length} messages, ~${totalTokens} tokens, budget: ${effectiveBudget}):\\n`;\n // Reserve tokens for the system prefix and output (maxOutputTokens), then give the\n // rest to the formatted history so the selector sees the maximum possible context.\n const systemTokens = estimateTextTokens(systemText);\n const historyBudget = Math.max(512, effectiveBudget - systemTokens - this.maxOutputTokens);\n\n // Build a concise representation of the conversation within the token budget\n const historyText = formatMessages(messages, historyBudget);\n\n // Add instruction to stay within budget\n const budgetInstruction =\n totalTokens > effectiveBudget\n ? `\\n\\nIMPORTANT: Total conversation (${totalTokens} tokens) exceeds budget (${effectiveBudget}). You MUST collapse enough to fit. Prefer collapsing older/lower-importance ranges.`\n : '';\n\n const req: Request = {\n model: this.model,\n system: [{ type: 'text', text: systemText + budgetInstruction }],\n messages: [{ role: 'user', content: historyText }],\n maxTokens: this.maxOutputTokens,\n };\n\n let raw: string;\n const ac = new AbortController();\n try {\n // 30-second timeout so a stuck selector LLM call can't hang the compactor.\n const timeoutSignal = AbortSignal.timeout(30_000);\n const res = await this.provider.complete(req, {\n signal: AbortSignal.any([ac.signal, timeoutSignal]),\n });\n const textBlocks = res.content.filter(isTextBlock);\n raw = textBlocks\n .map((b) => b.text)\n .join('\\n')\n .trim();\n } catch (err) {\n if (err instanceof Error) {\n console.warn('[LLMSelector] selector call failed, using recency fallback:', err.message);\n }\n return this.fallbackSelect(messages, effectiveBudget);\n } finally {\n ac.abort();\n }\n\n return this.parseSelectorOutput(raw, messages);\n }\n\n private fallbackSelect(messages: Message[], budget: number): SelectorResult {\n // Simple fallback: keep from the end until we hit budget\n const toKeep: SelectorResult['kept'] = [];\n const toCollapse: SelectorResult['collapsed'] = [];\n\n let tokenCount = 0;\n let startIdx = 0;\n\n // Scan from the end backwards\n for (let i = messages.length - 1; i >= 0; i--) {\n const m = expectDefined(messages[i]);\n const cost = estimateMessageTokens([m]);\n\n if (tokenCount + cost <= budget) {\n tokenCount += cost;\n } else {\n startIdx = i + 1;\n break;\n }\n }\n\n if (startIdx > 0) {\n toCollapse.push({ from: 0, to: startIdx - 1 });\n }\n toKeep.push({ from: startIdx, to: messages.length - 1, importance: 'high' });\n\n return {\n kept: toKeep,\n collapsed: toCollapse,\n reasoning: `Fallback: kept last ${messages.length - startIdx} messages within ${budget} token budget`,\n };\n }\n\n /**\n * Parse and validate the raw LLM output into a SelectorResult.\n * Falls back to recency-based selection if the LLM output is malformed,\n * out-of-bounds, or internally inconsistent.\n */\n private parseSelectorOutput(raw: string, messages: Message[]): SelectorResult {\n const messageCount = messages.length;\n if (messageCount === 0) {\n return { kept: [], collapsed: [], reasoning: 'empty session' };\n }\n\n // Try to extract JSON from the response\n const jsonStart = raw.indexOf('{');\n const jsonEnd = raw.lastIndexOf('}');\n if (jsonStart === -1 || jsonEnd === -1) {\n return this.fallbackSelect(messages, this.maxContextTokens);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw.slice(jsonStart, jsonEnd + 1));\n } catch {\n return this.fallbackSelect(messages, this.maxContextTokens);\n }\n\n const obj = parsed as Record<string, unknown>;\n const keptRaw =\n (obj.kept as Array<{ from: number; to: number; importance: string }> | undefined) ?? [];\n const collapsedRaw =\n (obj.collapsed as Array<{ from: number; to: number; summary?: string | undefined }> | undefined) ?? [];\n\n // Validate kept ranges — must be within [0, messageCount), from <= to\n const kept: SelectorResult['kept'] = [];\n for (const k of keptRaw) {\n if (\n typeof k.from !== 'number' ||\n typeof k.to !== 'number' ||\n k.from < 0 ||\n k.to >= messageCount ||\n k.from > k.to\n ) {\n return this.fallbackSelect(messages, this.maxContextTokens);\n }\n kept.push({\n from: k.from,\n to: k.to,\n importance: (k.importance ?? 'medium') as 'critical' | 'high' | 'medium',\n });\n }\n\n // Validate collapsed ranges — same bounds check\n const collapsed: SelectorResult['collapsed'] = [];\n for (const c of collapsedRaw) {\n if (\n typeof c.from !== 'number' ||\n typeof c.to !== 'number' ||\n c.from < 0 ||\n c.to >= messageCount ||\n c.from > c.to\n ) {\n return this.fallbackSelect(messages, this.maxContextTokens);\n }\n collapsed.push({ from: c.from, to: c.to, summary: c.summary });\n }\n\n // Check for overlaps: kept ranges must not overlap with each other or with collapsed ranges\n const allRanges: Array<{ from: number; to: number }> = [...kept, ...collapsed];\n for (let i = 0; i < allRanges.length; i++) {\n const a = allRanges[i];\n if (!a) continue;\n for (let j = i + 1; j < allRanges.length; j++) {\n const b = allRanges[j];\n if (!b) continue;\n // Overlap: a starts before b ends AND a ends after b starts\n if (a.from <= b.to && a.to >= b.from) {\n return this.fallbackSelect(messages, this.maxContextTokens);\n }\n }\n }\n\n return {\n kept,\n collapsed,\n reasoning: typeof obj.reasoning === 'string' ? obj.reasoning : '',\n };\n }\n}\n","/**\n * Offline **floor** for the ChatGPT \"Sign in with ChatGPT\" (`openai-codex`)\n * models, mirroring what the official Codex CLI / ChatGPT model picker shows.\n *\n * Source-of-truth precedence (live path wins):\n * 1. The curated overlay `packages/cli/data/providers.json` — provider\n * `openai-codex` — which is **synced from raw GitHub** + cached + bundled\n * offline by `DefaultModelsRegistry` (overlayUrl/overlayFile). Editing that\n * JSON and pushing updates every client without a code release; this is the\n * authoritative list whenever the registry overlay is wired (the CLI path).\n * 2. This hardcoded table — the last-resort floor used where no overlay is\n * available (a standalone registry without the bundled file) and by the CLI\n * auth-menu login flow, which needs a synchronous id list.\n *\n * Keep this in lockstep with the `openai-codex` block in `providers.json`; the\n * drift-guard test `packages/cli/tests/codex-catalog-overlay-sync.test.ts`\n * asserts they agree.\n *\n * Layer note: this lives in `core` (not the CLI auth-menu) so the model-list\n * resolver can read it without `core` depending on `cli`. The CLI's\n * `FALLBACK_CODEX_MODELS` is derived from this list.\n */\n\nexport interface CodexModelMeta {\n /** The wire id sent to the backend and stored in config (e.g. `gpt-5.5`). */\n id: string;\n /** Human-readable display name shown in pickers. */\n name: string;\n /** One-line capability blurb, matching the official Codex picker copy. */\n description: string;\n /** The recommended / latest model — tagged \"(current)\" in the official UI. */\n current?: boolean;\n}\n\n/**\n * Current ChatGPT sign-in models, newest first. The first entry is the\n * recommended default (`current`). Order is significant: callers that need a\n * default model id use `CODEX_MODELS[0]`.\n */\nexport const CODEX_MODELS: ReadonlyArray<CodexModelMeta> = [\n {\n id: 'gpt-5.5',\n name: 'GPT-5.5',\n description: 'Frontier model for complex coding, research, and real-world work.',\n current: true,\n },\n {\n id: 'gpt-5.4',\n name: 'GPT-5.4',\n description: 'Strong model for everyday coding.',\n },\n {\n id: 'gpt-5.4-mini',\n name: 'GPT-5.4 Mini',\n description: 'Small, fast, and cost-efficient model for simpler coding tasks.',\n },\n {\n id: 'gpt-5.3-codex-spark',\n name: 'GPT-5.3 Codex Spark',\n description: 'Ultra-fast coding model.',\n },\n];\n\nconst BY_ID: ReadonlyMap<string, CodexModelMeta> = new Map(CODEX_MODELS.map((m) => [m.id, m]));\n\n/** Look up the canonical metadata for a Codex model id, or `undefined`. */\nexport function codexModelMeta(id: string): CodexModelMeta | undefined {\n return BY_ID.get(id);\n}\n","import type { ModelsDevModel, ResolvedProvider } from '../types/models-registry.js';\nimport { codexModelMeta } from './codex-catalog.js';\n\n/**\n * A model descriptor shaped for the WebUI `provider.models` message. All\n * metadata fields are optional because OAuth / subscription providers that\n * models.dev doesn't list contribute only a bare id.\n */\nexport interface ProviderModelDescriptor {\n id: string;\n name: string;\n /** One-line capability blurb, when known (e.g. the Codex subscription models). */\n description?: string | undefined;\n releaseDate?: string | undefined;\n contextWindow?: number | undefined;\n inputCost?: number | undefined;\n outputCost?: number | undefined;\n capabilities: string[];\n}\n\n/** Map a models.dev catalog model to the WebUI descriptor shape. */\nexport function describeCatalogModel(m: ModelsDevModel): ProviderModelDescriptor {\n return {\n id: m.id,\n name: m.name,\n ...(m.description !== undefined ? { description: m.description } : {}),\n releaseDate: m.release_date,\n contextWindow: m.limit?.context,\n inputCost: m.cost?.input,\n outputCost: m.cost?.output,\n capabilities: [\n ...(m.tool_call ? ['tools'] : []),\n ...(m.reasoning ? ['reasoning'] : []),\n ...(m.modalities?.input?.includes('image') ? ['vision'] : []),\n ...(m.open_weights ? ['open_weights'] : []),\n ],\n };\n}\n\n/**\n * Resolve the model list to offer for a provider, merging a saved-config\n * allowlist with optional models.dev catalog metadata.\n *\n * Priority:\n * 1. The saved `models` allowlist is authoritative. This is the only source\n * for OAuth / subscription / custom providers that models.dev does not\n * list — `github-copilot`, `anthropic-oauth`, `openai-codex`,\n * `zai-coding-plan`, etc. Each id is enriched with catalog metadata when a\n * same-id catalog model exists, otherwise returned as a bare `{id, name}`.\n * 2. Otherwise the full catalog model list (standard API-key providers with no\n * saved allowlist).\n * 3. Otherwise an empty list — *never* an error. A provider the user saved\n * that is neither in the catalog nor carries an allowlist simply has no\n * suggestions yet; callers must not raise a toast for that case (doing so\n * produced the \"not found in catalog\" notification flood when the WebUI\n * model switcher lazy-loaded every saved provider).\n */\nexport function resolveProviderModelList(\n savedModels: string[] | undefined,\n catalog: ResolvedProvider | undefined,\n): ProviderModelDescriptor[] {\n if (savedModels && savedModels.length > 0) {\n const byId = new Map((catalog?.models ?? []).map((m) => [m.id, m]));\n return savedModels.map((id) => {\n // OAuth / subscription ids (openai-codex) are absent from the models.dev\n // catalog, so layer their canonical name + description on top: enrich a\n // catalog hit with the blurb, or synthesize a full descriptor from it.\n const codex = codexModelMeta(id);\n const hit = byId.get(id);\n if (hit) {\n const described = describeCatalogModel(hit);\n return codex ? { ...described, description: codex.description } : described;\n }\n if (codex) {\n return { id, name: codex.name, description: codex.description, capabilities: [] };\n }\n return { id, name: id, capabilities: [] };\n });\n }\n if (catalog) return catalog.models.map(describeCatalogModel);\n return [];\n}\n","/**\n * Model Intelligence — knowledge base of model capabilities, strengths,\n * and task-type suitability. Powers automatic agent → model routing.\n *\n * Each entry records:\n * - Known strengths (what this model family excels at)\n * - Known weaknesses (what it struggles with)\n * - Best-for task types (coding, planning, security, docs, etc.)\n * - Cost tier (budget / standard / premium)\n *\n * This is a curated dataset updated as new models release. Falls back\n * gracefully for unknown models.\n */\n\nexport interface ModelProfile {\n /** Provider id (e.g. \"anthropic\", \"openai\"). */\n provider: string;\n /** Model id regex — matches partial ids (e.g. \"claude-sonnet\" matches \"claude-sonnet-4-20250514\"). */\n pattern: RegExp;\n /** Human-readable model family name. */\n family: string;\n /** What this model is particularly good at. */\n strengths: string[];\n /** Known limitations. */\n weaknesses?: string[];\n /** Task types this model is the best choice for. Ordered by preference. */\n bestFor: TaskType[];\n /** Task types to avoid with this model (use a different one). */\n avoidFor?: TaskType[];\n /** Approximate cost tier. */\n costTier: 'budget' | 'standard' | 'premium';\n /** Approximate speed tier (relative to other models). */\n speedTier: 'fast' | 'normal' | 'slow';\n /** Minimum recommended context window. */\n minContext?: number;\n}\n\n/** Task categories that map to agent roles. */\nexport type TaskType =\n | 'coding' // general software development\n | 'planning' // architecture, design, strategy\n | 'security' // vulnerability scanning, security review\n | 'docs' // documentation, writing, explanation\n | 'testing' // test writing, test review\n | 'refactoring' // code restructuring, cleanup\n | 'debugging' // bug hunting, error tracing\n | 'data' // data analysis, JSON, DB queries\n | 'frontend' // React, UI, CSS\n | 'backend' // API, server, infrastructure\n | 'review' // code review, PR review\n | 'lightweight' // simple tasks, quick answers\n | 'general'; // fallback — any task\n\n/** Known model profiles. Patterns are tried in order; first match wins. */\nexport const MODEL_PROFILES: ModelProfile[] = [\n // ── Anthropic ──\n {\n provider: 'anthropic',\n pattern: /claude-opus/i,\n family: 'Claude Opus',\n strengths: ['complex reasoning', 'multi-step planning', 'nuanced judgment', 'long-form analysis'],\n weaknesses: ['latency', 'cost'],\n bestFor: ['planning', 'security', 'debugging', 'review'],\n costTier: 'premium',\n speedTier: 'slow',\n },\n {\n provider: 'anthropic',\n pattern: /claude-sonnet/i,\n family: 'Claude Sonnet',\n strengths: ['coding', 'balanced reasoning', 'tool use', 'fast iteration'],\n bestFor: ['coding', 'refactoring', 'backend', 'general'],\n costTier: 'standard',\n speedTier: 'fast',\n },\n {\n provider: 'anthropic',\n pattern: /claude-haiku/i,\n family: 'Claude Haiku',\n strengths: ['speed', 'low cost', 'simple tasks'],\n weaknesses: ['complex reasoning', 'long context'],\n bestFor: ['lightweight', 'docs', 'frontend'],\n avoidFor: ['planning', 'security'],\n costTier: 'budget',\n speedTier: 'fast',\n },\n\n // ── OpenAI ──\n {\n provider: 'openai',\n pattern: /gpt-5|o3|o4/i,\n family: 'GPT-5 / o3 / o4',\n strengths: ['complex reasoning', 'coding', 'multi-modal'],\n bestFor: ['planning', 'coding', 'debugging', 'general'],\n costTier: 'premium',\n speedTier: 'normal',\n },\n {\n provider: 'openai',\n pattern: /gpt-4\\.1|gpt-4o/i,\n family: 'GPT-4.1 / 4o',\n strengths: ['coding', 'balanced reasoning', 'fast'],\n bestFor: ['coding', 'refactoring', 'backend', 'docs'],\n costTier: 'standard',\n speedTier: 'fast',\n },\n {\n provider: 'openai',\n pattern: /gpt-4o-mini/i,\n family: 'GPT-4o Mini',\n strengths: ['speed', 'low cost', 'simple tasks'],\n weaknesses: ['complex reasoning'],\n bestFor: ['lightweight', 'frontend', 'docs'],\n avoidFor: ['planning', 'security'],\n costTier: 'budget',\n speedTier: 'fast',\n },\n\n // ── Google ──\n {\n provider: 'google',\n pattern: /gemini-(?:2\\.5|3)/i,\n family: 'Gemini 2.5 / 3',\n strengths: ['long context', 'multi-modal', 'coding', 'reasoning'],\n bestFor: ['coding', 'planning', 'data', 'general'],\n costTier: 'standard',\n speedTier: 'normal',\n },\n {\n provider: 'google',\n pattern: /gemini-2\\.0-flash|gemini-flash/i,\n family: 'Gemini Flash',\n strengths: ['speed', 'low cost', 'long context'],\n weaknesses: ['deep reasoning'],\n bestFor: ['lightweight', 'docs', 'frontend', 'data'],\n avoidFor: ['planning', 'security'],\n costTier: 'budget',\n speedTier: 'fast',\n },\n\n // ── DeepSeek ──\n {\n provider: 'deepseek',\n pattern: /deepseek-v3|deepseek-r1/i,\n family: 'DeepSeek V3 / R1',\n strengths: ['coding', 'math', 'reasoning', 'cost-effective'],\n bestFor: ['coding', 'refactoring', 'debugging', 'general'],\n costTier: 'standard',\n speedTier: 'normal',\n },\n\n // ── OpenRouter / catch-all ──\n {\n provider: 'openrouter',\n pattern: /.*/,\n family: 'OpenRouter (routed)',\n strengths: ['model variety', 'fallback'],\n bestFor: ['general'],\n costTier: 'standard',\n speedTier: 'normal',\n },\n];\n\n/** Map task types to the agent roles that handle them. */\nexport const TASK_TO_ROLE: Record<TaskType, string[]> = {\n coding: ['executor', 'architect', 'bug-hunter'],\n planning: ['planner', 'architect', 'refactor-planner'],\n security: ['security-scanner', 'security-reviewer'],\n docs: ['document', 'simplifier'],\n testing: ['test', 'e2e'],\n refactoring: ['refactor-planner', 'refactor', 'simplifier'],\n debugging: ['debugger', 'bug-hunter', 'tracer'],\n data: ['analyst', 'data', 'database'],\n frontend: ['frontend', 'designer'],\n backend: ['backend', 'api', 'auth'],\n review: ['code-reviewer', 'critic'],\n lightweight: ['executor', 'simplifier'],\n general: ['executor', 'analyst'],\n};\n\n/**\n * Infer the most likely task type from a task description and target role.\n * Uses keyword matching; falls back to the role's primary task type.\n */\nexport function inferTaskType(description: string, role?: string): TaskType {\n const d = description.toLowerCase();\n\n // Keyword → task type mapping\n const keywords: [RegExp, TaskType][] = [\n [/plan|architect|design|strategy|blueprint|system\\s*design/i, 'planning'],\n [/security|vuln|exploit|injection|auth/i, 'security'],\n [/doc|readme|explain|write\\s*(a|the)\\s*doc|tutorial/i, 'docs'],\n [/test|spec|assert|mock|coverage/i, 'testing'],\n [/refactor|clean\\s*up|restructure|simplify/i, 'refactoring'],\n [/bug|fix|debug|trace|crash|error/i, 'debugging'],\n [/data|json|sql|query|analyze|parse/i, 'data'],\n [/frontend|react|ui|css|component|jsx/i, 'frontend'],\n [/backend|api|server|endpoint|route|middleware/i, 'backend'],\n [/review|audit|inspect|check/i, 'review'],\n [/simple|quick|one-liner|trivial/i, 'lightweight'],\n ];\n\n for (const [re, taskType] of keywords) {\n if (re.test(d)) return taskType;\n }\n\n // Fallback: map role to best task type\n if (role) {\n for (const [taskType, roles] of Object.entries(TASK_TO_ROLE)) {\n if (roles.includes(role)) return taskType as TaskType;\n }\n }\n\n return 'general';\n}\n\n/**\n * Find the best matching model profile for a given provider + model id.\n */\nexport function findModelProfile(provider: string, modelId: string): ModelProfile | undefined {\n const candidates = MODEL_PROFILES.filter((p) => p.provider === provider);\n // Try exact match first, then pattern match\n for (const p of candidates) {\n if (p.pattern.test(modelId)) return p;\n }\n return undefined;\n}\n\n/**\n * Score a model for a given task type. Higher = better fit.\n * Returns 0-100.\n */\nexport function scoreModelForTask(profile: ModelProfile | undefined, taskType: TaskType): number {\n if (!profile) return 50; // unknown model — neutral\n\n // Explicitly avoided → very low score\n if (profile.avoidFor?.includes(taskType)) return 10;\n\n // Best-for match → high score\n const bestIdx = profile.bestFor.indexOf(taskType);\n if (bestIdx >= 0) {\n // Earlier in the list = better fit\n return 90 - bestIdx * 10;\n }\n\n // Cost/speed adjustments\n let score = 50;\n if (taskType === 'lightweight') {\n score += profile.costTier === 'budget' ? 30 : profile.costTier === 'standard' ? 15 : 0;\n score += profile.speedTier === 'fast' ? 20 : 0;\n }\n if (taskType === 'planning' || taskType === 'security') {\n score += profile.costTier === 'premium' ? 20 : 0;\n score += profile.speedTier === 'slow' ? 10 : 0; // slow = thorough\n }\n\n return score;\n}\n","/**\n * ModelRouter — intelligent model selection for subagent delegation.\n *\n * Combines:\n * 1. User-configured model matrix (/setmodel overrides)\n * 2. Model intelligence profiles (strengths/weaknesses per model family)\n * 3. Provider availability (which models have API keys configured)\n * 4. Per-model cost tracking\n *\n * Usage:\n * const router = new ModelRouter({ matrix, config, profiles: MODEL_PROFILES });\n * const pick = router.pickForTask('security-scanner', 'Audit the auth module');\n * // → { provider: 'anthropic', model: 'claude-sonnet-...', reason: 'best-for security' }\n */\n\nimport type { ModelMatrixEntry, ProviderConfig } from '../types/config.js';\n\nexport interface ModelIntelligenceEntry {\n provider: string;\n pattern: RegExp;\n family: string;\n strengths: string[];\n weaknesses?: string[];\n bestFor: string[];\n avoidFor?: string[];\n costTier: 'budget' | 'standard' | 'premium';\n speedTier: 'fast' | 'normal' | 'slow';\n minContext?: number;\n}\n\nexport interface RouterConfig {\n /** User-configured model matrix (from /setmodel). */\n matrix?: Record<string, ModelMatrixEntry> | undefined;\n /** Provider configurations (to check API key availability). */\n config: {\n provider: string;\n model: string;\n providers?: Record<string, ProviderConfig>;\n };\n /** Known model intelligence profiles. */\n profiles?: ModelIntelligenceEntry[] | undefined;\n}\n\nexport interface ModelPick {\n provider: string;\n model: string;\n /** Why this model was chosen. */\n reason: string;\n /** Whether this came from the user's matrix (true) or auto-detected (false). */\n fromMatrix: boolean;\n}\n\nexport interface RouterCosts {\n /** Cumulative cost per provider/model key. */\n byModel: Record<string, { cost: number; tokens: { input: number; output: number }; calls: number }>;\n /** Grand total. */\n totalCost: number;\n}\n\n/**\n * Default profiles used when none are provided. Kept inline so the router\n * is self-contained — callers can override with richer data from model-intelligence.\n */\nconst DEFAULT_PROFILES: ModelIntelligenceEntry[] = [\n { provider: 'anthropic', pattern: /claude-opus/i, family: 'Claude Opus', strengths: ['reasoning', 'planning'], bestFor: ['planning', 'security', 'debugging'], costTier: 'premium', speedTier: 'slow' },\n { provider: 'anthropic', pattern: /claude-sonnet/i, family: 'Claude Sonnet', strengths: ['coding', 'balanced'], bestFor: ['coding', 'general'], costTier: 'standard', speedTier: 'fast' },\n { provider: 'anthropic', pattern: /claude-haiku/i, family: 'Claude Haiku', strengths: ['speed'], bestFor: ['lightweight', 'docs'], avoidFor: ['planning'], costTier: 'budget', speedTier: 'fast' },\n { provider: 'openai', pattern: /gpt-5|o3|o4/i, family: 'GPT-5/o3/o4', strengths: ['reasoning', 'coding'], bestFor: ['planning', 'coding', 'debugging'], costTier: 'premium', speedTier: 'normal' },\n { provider: 'openai', pattern: /gpt-4/i, family: 'GPT-4', strengths: ['coding'], bestFor: ['coding', 'docs'], costTier: 'standard', speedTier: 'fast' },\n { provider: 'openai', pattern: /gpt-4o-mini/i, family: 'GPT-4o Mini', strengths: ['speed'], bestFor: ['lightweight', 'docs'], avoidFor: ['planning'], costTier: 'budget', speedTier: 'fast' },\n { provider: 'google', pattern: /gemini-(?:2\\.5|3)/i, family: 'Gemini 2.5/3', strengths: ['context', 'coding'], bestFor: ['coding', 'data'], costTier: 'standard', speedTier: 'normal' },\n { provider: 'google', pattern: /gemini.*flash/i, family: 'Gemini Flash', strengths: ['speed'], bestFor: ['lightweight', 'docs'], avoidFor: ['planning'], costTier: 'budget', speedTier: 'fast' },\n { provider: 'deepseek', pattern: /deepseek/i, family: 'DeepSeek', strengths: ['coding', 'cost-effective'], bestFor: ['coding', 'general'], costTier: 'standard', speedTier: 'normal' },\n];\n\n/** Map common task keywords to categories for model matching. */\nconst TASK_CATEGORIES: Record<string, string> = {\n plan: 'planning', architect: 'planning', design: 'planning', strategy: 'planning',\n security: 'security', vuln: 'security', exploit: 'security', auth: 'security',\n doc: 'docs', readme: 'docs', explain: 'docs', write: 'docs',\n test: 'testing', spec: 'testing', assert: 'testing', coverage: 'testing',\n refactor: 'refactoring', cleanup: 'refactoring', restructure: 'refactoring',\n bug: 'debugging', fix: 'debugging', debug: 'debugging', trace: 'debugging', crash: 'debugging',\n data: 'data', json: 'data', sql: 'data', query: 'data', analyze: 'data', parse: 'data',\n frontend: 'frontend', react: 'frontend', ui: 'frontend', css: 'frontend', component: 'frontend',\n backend: 'backend', api: 'backend', server: 'backend', endpoint: 'backend',\n review: 'review', audit: 'review', inspect: 'review',\n simple: 'lightweight', quick: 'lightweight', trivial: 'lightweight',\n};\n\nexport class ModelRouter {\n private profiles: ModelIntelligenceEntry[];\n private matrix: Record<string, ModelMatrixEntry>;\n private config: RouterConfig['config'];\n private costs: RouterCosts = { byModel: {}, totalCost: 0 };\n\n constructor(opts: RouterConfig) {\n this.profiles = opts.profiles ?? DEFAULT_PROFILES;\n this.matrix = opts.matrix ?? {};\n this.config = opts.config;\n }\n\n /** Look up the model matrix resolution for a role (role → phase → * → leader). */\n private resolveMatrix(role: string): ModelMatrixEntry | undefined {\n // Exact role match\n if (this.matrix[role]) return this.matrix[role];\n // Phase match\n const phase = this.roleToPhase(role);\n if (phase && this.matrix[phase]) return this.matrix[phase];\n // Wildcard\n if (this.matrix['*']) return this.matrix['*'];\n return undefined;\n }\n\n /** Simplified phase lookup for common roles. */\n private roleToPhase(role: string): string | undefined {\n const phaseMap: Record<string, string> = {\n planner: 'plan', architect: 'plan', 'refactor-planner': 'plan',\n executor: 'code', refactor: 'code', simplifier: 'code', migration: 'code',\n 'bug-hunter': 'code', debugger: 'code', tracer: 'code',\n test: 'code', e2e: 'code', performance: 'code', chaos: 'code',\n 'security-scanner': 'review', 'security-reviewer': 'review', 'code-reviewer': 'review',\n critic: 'review', accessibility: 'review', compliance: 'review',\n analyst: 'code', data: 'code', database: 'code',\n frontend: 'code', backend: 'code', api: 'code', auth: 'code',\n designer: 'code', document: 'code',\n researcher: 'plan', explore: 'plan', search: 'plan',\n };\n return phaseMap[role];\n }\n\n /**\n * Pick the best model for a task.\n *\n * Priority:\n * 1. User's /setmodel matrix entry for this role (explicit override)\n * 2. Best-matching model from intelligence profiles\n * 3. Leader model (fallback)\n */\n pickForTask(role: string, description: string): ModelPick {\n // 1. Check user matrix\n const matrixEntry = this.resolveMatrix(role);\n if (matrixEntry) {\n const provider = matrixEntry.provider ?? this.config.provider;\n return {\n provider,\n model: matrixEntry.model,\n reason: `matrix override for role ${role}`,\n fromMatrix: true,\n };\n }\n\n // 2. Auto-detect from task description + role\n const category = this.inferCategory(description, role);\n const best = this.findBestModel(category);\n if (best) {\n return { ...best, reason: `best-for ${category} (auto-detected)`, fromMatrix: false };\n }\n\n // 3. Leader fallback\n return {\n provider: this.config.provider,\n model: this.config.model,\n reason: 'leader fallback',\n fromMatrix: false,\n };\n }\n\n /** Infer task category from description keywords + role. */\n private inferCategory(description: string, role: string): string {\n const d = description.toLowerCase();\n for (const [keyword, category] of Object.entries(TASK_CATEGORIES)) {\n if (d.includes(keyword)) return category;\n }\n // Map role to category\n const roleMap: Record<string, string> = {\n 'security-scanner': 'security', 'security-reviewer': 'security',\n 'bug-hunter': 'debugging', debugger: 'debugging',\n planner: 'planning', architect: 'planning',\n 'refactor-planner': 'refactoring', refactor: 'refactoring',\n test: 'testing', e2e: 'testing',\n document: 'docs', simplifier: 'docs',\n 'code-reviewer': 'review', critic: 'review',\n 'frontend': 'frontend', 'backend': 'backend',\n };\n return roleMap[role] ?? 'general';\n }\n\n /** Find the best available model for a task category. */\n private findBestModel(category: string): { provider: string; model: string } | undefined {\n // Score each profile for this category\n const scored = this.profiles\n .filter((p) => this.hasKey(p.provider))\n .map((p) => {\n let score = 50;\n if (p.bestFor.includes(category)) score += 40;\n if (p.avoidFor?.includes(category)) score -= 50;\n if (category === 'lightweight' && p.costTier === 'budget') score += 20;\n if (category === 'planning' && p.costTier === 'premium') score += 15;\n if (category === 'planning' && p.speedTier === 'slow') score += 10; // slow = thorough\n return { profile: p, score };\n })\n .filter((s) => s.score > 0)\n .sort((a, b) => b.score - a.score);\n\n if (scored.length === 0) return undefined;\n\n // Guarded by scored.length === 0 check above — but use optional\n // chaining instead of `!` to satisfy the non-null assertion lint rule.\n const best = scored[0]?.profile;\n if (!best) return undefined;\n // Find the actual model id from the provider's configured models\n const models = this.getProviderModels(best.provider);\n const match = models.find((m) => best.pattern.test(m)) ?? models[0];\n if (!match) return undefined;\n\n return { provider: best.provider, model: match };\n }\n\n /** Check if a provider has an API key configured. */\n private hasKey(providerId: string): boolean {\n const pc = this.config.providers?.[providerId];\n if (!pc) return providerId === this.config.provider;\n if (typeof pc.apiKey === 'string' && pc.apiKey.length > 0) return true;\n if (Array.isArray(pc.apiKeys) && pc.apiKeys.some((k) => k?.apiKey)) return true;\n return false;\n }\n\n /** Get the configured model list for a provider. */\n private getProviderModels(providerId: string): string[] {\n const pc = this.config.providers?.[providerId];\n return pc?.models ?? [];\n }\n\n /** Record cost for a model. */\n recordCost(provider: string, model: string, cost: number, tokens?: { input: number; output: number }): void {\n const key = `${provider}/${model}`;\n const entry = this.costs.byModel[key] ?? { cost: 0, tokens: { input: 0, output: 0 }, calls: 0 };\n entry.cost += cost;\n if (tokens) {\n entry.tokens.input += tokens.input;\n entry.tokens.output += tokens.output;\n }\n entry.calls += 1;\n this.costs.byModel[key] = entry;\n this.costs.totalCost += cost;\n }\n\n /** Get cumulative costs. */\n getCosts(): RouterCosts {\n return { ...this.costs, byModel: { ...this.costs.byModel } };\n }\n\n /** Reset cost tracking. */\n resetCosts(): void {\n this.costs = { byModel: {}, totalCost: 0 };\n }\n\n /** List all available providers with their best model for each task category. */\n suggestMatrix(): Record<string, ModelPick> {\n const matrix: Record<string, ModelPick> = {};\n const roles = [\n 'security-scanner', 'bug-hunter', 'planner', 'architect',\n 'refactor-planner', 'test', 'document', 'code-reviewer',\n 'executor', 'debugger', 'analyst',\n ];\n\n for (const role of roles) {\n // Don't override explicit user matrix entries\n if (this.matrix[role]) continue;\n\n const pick = this.pickForTask(role, role);\n if (!pick.fromMatrix) {\n matrix[role] = pick;\n }\n }\n\n return matrix;\n }\n}\n"]}