@wrongstack/core 0.292.0 → 0.292.1

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/expect-defined.ts", "../../src/utils/error.ts", "../../src/security/capabilities.ts", "../../src/infrastructure/mcp-servers.ts", "../../src/utils/config-json.ts", "../../src/utils/atomic-write.ts", "../../src/types/blocks.ts", "../../src/utils/string.ts", "../../src/types/errors.ts", "../../src/tools/mcp-control.ts", "../../src/execution/council-personas.ts", "../../src/execution/council-profiles.ts", "../../src/utils/instruction-file.ts", "../../src/execution/council-prompts.ts", "../../src/execution/council-resolution.ts", "../../src/execution/council-orchestrator.ts", "../../src/tools/council-tool.ts", "../../src/core/model-availability-calendar.ts", "../../src/types/provider.ts", "../../src/execution/one-shot-llm.ts", "../../src/tools/one-shot-llm-tool.ts", "../../src/coordination/agents/types.ts", "../../src/coordination/agents/agent-prompts.ts", "../../src/coordination/agents/phase1-discovery.ts", "../../src/coordination/agents/phase2-planning.ts", "../../src/coordination/agents/phase3-build.ts", "../../src/coordination/agents/phase4-verify.ts", "../../src/coordination/agents/phase5-review.ts", "../../src/coordination/agents/phase6-domain.ts", "../../src/coordination/agents/phase7-knowledge.ts", "../../src/coordination/agents/phase8-delivery.ts", "../../src/coordination/agents/phase9-meta.ts", "../../src/coordination/agents/index.ts", "../../src/core/fallback-profile-manager.ts", "../../src/core/fallback-model.ts", "../../src/coordination/model-matrix.ts", "../../src/tools/fallback-manage-tools.ts"],
4
- "sourcesContent": ["/** 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", "/**\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", "/**\n * Well-known tool capabilities used for authorization decisions.\n *\n * These are the preferred values for `Tool.capabilities`.\n * New capabilities should be added here with clear documentation.\n *\n * Philosophy (2026-06+):\n * - Prefer capabilities over exact tool name matching.\n * - Subagent guards and future policies should primarily key off capabilities.\n * - Name-based denylists are legacy and will be phased down.\n */\nexport const ToolCapabilities = {\n /** Can execute arbitrary commands in the user's shell (the `bash` tool). */\n SHELL_ARBITRARY: 'shell.arbitrary',\n\n /** Can execute a restricted set of commands (the `exec` tool). */\n SHELL_RESTRICTED: 'shell.restricted',\n\n /** Can run a restricted project formatter/linter-style command. */\n SHELL_EXEC: 'shell.exec',\n\n /** Can read files inside the project (and possibly outside via symlinks if not guarded). */\n FS_READ: 'fs.read',\n\n /** Can write / modify / delete files inside the project. */\n FS_WRITE: 'fs.write',\n\n /** Can write files outside the current project root (very high risk). */\n FS_WRITE_OUTSIDE_PROJECT: 'fs.write.outside-project',\n\n /** Can perform outbound network requests. */\n NET_OUTBOUND: 'net.outbound',\n\n /** Can mutate in-memory session todos only. */\n SESSION_TODO: 'session.todo',\n\n /** Can mutate in-memory session mode only. */\n SESSION_MODE: 'session.mode',\n\n /** Can inspect registered tool metadata. */\n TOOL_META: 'tool.meta',\n\n /** Can invoke arbitrary registered tools through a meta-tool. */\n TOOL_MUTATE_ANY: 'tool.mutate.any',\n\n /** Can read persistent memory. */\n MEMORY_READ: 'memory.read',\n\n /** Can write persistent memory. */\n MEMORY_WRITE: 'memory.write',\n\n /** Can delete persistent memory. */\n MEMORY_DELETE: 'memory.delete',\n\n /** Proxies tools from external MCP servers (unknown capability). */\n MCP_PROXY: 'mcp.proxy',\n\n /** Can spawn or manage subagents / multi-agent tasks. */\n SUBAGENT_SPAWN: 'subagent.spawn',\n\n /** Can inspect fleet/subagent coordination state without mutating it. */\n COORDINATION_FLEET_READ: 'coordination.fleet.read',\n\n /** Can publish attributed, schema-checked events onto the fleet bus. */\n COORDINATION_FLEET_EMIT: 'coordination.fleet.emit',\n\n /** Can submit a task-local structured result to the parent Director. */\n COORDINATION_RESULT_SUBMIT: 'coordination.result.submit',\n\n /** Can read or write inter-agent mailbox messages. */\n COORDINATION_MAIL: 'coordination.mail',\n\n /** Can schedule, inspect, or cancel in-session cron jobs. */\n COORDINATION_CRON: 'coordination.cron',\n\n /** Can mutate global or session configuration / trust state. */\n CONFIG_MUTATE: 'config.mutate',\n\n /** Can install packages or run package managers with side effects. */\n PACKAGE_INSTALL: 'package.install',\n} as const;\n\nexport type ToolCapability = (typeof ToolCapabilities)[keyof typeof ToolCapabilities];\n\n/**\n * Set of capabilities that are considered dangerous for subagents by default.\n * Subagents should not receive these capabilities unless the leader explicitly\n * allows the specific tool at spawn time.\n */\nexport const DANGEROUS_FOR_SUBAGENTS: readonly ToolCapability[] = [\n ToolCapabilities.SHELL_ARBITRARY,\n ToolCapabilities.SHELL_RESTRICTED,\n ToolCapabilities.SHELL_EXEC,\n ToolCapabilities.FS_WRITE,\n ToolCapabilities.FS_WRITE_OUTSIDE_PROJECT,\n ToolCapabilities.TOOL_MUTATE_ANY,\n ToolCapabilities.MEMORY_WRITE,\n ToolCapabilities.MEMORY_DELETE,\n ToolCapabilities.MCP_PROXY,\n ToolCapabilities.SUBAGENT_SPAWN,\n ToolCapabilities.CONFIG_MUTATE,\n ToolCapabilities.PACKAGE_INSTALL,\n];\n\n/**\n * Wide capability allowlist for subagents that the user has authorized to act\n * with full developer power (the CLI fleet host applies this to any subagent\n * that isn't given an explicit, narrower grant). It covers everything needed to\n * do real work end-to-end \u2014 read, write/edit inside the project, outbound\n * network, all shell/build/install capabilities, session todos, tool metadata, and read-only\n * memory lookup \u2014 so a delegated coding or build agent runs the same toolchain\n * the leader would, without per-tool confirmation it cannot answer.\n *\n * Deliberately EXCLUDED (require an explicit per-spawn `allowedCapabilities`\n * grant, because they escape the task's blast radius rather than perform it):\n * - `fs.write.outside-project` \u2014 writing outside the repo (e.g. ~/.ssh).\n * - `tool.mutate.any` \u2014 arbitrary meta-tool dispatch.\n * - `memory.write` / `memory.delete` \u2014 persistent memory mutation.\n * - `mcp.proxy` \u2014 third-party MCP tools (also hard-blocked by name).\n * - `subagent.spawn` \u2014 recursive delegation (the baseline prompt forbids it).\n * - `config.mutate` \u2014 rewriting trust/config is privilege escalation, not work.\n */\nexport const WIDE_SUBAGENT_CAPABILITIES: readonly ToolCapability[] = [\n ToolCapabilities.FS_READ,\n ToolCapabilities.FS_WRITE,\n ToolCapabilities.NET_OUTBOUND,\n ToolCapabilities.SESSION_TODO,\n ToolCapabilities.TOOL_META,\n ToolCapabilities.MEMORY_READ,\n ToolCapabilities.SHELL_ARBITRARY,\n ToolCapabilities.SHELL_RESTRICTED,\n ToolCapabilities.SHELL_EXEC,\n ToolCapabilities.PACKAGE_INSTALL,\n // Read-only fleet visibility (fleet_status) \u2014 peer awareness has no blast\n // radius and every fleet worker should coordinate around its peers.\n ToolCapabilities.COORDINATION_FLEET_READ,\n ToolCapabilities.COORDINATION_RESULT_SUBMIT,\n];\n\n/**\n * Check if a tool (or its capabilities array) includes any dangerous capability\n * for subagent execution.\n */\nexport function hasDangerousCapabilityForSubagents(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n): boolean {\n if (!toolOrCaps) return false;\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n return caps.some((c) => DANGEROUS_FOR_SUBAGENTS.includes(c as ToolCapability));\n}\n\n/**\n * Check if a tool declares a specific capability (or any of the provided ones).\n */\nexport function hasCapability(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n capability: ToolCapability | ToolCapability[],\n): boolean {\n if (!toolOrCaps) return false;\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n const toCheck = Array.isArray(capability) ? capability : [capability];\n return toCheck.some((c) => caps.includes(c));\n}\n\n/**\n * Returns the intersection of a tool's capabilities with the dangerous set.\n * Useful for logging and audit trails.\n */\nexport function getDangerousCapabilities(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n): ToolCapability[] {\n if (!toolOrCaps) return [];\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n return caps.filter((c): c is ToolCapability =>\n DANGEROUS_FOR_SUBAGENTS.includes(c as ToolCapability),\n );\n}\n", "import type { MCPServerConfig } from '../types/config.js';\n\n/**\n * Built-in MCP server presets available to all WrongStack users out of the box.\n * These servers must be explicitly enabled in config (disabled by default).\n *\n * To enable: set `mcpServers: { serverName: { enabled: true } }` in your config.\n *\n * Some servers require environment variables or additional config \u2014 see notes below.\n *\n * Transport types:\n * stdio \u2014 spawns a local npm package binary via child_process\n * sse \u2014 HTTP SSE endpoint (client POSTs requests)\n * streamable-http \u2014 session-based HTTP with NDJSON responses\n */\n\n/** Filesystem access: read, write, list, search, tree. Good for exploring projects. */\nexport const filesystemServer = (): MCPServerConfig => ({\n name: 'filesystem',\n description: 'Read, write, and navigate the local filesystem (read-heavy tools)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-filesystem', '.'],\n permission: 'confirm',\n});\n\n/** GitHub API: issues, PRs, repos, search, file operations. Requires GITHUB_PERSONAL_ACCESS_TOKEN. */\nexport const githubServer = (): MCPServerConfig => ({\n name: 'github',\n description:\n 'GitHub API \u2014 issues, PRs, repos, search, file ops (requires GITHUB_PERSONAL_ACCESS_TOKEN)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-github'],\n passthroughEnv: ['GITHUB_PERSONAL_ACCESS_TOKEN', 'GITHUB_TOKEN'],\n permission: 'confirm',\n});\n\n/**\n * Context7 \u2014 codebase-aware documentation and Q&A using context from your code.\n * Live documentation for any library, grounded in your actual versions.\n */\nexport const context7Server = (): MCPServerConfig => ({\n name: 'context7',\n description: 'Codebase-aware documentation and Q&A (context7.ai)',\n transport: 'streamable-http',\n url: 'https://mcp.context7.com/mcp',\n permission: 'confirm',\n});\n\n/**\n * Brave Search \u2014 web search via Brave Browser's API.\n * Requires BRAVE_SEARCH_API_KEY. Free tier: 2,000 queries/month.\n * Sign up at https://api.search.brave.com/\n */\nexport const braveSearchServer = (): MCPServerConfig => ({\n name: 'brave-search',\n description: 'Web search (Brave). Requires BRAVE_SEARCH_API_KEY \u2014 free tier 2k queries/month',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-brave-search'],\n passthroughEnv: ['BRAVE_SEARCH_API_KEY'],\n permission: 'confirm',\n});\n\n/**\n * Block (Block, Inc.) \u2014 Postgres database access via SQL.\n * Useful for running queries against a connected database during development.\n */\nexport const blockServer = (): MCPServerConfig => ({\n name: 'block',\n description: 'Postgres database access via SQL (Block MCP server)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-block'],\n permission: 'confirm',\n});\n\n/**\n * EverArt \u2014 AI image generation via various providers.\n * Requires EVERART_API_KEY.\n */\nexport const everArtServer = (): MCPServerConfig => ({\n name: 'everart',\n description: 'AI image generation (EverArt). Requires EVERART_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-everart'],\n passthroughEnv: ['EVERART_API_KEY'],\n permission: 'confirm',\n});\n\n/**\n * Slack \u2014 messaging, channels, search.\n * Requires SLACK_BOT_TOKEN and either SLACK_TEAM_ID or SLACK_USER_TOKEN.\n */\nexport const slackServer = (): MCPServerConfig => ({\n name: 'slack',\n description: 'Slack \u2014 messaging, channels, search. Requires SLACK_BOT_TOKEN + SLACK_TEAM_ID',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-slack'],\n passthroughEnv: ['SLACK_BOT_TOKEN', 'SLACK_TEAM_ID'],\n permission: 'confirm',\n});\n\n/**\n * AWS knowledge base \u2014 EC2, S3, Lambda, IAM, CloudFormation, cost management.\n * Requires AWS access key + secret in environment.\n */\nexport const awsServer = (): MCPServerConfig => ({\n name: 'aws',\n description: 'AWS \u2014 EC2, S3, Lambda, IAM, CloudFormation, costs. Requires AWS credentials',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-aws'],\n passthroughEnv: ['AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'AWS_REGION', 'AWS_SESSION_TOKEN'],\n permission: 'confirm',\n});\n\n/**\n * Google Maps \u2014 directions, distance matrix, geocoding, places.\n * Requires GOOGLE_MAPS_API_KEY.\n */\nexport const googleMapsServer = (): MCPServerConfig => ({\n name: 'google-maps',\n description: 'Google Maps \u2014 directions, geocoding, places. Requires GOOGLE_MAPS_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-google-maps'],\n passthroughEnv: ['GOOGLE_MAPS_API_KEY'],\n permission: 'confirm',\n});\n\n/** Sentinel \u2014 security vulnerability scanning (sentinel-labs). */\nexport const sentinelServer = (): MCPServerConfig => ({\n name: 'sentinel',\n description: 'Security vulnerability scanning (Sentinel)',\n transport: 'streamable-http',\n url: 'https://mcp.sentinel.ai',\n permission: 'deny', // security tool \u2014 require explicit confirmation\n});\n\n/**\n * Z.AI Vision MCP \u2014 image understanding fallback for text-only models.\n * Requires Z_AI_API_KEY. Tools are read-only and safe to run automatically.\n */\nexport const zaiVisionServer = (): MCPServerConfig => ({\n name: 'zai-vision',\n description: 'Z.AI Vision MCP \u2014 image analysis and screenshot understanding',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@z_ai/mcp-server@latest'],\n env: { Z_AI_MODE: 'ZAI' },\n passthroughEnv: ['Z_AI_API_KEY'],\n allowedTools: [\n 'image_analysis',\n 'extract_text_from_screenshot',\n 'diagnose_error_screenshot',\n 'understand_technical_diagram',\n 'analyze_data_visualization',\n 'ui_diff_check',\n ],\n permission: 'auto',\n});\n\n/**\n * Playwright \u2014 browser automation: navigate, click, type, screenshot, evaluate JS.\n * Spawns a headless Chromium browser via @modelcontextprotocol/server-playwright.\n * Tools can read and interact with live web pages \u2014 permission defaults to\n * `confirm` because form submission / DOM mutation is possible.\n */\nexport const playwrightServer = (): MCPServerConfig => ({\n name: 'playwright',\n description:\n 'Browser automation \u2014 navigate, screenshot, click, type, evaluate JS (headless Chromium)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-playwright'],\n permission: 'confirm',\n});\n\n/**\n * MiniMax Token Plan MCP \u2014 search + understand_image.\n * This preset exposes only the read-only image understanding tool by default.\n * Requires MINIMAX_API_KEY and uvx on PATH.\n */\nexport const miniMaxVisionServer = (): MCPServerConfig => ({\n name: 'minimax-vision',\n description: 'MiniMax MCP \u2014 image understanding via understand_image',\n transport: 'stdio',\n command: 'uvx',\n args: ['minimax-coding-plan-mcp', '-y'],\n env: {\n MINIMAX_MCP_BASE_PATH: './.wrongstack/minimax-output',\n MINIMAX_API_HOST: 'https://api.minimax.io',\n MINIMAX_API_RESOURCE_MODE: 'url',\n },\n passthroughEnv: ['MINIMAX_API_KEY'],\n allowedTools: ['understand_image'],\n permission: 'auto',\n});\n\n/**\n * SSH Manager \u2014 remote SSH execution, file transfer, tunnels, health checks, and deployment ops.\n * Server credentials are intentionally NOT embedded here. Configure hosts via mcp-ssh-manager's\n * env/TOML config (for example SSH_SERVER_<NAME>_HOST, USER, KEYPATH/PASSWORD) or ssh-agent.\n */\nexport const sshManagerServer = (): MCPServerConfig => ({\n name: 'ssh',\n description:\n 'Remote SSH management \u2014 execute commands, transfer files, tunnels, health checks (mcp-ssh-manager)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', 'mcp-ssh-manager'],\n env: {\n MCP_SSH_COMPACT_JSON: 'true',\n MCP_SSH_DEFAULT_TIMEOUT: '120000',\n },\n permission: 'confirm',\n requestTimeoutMs: 180_000,\n});\n\n/** Everything bundled \u2014 full set of built-in servers. Useful for `wstack mcp add --all`. */\nexport const allServers = (): Record<string, MCPServerConfig> => ({\n filesystem: { ...filesystemServer(), enabled: false },\n github: { ...githubServer(), enabled: false },\n context7: { ...context7Server(), enabled: false },\n 'brave-search': { ...braveSearchServer(), enabled: false },\n block: { ...blockServer(), enabled: false },\n everart: { ...everArtServer(), enabled: false },\n slack: { ...slackServer(), enabled: false },\n aws: { ...awsServer(), enabled: false },\n 'google-maps': { ...googleMapsServer(), enabled: false },\n sentinel: { ...sentinelServer(), enabled: false },\n 'zai-vision': { ...zaiVisionServer(), enabled: false },\n 'minimax-vision': { ...miniMaxVisionServer(), enabled: false },\n playwright: { ...playwrightServer(), enabled: false },\n ssh: { ...sshManagerServer(), enabled: false },\n});\n", "import * as fs from 'node:fs/promises';\nimport { atomicWrite } from './atomic-write.js';\n\nexport type JsonObject = Record<string, unknown>;\nexport type JsonPathSegment = string | number;\nexport type JsonPath = readonly JsonPathSegment[];\n\nexport async function readJsonObjectFile(filePath: string): Promise<JsonObject> {\n try {\n const parsed = JSON.parse(await fs.readFile(filePath, 'utf8')) as unknown;\n return isJsonObject(parsed) ? parsed : {};\n } catch {\n return {};\n }\n}\n\nexport async function jsonObjectFileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function writeJsonObjectFile(filePath: string, value: JsonObject): Promise<void> {\n await atomicWrite(filePath, JSON.stringify(value, null, 2), { mode: 0o600 });\n}\n\nexport async function updateJsonObjectFile(\n filePath: string,\n mutator: (config: JsonObject) => void | JsonObject | Promise<void | JsonObject>,\n): Promise<JsonObject> {\n const config = await readJsonObjectFile(filePath);\n const maybeNext = await mutator(config);\n const next = maybeNext && isJsonObject(maybeNext) ? maybeNext : config;\n await writeJsonObjectFile(filePath, next);\n return next;\n}\n\nexport function getJsonPath(root: unknown, path: JsonPath): unknown {\n let current = root;\n for (const segment of path) {\n if (typeof segment === 'number') {\n if (!Array.isArray(current)) return undefined;\n current = current[segment];\n continue;\n }\n if (!isJsonObject(current)) return undefined;\n current = current[segment];\n }\n return current;\n}\n\nexport function setJsonPath(root: JsonObject, path: JsonPath, value: unknown): JsonObject {\n if (path.length === 0) {\n if (!isJsonObject(value)) throw new Error('Root config value must be an object');\n return value;\n }\n const parent = ensureJsonParent(root, path);\n const leaf = lastPathSegment(path);\n if (typeof leaf === 'number') {\n if (!Array.isArray(parent)) throw new Error(`Cannot set numeric segment ${leaf} on non-array parent`);\n parent[leaf] = value;\n } else {\n if (!isJsonObject(parent)) throw new Error(`Cannot set property ${leaf} on non-object parent`);\n parent[leaf] = value;\n }\n return root;\n}\n\nexport function removeJsonPath(root: JsonObject, path: JsonPath): boolean {\n if (path.length === 0) return false;\n const parent = getJsonPath(root, path.slice(0, -1));\n const leaf = lastPathSegment(path);\n if (typeof leaf === 'number') {\n if (!Array.isArray(parent) || leaf < 0 || leaf >= parent.length) return false;\n parent.splice(leaf, 1);\n return true;\n }\n if (!isJsonObject(parent) || !(leaf in parent)) return false;\n delete parent[leaf];\n return true;\n}\n\nexport async function setJsonPathInFile(filePath: string, path: JsonPath, value: unknown): Promise<JsonObject> {\n return updateJsonObjectFile(filePath, (config) => setJsonPath(config, path, value));\n}\n\nexport async function removeJsonPathInFile(filePath: string, path: JsonPath): Promise<JsonObject> {\n return updateJsonObjectFile(filePath, (config) => {\n removeJsonPath(config, path);\n });\n}\n\nexport function isJsonObject(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction lastPathSegment(path: JsonPath): JsonPathSegment {\n const segment = path[path.length - 1];\n /* v8 ignore next -- defensive: callers guard path.length === 0 before here */\n if (segment === undefined) throw new Error('Invalid empty JSON path');\n return segment;\n}\n\nfunction ensureJsonParent(root: JsonObject, path: JsonPath): JsonObject | unknown[] {\n let current: JsonObject | unknown[] = root;\n for (let i = 0; i < path.length - 1; i += 1) {\n const segment = path[i];\n const nextSegment = path[i + 1];\n /* v8 ignore next -- defensive: sparse-array paths are never produced by callers */\n if (segment === undefined) throw new Error('Invalid empty JSON path segment');\n const nextContainer = typeof nextSegment === 'number' ? [] : {};\n\n if (typeof segment === 'number') {\n if (!Array.isArray(current)) throw new Error(`Cannot traverse numeric segment ${segment} on non-array parent`);\n if (!isJsonObject(current[segment]) && !Array.isArray(current[segment])) current[segment] = nextContainer;\n current = current[segment] as JsonObject | unknown[];\n } else {\n if (!isJsonObject(current)) throw new Error(`Cannot traverse property ${segment} on non-object parent`);\n if (!isJsonObject(current[segment]) && !Array.isArray(current[segment])) current[segment] = nextContainer;\n current = current[segment] as JsonObject | unknown[];\n }\n }\n return current;\n}\n", "import { randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport { watch as watchDir } from 'node:fs';\nimport type { FSWatcher } from 'node:fs';\nimport * as path from 'node:path';\nimport { FsError } from '../types/errors.js';\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 \u2014 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 // P3 #20 (before-release.md): on Windows, fs.rename (MoveFileExW) does\n // not preserve Unix permission bits \u2014 the chmod above applies to the tmp\n // file, but the rename may reset the destination's mode to the Windows\n // default. Re-apply the mode after rename on win32 so an edited file\n // keeps its executable bit (or any non-default permission). On POSIX,\n // rename preserves metadata so this is a no-op (chmod is idempotent and\n // cheap), but we gate it on win32 to avoid the extra stat+chmod on the\n // common path.\n if (mode !== undefined && process.platform === 'win32') {\n try {\n await fs.chmod(targetPath, mode);\n } catch {\n // Best-effort: a transient EPERM (antivirus lock) should not fail\n // the write \u2014 the content is already on disk.\n }\n }\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 // A lock holder can be scheduled out for several seconds when the full test\n // suite (or a busy workstation) is spawning many child processes. Five\n // seconds was short enough to turn ordinary contention into a dropped\n // best-effort index write. Keep the wait bounded, but leave enough headroom\n // for the holder to resume and release before stale-lock recovery applies.\n const timeoutMs = opts.timeoutMs ?? 15_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 // If fs.open succeeded but handle.writeFile threw (e.g. ENOSPC, EIO),\n // `handle` owns an open exclusive lock file. Close the handle and remove\n // the orphan lock so the next iteration (or a peer) can acquire it\n // without timing out on the stale-lock window or dead-looping on EEXIST.\n if (handle) {\n await handle.close().catch(() => {});\n await fs.unlink(lockPath).catch(() => {});\n handle = undefined;\n }\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' && code !== 'EPERM') 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 const elapsed = Date.now() - started;\n if (elapsed >= timeoutMs) {\n throw new FsError({\n message: `Timed out waiting for file lock: ${targetPath}`,\n code: 'FS_ATOMIC_WRITE_FAILED',\n path: targetPath,\n context: { timeoutMs },\n });\n }\n // Wait for the lock to be released, using a filesystem watcher for\n // nearly-instant wake-up instead of polling. The watcher is best-effort:\n // a safety timeout fires at most every 100ms so we don't busy-wait.\n await waitForLockRelease(lockPath, timeoutMs - elapsed);\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/**\n * Watch a lock file's parent directory for the file being removed (unlinked),\n * which signals that the lock holder has released it. A safety timeout caps\n * the wait so the overall `withFileLock` timeout is always respected.\n *\n * Uses a bounded safety interval (up to 100ms) so even if `fs.watch` is\n * unavailable or misses the event, we never busy-wait at 25ms fixed polling.\n */\nasync function waitForLockRelease(lockPath: string, remainingMs: number): Promise<void> {\n const parentDir = path.dirname(lockPath);\n const lockName = path.basename(lockPath);\n const intervalMs = Math.min(remainingMs, 100);\n\n return new Promise<void>((resolve) => {\n let settled = false;\n let watcher: FSWatcher | null = null;\n\n // Safety timer \u2014 always fires, even if fs.watch is unavailable.\n const timer = setTimeout(() => {\n settled = true;\n watcher?.close();\n resolve();\n }, intervalMs);\n\n try {\n watcher = watchDir(parentDir, (eventType, filename) => {\n if (settled) return;\n // 'rename' fires on unlink on most platforms; 'change' is a\n // conservative fallback for environments that only emit 'change'.\n if (filename === lockName && (eventType === 'rename' || eventType === 'change')) {\n settled = true;\n clearTimeout(timer);\n watcher?.close();\n resolve();\n }\n });\n } catch {\n // fs.watch not supported (e.g. some container environments, network\n // filesystems). Clear the safety timer and fall back to a single\n // short delay \u2014 the caller's loop will retry on the next iteration.\n clearTimeout(timer);\n if (!settled) {\n settled = true;\n setTimeout(resolve, Math.min(remainingMs, 25));\n }\n return;\n }\n\n // Re-check lock existence after setting up the watch to close the race\n // where the lock was released between our last EEXIST check and now.\n fs.access(lockPath).then(\n () => {\n // Lock still exists \u2014 the watch (or safety timer) will resolve.\n },\n () => {\n // Lock was already released \u2014 respond immediately.\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n watcher?.close();\n resolve();\n }\n },\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 \u2014 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", "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` \u2014 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` \u2014 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` \u2014 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 \u2014 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}\n", "/**\n * String utilities shared across the WrongStack codebase.\n */\n\n/**\n * Truncate a string to at most `max` characters, appending an ellipsis if it\n * was longer. Returns the original string unchanged when it fits.\n */\nexport function truncate(s: string, max: number): string {\n return s.length <= max ? s : `${s.slice(0, max - 1)}\u2026`;\n}\n", "import { toErrorMessage } from '../utils/index.js';\n\n/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// \u2500\u2500 Error codes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n PARSE_FAILED: 'PARSE_FAILED',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` \u2014 no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// \u2500\u2500 Base error class \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// \u2500\u2500 Specific error classes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Tool execution errors \u2014 thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors \u2014 thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = toErrorMessage(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors \u2014 spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n/**\n * HTTP fetch error \u2014 thrown when a network request returns a non-OK status.\n * Carries the response status so {@link classifyToolError} can branch on it\n * (429 \u2192 transient, 404 \u2192 not_found, 401 \u2192 permission) without duck-typing\n * the error via `'response' in err`.\n *\n * P3 #18 (before-release.md): the previous `'response' in err` check caught\n * any Error with a `response` property, including custom errors, proxy\n * objects, or mocked errors in tests. `instanceof FetchError` is reliable.\n *\n * Tools and providers that make HTTP requests and need the executor to\n * classify their failures should throw `new FetchError({ status, message })`\n * instead of a bare `Error` with an ad-hoc `response` field.\n */\nexport class FetchError extends WrongStackError {\n readonly status: number;\n\n constructor(opts: {\n message: string;\n status: number;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: opts.status === 429 || opts.status >= 500,\n context: { status: opts.status, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FetchError';\n this.status = opts.status;\n }\n}\n\n/**\n * Tool input validation error \u2014 thrown when a tool's input fails a validation\n * check that the JSON Schema cannot express (e.g. `old_string === new_string`\n * in edit, or a cross-field invariant). Use this instead of a bare\n * `throw new Error('...validation...')` so {@link classifyToolError} can\n * match on `instanceof` rather than a locale-dependent message substring.\n *\n * P2 #6 (before-release.md): the previous `err.message.includes('validation')`\n * check misclassified any error whose message happened to contain \"validation\"\n * (e.g. a third-party \"input validation timeout\") as a VALIDATION error.\n *\n * Named `ToolValidationError` (not `ValidationError`) to avoid colliding with\n * the existing `ValidationError` interface exported by json-schema-validate.ts\n * (a validation-result shape, not an Error subclass).\n */\nexport class ToolValidationError extends WrongStackError {\n constructor(opts: {\n message: string;\n /** Field path or tool name that failed validation, for diagnostics. */\n field?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { field: opts.field, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolValidationError';\n }\n}\n\n/**\n * Response / payload parse error \u2014 thrown when an upstream HTTP response,\n * file, or data structure is well-formed at the transport layer (HTTP 200,\n * valid JSON) but is missing required fields or has an unexpected shape.\n *\n * Distinct from `ConfigError(CONFIG_PARSE_FAILED)` (which is specifically\n * for config-file parsing) and `FetchError` (which covers HTTP non-OK\n * responses). `ParseError` fills the gap: the request succeeded but the\n * response body couldn't be interpreted.\n *\n * Common sites: OAuth token responses missing `access_token`, device-code\n * responses missing `device_code`, registry responses with unexpected\n * schemas.\n */\nexport class ParseError extends WrongStackError {\n readonly source?: string | undefined;\n\n constructor(opts: {\n message: string;\n /**\n * What was being parsed \u2014 e.g. `'oauth-token-response'`,\n * `'device-code-response'`. Lets consumers distinguish parse failures\n * from different upstream APIs without parsing the message.\n */\n source?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.PARSE_FAILED,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { source: opts.source, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ParseError';\n this.source = opts.source;\n }\n}\n\n// \u2500\u2500 Type guards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isToolValidationError(err: unknown): err is ToolValidationError {\n return err instanceof ToolValidationError;\n}\n\nexport function isFetchError(err: unknown): err is FetchError {\n return err instanceof FetchError;\n}\n\nexport function isParseError(err: unknown): err is ParseError {\n return err instanceof ParseError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n", "import { expectDefined } from '../utils/expect-defined.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { ToolCapabilities } from '../security/capabilities.js';\n/**\n * `mcp_control` \u2014 LLM-driven MCP server lifecycle management.\n *\n * The model calls this tool to:\n * list \u2014 see all known servers (running or not) without starting any\n * search \u2014 filter the server catalog by name or description keyword\n * enable \u2014 start a server and register its tools\n * disable \u2014 stop a server and unregister its tools\n * restart \u2014 stop then re-start a running server\n *\n * This is the primary mechanism by which the LLM autonomously extends its\n * own capabilities at runtime \u2014 e.g. \"I need GitHub access, let me enable it.\"\n */\nimport { allServers } from '../infrastructure/mcp-servers.js';\nimport { readJsonObjectFile, setJsonPath, updateJsonObjectFile } from '../utils/config-json.js';\nimport type { Config, JSONSchema, MCPServerConfig, Tool } from '../index.js';\nexport interface MCPRegistryHandle {\n start(cfg: MCPServerConfig): Promise<void>;\n stop(name: string): Promise<void>;\n restart(name: string): Promise<void>;\n describe(): {\n name: string;\n state: string;\n toolCount: number;\n enabled: boolean;\n tools?: string[];\n }[];\n list(): { name: string; state: string; toolCount: number; tools?: string[] }[];\n /**\n * Register all cached tools for a server without restarting it.\n * No-op if the server is not connected or tools are already active.\n * Used in token-saving mode to temporarily expose MCP tools.\n */\n activateServer?(name: string): void;\n /**\n * Unregister all tools for a server without disconnecting it.\n * Returns the number of tools that were deactivated.\n * Used in token-saving mode to hide MCP tools after use.\n */\n deactivateServer?(name: string): number;\n /**\n * Check whether a server's tools are currently registered.\n */\n isActivated?(name: string): boolean;\n}\n\nexport interface CreateMcpControlToolOptions {\n /**\n * Read the current config object. The tool never mutates this directly \u2014\n * writes go to the global config file via `configPath`.\n */\n getConfig: () => Config;\n /**\n * Path to the active profile config for atomic config writes.\n */\n configPath: string;\n /**\n * Live MCP registry for runtime start/stop/restart. The tool calls these\n * immediately so the LLM sees the result of its action in the same turn.\n */\n registry: MCPRegistryHandle;\n}\n\nexport function createMcpControlTool(opts: CreateMcpControlToolOptions): Tool {\n const { getConfig, configPath, registry } = opts;\n\n const inputSchema: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'search', 'enable', 'disable', 'restart', 'activate', 'deactivate'],\n description: 'The management action to perform. activate/deactivate toggle tool registration ephemerally without disconnecting.',\n },\n /** Filter for `search`. Matches server name or description case-insensitively. */\n query: {\n type: 'string',\n description: 'Search term for `search` action. Matches server name or description.',\n },\n /** Target server name for `enable`, `disable`, `restart`, `activate`, `deactivate`. */\n server: {\n type: 'string',\n description: 'Server name (e.g. \"github\", \"filesystem\", \"brave-search\").',\n },\n },\n required: ['action'],\n };\n\n return {\n name: 'mcp_control',\n description:\n 'Manage MCP server lifecycle: list available servers, search by name or capability, enable or disable servers at runtime, restart running servers. Use activate/deactivate to ephemerally toggle tool registration without disconnecting \u2014 ideal for token-saving mode where MCP tools are lazy-loaded on demand. NOTE: `enable`/`restart` start a server process, which for the built-in stdio presets runs `npx -y <package>` \u2014 i.e. it fetches and executes an npm package from the network. Treat it as code execution.',\n category: 'mcp',\n permission: 'confirm',\n mutating: true,\n // `enable`/`restart` spawn a server process that, for the stdio presets,\n // fetches and runs an npm package (`npx -y <pkg>`) \u2014 effectively remote\n // code execution. Marking the tool destructive preserves risk metadata for\n // UI/audit surfaces; YOLO itself still auto-approves unless an explicit\n // deny rule blocks the call. Read-only actions (list/search) ride the same\n // tool but are cheap to confirm/trust once when YOLO is off.\n riskTier: 'destructive',\n capabilities: [ToolCapabilities.CONFIG_MUTATE],\n inputSchema,\n async execute(raw) {\n const input = raw as { action: string; query?: string | undefined; server?: string | undefined };\n return mcpControlDispatch(input, { getConfig, configPath, registry });\n },\n };\n}\n\n// \u2500\u2500 Dispatch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function mcpControlDispatch(\n input: { action: string; query?: string | undefined; server?: string | undefined },\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n const { action, query, server } = input;\n\n switch (action) {\n case 'list': return renderList(deps);\n case 'search': return renderSearch(query ?? '', deps);\n case 'enable': return server ? runEnable(server, deps) : '`server` is required for enable.';\n case 'disable': return server ? runDisable(server, deps) : '`server` is required for disable.';\n case 'restart': return server ? runRestart(server, deps) : '`server` is required for restart.';\n case 'activate': return server ? runActivate(server, deps) : '`server` is required for activate.';\n case 'deactivate': return server ? runDeactivate(server, deps) : '`server` is required for deactivate.';\n default:\n return `Unknown action \"${action}\". Use one of: list, search, enable, disable, restart, activate, deactivate.`;\n }\n}\n\n// \u2500\u2500 Actions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function renderList(deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle }): Promise<string> {\n const configured = await getConfiguredMcpServers(deps);\n const live = deps.registry.describe();\n\n if (Object.keys(configured).length === 0) {\n return [\n 'No MCP servers configured.',\n ' Use `mcp_control({ action: \"search\" })` to see available presets,',\n ' then `mcp_control({ action: \"enable\", server: \"<name>\" })` to add one.',\n ].join('\\n');\n }\n\n const lines: string[] = [];\n const liveMap = new Map(live.map((s) => [s.name, s]));\n\n for (const [name, cfg] of Object.entries(configured)) {\n const liveInfo = liveMap.get(name);\n const toolCount = liveInfo ? ` (${liveInfo.toolCount} tools)` : '';\n const stateStr = liveInfo ? badge(liveInfo.state) : dim('\u25CB not loaded');\n const enabled = cfg.enabled === false\n ? `${dim('disabled')} `\n : `${green('\u25CF enabled')} `;\n lines.push(` ${bold(name)} ${enabled}${stateStr}${toolCount}`);\n if (cfg.description) lines.push(` ${dim(cfg.description)}`);\n }\n\n lines.push('');\n lines.push(dim(' Use `mcp_control({ action: \"search\", query: \"<keyword>\" })` to find servers.'));\n lines.push(dim(' Use `mcp_control({ action: \"enable\", server: \"<name>\" })` to start a server.'));\n return lines.join('\\n');\n}\n\nasync function renderSearch(\n query: string,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n const configured = await getConfiguredMcpServers(deps);\n const all = allServers();\n const q = query.toLowerCase();\n\n const configuredNames = new Set(Object.keys(configured));\n\n // Match against configured servers first, then remaining presets\n const configuredEntries = Object.entries(configured).filter(\n ([name, cfg]) =>\n name.toLowerCase().includes(q) ||\n (cfg.description ?? '').toLowerCase().includes(q),\n );\n\n const unconfiguredEntries = Object.entries(all)\n .filter(([name]) => !configuredNames.has(name))\n .filter(\n ([name, cfg]) =>\n name.toLowerCase().includes(q) ||\n (cfg.description ?? '').toLowerCase().includes(q),\n );\n\n const lines: string[] = [];\n\n if (configuredEntries.length > 0) {\n lines.push(bold('Configured servers matching \"') + query + '\":');\n for (const [name, cfg] of configuredEntries) {\n lines.push(` ${bold(name)} ${cfg.description ?? cfg.transport}`);\n }\n lines.push('');\n }\n\n if (unconfiguredEntries.length > 0) {\n lines.push(bold('Available presets matching \"') + query + '\":');\n for (const [name, cfg] of unconfiguredEntries) {\n const warn = cfg.permission === 'deny' ? red(' \u26A0 confirm required') : '';\n lines.push(` ${bold(name)} ${cfg.description ?? cfg.transport}${warn}`);\n }\n lines.push('');\n }\n\n if (configuredEntries.length === 0 && unconfiguredEntries.length === 0) {\n return `No servers match \"${query}\". Try a shorter keyword or \\`mcp_control({ action: \"list\" })\\`.`;\n }\n\n const total = configuredEntries.length + unconfiguredEntries.length;\n lines.push(dim(` ${total} server${total !== 1 ? 's' : ''} shown. Run \\`enable\\` on one to activate it.`));\n return lines.join('\\n');\n}\n\nasync function runEnable(\n name: string | undefined,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for enable. Example: { action: \"enable\", server: \"github\" }';\n\n const all = allServers();\n const configured = deps.getConfig().mcpServers ?? {};\n\n // Resolve the target config \u2014 it may be a preset not yet in config\n const cfg = configured[name] ?? all[name];\n if (!cfg) {\n const known = Object.keys(all).join(', ');\n return `Unknown server \"${name}\". Available presets: ${known}`;\n }\n\n // Write to config (add or update) using the shared JSON path helper.\n await updateJsonObjectFile(deps.configPath, (full) => {\n const current = isMcpServerRecord(full.mcpServers) ? full.mcpServers : {};\n setJsonPath(full, ['mcpServers', name], { ...current[name], ...cfg, enabled: true });\n });\n\n // Start the server in the registry\n try {\n const live = deps.registry.describe().find((s) => s.name === name);\n if (live && live.state === 'connected') {\n return `${green('\u25CF')} Server \"${name}\" is already running (${live.toolCount} tools registered).`;\n }\n await deps.registry.start({ ...cfg, enabled: true });\n const updated = deps.registry.describe().find((s) => s.name === name);\n return `${green('\u2713 Enabled and started')} \"${name}\"${updated ? ` (${updated.toolCount} tools registered).` : '.'}`;\n } catch (err) {\n return `${red('\u2717 Failed to start')} \"${name}\": ${toErrorMessage(err)}`;\n }\n}\n\nasync function runDisable(\n name: string | undefined,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for disable. Example: { action: \"disable\", server: \"github\" }';\n\n const configured = deps.getConfig().mcpServers ?? {};\n if (!configured[name]) {\n return `Server \"${name}\" is not in config. Add it with \\`mcp_control({ action: \"enable\", server: \"${name}\" })\\`.`;\n }\n\n // Write to config using the shared JSON path helper.\n await updateJsonObjectFile(deps.configPath, (full) => {\n const current = isMcpServerRecord(full.mcpServers) ? full.mcpServers : {};\n const existing = expectDefined(current[name]);\n setJsonPath(full, ['mcpServers', name], { ...existing, enabled: false });\n });\n\n // Stop the running server\n try {\n await deps.registry.stop(name);\n return `${yellow('\u25CB Disabled')} \"${name}\". It will not be started on next boot.`;\n } catch {\n return `${yellow('\u25CB Disabled')} \"${name}\" (it was not running). Config updated.`;\n }\n}\n\nasync function runRestart(\n name: string | undefined,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for restart. Example: { action: \"restart\", server: \"github\" }';\n\n const configured = deps.getConfig().mcpServers ?? {};\n if (!configured[name]) {\n return `Server \"${name}\" is not configured. Use \\`mcp_control({ action: \"enable\", server: \"${name}\" })\\` first.`;\n }\n\n try {\n await deps.registry.restart(name);\n const updated = deps.registry.describe().find((s) => s.name === name);\n return `${green('\u2713 Restarted')} \"${name}\"${updated ? ` (${updated.toolCount} tools registered).` : '.'}`;\n } catch (err) {\n return `${red('\u2717 Restart failed')} for \"${name}\": ${toErrorMessage(err)}`;\n }\n}\n\n/**\n * Ephemerally activate a server's tools without writing to config or\n * restarting the connection. The server must already be connected (lazy mode).\n * Calls `registry.activateServer()` when available; falls back to a message\n * if the registry doesn't support ephemeral activation.\n */\nasync function runActivate(\n name: string | undefined,\n deps: { registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for activate.';\n if (!deps.registry.activateServer) {\n return `Registry does not support ephemeral activation. Use \\`enable\\` to start \"${name}\" instead.`;\n }\n const live = deps.registry.describe().find((s) => s.name === name);\n if (!live) {\n return `Server \"${name}\" is not registered. Use \\`mcp_control({ action: \"enable\", server: \"${name}\" })\\` first.`;\n }\n if (live.state !== 'connected') {\n return `Server \"${name}\" is not connected (state: ${live.state}). Use \\`enable\\` to start it first.`;\n }\n if (deps.registry.isActivated?.(name)) {\n return `${green('\u25CF')} Server \"${name}\" tools are already active. Use \\`deactivate\\` to hide them.`;\n }\n deps.registry.activateServer(name);\n const updated = deps.registry.describe().find((s) => s.name === name);\n return `${green('\u2713 Activated')} \"${name}\" \u2014 ${updated?.toolCount ?? 0} tool(s) now registered. Use \\`mcp_control({ action: \"deactivate\", server: \"${name}\" })\\` to hide them when done.`;\n}\n\n/**\n * Ephemerally deactivate a server's tools without disconnecting.\n * Calls `registry.deactivateServer()` when available.\n */\nasync function runDeactivate(\n name: string | undefined,\n deps: { registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for deactivate.';\n if (!deps.registry.deactivateServer) {\n return `Registry does not support ephemeral deactivation. Use \\`disable\\` to stop \"${name}\" instead.`;\n }\n if (!deps.registry.isActivated?.(name)) {\n return `Server \"${name}\" tools are not currently active.`;\n }\n const count = deps.registry.deactivateServer(name);\n return `${yellow('\u25CB Deactivated')} \"${name}\" \u2014 ${count} tool(s) unregistered. Server stays connected.`;\n}\n\n// \u2500\u2500 Config helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function getConfiguredMcpServers(deps: { getConfig: () => Config; configPath: string }): Promise<Record<string, MCPServerConfig>> {\n const diskConfig = await readJsonObjectFile(deps.configPath);\n if (isMcpServerRecord(diskConfig.mcpServers)) return diskConfig.mcpServers;\n return deps.getConfig().mcpServers ?? {};\n}\n\nfunction isMcpServerRecord(value: unknown): value is Record<string, MCPServerConfig> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\n// \u2500\u2500 Colour helpers (no dep on core color \u2014 inline) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bold(s: string) { return `\\x1b[1m${s}\\x1b[0m`; }\nfunction dim(s: string) { return `\\x1b[2m${s}\\x1b[0m`; }\nfunction green(s: string) { return `\\x1b[32m${s}\\x1b[0m`; }\nfunction yellow(s: string){ return `\\x1b[33m${s}\\x1b[0m`; }\nfunction red(s: string) { return `\\x1b[31m${s}\\x1b[0m`; }\n\nfunction badge(state: string): string {\n switch (state) {\n case 'connected': return green('\u25CF connected');\n case 'connecting': return `\\x1b[36m\u25D0 connecting\\x1b[0m`;\n case 'reconnecting': return `\\x1b[36m\u25D1 reconnecting\\x1b[0m`;\n case 'disconnected': return dim('\u25CB disconnected');\n case 'failed': return red('\u2717 failed');\n default: return dim(state);\n }\n}\n", "import type { CouncilPersona } from '../types/council.js';\n\nconst PERSONA_ID_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\n/** Provider-neutral personas shipped with every Council installation. */\nexport const BUILTIN_COUNCIL_PERSONAS: readonly CouncilPersona[] = Object.freeze([\n freezePersona({\n id: 'executor',\n name: 'Executor',\n description: 'Tests whether a proposal is practical and keeps useful work moving.',\n instruction:\n 'Evaluate operational feasibility, concrete progress, and the cost of delay. Favor decisive action when evidence supports it, but reject action whose prerequisites are missing.',\n tags: ['delivery', 'feasibility', 'progress'],\n }),\n freezePersona({\n id: 'skeptic',\n name: 'Skeptic',\n description: 'Challenges assumptions and looks for concrete failure modes.',\n instruction:\n 'Identify unsupported assumptions, unsafe premises, irreversible consequences, and credible failure modes. Oppose or refuse only when you can name a concrete reason.',\n defaultVeto: true,\n tags: ['risk', 'assumptions', 'failure-modes'],\n }),\n freezePersona({\n id: 'auditor',\n name: 'Auditor',\n description: 'Evaluates cost, waste, evidence quality, and expected value.',\n instruction:\n 'Compare resource cost, opportunity cost, evidence quality, reversibility, and expected value. Prefer the option that achieves the objective with the least avoidable waste.',\n tags: ['cost', 'evidence', 'efficiency'],\n }),\n freezePersona({\n id: 'security',\n name: 'Security Reviewer',\n description: 'Examines trust boundaries, abuse cases, and security impact.',\n instruction:\n 'Evaluate trust boundaries, attacker-controlled inputs, privilege changes, data exposure, abuse cases, and recovery options. Treat unmitigated high-impact security risk as grounds to refuse.',\n defaultVeto: true,\n tags: ['security', 'trust', 'abuse-cases'],\n }),\n freezePersona({\n id: 'maintainer',\n name: 'Maintainer',\n description: 'Evaluates complexity, compatibility, and long-term ownership.',\n instruction:\n 'Evaluate behavioral compatibility, conceptual complexity, testability, migration cost, and future maintenance. Prefer the smallest design that remains clear and extensible.',\n tags: ['maintenance', 'compatibility', 'simplicity'],\n }),\n freezePersona({\n id: 'user-advocate',\n name: 'User Advocate',\n description: 'Evaluates the decision from the affected user\u2019s perspective.',\n instruction:\n 'Evaluate usability, surprise, accessibility, failure recovery, and whether the outcome solves the user\u2019s stated need. Prefer understandable behavior with safe recovery paths.',\n tags: ['users', 'usability', 'accessibility'],\n }),\n]);\n\n/** Immutable registry of trusted Council persona definitions. */\nexport class CouncilPersonaRegistry {\n private readonly byId: ReadonlyMap<string, CouncilPersona>;\n\n constructor(personas: readonly CouncilPersona[] = []) {\n const entries = new Map<string, CouncilPersona>();\n for (const persona of personas) {\n const normalized = freezePersona(persona);\n if (entries.has(normalized.id)) {\n throw new Error(`CouncilPersonaRegistry: duplicate persona id \"${normalized.id}\".`);\n }\n entries.set(normalized.id, normalized);\n }\n this.byId = entries;\n }\n\n has(id: string): boolean {\n return this.byId.has(id);\n }\n\n get(id: string): CouncilPersona | undefined {\n return this.byId.get(id);\n }\n\n require(id: string): CouncilPersona {\n const persona = this.get(id);\n if (!persona) throw new Error(`CouncilPersonaRegistry: unknown persona \"${id}\".`);\n return persona;\n }\n\n list(): readonly CouncilPersona[] {\n return Object.freeze([...this.byId.values()]);\n }\n\n /** Return a new registry; the current registry is never mutated. */\n with(persona: CouncilPersona, opts: { replace?: boolean | undefined } = {}): CouncilPersonaRegistry {\n const normalized = freezePersona(persona);\n if (this.has(normalized.id) && opts.replace !== true) {\n throw new Error(`CouncilPersonaRegistry: persona \"${normalized.id}\" already exists.`);\n }\n return new CouncilPersonaRegistry([\n ...this.list().filter((entry) => entry.id !== normalized.id),\n normalized,\n ]);\n }\n}\n\nexport const DEFAULT_COUNCIL_PERSONA_REGISTRY = new CouncilPersonaRegistry(\n BUILTIN_COUNCIL_PERSONAS,\n);\n\nexport function createCouncilPersonaRegistry(\n additional: readonly CouncilPersona[] = [],\n): CouncilPersonaRegistry {\n let registry = DEFAULT_COUNCIL_PERSONA_REGISTRY;\n for (const persona of additional) registry = registry.with(persona);\n return registry;\n}\n\nfunction freezePersona(persona: CouncilPersona): CouncilPersona {\n const id = persona.id.trim();\n const name = persona.name.trim();\n const description = persona.description.trim();\n const instruction = persona.instruction.trim();\n if (!PERSONA_ID_RE.test(id)) {\n throw new Error(`CouncilPersonaRegistry: invalid persona id \"${persona.id}\".`);\n }\n if (!name) throw new Error(`CouncilPersonaRegistry: persona \"${id}\" requires a name.`);\n if (!description) {\n throw new Error(`CouncilPersonaRegistry: persona \"${id}\" requires a description.`);\n }\n if (!instruction) {\n throw new Error(`CouncilPersonaRegistry: persona \"${id}\" requires an instruction.`);\n }\n if (\n persona.defaultWeight !== undefined &&\n (!Number.isFinite(persona.defaultWeight) || persona.defaultWeight <= 0)\n ) {\n throw new Error(`CouncilPersonaRegistry: persona \"${id}\" has an invalid default weight.`);\n }\n const tags = Object.freeze(\n [...new Set((persona.tags ?? []).map((tag) => tag.trim()).filter(Boolean))],\n );\n return Object.freeze({\n id,\n name,\n description,\n instruction,\n ...(persona.defaultWeight !== undefined ? { defaultWeight: persona.defaultWeight } : {}),\n ...(persona.defaultVeto !== undefined ? { defaultVeto: persona.defaultVeto } : {}),\n ...(tags.length > 0 ? { tags } : {}),\n });\n}\n", "import type {\n CouncilDistinctness,\n CouncilModelTarget,\n CouncilProfileConfig,\n ResolvedCouncilProfile,\n ResolvedCouncilSeat,\n} from '../types/council.js';\nimport {\n type CouncilPersonaRegistry,\n DEFAULT_COUNCIL_PERSONA_REGISTRY,\n} from './council-personas.js';\n\nconst PROFILE_ID_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nconst DISTINCTNESS_VALUES: ReadonlySet<CouncilDistinctness> = new Set([\n 'none',\n 'model',\n 'provider',\n]);\n\nexport const DEFAULT_COUNCIL_QUORUM_FRACTION = 0.5;\nexport const DEFAULT_COUNCIL_APPROVAL_FRACTION = 0.5;\nexport const DEFAULT_COUNCIL_VOTER_MAX_TOKENS = 300;\nexport const DEFAULT_COUNCIL_JUDGE_MAX_TOKENS = 500;\nexport const DEFAULT_COUNCIL_PER_CALL_TIMEOUT_MS = 30_000;\nexport const DEFAULT_COUNCIL_OVERALL_TIMEOUT_MS = 90_000;\n\n/** Model-agnostic profiles. Roles are routing hints, never provider/model pins. */\nexport const BUILTIN_COUNCIL_PROFILES: readonly CouncilProfileConfig[] = Object.freeze([\n Object.freeze({\n id: 'balanced',\n name: 'Balanced',\n description: 'Three complementary lenses plus an independent judge for general decisions.',\n seats: Object.freeze([\n Object.freeze({ persona: 'executor', target: Object.freeze({ role: 'planner' }) }),\n Object.freeze({ persona: 'skeptic', target: Object.freeze({ role: 'critic' }) }),\n Object.freeze({ persona: 'auditor', target: Object.freeze({ role: 'analyst' }) }),\n ]),\n judge: Object.freeze({ role: 'reviewer' }),\n quorumFraction: 0.5,\n approvalFraction: 0.5,\n distinctness: 'model',\n }),\n Object.freeze({\n id: 'fast',\n name: 'Fast',\n description: 'Two-seat panel without a judge for quick, low-cost decisions.',\n seats: Object.freeze([\n Object.freeze({ persona: 'executor', target: Object.freeze({ role: 'planner' }) }),\n Object.freeze({ persona: 'skeptic', target: Object.freeze({ role: 'critic' }) }),\n ]),\n judge: false,\n quorumFraction: 0.5,\n approvalFraction: 0.5,\n distinctness: 'none',\n voterMaxTokens: 200,\n perCallTimeoutMs: 20_000,\n overallTimeoutMs: 30_000,\n }),\n Object.freeze({\n id: 'risk-review',\n name: 'Risk Review',\n description: 'Security, assumptions, maintenance, and cost review for high-impact choices.',\n seats: Object.freeze([\n Object.freeze({ persona: 'skeptic', target: Object.freeze({ role: 'critic' }) }),\n Object.freeze({ persona: 'security', target: Object.freeze({ role: 'security-reviewer' }) }),\n Object.freeze({ persona: 'maintainer', target: Object.freeze({ role: 'reviewer' }) }),\n Object.freeze({ persona: 'auditor', target: Object.freeze({ role: 'analyst' }) }),\n ]),\n judge: Object.freeze({ role: 'architect' }),\n quorumFraction: 0.75,\n approvalFraction: 0.5,\n distinctness: 'provider',\n judgeMaxTokens: 700,\n overallTimeoutMs: 120_000,\n }),\n]);\n\n/** Immutable registry of normalized Council profiles. */\nexport class CouncilProfileRegistry {\n private readonly byId: ReadonlyMap<string, ResolvedCouncilProfile>;\n private readonly personas: CouncilPersonaRegistry;\n\n constructor(\n profiles: readonly CouncilProfileConfig[] = [],\n personas: CouncilPersonaRegistry = DEFAULT_COUNCIL_PERSONA_REGISTRY,\n ) {\n this.personas = personas;\n const entries = new Map<string, ResolvedCouncilProfile>();\n for (const profile of profiles) {\n const normalized = normalizeCouncilProfile(profile, personas);\n if (entries.has(normalized.id)) {\n throw new Error(`CouncilProfileRegistry: duplicate profile id \"${normalized.id}\".`);\n }\n entries.set(normalized.id, normalized);\n }\n this.byId = entries;\n }\n\n has(id: string): boolean {\n return this.byId.has(id);\n }\n\n get(id: string): ResolvedCouncilProfile | undefined {\n return this.byId.get(id);\n }\n\n require(id: string): ResolvedCouncilProfile {\n const profile = this.get(id);\n if (!profile) throw new Error(`CouncilProfileRegistry: unknown profile \"${id}\".`);\n return profile;\n }\n\n list(): readonly ResolvedCouncilProfile[] {\n return Object.freeze([...this.byId.values()]);\n }\n\n /** Return a new registry; the current registry is never mutated. */\n with(\n profile: CouncilProfileConfig,\n opts: {\n replace?: boolean | undefined;\n personas?: CouncilPersonaRegistry | undefined;\n } = {},\n ): CouncilProfileRegistry {\n const personas = opts.personas ?? this.personas;\n const normalized = normalizeCouncilProfile(profile, personas);\n if (this.has(normalized.id) && opts.replace !== true) {\n throw new Error(`CouncilProfileRegistry: profile \"${normalized.id}\" already exists.`);\n }\n return new CouncilProfileRegistry(\n [\n ...this.list().filter((entry) => entry.id !== normalized.id),\n profile,\n ],\n personas,\n );\n }\n}\n\nexport const DEFAULT_COUNCIL_PROFILE_REGISTRY = new CouncilProfileRegistry(\n BUILTIN_COUNCIL_PROFILES,\n);\n\nexport function createCouncilProfileRegistry(\n additional: readonly CouncilProfileConfig[] = [],\n personas: CouncilPersonaRegistry = DEFAULT_COUNCIL_PERSONA_REGISTRY,\n): CouncilProfileRegistry {\n return new CouncilProfileRegistry([...BUILTIN_COUNCIL_PROFILES, ...additional], personas);\n}\n\nexport function resolveCouncilProfile(\n profile: string | CouncilProfileConfig | undefined,\n opts: {\n registry?: CouncilProfileRegistry | undefined;\n personas?: CouncilPersonaRegistry | undefined;\n defaultProfile?: string | undefined;\n } = {},\n): ResolvedCouncilProfile {\n const personas = opts.personas ?? DEFAULT_COUNCIL_PERSONA_REGISTRY;\n if (profile && typeof profile !== 'string') return normalizeCouncilProfile(profile, personas);\n const id = profile ?? opts.defaultProfile ?? 'balanced';\n return (opts.registry ?? DEFAULT_COUNCIL_PROFILE_REGISTRY).require(id);\n}\n\nexport function normalizeCouncilProfile(\n profile: CouncilProfileConfig,\n personas: CouncilPersonaRegistry = DEFAULT_COUNCIL_PERSONA_REGISTRY,\n): ResolvedCouncilProfile {\n const id = profile.id.trim();\n if (!PROFILE_ID_RE.test(id)) {\n throw new Error(`CouncilProfileRegistry: invalid profile id \"${profile.id}\".`);\n }\n if (profile.seats.length === 0) {\n throw new Error(`CouncilProfileRegistry: profile \"${id}\" requires at least one seat.`);\n }\n\n const usedIds = new Set<string>();\n const seats = profile.seats.map((seat) => {\n const persona = personas.require(seat.persona.trim());\n const explicitSeatId = seat.id?.trim();\n if (explicitSeatId && usedIds.has(explicitSeatId)) {\n throw new Error(`CouncilProfileRegistry: duplicate seat id \"${explicitSeatId}\".`);\n }\n const seatId = uniqueSeatId(explicitSeatId || persona.id, usedIds);\n const label = seat.label?.trim() || persona.name;\n const weight = seat.weight ?? persona.defaultWeight ?? 1;\n if (!Number.isFinite(weight) || weight <= 0) {\n throw new Error(`CouncilProfileRegistry: seat \"${seatId}\" has an invalid weight.`);\n }\n return Object.freeze({\n id: seatId,\n label,\n persona: persona.id,\n ...(seat.target ? { target: freezeTarget(seat.target, `seat \"${seatId}\"`) } : {}),\n weight,\n veto: seat.veto ?? persona.defaultVeto ?? false,\n }) satisfies ResolvedCouncilSeat;\n });\n\n const quorumFraction = fraction(\n profile.quorumFraction ?? DEFAULT_COUNCIL_QUORUM_FRACTION,\n 'quorumFraction',\n id,\n );\n const approvalFraction = fraction(\n profile.approvalFraction ?? DEFAULT_COUNCIL_APPROVAL_FRACTION,\n 'approvalFraction',\n id,\n );\n const distinctness = profile.distinctness ?? 'model';\n if (!DISTINCTNESS_VALUES.has(distinctness)) {\n throw new Error(`CouncilProfileRegistry: profile \"${id}\" has invalid distinctness.`);\n }\n const voterMaxTokens = positiveInteger(\n profile.voterMaxTokens ?? DEFAULT_COUNCIL_VOTER_MAX_TOKENS,\n 'voterMaxTokens',\n id,\n );\n const judgeMaxTokens = positiveInteger(\n profile.judgeMaxTokens ?? DEFAULT_COUNCIL_JUDGE_MAX_TOKENS,\n 'judgeMaxTokens',\n id,\n );\n const perCallTimeoutMs = positiveInteger(\n profile.perCallTimeoutMs ?? DEFAULT_COUNCIL_PER_CALL_TIMEOUT_MS,\n 'perCallTimeoutMs',\n id,\n );\n const overallTimeoutMs = positiveInteger(\n profile.overallTimeoutMs ?? DEFAULT_COUNCIL_OVERALL_TIMEOUT_MS,\n 'overallTimeoutMs',\n id,\n );\n if (overallTimeoutMs < perCallTimeoutMs) {\n throw new Error(\n `CouncilProfileRegistry: profile \"${id}\" overallTimeoutMs must be at least perCallTimeoutMs.`,\n );\n }\n\n return Object.freeze({\n id,\n name: profile.name?.trim() || id,\n description: profile.description?.trim() || '',\n seats: Object.freeze(seats),\n judge: profile.judge ? freezeTarget(profile.judge, 'judge') : false,\n quorumFraction,\n approvalFraction,\n distinctness,\n voterMaxTokens,\n judgeMaxTokens,\n perCallTimeoutMs,\n overallTimeoutMs,\n });\n}\n\nfunction uniqueSeatId(base: string, used: Set<string>): string {\n if (!PROFILE_ID_RE.test(base)) {\n throw new Error(`CouncilProfileRegistry: invalid seat id \"${base}\".`);\n }\n let id = base;\n let suffix = 2;\n while (used.has(id)) id = `${base}-${suffix++}`;\n used.add(id);\n return id;\n}\n\nfunction freezeTarget(target: CouncilModelTarget, label: string): CouncilModelTarget {\n const providerId = optionalText(target.providerId);\n const model = optionalText(target.model);\n const role = optionalText(target.role);\n const fallbackProfile = optionalText(target.fallbackProfile);\n const fallbackModels = Object.freeze(\n [...new Set((target.fallbackModels ?? []).map((ref) => ref.trim()).filter(Boolean))],\n );\n if (\n !providerId &&\n !model &&\n !role &&\n !fallbackProfile &&\n fallbackModels.length === 0\n ) {\n throw new Error(`CouncilProfileRegistry: ${label} target is empty.`);\n }\n return Object.freeze({\n ...(providerId ? { providerId } : {}),\n ...(model ? { model } : {}),\n ...(role ? { role } : {}),\n ...(fallbackProfile ? { fallbackProfile } : {}),\n ...(fallbackModels.length > 0 ? { fallbackModels } : {}),\n });\n}\n\nfunction optionalText(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed || undefined;\n}\n\nfunction fraction(value: number, field: string, profileId: string): number {\n if (!Number.isFinite(value) || value <= 0 || value > 1) {\n throw new Error(`CouncilProfileRegistry: profile \"${profileId}\" ${field} must be in (0, 1].`);\n }\n return value;\n}\n\nfunction positiveInteger(value: number, field: string, profileId: string): number {\n if (!Number.isSafeInteger(value) || value <= 0) {\n throw new Error(\n `CouncilProfileRegistry: profile \"${profileId}\" ${field} must be a positive integer.`,\n );\n }\n return value;\n}\n", "import { readFileSync, statSync } from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Cache of resolved instruction text, keyed by the relative path. Bundled\n * instruction files are immutable for the process lifetime, so re-reading them\n * on every call (some callers do so per LLM request) is wasted disk I/O.\n */\nconst textCache = new Map<string, string>();\n\n/** Resolved once \u2014 the candidate roots only depend on this module's location. */\nlet rootCandidates: string[] | undefined;\n\nexport function readBundledInstructionText(relativePath: string): string {\n const cached = textCache.get(relativePath);\n if (cached !== undefined) return cached;\n\n let resolved = '';\n for (const root of instructionRootCandidates()) {\n try {\n resolved = readFileSync(path.join(root, relativePath), 'utf8').trimEnd();\n break;\n } catch {\n // try next candidate\n }\n }\n textCache.set(relativePath, resolved);\n return resolved;\n}\n\nexport function renderInstructionTemplate(\n template: string,\n values: Record<string, string>,\n): string {\n return template.replace(/\\{\\{\\s*([a-zA-Z0-9_.-]+)\\s*\\}\\}/g, (match, key: string) =>\n Object.hasOwn(values, key) ? (values[key] ?? '') : match,\n );\n}\n\nfunction instructionRootCandidates(): string[] {\n if (rootCandidates !== undefined) return rootCandidates;\n const here = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n path.resolve(here, '../../instructions'),\n path.resolve(here, '../instructions'),\n path.resolve(here, 'instructions'),\n ];\n rootCandidates = candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));\n return rootCandidates;\n}\n\nfunction isDirectory(candidate: string): boolean {\n try {\n return statSync(candidate).isDirectory();\n } catch {\n return false;\n }\n}\n", "import type {\n CouncilOption,\n CouncilPersona,\n CouncilQuestion,\n CouncilVoteResult,\n ResolvedCouncilSeat,\n} from '../types/council.js';\nimport {\n readBundledInstructionText,\n renderInstructionTemplate,\n} from '../utils/instruction-file.js';\n\nexport const COUNCIL_VOTER_PROMPT_PATH = 'llm/council-voter.md';\nexport const COUNCIL_JUDGE_PROMPT_PATH = 'llm/council-judge.md';\n\n/** Build the trusted system instruction for one independent seat. */\nexport function buildCouncilVoterSystemPrompt(persona: CouncilPersona): string {\n const template = requiredInstruction(COUNCIL_VOTER_PROMPT_PATH);\n return renderInstructionTemplate(template, {\n personaInstruction: persona.instruction,\n });\n}\n\n/** Build the trusted system instruction for the final judge. */\nexport function buildCouncilJudgeSystemPrompt(): string {\n return requiredInstruction(COUNCIL_JUDGE_PROMPT_PATH);\n}\n\n/** Render the original question as delimited, untrusted user data. */\nexport function buildCouncilQuestionPrompt(\n question: CouncilQuestion,\n opts: { refusalOptionId?: string | undefined } = {},\n): string {\n const text = question.question.trim();\n if (!text) throw new Error('buildCouncilQuestionPrompt: question must not be empty.');\n const options = normalizeOptions(question.options);\n return [\n '<council-question>',\n `Question: ${text}`,\n question.context?.trim() ? `Context:\\n${question.context.trim()}` : '',\n options.length > 0 ? `Options (JSON):\\n${JSON.stringify(options)}` : 'Options: none',\n opts.refusalOptionId\n ? `Refusal option id: ${opts.refusalOptionId}`\n : 'Refusal option id: not supplied',\n '</council-question>',\n ]\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/** Build the voter user prompt. Persona instructions stay in the system prompt. */\nexport function buildCouncilVoterUserPrompt(\n question: CouncilQuestion,\n seat: ResolvedCouncilSeat,\n opts: { refusalOptionId?: string | undefined } = {},\n): string {\n return [\n buildCouncilQuestionPrompt(question, opts),\n '<seat-metadata>',\n `Seat id: ${seat.id}`,\n `Seat label: ${seat.label}`,\n `Persona id: ${seat.persona}`,\n '</seat-metadata>',\n ].join('\\n');\n}\n\n/** Build the judge user prompt with seat outputs serialized as untrusted JSON. */\nexport function buildCouncilJudgeUserPrompt(\n question: CouncilQuestion,\n votes: readonly CouncilVoteResult[],\n opts: {\n reason?: string | undefined;\n refusalOptionId?: string | undefined;\n } = {},\n): string {\n const ballots = votes.map((vote) => ({\n seatId: vote.seatId,\n persona: vote.persona,\n status: vote.status,\n ...(vote.optionId ? { optionId: vote.optionId } : {}),\n ...(vote.stance ? { stance: vote.stance } : {}),\n ...(vote.rationale ? { rationale: vote.rationale } : {}),\n }));\n return [\n buildCouncilQuestionPrompt(question, { refusalOptionId: opts.refusalOptionId }),\n '<council-ballots>',\n opts.reason?.trim() ? `Reason judging is required: ${opts.reason.trim()}` : '',\n JSON.stringify(ballots),\n '</council-ballots>',\n ]\n .filter(Boolean)\n .join('\\n\\n');\n}\n\nfunction normalizeOptions(options: readonly CouncilOption[] | undefined): CouncilOption[] {\n if (!options) return [];\n const seen = new Set<string>();\n return options.map((option) => {\n const id = option.id.trim();\n const label = option.label.trim();\n if (!id) throw new Error('buildCouncilQuestionPrompt: option id must not be empty.');\n if (!label) throw new Error(`buildCouncilQuestionPrompt: option \"${id}\" needs a label.`);\n if (seen.has(id)) throw new Error(`buildCouncilQuestionPrompt: duplicate option id \"${id}\".`);\n seen.add(id);\n return {\n id,\n label,\n ...(option.consequence?.trim() ? { consequence: option.consequence.trim() } : {}),\n };\n });\n}\n\nfunction requiredInstruction(path: string): string {\n const text = readBundledInstructionText(path);\n if (!text) throw new Error(`Council instruction file is unavailable: ${path}`);\n return text;\n}\n", "/**\n * Provider- and Brain-independent council vote resolution.\n *\n * This module contains only deterministic quorum, veto, weighted-majority,\n * refusal, and judge-escalation rules. LLM calls, prompts, parsing, and host\n * decision types belong in adapters such as `council-brain.ts`.\n */\n\nexport interface CouncilResolutionSeat {\n id: string;\n /** Vote weight in the tally. Default 1. */\n weight?: number | undefined;\n /** A refusal from this seat immediately denies the proposal. */\n veto?: boolean | undefined;\n}\n\nexport interface CouncilResolutionVote {\n seatId: string;\n optionId: string;\n}\n\nexport interface CouncilResolutionInput {\n seats: readonly CouncilResolutionSeat[];\n votes: readonly CouncilResolutionVote[];\n refusalOptionId: string;\n /** Fraction of configured seats required to return a vote. */\n quorumFraction: number;\n /** Winning weight must exceed this fraction of cast weight. */\n approvalFraction: number;\n}\n\nexport type CouncilResolution =\n | {\n status: 'abstained';\n reason: 'quorum_not_met';\n validVoteCount: number;\n seatCount: number;\n }\n | {\n status: 'denied';\n method: 'veto';\n optionId: string;\n seatId: string;\n }\n | {\n status: 'denied';\n method: 'refusal';\n optionId: string;\n winningWeight: number;\n castWeight: number;\n }\n | {\n status: 'decided';\n method: 'majority';\n optionId: string;\n winningWeight: number;\n castWeight: number;\n }\n | {\n status: 'needs_judge';\n reason: 'tie' | 'approval_threshold_not_met';\n castWeight: number;\n };\n\n/** Resolve already-parsed council votes without performing any I/O. */\nexport function resolveCouncilVotes(input: CouncilResolutionInput): CouncilResolution {\n validateInput(input);\n\n const seatById = new Map(input.seats.map((seat) => [seat.id, seat] as const));\n const validVotes: CouncilResolutionVote[] = [];\n const votedSeatIds = new Set<string>();\n for (const vote of input.votes) {\n if (!seatById.has(vote.seatId) || votedSeatIds.has(vote.seatId)) continue;\n votedSeatIds.add(vote.seatId);\n validVotes.push(vote);\n }\n\n if (validVotes.length / input.seats.length < input.quorumFraction) {\n return {\n status: 'abstained',\n reason: 'quorum_not_met',\n validVoteCount: validVotes.length,\n seatCount: input.seats.length,\n };\n }\n\n const veto = validVotes.find(\n (vote) =>\n vote.optionId === input.refusalOptionId && seatById.get(vote.seatId)?.veto === true,\n );\n if (veto) {\n return {\n status: 'denied',\n method: 'veto',\n optionId: veto.optionId,\n seatId: veto.seatId,\n };\n }\n\n const weightByOption = new Map<string, number>();\n let castWeight = 0;\n for (const vote of validVotes) {\n const weight = seatById.get(vote.seatId)?.weight ?? 1;\n castWeight += weight;\n weightByOption.set(vote.optionId, (weightByOption.get(vote.optionId) ?? 0) + weight);\n }\n\n let winner: { optionId: string; weight: number } | undefined;\n let contested = false;\n for (const [optionId, weight] of weightByOption) {\n if (!winner || weight > winner.weight) {\n winner = { optionId, weight };\n contested = false;\n } else if (weight === winner.weight) {\n contested = true;\n }\n }\n\n const decisive =\n winner !== undefined &&\n !contested &&\n winner.weight > input.approvalFraction * castWeight;\n\n if (!decisive || !winner) {\n return {\n status: 'needs_judge',\n reason: contested ? 'tie' : 'approval_threshold_not_met',\n castWeight,\n };\n }\n\n if (winner.optionId === input.refusalOptionId) {\n return {\n status: 'denied',\n method: 'refusal',\n optionId: winner.optionId,\n winningWeight: winner.weight,\n castWeight,\n };\n }\n\n return {\n status: 'decided',\n method: 'majority',\n optionId: winner.optionId,\n winningWeight: winner.weight,\n castWeight,\n };\n}\n\nfunction validateInput(input: CouncilResolutionInput): void {\n if (input.seats.length === 0) {\n throw new Error('resolveCouncilVotes: at least one seat is required.');\n }\n requireFraction(input.quorumFraction, 'quorumFraction');\n requireFraction(input.approvalFraction, 'approvalFraction');\n\n const seatIds = new Set<string>();\n for (const seat of input.seats) {\n if (!seat.id.trim()) throw new Error('resolveCouncilVotes: seat id must not be empty.');\n if (seatIds.has(seat.id)) {\n throw new Error(`resolveCouncilVotes: duplicate seat id \"${seat.id}\".`);\n }\n seatIds.add(seat.id);\n if (seat.weight !== undefined && (!Number.isFinite(seat.weight) || seat.weight <= 0)) {\n throw new Error(`resolveCouncilVotes: invalid weight for seat \"${seat.id}\".`);\n }\n }\n}\n\nfunction requireFraction(value: number, label: string): void {\n if (!Number.isFinite(value) || value <= 0 || value > 1) {\n throw new Error(`resolveCouncilVotes: ${label} must be in (0, 1].`);\n }\n}\n", "import type {\n CouncilLLMCaller,\n CouncilModelTarget,\n CouncilQuestion,\n CouncilResult,\n CouncilUsage,\n CouncilVoteResult,\n ResolvedCouncilProfile,\n ResolvedCouncilSeat,\n} from '../types/council.js';\nimport type { OneShotLLMResult } from '../types/one-shot-llm.js';\nimport {\n DEFAULT_COUNCIL_PERSONA_REGISTRY,\n type CouncilPersonaRegistry,\n} from './council-personas.js';\nimport {\n DEFAULT_COUNCIL_PROFILE_REGISTRY,\n type CouncilProfileRegistry,\n resolveCouncilProfile,\n} from './council-profiles.js';\nimport {\n buildCouncilJudgeSystemPrompt,\n buildCouncilJudgeUserPrompt,\n buildCouncilVoterSystemPrompt,\n buildCouncilVoterUserPrompt,\n} from './council-prompts.js';\nimport { resolveCouncilVotes } from './council-resolution.js';\nimport type { FallbackProfileManager } from '../core/fallback-profile-manager.js';\nimport type { Config } from '../types/config.js';\n\n/** Synthetic ballot entry for \"refuse every real option\". */\nexport const COUNCIL_REFUSAL_OPTION_ID = 'council_refuse';\nexport const DEFAULT_COUNCIL_MAX_CONCURRENCY = 3;\nexport const MAX_COUNCIL_CONCURRENCY = 8;\n\nexport interface CouncilOrchestratorOptions {\n caller: CouncilLLMCaller;\n personas?: CouncilPersonaRegistry | undefined;\n profiles?: CouncilProfileRegistry | undefined;\n defaultProfile?: string | undefined;\n maxConcurrency?: number | undefined;\n refusalOptionId?: string | undefined;\n /** Live config accessor for fallback profile resolution. */\n getConfig?: (() => Config) | undefined;\n /**\n * Shared live FallbackProfileManager \u2014 required for reliable fallback\n * profile pre-resolution. Pass the runtime container's manager.\n */\n fallbackProfileManager?: FallbackProfileManager | undefined;\n /**\n * Per-seat LLM caller factory. When set, each seat gets its own caller\n * instead of the shared `caller`. The factory receives (seatIndex) and\n * returns a CouncilLLMCaller. Used by Brain council arbitration where\n * each voter has its own Provider instance.\n */\n seatCaller?: ((seatIndex: number) => CouncilLLMCaller) | undefined;\n /**\n * Separate caller for the judge seat. Required when `seatCaller` is set\n * because the judge uses the shared caller path. When absent and\n * `seatCaller` is set, the judge falls back to `seatCaller(0)`.\n */\n judgeCaller?: CouncilLLMCaller | undefined;\n}\n\ninterface ParsedVote {\n optionId?: string | undefined;\n stance?: string | undefined;\n rationale?: string | undefined;\n}\n\ninterface ParsedJudge {\n optionId?: string | undefined;\n answer?: string | undefined;\n rationale?: string | undefined;\n}\n\ninterface UsageAccumulator {\n calls: number;\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n}\n\n/** Provider-neutral Council runner backed by an injected one-shot LLM caller. */\nexport class CouncilOrchestrator {\n private readonly caller: CouncilLLMCaller;\n private readonly personas: CouncilPersonaRegistry;\n private readonly profiles: CouncilProfileRegistry;\n private readonly defaultProfile: string | undefined;\n private readonly maxConcurrency: number;\n private readonly refusalOptionId: string;\n private readonly fallbackProfileManager: FallbackProfileManager | undefined;\n private readonly seatCaller: ((seatIndex: number) => CouncilLLMCaller) | undefined;\n private readonly judgeCaller: CouncilLLMCaller | undefined;\n\n constructor(opts: CouncilOrchestratorOptions) {\n this.caller = opts.caller;\n this.personas = opts.personas ?? DEFAULT_COUNCIL_PERSONA_REGISTRY;\n this.profiles = opts.profiles ?? DEFAULT_COUNCIL_PROFILE_REGISTRY;\n this.defaultProfile = opts.defaultProfile;\n this.maxConcurrency = validateConcurrency(\n opts.maxConcurrency ?? DEFAULT_COUNCIL_MAX_CONCURRENCY,\n );\n this.refusalOptionId = opts.refusalOptionId?.trim() || COUNCIL_REFUSAL_OPTION_ID;\n this.fallbackProfileManager = opts.fallbackProfileManager;\n this.seatCaller = opts.seatCaller;\n this.judgeCaller = opts.judgeCaller;\n }\n\n async ask(question: CouncilQuestion): Promise<CouncilResult> {\n const startedAt = Date.now();\n const profile = resolveCouncilProfile(question.profile, {\n registry: this.profiles,\n personas: this.personas,\n defaultProfile: this.defaultProfile,\n });\n validateRefusalCollision(question, this.refusalOptionId);\n\n const timeoutSignal = AbortSignal.timeout(profile.overallTimeoutMs);\n const signal = question.signal\n ? AbortSignal.any([question.signal, timeoutSignal])\n : timeoutSignal;\n const usage: UsageAccumulator = {\n calls: 0,\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n };\n\n const votes = await mapConcurrent(\n profile.seats,\n Math.min(this.maxConcurrency, profile.seats.length),\n async (seat, i) => {\n try {\n return await this.callSeat(question, profile, seat, i, signal, usage);\n } catch (error) {\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: signal.aborted ? 'cancelled' : 'failed',\n error: errorMessage(error),\n } satisfies CouncilVoteResult;\n }\n },\n );\n const warnings = distinctnessWarnings(votes, profile);\n const errors = votes\n .filter((vote) => vote.status === 'failed' || vote.status === 'invalid')\n .map((vote) => `${vote.seatId}: ${vote.error ?? vote.status}`);\n\n if (question.signal?.aborted) {\n return resultEnvelope({\n status: 'cancelled',\n reason: 'Council call cancelled.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (timeoutSignal.aborted) {\n return resultEnvelope({\n status: 'failed',\n reason: 'Council overall timeout exceeded.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors: [...errors, 'Council overall timeout exceeded.'],\n });\n }\n\n if (!question.options || question.options.length === 0) {\n return this.resolveOpenQuestion(\n question,\n profile,\n votes,\n signal,\n usage,\n startedAt,\n warnings,\n errors,\n );\n }\n return this.resolveOptionQuestion(\n question,\n profile,\n votes,\n signal,\n usage,\n startedAt,\n warnings,\n errors,\n );\n }\n\n private async callSeat(\n question: CouncilQuestion,\n profile: ResolvedCouncilProfile,\n seat: ResolvedCouncilSeat,\n seatIndex: number,\n signal: AbortSignal,\n usage: UsageAccumulator,\n ): Promise<CouncilVoteResult> {\n if (signal.aborted) return cancelledVote(seat);\n let persona;\n try {\n persona = this.personas.require(seat.persona);\n } catch (error) {\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: 'failed',\n error: errorMessage(error),\n };\n }\n const result = await this.safeCall({\n system: buildCouncilVoterSystemPrompt(persona),\n userPrompt: buildCouncilVoterUserPrompt(question, seat, {\n refusalOptionId: question.options?.length ? this.refusalOptionId : undefined,\n }),\n target: seat.target,\n maxTokens: profile.voterMaxTokens,\n timeoutMs: profile.perCallTimeoutMs,\n signal,\n usage,\n seatIndex,\n });\n\n const metadata = callMetadata(result);\n if (result.error) {\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: signal.aborted ? 'cancelled' : 'failed',\n ...metadata,\n error: result.error,\n };\n }\n const parsed = parseVote(result.text, question, this.refusalOptionId);\n if (!parsed.ok) {\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: 'invalid',\n ...metadata,\n error: parsed.error,\n };\n }\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: 'valid',\n ...parsed.vote,\n ...metadata,\n };\n }\n\n private async resolveOptionQuestion(\n question: CouncilQuestion,\n profile: ResolvedCouncilProfile,\n votes: CouncilVoteResult[],\n signal: AbortSignal,\n usage: UsageAccumulator,\n startedAt: number,\n warnings: string[],\n errors: string[],\n ): Promise<CouncilResult> {\n const validVotes = votes.filter(\n (vote): vote is CouncilVoteResult & { optionId: string } =>\n vote.status === 'valid' && typeof vote.optionId === 'string',\n );\n const resolution = resolveCouncilVotes({\n seats: profile.seats.map((seat) => ({\n id: seat.id,\n weight: seat.weight,\n veto: seat.veto,\n })),\n votes: validVotes.map((vote) => ({ seatId: vote.seatId, optionId: vote.optionId })),\n refusalOptionId: this.refusalOptionId,\n quorumFraction: profile.quorumFraction,\n approvalFraction: profile.approvalFraction,\n });\n\n if (resolution.status === 'abstained') {\n return resultEnvelope({\n status: 'abstained',\n reason: 'Council quorum was not met.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (resolution.status === 'denied') {\n return resultEnvelope({\n status: 'denied',\n optionId: resolution.optionId,\n reason: `Council denied the proposal via ${resolution.method}.`,\n resolution: resolution.method,\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (resolution.status === 'decided') {\n return resultEnvelope({\n status: 'decided',\n optionId: resolution.optionId,\n answer: optionLabel(question, resolution.optionId),\n resolution: 'majority',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (!profile.judge) {\n return resultEnvelope({\n status: 'abstained',\n reason: `Council requires a judge (${resolution.reason}), but this profile has none.`,\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n\n const judged = await this.callJudge(\n question,\n profile,\n votes,\n profile.judge,\n resolution.reason,\n signal,\n usage,\n );\n if (!judged.ok) {\n return resultEnvelope({\n status: signal.aborted ? 'cancelled' : 'abstained',\n reason: judged.error,\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors: [...errors, judged.error],\n judgeUsed: true,\n });\n }\n if (judged.value.optionId === this.refusalOptionId) {\n return resultEnvelope({\n status: 'denied',\n optionId: this.refusalOptionId,\n reason: judged.value.rationale ?? 'Council judge refused all options.',\n resolution: 'judge',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n judgeUsed: true,\n });\n }\n return resultEnvelope({\n status: 'decided',\n optionId: judged.value.optionId,\n answer: optionLabel(question, judged.value.optionId),\n reason: judged.value.rationale,\n resolution: 'judge',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n judgeUsed: true,\n });\n }\n\n private async resolveOpenQuestion(\n question: CouncilQuestion,\n profile: ResolvedCouncilProfile,\n votes: CouncilVoteResult[],\n signal: AbortSignal,\n usage: UsageAccumulator,\n startedAt: number,\n warnings: string[],\n errors: string[],\n ): Promise<CouncilResult> {\n const valid = votes.filter(\n (vote): vote is CouncilVoteResult & { stance: string } =>\n vote.status === 'valid' && typeof vote.stance === 'string',\n );\n if (valid.length / profile.seats.length < profile.quorumFraction) {\n return resultEnvelope({\n status: 'abstained',\n reason: 'Council quorum was not met.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (!profile.judge) {\n const first = valid[0];\n if (!first) {\n return resultEnvelope({\n status: 'failed',\n reason: 'Council produced no valid stance.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n return resultEnvelope({\n status: 'decided',\n answer: first.stance,\n reason: first.rationale,\n resolution: 'first_stance',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n\n const judged = await this.callJudge(\n question,\n profile,\n votes,\n profile.judge,\n 'open_question_synthesis',\n signal,\n usage,\n );\n if (!judged.ok) {\n return resultEnvelope({\n status: signal.aborted ? 'cancelled' : 'failed',\n reason: judged.error,\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors: [...errors, judged.error],\n judgeUsed: true,\n });\n }\n return resultEnvelope({\n status: 'decided',\n answer: judged.value.answer,\n reason: judged.value.rationale,\n resolution: 'judge',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n judgeUsed: true,\n });\n }\n\n private async callJudge(\n question: CouncilQuestion,\n profile: ResolvedCouncilProfile,\n votes: CouncilVoteResult[],\n target: CouncilModelTarget,\n reason: string,\n signal: AbortSignal,\n usage: UsageAccumulator,\n ): Promise<{ ok: true; value: ParsedJudge } | { ok: false; error: string }> {\n const result = await this.safeCall({\n system: buildCouncilJudgeSystemPrompt(),\n userPrompt: buildCouncilJudgeUserPrompt(question, votes, {\n reason,\n refusalOptionId: question.options?.length ? this.refusalOptionId : undefined,\n }),\n target,\n maxTokens: profile.judgeMaxTokens,\n timeoutMs: profile.perCallTimeoutMs,\n signal,\n usage,\n });\n if (result.error) return { ok: false, error: result.error };\n return parseJudge(result.text, question, this.refusalOptionId);\n }\n\n private async safeCall(input: {\n system: string;\n userPrompt: string;\n target?: CouncilModelTarget | undefined;\n maxTokens: number;\n timeoutMs: number;\n signal: AbortSignal;\n usage: UsageAccumulator;\n seatIndex?: number | undefined;\n }): Promise<OneShotLLMResult> {\n const effectiveCaller =\n input.seatIndex !== undefined && this.seatCaller\n ? this.seatCaller(input.seatIndex)\n : this.judgeCaller ?? (this.seatCaller ? this.seatCaller(0) : this.caller);\n\n const resolvedTarget = this.resolveCouncilTarget(input.target);\n\n try {\n const result = await effectiveCaller.call({\n system: input.system,\n userPrompt: input.userPrompt,\n responseFormat: { type: 'json_object' },\n maxTokens: input.maxTokens,\n timeoutMs: input.timeoutMs,\n signal: input.signal,\n ...(resolvedTarget?.providerId ? { providerId: resolvedTarget.providerId } : {}),\n ...(resolvedTarget?.model ? { model: resolvedTarget.model } : {}),\n ...(resolvedTarget?.role ? { role: resolvedTarget.role } : {}),\n ...(resolvedTarget?.fallbackModels && resolvedTarget.fallbackModels.length > 0\n ? { fallbackModels: [...resolvedTarget.fallbackModels] }\n : {}),\n });\n addUsage(input.usage, result);\n return result;\n } catch (error) {\n input.usage.calls += 1;\n return emptyCallResult(errorMessage(error));\n }\n }\n\n /**\n * Resolve a CouncilModelTarget: pre-resolve fallbackProfile to fallbackModels\n * so the downstream caller only sees the resolved chain.\n */\n private resolveCouncilTarget(\n target?: CouncilModelTarget | undefined,\n ): CouncilModelTarget | undefined {\n if (!target) return undefined;\n if (!target.fallbackProfile) return target;\n\n const mgr = this.fallbackProfileManager;\n if (!mgr) return target;\n const chain = mgr.resolve(target.fallbackProfile);\n if (chain.length === 0) return target;\n\n // Combine profile-resolved chain with any explicit fallbackModels\n const combined = [\n ...chain.map((e) => `${e.providerId}/${e.model}`),\n ...(target.fallbackModels ?? []),\n ];\n // Deduplicate while preserving order\n const seen = new Set<string>();\n const deduped = combined.filter((ref) => {\n if (seen.has(ref)) return false;\n seen.add(ref);\n return true;\n });\n\n return {\n ...(target.providerId ? { providerId: target.providerId } : {}),\n ...(target.model ? { model: target.model } : {}),\n ...(target.role ? { role: target.role } : {}),\n fallbackModels: deduped,\n };\n }\n}\n\nfunction parseVote(\n text: string,\n question: CouncilQuestion,\n refusalOptionId: string,\n): { ok: true; vote: ParsedVote } | { ok: false; error: string } {\n const parsed = parseObject(text);\n if (!parsed.ok && (!question.options || question.options.length === 0)) {\n // Optionless: if JSON parsing fails, use the raw text as stance\n // (backward compat with old council-brain behavior).\n const fallback = text.trim();\n if (fallback) return { ok: true, vote: { stance: fallback } };\n return { ok: false, error: 'Voter returned an empty response.' };\n }\n if (!parsed.ok) return parsed;\n const rationale = optionalString(parsed.value['rationale']);\n if (question.options && question.options.length > 0) {\n const optionId = optionalString(parsed.value['optionId']);\n const allowed = new Set([...question.options.map((option) => option.id.trim()), refusalOptionId]);\n if (!optionId || !allowed.has(optionId)) {\n return { ok: false, error: 'Voter returned an unknown or missing optionId.' };\n }\n return { ok: true, vote: { optionId, ...(rationale ? { rationale } : {}) } };\n }\n const stance = optionalString(parsed.value['stance']);\n if (!stance) return { ok: false, error: 'Voter returned an empty or missing stance.' };\n return { ok: true, vote: { stance, ...(rationale ? { rationale } : {}) } };\n}\n\nfunction parseJudge(\n text: string,\n question: CouncilQuestion,\n refusalOptionId: string,\n): { ok: true; value: ParsedJudge } | { ok: false; error: string } {\n const parsed = parseObject(text);\n if (!parsed.ok && (!question.options || question.options.length === 0)) {\n // Optionless: if JSON parsing fails, use raw text as answer\n const fallback = text.trim();\n if (fallback) return { ok: true, value: { answer: fallback } };\n return { ok: false, error: 'Judge returned an empty response.' };\n }\n if (!parsed.ok) return parsed;\n const rationale = optionalString(parsed.value['rationale']);\n if (question.options && question.options.length > 0) {\n const optionId = optionalString(parsed.value['optionId']);\n const allowed = new Set([...question.options.map((option) => option.id.trim()), refusalOptionId]);\n if (!optionId || !allowed.has(optionId)) {\n return { ok: false, error: 'Judge returned an unknown or missing optionId.' };\n }\n return { ok: true, value: { optionId, ...(rationale ? { rationale } : {}) } };\n }\n const answer = optionalString(parsed.value['answer']);\n if (!answer) return { ok: false, error: 'Judge returned an empty or missing answer.' };\n return { ok: true, value: { answer, ...(rationale ? { rationale } : {}) } };\n}\n\nfunction parseObject(\n text: string,\n): { ok: true; value: Record<string, unknown> } | { ok: false; error: string } {\n const trimmed = text.trim();\n const first = trimmed.indexOf('{');\n const last = trimmed.lastIndexOf('}');\n if (first < 0 || last < first) return { ok: false, error: 'LLM response did not contain JSON.' };\n try {\n const value: unknown = JSON.parse(trimmed.slice(first, last + 1));\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return { ok: false, error: 'LLM response JSON must be an object.' };\n }\n return { ok: true, value: value as Record<string, unknown> };\n } catch (error) {\n return { ok: false, error: `Invalid LLM response JSON: ${errorMessage(error)}` };\n }\n}\n\nfunction resultEnvelope(input: {\n status: CouncilResult['status'];\n answer?: string | undefined;\n optionId?: string | undefined;\n reason?: string | undefined;\n resolution: CouncilResult['resolution'];\n votes: CouncilVoteResult[];\n profile: ResolvedCouncilProfile;\n usage: UsageAccumulator;\n startedAt: number;\n warnings: string[];\n errors: string[];\n judgeUsed?: boolean | undefined;\n}): CouncilResult {\n const validVoteCount = input.votes.filter((vote) => vote.status === 'valid').length;\n return {\n status: input.status,\n ...(input.answer ? { answer: input.answer } : {}),\n ...(input.optionId ? { optionId: input.optionId } : {}),\n ...(input.reason ? { reason: input.reason } : {}),\n resolution: input.resolution,\n votes: Object.freeze([...input.votes]),\n configuredSeatCount: input.profile.seats.length,\n validVoteCount,\n distinctTargetCount: distinctTargetCount(input.votes, input.profile),\n judgeUsed: input.judgeUsed ?? false,\n usage: usageResult(input.usage, input.startedAt),\n ...(input.warnings.length > 0 ? { warnings: Object.freeze([...input.warnings]) } : {}),\n ...(input.errors.length > 0 ? { errors: Object.freeze([...input.errors]) } : {}),\n };\n}\n\nfunction callMetadata(result: OneShotLLMResult): Omit<CouncilVoteResult, 'seatId' | 'persona' | 'status'> {\n return {\n ...(result.provider ? { provider: result.provider } : {}),\n ...(result.model ? { model: result.model } : {}),\n ...(result.fromFallback ? { fromFallback: true } : {}),\n durationMs: result.durationMs,\n };\n}\n\nfunction addUsage(usage: UsageAccumulator, result: OneShotLLMResult): void {\n usage.calls += 1;\n usage.inputTokens += result.tokens.input;\n usage.outputTokens += result.tokens.output;\n usage.totalTokens += result.tokens.total;\n}\n\nfunction usageResult(usage: UsageAccumulator, startedAt: number): CouncilUsage {\n return Object.freeze({ ...usage, durationMs: Math.max(0, Date.now() - startedAt) });\n}\n\nfunction cancelledVote(seat: ResolvedCouncilSeat): CouncilVoteResult {\n return { seatId: seat.id, persona: seat.persona, status: 'cancelled', error: 'Cancelled.' };\n}\n\nfunction distinctTargetCount(\n votes: readonly CouncilVoteResult[],\n profile: ResolvedCouncilProfile,\n): number {\n const keys = votes\n .filter((vote) => vote.status === 'valid')\n .map((vote) =>\n profile.distinctness === 'provider'\n ? vote.provider\n : `${vote.provider ?? ''}/${vote.model ?? ''}`,\n )\n .filter(Boolean);\n return new Set(keys).size;\n}\n\nfunction distinctnessWarnings(\n votes: readonly CouncilVoteResult[],\n profile: ResolvedCouncilProfile,\n): string[] {\n if (profile.distinctness === 'none') return [];\n const valid = votes.filter((vote) => vote.status === 'valid');\n const distinct = distinctTargetCount(valid, profile);\n if (valid.length > 1 && distinct < valid.length) {\n return [\n `Council distinctness policy \"${profile.distinctness}\" was not met: ${distinct} distinct target(s) served ${valid.length} valid vote(s).`,\n ];\n }\n return [];\n}\n\nfunction optionLabel(question: CouncilQuestion, optionId: string | undefined): string | undefined {\n if (!optionId) return undefined;\n return question.options?.find((option) => option.id.trim() === optionId)?.label.trim();\n}\n\nfunction validateRefusalCollision(question: CouncilQuestion, refusalOptionId: string): void {\n if (question.options?.some((option) => option.id.trim() === refusalOptionId)) {\n throw new Error(`CouncilOrchestrator: option id \"${refusalOptionId}\" is reserved.`);\n }\n}\n\nfunction validateConcurrency(value: number): number {\n if (!Number.isSafeInteger(value) || value <= 0 || value > MAX_COUNCIL_CONCURRENCY) {\n throw new Error(\n `CouncilOrchestrator: maxConcurrency must be an integer in [1, ${MAX_COUNCIL_CONCURRENCY}].`,\n );\n }\n return value;\n}\n\nasync function mapConcurrent<T, R>(\n items: readonly T[],\n concurrency: number,\n worker: (item: T, index: number) => Promise<R>,\n): Promise<R[]> {\n const results = new Array<R>(items.length);\n let next = 0;\n const run = async (): Promise<void> => {\n while (true) {\n const index = next++;\n if (index >= items.length) return;\n const item = items[index];\n if (item !== undefined) results[index] = await worker(item, index);\n }\n };\n await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => run()));\n return results;\n}\n\nfunction emptyCallResult(error: string): OneShotLLMResult {\n return {\n text: '',\n model: '',\n provider: '',\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: 0,\n fromFallback: false,\n error,\n };\n}\n\nfunction optionalString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n", "import { CouncilOrchestrator } from '../execution/council-orchestrator.js';\nimport type { FallbackProfileManager } from '../core/fallback-profile-manager.js';\nimport type {\n CouncilLLMCaller,\n CouncilOption,\n CouncilProfileConfig,\n CouncilQuestion,\n CouncilResult,\n} from '../types/council.js';\nimport type { JSONSchema, Tool } from '../types/tool.js';\nimport type { CouncilPersonaRegistry } from '../execution/council-personas.js';\nimport type { CouncilProfileRegistry } from '../execution/council-profiles.js';\n\nexport const COUNCIL_TOOL_NAME = 'council';\nexport const MAX_COUNCIL_TOOL_OPTIONS = 12;\nexport const MAX_COUNCIL_QUESTION_CHARS = 20_000;\nexport const MAX_COUNCIL_CONTEXT_CHARS = 80_000;\n\nexport interface CouncilToolInput {\n question: string;\n context?: string | undefined;\n options?: CouncilOption[] | undefined;\n profile?: string | CouncilProfileConfig | undefined;\n}\n\nexport interface CreateCouncilToolOptions {\n caller: CouncilLLMCaller;\n personas?: CouncilPersonaRegistry | undefined;\n profiles?: CouncilProfileRegistry | undefined;\n defaultProfile?: string | undefined;\n maxConcurrency?: number | undefined;\n refusalOptionId?: string | undefined;\n /** Shared live FallbackProfileManager. */\n fallbackProfileManager?: FallbackProfileManager | undefined;\n}\n\nconst INPUT_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n question: {\n type: 'string',\n description: 'The decision or open question for the Council.',\n maxLength: MAX_COUNCIL_QUESTION_CHARS,\n },\n context: {\n type: 'string',\n description: 'Optional evidence and constraints. Treated as untrusted quoted data.',\n maxLength: MAX_COUNCIL_CONTEXT_CHARS,\n },\n options: {\n type: 'array',\n maxItems: MAX_COUNCIL_TOOL_OPTIONS,\n items: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Stable option id.' },\n label: { type: 'string', description: 'Human-readable option label.' },\n consequence: { type: 'string', description: 'Optional consequence or trade-off.' },\n },\n required: ['id', 'label'],\n additionalProperties: false,\n },\n description: 'Optional bounded list of choices. Omit for an open-ended Council answer.',\n },\n profile: {\n type: 'string',\n description: 'Registered Council profile id. Defaults to the host-configured profile.',\n },\n },\n required: ['question'],\n additionalProperties: false,\n};\n\n/** Create a read-only, bounded agent-callable Council tool. */\nexport function createCouncilTool(\n opts: CreateCouncilToolOptions,\n): Tool<CouncilToolInput, CouncilResult> {\n const orchestrator = new CouncilOrchestrator({\n ...opts,\n fallbackProfileManager: opts.fallbackProfileManager,\n });\n return {\n name: COUNCIL_TOOL_NAME,\n description:\n 'Ask an independent, multi-persona Council to evaluate a decision or synthesize an answer. ' +\n 'Uses bounded parallel voters, quorum/veto/weighted resolution, optional judging, model routing, fallback chains, and cancellation.',\n usageHint:\n 'Use for consequential or disputed decisions that benefit from independent lenses. ' +\n 'Provide `options` for a vote or omit them for an open answer. ' +\n 'Keep context evidence-focused; the Council treats it as untrusted data.',\n category: 'meta',\n inputSchema: INPUT_SCHEMA,\n permission: 'auto',\n mutating: false,\n riskTier: 'safe',\n managesOwnTimeout: true,\n maxOutputBytes: 256_000,\n async execute(input, _ctx, { signal }) {\n const question: CouncilQuestion = {\n question: input.question,\n ...(input.context ? { context: input.context } : {}),\n ...(input.options ? { options: input.options } : {}),\n ...(input.profile ? { profile: input.profile } : {}),\n signal,\n };\n return orchestrator.ask(question);\n },\n validate: validateCouncilToolInput,\n };\n}\n\nfunction validateCouncilToolInput(input: CouncilToolInput): string[] {\n const errors: string[] = [];\n const question = input.question?.trim() ?? '';\n if (!question) errors.push('`question` must not be empty.');\n if (question.length > MAX_COUNCIL_QUESTION_CHARS) {\n errors.push(`\\`question\\` must not exceed ${MAX_COUNCIL_QUESTION_CHARS} characters.`);\n }\n if ((input.context?.length ?? 0) > MAX_COUNCIL_CONTEXT_CHARS) {\n errors.push(`\\`context\\` must not exceed ${MAX_COUNCIL_CONTEXT_CHARS} characters.`);\n }\n if ((input.options?.length ?? 0) > MAX_COUNCIL_TOOL_OPTIONS) {\n errors.push(`\\`options\\` must not contain more than ${MAX_COUNCIL_TOOL_OPTIONS} items.`);\n }\n const ids = new Set<string>();\n for (const option of input.options ?? []) {\n const id = option.id.trim();\n if (!id) errors.push('Every option must have a non-empty `id`.');\n if (!option.label.trim()) errors.push(`Option \"${id || '<empty>'}\" must have a label.`);\n if (ids.has(id)) errors.push(`Duplicate option id \"${id}\".`);\n ids.add(id);\n }\n return errors;\n}\n", "export interface ModelBlackoutRule {\n id: string;\n enabled?: boolean | undefined;\n provider?: string | undefined;\n model?: string | undefined;\n /** JavaScript weekday numbers: Sunday=0 \u2026 Saturday=6. Empty means every day. */\n days?: number[] | undefined;\n /** Inclusive local start, HH:mm. */\n start: string;\n /** Exclusive local end, HH:mm. Equal to start means all day. */\n end: string;\n /** IANA timezone. Defaults to the host timezone. */\n timezone?: string | undefined;\n label?: string | undefined;\n /** `blackout`: deny inside. `allow_only`: deny outside all matching allow windows. */\n mode?: 'blackout' | 'allow_only' | undefined;\n}\n\nexport interface ModelCalendarDecision {\n allowed: boolean;\n rule?: ModelBlackoutRule | undefined;\n}\n\nexport function logicalCalendarTarget(\n providerId: string,\n model: string,\n): {\n providerId: string;\n model: string;\n} {\n if (providerId !== 'omniroute') return { providerId, model };\n const slash = model.indexOf('/');\n return slash > 0 && slash < model.length - 1\n ? { providerId: model.slice(0, slash), model: model.slice(slash + 1) }\n : { providerId, model };\n}\n\nconst WEEKDAYS: Record<string, number> = {\n Sun: 0,\n Mon: 1,\n Tue: 2,\n Wed: 3,\n Thu: 4,\n Fri: 5,\n Sat: 6,\n};\n\nfunction minuteOfDay(value: string): number | undefined {\n const match = /^(\\d{2}):(\\d{2})$/.exec(value);\n if (!match) return undefined;\n const hour = Number(match[1]);\n const minute = Number(match[2]);\n if (hour > 23 || minute > 59) return undefined;\n return hour * 60 + minute;\n}\n\nfunction clockAt(date: Date, timezone?: string): { day: number; minute: number } | undefined {\n try {\n const parts = new Intl.DateTimeFormat('en-US', {\n timeZone: timezone,\n weekday: 'short',\n hour: '2-digit',\n minute: '2-digit',\n hourCycle: 'h23',\n }).formatToParts(date);\n const weekday = parts.find((part) => part.type === 'weekday')?.value;\n const hour = Number(parts.find((part) => part.type === 'hour')?.value);\n const minute = Number(parts.find((part) => part.type === 'minute')?.value);\n if (!weekday || WEEKDAYS[weekday] === undefined || !Number.isFinite(hour + minute))\n return undefined;\n return { day: WEEKDAYS[weekday], minute: hour * 60 + minute };\n } catch {\n return undefined;\n }\n}\n\nfunction targetMatches(rule: ModelBlackoutRule, providerId: string, model: string): boolean {\n if (rule.provider && rule.provider !== providerId) return false;\n if (rule.model && rule.model !== model) return false;\n return Boolean(rule.provider || rule.model);\n}\n\nfunction timeMatches(rule: ModelBlackoutRule, day: number, minute: number): boolean {\n const start = minuteOfDay(rule.start);\n const end = minuteOfDay(rule.end);\n if (start === undefined || end === undefined) return false;\n const days = rule.days?.length ? new Set(rule.days) : undefined;\n if (start === end) return !days || days.has(day);\n if (start < end) return (!days || days.has(day)) && minute >= start && minute < end;\n // Overnight: Monday 22:00\u201307:00 includes early Tuesday morning.\n if (minute >= start) return !days || days.has(day);\n const previousDay = (day + 6) % 7;\n return minute < end && (!days || days.has(previousDay));\n}\n\nexport function evaluateModelCalendar(\n rules: readonly ModelBlackoutRule[] | undefined,\n providerId: string,\n model: string,\n at = new Date(),\n): ModelCalendarDecision {\n ({ providerId, model } = logicalCalendarTarget(providerId, model));\n const allowRules: ModelBlackoutRule[] = [];\n let allowMatched = false;\n for (const rule of rules ?? []) {\n if (rule.enabled === false || !targetMatches(rule, providerId, model)) continue;\n const clock = clockAt(at, rule.timezone);\n if (!clock || minuteOfDay(rule.start) === undefined || minuteOfDay(rule.end) === undefined)\n continue;\n if (rule.mode === 'allow_only') {\n allowRules.push(rule);\n if (timeMatches(rule, clock.day, clock.minute)) allowMatched = true;\n } else if (timeMatches(rule, clock.day, clock.minute)) {\n return { allowed: false, rule };\n }\n }\n if (allowRules.length > 0 && !allowMatched) return { allowed: false, rule: allowRules[0] };\n return { allowed: true };\n}\n", "import { truncate } from '../utils/string.js';\nimport type { ContentBlock, TextBlock } from './blocks.js';\nimport type { ErrorCode } from './errors.js';\nimport { ERROR_CODES, WrongStackError } from './errors.js';\nimport type { Message } from './messages.js';\nimport type { Tool } from './tool.js';\n\n/**\n * Token usage for a single provider call, normalized across providers.\n *\n * Disjoint semantics: the four fields never overlap. `input` is the count\n * of FRESH input tokens (billed at the full input rate); `cacheRead` and\n * `cacheWrite` are separate cached subsets each priced at their own rate.\n * The total context the model loaded for this turn is\n * `input + (cacheRead ?? 0) + (cacheWrite ?? 0)`.\n *\n * Provider quirks normalized at the adapter layer:\n * - Anthropic: returns `input_tokens` already disjoint from cache fields.\n * - OpenAI / OpenAI-compatible: `prompt_tokens` is the TOTAL including\n * cached portion; the adapter subtracts `cached_tokens` to stay disjoint.\n * - Google: `promptTokenCount` likewise includes cache; adapter subtracts\n * `cachedContentTokenCount`.\n *\n * Cost math and the context-fullness chip both depend on the disjoint\n * invariant \u2014 a TOTAL `input` plus a separate `cacheRead` count would bill\n * cached tokens twice and skew cache-hit-ratio reporting.\n */\nexport type ReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';\nexport type CacheTtl = '5m' | '1h';\n\n/**\n * Provider-agnostic response-format directive.\n *\n * - `{ type: 'text' }` \u2014 free-form text (default).\n * - `{ type: 'json_object' }` \u2014 valid JSON without a schema constraint.\n * - `{ type: 'json_schema', jsonSchema: { name, schema, strict? } }` \u2014 JSON\n * constrained to the supplied JSON Schema. The `strict` flag is\n * OpenAI-specific; Gemini ignores it in favour of `responseMimeType`.\n *\n * Each provider adapter maps this into its own wire format:\n * OpenAI \u2192 `response_format`\n * Gemini \u2192 `responseMimeType` + `responseSchema`\n * Anthropic \u2192 (not yet supported; uses tools for structured output)\n */\nexport interface JsonSchemaSpec {\n name: string;\n /** OpenAI-specific: enable strict schema adherence. */\n strict?: boolean | undefined;\n /** The JSON Schema object describing the expected shape. */\n schema: Record<string, unknown>;\n /** Optional human-readable description (OpenAI). */\n description?: string | undefined;\n}\n\nexport type ResponseFormat =\n | { type: 'text' }\n | { type: 'json_object' }\n | { type: 'json_schema'; jsonSchema: JsonSchemaSpec };\n\n/**\n * Safety category threshold pair used by Google Gemini's `safetySettings`.\n *\n * Categories: `HARM_CATEGORY_HARASSMENT`, `HARM_CATEGORY_HATE_SPEECH`,\n * `HARM_CATEGORY_SEXUALLY_EXPLICIT`, `HARM_CATEGORY_DANGEROUS_CONTENT`.\n *\n * Thresholds: `BLOCK_NONE`, `BLOCK_ONLY_HIGH`, `BLOCK_MEDIUM_AND_ABOVE`,\n * `BLOCK_LOW_AND_ABOVE`.\n */\nexport interface SafetySetting {\n category: string;\n threshold: string;\n}\n\nexport interface Usage {\n input: number;\n output: number;\n cacheRead?: number | undefined;\n /** Back-compat aggregate of all cache-write tokens. Prefer TTL-specific fields when present. */\n cacheWrite?: number | undefined;\n cacheWrite5m?: number | undefined;\n cacheWrite1h?: number | undefined;\n}\n\n/**\n * Effective prompt tokens loaded by the model for one request.\n *\n * Provider adapters normalize `Usage` to disjoint fields: `input` is fresh\n * full-rate tokens, `cacheRead` is cached prefix tokens, and `cacheWrite` is\n * the cache-written prefix segment. Context-window pressure cares about the\n * full prompt the model saw, not only the bill-at-full-rate slice.\n */\nexport function effectiveInputTokens(usage: Usage): number {\n return usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);\n}\n\nexport interface ReasoningRequest {\n enabled?: boolean | undefined;\n effort?: ReasoningEffort | undefined;\n preserve?: boolean | undefined;\n display?: 'summarized' | 'omitted' | undefined;\n}\n\nexport interface RequestCacheControl {\n ttl?: CacheTtl | undefined;\n /**\n * Provider-agnostic cache-partition key. A stable hash of the cacheable\n * system-prompt prefix (see `deriveCachePrefixKey`); requests sharing a prefix\n * share a key so provider backends route them to the same automatic-cache\n * partition. Consumed by OpenAI-family wires as `prompt_cache_key`; ignored by\n * Anthropic (which uses `ttl` + explicit `cache_control` markers).\n */\n key?: string | undefined;\n /**\n * Opt-in flag (from `ModelRuntimeCacheConfig.geminiExplicit`) telling the\n * Google provider to use explicit `cachedContents` for this request. Ignored\n * by other providers.\n */\n geminiExplicit?: boolean | undefined;\n /**\n * Resolved Gemini `cachedContents/*` resource name, injected by\n * `GoogleProvider.stream()` after it creates/reuses the cache. When present,\n * the Google wire sends `cachedContent` and OMITS the (now-cached) system\n * instruction + tool defs from the live body. Internal \u2014 never set by callers.\n */\n geminiCachedContentName?: string | undefined;\n}\n\nexport interface ReasoningConfig {\n default: 'enabled' | 'disabled' | 'adaptive' | 'always_on';\n disableSupported: boolean;\n effortSupported: boolean;\n effortLevels: ReasoningEffort[];\n preserveThinking: 'unsupported' | 'optional' | 'always_on';\n}\n\nexport interface Capabilities {\n tools: boolean;\n parallelTools: boolean;\n vision: boolean;\n streaming: boolean;\n promptCache: boolean;\n systemPrompt: boolean;\n jsonMode: boolean;\n reasoning: boolean;\n maxContext: number;\n /**\n * Maximum output tokens the model can produce in a single response.\n * Used as the default for `Request.maxTokens` when the caller doesn't\n * supply an explicit value \u2014 letting subagents run up to the model's\n * native ceiling instead of a fixed 8192 cap. Omit (undefined) to fall\n * back to a conservative default; populate per family in\n * `family-capabilities.ts` once you know the spec.\n */\n maxOutput?: number | undefined;\n cacheControl: 'native' | 'auto' | 'none';\n\n // \u2500\u2500 Extended parameter support (optional; family defaults in CAPABILITIES_BY_FAMILY) \u2500\u2500\n\n /** Model accepts `top_k` / `topK` sampling parameter. */\n topK?: boolean | undefined;\n /** Model accepts `frequency_penalty` / `frequencyPenalty` parameter. */\n frequencyPenalty?: boolean | undefined;\n /** Model accepts `presence_penalty` / `presencePenalty` parameter. */\n presencePenalty?: boolean | undefined;\n /** Model accepts `seed` parameter for deterministic generation. */\n seed?: boolean | undefined;\n /**\n * Model accepts JSON Schema / structured-output constraints\n * (OpenAI `response_format.json_schema`, Gemini `responseMimeType`+`responseSchema`).\n * Distinct from `jsonMode` (which is just a system-prompt hint).\n */\n structuredOutput?: boolean | undefined;\n /** Model supports log-probability output (`logprobs`, `top_logprobs`). */\n logprobs?: boolean | undefined;\n /** Model supports audio input/output modality. */\n audio?: boolean | undefined;\n /** Model supports the `n` parameter for multiple completions. */\n multipleCompletions?: boolean | undefined;\n}\n\nexport interface Request {\n model: string;\n system?: TextBlock[] | undefined;\n messages: Message[];\n tools?: Tool[] | undefined;\n /**\n * Cap on output tokens for this single response. Optional \u2014 when\n * omitted, the provider adapter falls back to its own\n * `capabilities.maxOutput` (which the catalog populates from\n * `ModelsDevModel.limit.output`). If neither is available, the\n * adapter applies a conservative 8192 safety net. Letting this stay\n * undefined at the call site means callers like Chimera can hand the\n * model its native output ceiling without hard-coding a number.\n */\n maxTokens?: number | undefined;\n temperature?: number | undefined;\n topP?: number | undefined;\n topK?: number | undefined;\n frequencyPenalty?: number | undefined;\n presencePenalty?: number | undefined;\n seed?: number | undefined;\n /**\n * End-user identifier for abuse monitoring and per-user rate limiting.\n * - Anthropic \u2192 `metadata.user_id`\n * - OpenAI \u2192 `user`\n * - Gemini \u2192 (not supported)\n */\n user?: string | undefined;\n /**\n * Number of response candidates to generate. Google Gemini supports\n * this via `generationConfig.candidateCount`. OpenAI does not have\n * an equivalent (`n` is conceptually similar but distinct).\n */\n candidateCount?: number | undefined;\n /**\n * Whether to return log probabilities for output tokens.\n * - OpenAI \u2192 `logprobs: boolean` (+ `topLogprobs: number`)\n * - Gemini \u2192 `generationConfig.logprobs: number` (how many top candidates)\n * Default undefined = no logprobs requested.\n */\n logprobs?: boolean | undefined;\n /**\n * Number of most probable tokens to return log probabilities for\n * (OpenAI `top_logprobs`). Only meaningful when `logprobs` is true.\n * Range: 0-20. Gemini ignores this (uses `logprobs` as the count).\n */\n topLogprobs?: number | undefined;\n stopSequences?: string[] | undefined;\n toolChoice?: 'auto' | 'required' | 'none' | { type: 'tool' | undefined; name: string };\n reasoning?: ReasoningRequest | undefined;\n cache?: RequestCacheControl | undefined;\n /**\n * Structured-output / response-format directive.\n * When set, the provider adapter maps this to its native response-format\n * parameter (OpenAI `response_format`, Gemini `responseMimeType`, etc.).\n * The model must advertise `capabilities.structuredOutput` for this to be\n * honoured; unsupported models will likely 400 or ignore it.\n */\n responseFormat?: ResponseFormat | undefined;\n /**\n * Safety category thresholds for filtering harmful content.\n * - Gemini \u2192 top-level `safetySettings` array with `{ category, threshold }`\n * - OpenAI \u2192 not supported (uses server-side moderation)\n * - Anthropic \u2192 not supported\n */\n safetySettings?: SafetySetting[] | undefined;\n}\n\nexport type StopReason = 'end_turn' | 'tool_use' | 'max_tokens' | 'stop_sequence' | 'refusal';\n\nexport interface Response {\n content: ContentBlock[];\n stopReason: StopReason;\n usage: Usage;\n model: string;\n}\n\nexport type StreamEvent =\n | { type: 'message_start'; model: string }\n | {\n type: 'content_block_start';\n kind: 'text' | 'tool_use' | 'thinking';\n id?: string | undefined;\n name?: string | undefined;\n }\n | { type: 'content_block_stop'; index: number }\n | { type: 'text_delta'; text: string }\n | { type: 'tool_use_start'; id: string; name: string }\n | { type: 'tool_use_input_delta'; id: string; partial: string }\n | { type: 'tool_use_stop'; id: string; input: unknown; providerMeta?: Record<string, unknown> }\n | { type: 'thinking_start'; providerMeta?: Record<string, unknown> }\n | { type: 'thinking_delta'; text: string }\n | { type: 'thinking_signature'; signature: string }\n | { type: 'thinking_stop' }\n | { type: 'message_stop'; stopReason: StopReason; usage: Usage };\n\nexport interface Provider {\n readonly id: string;\n readonly capabilities: Capabilities;\n /** Canonical streaming entry point. `complete()` defaults to a wrapper that\n * aggregates this stream \u2014 providers may override for non-streaming wires. */\n stream(req: Request, opts: { signal: AbortSignal }): AsyncIterable<StreamEvent>;\n complete(req: Request, opts: { signal: AbortSignal }): Promise<Response>;\n}\n\n/**\n * Structured body parsed from a provider's HTTP error response. Populated\n * best-effort: providers return JSON shaped differently (Anthropic uses\n * `{error: {type, message}}`, OpenAI uses `{error: {message, code}}`,\n * Google uses `{error: {status, message}}`), so the fields here are the\n * intersection that's usable for rendering and routing.\n */\nexport interface ProviderErrorBody {\n /** Provider-specific kind, e.g. \"overloaded_error\", \"rate_limit_error\", \"invalid_request_error\". */\n type?: string | undefined;\n /** Human-readable explanation from the provider. */\n message?: string | undefined;\n /** Provider request id, when present in the body or headers. */\n requestId?: string | undefined;\n /** Parsed Retry-After header (or equivalent body hint) in milliseconds. */\n retryAfterMs?: number | undefined;\n /** The raw response body (truncated to ~2 KB), kept for debugging. */\n raw?: string | undefined;\n /** True when `raw` was truncated; check `rawLength` for the original size. */\n truncated?: boolean | undefined;\n /** Original length of the response body in bytes, when `truncated` is true. */\n rawLength?: number | undefined;\n}\n\n/**\n * Canonical provider-failure taxonomy. Computed ONCE at error-construction\n * time (`classifyProviderError`) and carried on `ProviderError.kind` so\n * every downstream consumer \u2014 retry policy, cross-provider fallback,\n * recovery strategies, the subagent error classifier \u2014 branches on the\n * same classification instead of re-deriving it from status codes and\n * message regexes. When a new provider's error format needs special\n * handling, this module is the only place to teach it.\n */\nexport type ProviderErrorKind =\n | 'rate_limit' // 429 / rate_limit_error \u2014 back off (honour Retry-After), then failover\n | 'quota_exhausted' // credits/plan depleted \u2014 do not retry same route; fail over immediately\n | 'overloaded' // 529 / overloaded_error \u2014 retry with backoff, then failover\n | 'server' // other 5xx \u2014 retry same provider\n | 'timeout' // 408 request timeout\n | 'network' // status 0 \u2014 connection/DNS failure before a response arrived\n | 'stream_hang' // 599 sentinel \u2014 stream stalled mid-response (StreamHangError)\n | 'auth' // 401/403 \u2014 key invalid/expired; retrying without action is pointless\n | 'context_overflow' // 413 or an overflow-shaped 4xx \u2014 compact, don't retry as-is\n | 'content_filter' // provider refused on policy grounds \u2014 a sibling model may pass, but the `content_filter_reroute` recovery strategy owns that hop, NOT the fallback engine (which surfaces this kind)\n | 'invalid_request' // other 4xx \u2014 request is malformed; retrying won't help\n | 'unknown';\n\n/**\n * Overflow-shaped provider messages. Union of the patterns previously\n * scattered across `error-handler.ts` and `coordinator/error-classifier.ts`\n * (which had drifted apart) \u2014 keep additions here, nowhere else.\n */\nconst CONTEXT_OVERFLOW_RE =\n /context.length|context.window|maximum context|max.*tokens?.*exceeded|prompt is too long|too long|exceeds the context|\\btokens\\b.*exceed|too many tokens|reduce the length|resulted in \\d+ tokens|input.{0,12}too (?:large|long)|context_length_exceeded/i;\n\n/** Content-policy refusals surfaced as HTTP errors (Azure/OpenAI `content_filter`, etc.). */\nconst CONTENT_FILTER_RE = /content.(filter|policy|moderation)|safety (system|filter)/i;\nconst QUOTA_EXHAUSTED_RE =\n /(?:insufficient|exhausted|depleted|exceeded|no|not enough)[-_\\s]*(?:quota|credit|balance)|(?:quota|credit|balance)[-_\\s]*(?:exhausted|depleted|exceeded|insufficient)|billing[_\\s-]*(?:hard[_\\s-]*)?limit|payment required|spending limit|plan limit/i;\n\n/**\n * Classify a provider HTTP failure into the canonical taxonomy from its\n * status code plus the parsed error body (and, for message-only errors\n * without a structured body, the error message itself). Pure and total \u2014\n * always returns a kind, never throws.\n */\nexport function classifyProviderError(\n status: number,\n body?: ProviderErrorBody,\n message?: string,\n): ProviderErrorKind {\n const type = body?.type;\n const text = [message, body?.message, type, body?.raw].filter(Boolean).join('\\n');\n if (status === 0) return 'network';\n if (status === 408) return 'timeout';\n if (status === 599) return 'stream_hang';\n if (status === 402 || QUOTA_EXHAUSTED_RE.test(text)) return 'quota_exhausted';\n if (type === 'rate_limit_error' || status === 429) return 'rate_limit';\n if (type === 'overloaded_error' || status === 529) return 'overloaded';\n if (status >= 500) return 'server';\n if (\n type === 'authentication_error' ||\n type === 'permission_error' ||\n status === 401 ||\n status === 403\n ) {\n return 'auth';\n }\n if (type === 'content_filter' || CONTENT_FILTER_RE.test(text)) return 'content_filter';\n if (status === 413 || (status >= 400 && CONTEXT_OVERFLOW_RE.test(text))) {\n return 'context_overflow';\n }\n if (status >= 400) return 'invalid_request';\n return 'unknown';\n}\n\n/**\n * Whether a kind is worth retrying against the SAME provider/model.\n * `context_overflow` is deliberately false \u2014 the request must shrink first;\n * `auth`/`invalid_request`/`content_filter` won't improve on replay.\n *\n * Exhaustive by construction (`Record<ProviderErrorKind, \u2026>`): adding a new\n * kind refuses to compile until it is classified here. Every kind\u2192X mapping\n * in the codebase follows this drift-guard pattern \u2014 see also KIND_TO_CODE\n * below, DefaultRetryPolicy.maxAttempts, fallback-model shouldFallback, and\n * the coordinator's providerErrorToSubagentError.\n */\nexport function isRetryableKind(kind: ProviderErrorKind): boolean {\n return RETRYABLE_BY_KIND[kind];\n}\n\nconst RETRYABLE_BY_KIND: Record<ProviderErrorKind, boolean> = {\n rate_limit: true,\n quota_exhausted: false,\n overloaded: true,\n server: true,\n timeout: true,\n network: true,\n stream_hang: true,\n auth: false,\n context_overflow: false,\n content_filter: false,\n invalid_request: false,\n unknown: false,\n};\n\n/**\n * Whether a kind is worth HOPPING to a different provider/model \u2014 the gate for\n * the cross-provider fallback engine (agent-loop extension AND the one-shot\n * orchestrator both branch on this ONE table, so their behavior can't drift).\n *\n * A distinct question from {@link isRetryableKind} (retry the SAME model):\n * a hop only helps for capacity/transport failures. Request-shaped failures\n * surface instead \u2014 `context_overflow` needs compaction, `content_filter` is\n * owned by the `content_filter_reroute` recovery strategy, and `auth` /\n * `invalid_request` are user-actionable and would fail identically on a hop.\n * The value set is currently identical to the retryable set, but it is kept as\n * its own table on purpose: the two answer different questions and may diverge.\n *\n * Exhaustive by construction (`Record<ProviderErrorKind, \u2026>`) \u2014 a new kind\n * refuses to compile until it is classified here.\n */\nexport function isFallbackWorthy(kind: ProviderErrorKind): boolean {\n return FALLBACK_WORTHY_BY_KIND[kind];\n}\n\nconst FALLBACK_WORTHY_BY_KIND: Record<ProviderErrorKind, boolean> = {\n rate_limit: true,\n quota_exhausted: true,\n overloaded: true,\n server: true,\n timeout: true,\n network: true,\n stream_hang: true,\n auth: false,\n context_overflow: false,\n content_filter: false,\n invalid_request: false,\n unknown: false,\n};\n\nexport class ProviderError extends WrongStackError {\n public readonly status: number;\n public readonly retryable: boolean;\n public readonly providerId: string;\n /** Canonical failure classification \u2014 see {@link ProviderErrorKind}. */\n public readonly kind: ProviderErrorKind;\n public readonly body?: ProviderErrorBody | undefined;\n\n constructor(\n message: string,\n status: number,\n retryable: boolean,\n providerId: string,\n opts: {\n body?: ProviderErrorBody | undefined;\n cause?: unknown | undefined;\n /** Override the computed classification (rarely needed \u2014 tests, custom wires). */\n kind?: ProviderErrorKind | undefined;\n } = {},\n ) {\n const kind = opts.kind ?? classifyProviderError(status, opts.body, message);\n super({\n message,\n code: kindToCode(kind),\n subsystem: 'provider',\n severity: status >= 500 ? 'error' : 'warning',\n recoverable: retryable,\n context: { providerId, status },\n cause: opts.cause,\n });\n this.name = 'ProviderError';\n this.status = status;\n this.retryable = retryable;\n this.providerId = providerId;\n this.kind = kind;\n this.body = opts.body;\n }\n\n /**\n * Render a one-line, user-facing description. Designed for the CLI/TUI\n * status line and the agent's retry warning. Avoids dumping raw JSON\n * (which is what users see today when a 529 lands and the log message\n * includes the full `{\"type\":\"error\",...}` body).\n *\n * Examples:\n * \"minimax-coding-plan overloaded (529): High traffic detected. Upgrade for highspeed model. [req 06534785201de9c0\u2026]\"\n * \"openai rate limited (429): Retry after 12s\"\n * \"anthropic invalid request (400): messages.0.role must be one of 'user'|'assistant'\"\n * \"groq HTTP 500 (server error)\"\n */\n override describe(): string {\n const kind = describeStatus(this.status, this.body?.type);\n const head = `${this.providerId} ${kind}`;\n const detail = this.body?.message?.trim();\n const reqId = this.body?.requestId\n ? ` [req ${this.body.requestId.slice(0, 16)}${this.body.requestId.length > 16 ? '\u2026' : ''}]`\n : '';\n if (detail && detail.length > 0) {\n return `${head}: ${truncate(detail, 240)}${reqId}`;\n }\n return `${head}${reqId}`;\n }\n}\n\n/**\n * Belt-and-suspenders overflow detection for the recovery layer. Returns true\n * when a `ProviderError` is *shaped* like a context overflow even if its `kind`\n * says otherwise \u2014 an HTTP 413, or an overflow phrase anywhere in its message /\n * body. Gateways and proxies sometimes relabel an overflow as a generic\n * `invalid_request`/400 (or a caller constructs the error with an explicit\n * wrong `kind`); the `context_overflow_reduce` strategy uses this so those\n * still trigger compact-and-retry instead of failing terminally.\n */\nexport function isContextOverflowShaped(err: unknown): boolean {\n if (!(err instanceof ProviderError)) return false;\n if (err.kind === 'context_overflow' || err.status === 413) return true;\n if (err.status < 400) return false;\n const text = [err.message, err.body?.message, err.body?.type, err.body?.raw]\n .filter(Boolean)\n .join('\\n');\n return CONTEXT_OVERFLOW_RE.test(text);\n}\n\nfunction describeStatus(status: number, type?: string): string {\n if (status === 0) return 'network error';\n if (status === 599) return `stream hang (${status})`;\n if (type === 'overloaded_error' || status === 529) return `overloaded (${status})`;\n if (type === 'rate_limit_error' || status === 429) return `rate limited (${status})`;\n if (type === 'authentication_error' || status === 401) return `auth failed (${status})`;\n if (type === 'permission_error' || status === 403) return `forbidden (${status})`;\n if (type === 'not_found_error' || status === 404) return `not found (${status})`;\n if (type === 'content_filter') return `content filtered (${status})`;\n if (type === 'invalid_request_error' || status === 400) return `invalid request (${status})`;\n if (status === 408) return `timeout (${status})`;\n if (status >= 500 && status < 600) return `HTTP ${status} (server error)`;\n if (type) return `${type} (${status})`;\n return `HTTP ${status}`;\n}\n\n/**\n * Thrown when the provider stream stops delivering data mid-response.\n * This is distinct from a network error (TCP reset, DNS failure) \u2014 the\n * connection is established and the response started, but chunks stopped\n * arriving before the stream completed.\n *\n * Status 599 is used as a sentinel to distinguish stream hangs from\n * regular HTTP errors while still flowing through ProviderError-based\n * retry and fallback infrastructure.\n */\nexport class StreamHangError extends ProviderError {\n /** Name of the provider that hung, e.g. \"zai\", \"anthropic\". */\n public readonly hungProviderId: string;\n /** Model that was being called when the hang occurred. */\n public readonly hungModel: string;\n /** How long (ms) we waited for the next chunk before declaring a hang. */\n public readonly hangTimeoutMs: number;\n /** How many bytes were received before the hang. */\n public readonly bytesReceived: number;\n /** Elapsed time (ms) from the start of the stream until the hang. */\n public readonly elapsedMs: number;\n\n constructor(opts: {\n providerId: string;\n model: string;\n hangTimeoutMs: number;\n bytesReceived: number;\n elapsedMs: number;\n cause?: unknown | undefined;\n }) {\n super(\n `Stream hang: ${opts.providerId}/${opts.model} \u2014 no data for ${opts.hangTimeoutMs}ms after ${opts.bytesReceived} bytes (${opts.elapsedMs}ms elapsed)`,\n 599,\n true, // always retryable\n opts.providerId,\n {\n body: {\n message: `Stream stalled after ${opts.elapsedMs}ms, ${opts.bytesReceived} bytes received`,\n },\n cause: opts.cause,\n },\n );\n this.name = 'StreamHangError';\n this.hungProviderId = opts.providerId;\n this.hungModel = opts.model;\n this.hangTimeoutMs = opts.hangTimeoutMs;\n this.bytesReceived = opts.bytesReceived;\n this.elapsedMs = opts.elapsedMs;\n }\n}\n\n/** Exhaustive kind \u2192 ErrorCode mapping \u2014 new kinds must be added here or the\n * file stops compiling (same drift-guard pattern as RETRYABLE_BY_KIND). */\nconst KIND_TO_CODE: Record<ProviderErrorKind, ErrorCode> = {\n network: ERROR_CODES.PROVIDER_NETWORK_ERROR,\n timeout: ERROR_CODES.PROVIDER_NETWORK_ERROR,\n rate_limit: ERROR_CODES.PROVIDER_RATE_LIMITED,\n quota_exhausted: ERROR_CODES.PROVIDER_RATE_LIMITED,\n auth: ERROR_CODES.PROVIDER_AUTH_FAILED,\n overloaded: ERROR_CODES.PROVIDER_OVERLOADED,\n context_overflow: ERROR_CODES.PROVIDER_CONTEXT_OVERFLOW,\n server: ERROR_CODES.PROVIDER_SERVER_ERROR,\n stream_hang: ERROR_CODES.PROVIDER_SERVER_ERROR,\n content_filter: ERROR_CODES.PROVIDER_INVALID_REQUEST,\n invalid_request: ERROR_CODES.PROVIDER_INVALID_REQUEST,\n unknown: ERROR_CODES.PROVIDER_INVALID_REQUEST,\n};\n\nfunction kindToCode(kind: ProviderErrorKind): ErrorCode {\n return KIND_TO_CODE[kind];\n}\n", "import type { FallbackChain } from '../core/fallback-profile-manager.js';\nimport { evaluateModelCalendar } from '../core/model-availability-calendar.js';\nimport { isTextBlock } from '../types/blocks.js';\nimport type { Config } from '../types/config.js';\nimport type { Message } from '../types/messages.js';\nimport type {\n OneShotLLMInput,\n OneShotLLMResult,\n OneShotOrchestratorOptions,\n} from '../types/one-shot-llm.js';\nimport {\n isFallbackWorthy,\n type Provider,\n ProviderError,\n type Request,\n type Response,\n} from '../types/provider.js';\n\n/**\n * Default timeout for one-shot LLM calls when the caller doesn't specify one.\n */\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/**\n * Default max output tokens when the caller doesn't specify.\n */\nconst DEFAULT_MAX_TOKENS = 1024;\n\ntype CallAttempt =\n | { response: Response; error?: never; fallbackEligible: false }\n | { response?: never; error: unknown; fallbackEligible: boolean };\n\n/**\n * OneShotOrchestrator \u2014 a stateless, reusable utility for making single\n * LLM calls with provider resolution, fallback chains, and structured results.\n *\n * Usage:\n * ```ts\n * const oneShot = new OneShotOrchestrator({ buildProvider, getConfig });\n * const result = await oneShot.call({\n * system: 'You are a helpful assistant.',\n * userPrompt: 'Summarize this conversation.',\n * model: 'deepseek-chat',\n * fallbackModels: ['anthropic/claude-haiku'],\n * });\n * console.log(result.text);\n * ```\n *\n * Every method is stateless \u2014 a single instance can be shared across\n * the entire process lifetime.\n */\nexport class OneShotOrchestrator {\n private readonly opts: OneShotOrchestratorOptions;\n\n constructor(opts: OneShotOrchestratorOptions) {\n this.opts = opts;\n }\n\n /**\n * Make a one-shot LLM call. Resolves provider+model, applies fallback\n * chain on transient errors, and returns a structured result.\n *\n * Never throws \u2014 all errors are captured in `OneShotLLMResult.error`.\n */\n async call(input: OneShotLLMInput): Promise<OneShotLLMResult> {\n const startedAt = performance.now();\n const config = this.opts.getConfig();\n\n // \u2500\u2500 1. Resolve target provider + model \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const target = this.resolveTarget(input, config);\n if (!target) {\n return {\n text: '',\n model: input.model ?? config.model ?? 'unknown',\n provider: input.providerId ?? config.provider ?? 'unknown',\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: Math.round(performance.now() - startedAt),\n fromFallback: false,\n error: 'No provider or model could be resolved. Check your config.',\n };\n }\n\n let provider: Provider;\n try {\n provider = await this.opts.buildProvider(target.providerId, target.model);\n } catch (err) {\n return {\n text: '',\n model: target.model,\n provider: target.providerId,\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: Math.round(performance.now() - startedAt),\n fromFallback: false,\n error: `Cannot build provider \"${target.providerId}\": ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n // \u2500\u2500 2. Build the request \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const request = this.buildRequest(input, target.model);\n const signal = this.resolveSignal(input);\n\n // \u2500\u2500 3. Build fallback chain \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const chain = this.resolveFallbackChain(input, config, target);\n\n // \u2500\u2500 4. Attempt the call with fallback rotation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const tracker = this.opts.statusTracker;\n let servingProviderId = provider.id;\n let servingModel = target.model;\n let fromFallback = false;\n let lastError: unknown;\n let fallbackEligible = false;\n\n // Check if the primary target is blocked\n if (\n (tracker && !tracker.isAvailable(target.providerId, target.model)) ||\n !evaluateModelCalendar(config.modelAvailabilitySchedule, target.providerId, target.model)\n .allowed\n ) {\n this.opts.logger?.debug(\n `one-shot: primary \"${target.providerId}/${target.model}\" is blocked \u2014 trying fallback`,\n );\n // Fall through to the fallback chain\n } else {\n const primaryAttempt = await this.tryCall(\n provider,\n request,\n signal,\n target.providerId,\n target.model,\n );\n const result = primaryAttempt.response;\n lastError = primaryAttempt.error;\n fallbackEligible = primaryAttempt.fallbackEligible;\n\n if (result) {\n tracker?.recordSuccess(target.providerId, target.model);\n servingProviderId = provider.id;\n servingModel = target.model;\n return this.buildResult(result, servingProviderId, servingModel, false, startedAt);\n }\n\n if (!fallbackEligible || chain.length === 0) {\n return this.buildErrorResult(lastError, target.providerId, target.model, false, startedAt);\n }\n }\n\n // \u2500\u2500 4b. Fallback chain \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Filter blocked entries from the chain\n const usableChain = tracker\n ? chain.filter((e) => tracker.isAvailable(e.providerId, e.model))\n : chain;\n\n for (const entry of usableChain) {\n if (\n !evaluateModelCalendar(config.modelAvailabilitySchedule, entry.providerId, entry.model)\n .allowed\n )\n continue;\n if (entry.providerId === provider.id && entry.model === target.model) continue;\n\n let fbProvider: Provider;\n try {\n fbProvider = await this.opts.buildProvider(entry.providerId, entry.model);\n } catch (err) {\n lastError = err;\n continue;\n }\n\n servingProviderId = fbProvider.id;\n servingModel = entry.model;\n const attempt = await this.tryCall(\n fbProvider,\n this.buildRequest(input, entry.model),\n signal,\n entry.providerId,\n entry.model,\n );\n if (attempt.response) {\n tracker?.recordSuccess(entry.providerId, entry.model);\n fromFallback = true;\n return this.buildResult(attempt.response, servingProviderId, servingModel, true, startedAt);\n }\n\n lastError = attempt.error;\n fallbackEligible = attempt.fallbackEligible;\n if (!fallbackEligible) break;\n }\n\n // Total failure \u2014 all providers exhausted or non-retryable error.\n return this.buildErrorResult(\n lastError,\n servingProviderId,\n servingModel,\n fromFallback,\n startedAt,\n );\n }\n\n // \u2500\u2500 Private helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Resolve the target provider + model from input + config.\n * Priority: role-based routing > explicit providerId+model > defaults.\n */\n private resolveTarget(\n input: OneShotLLMInput,\n config: import('../types/config.js').Config,\n ): { providerId: string; model: string } | undefined {\n // Role-based routing via ModelRouter (highest priority)\n if (input.role && this.opts.modelRouter) {\n const pick = this.opts.modelRouter.pickForTask(input.role, '');\n if (pick) {\n return { providerId: pick.provider, model: pick.model };\n }\n }\n\n // Explicit providerId + model\n if (input.providerId && input.model) {\n return { providerId: input.providerId, model: input.model };\n }\n\n // Model only \u2014 use default provider\n if (input.model) {\n return { providerId: config.provider, model: input.model };\n }\n\n // Provider only \u2014 use default model\n if (input.providerId) {\n return { providerId: input.providerId, model: config.model };\n }\n\n // Neither \u2014 use session defaults\n if (config.provider && config.model) {\n return { providerId: config.provider, model: config.model };\n }\n\n return undefined;\n }\n\n /**\n * Build a Provider Request from the input.\n */\n private buildRequest(input: OneShotLLMInput, model: string): Request {\n const messages: Message[] = [...(input.messages ?? [])];\n if (input.userPrompt) {\n messages.push({ role: 'user', content: input.userPrompt });\n }\n\n const system = asTextBlocks(input.system);\n\n return {\n model,\n ...(system.length > 0 ? { system } : {}),\n messages,\n maxTokens: input.maxTokens ?? DEFAULT_MAX_TOKENS,\n ...(input.temperature !== undefined ? { temperature: input.temperature } : {}),\n ...(input.responseFormat ? { responseFormat: input.responseFormat } : {}),\n };\n }\n\n /**\n * Resolve the abort signal. Provider calls always receive the per-call\n * timeout, composed with external cancellation when the caller supplies it.\n */\n private resolveSignal(input: OneShotLLMInput): AbortSignal {\n const timeoutSignal = AbortSignal.timeout(input.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n return input.signal ? AbortSignal.any([input.signal, timeoutSignal]) : timeoutSignal;\n }\n\n /**\n * Build the fallback model chain from input + config + current target.\n * The injected {@link OneShotOrchestratorOptions.fallbackProfileManager}\n * is the only allowed manager \u2014 OneShot never owns a private snapshot\n * so a live `ConfigStore` change reaches every call without rebuilding\n * the manager.\n */\n private resolveFallbackChain(\n input: OneShotLLMInput,\n config: Config,\n target: { providerId: string; model: string },\n ): FallbackChain {\n const mgr = this.opts.fallbackProfileManager;\n\n // Explicit chain wins\n if (input.fallbackModels && input.fallbackModels.length > 0) {\n return mgr.resolveRefs(input.fallbackModels, target);\n }\n\n // Config-level fallbackModels \u2014 independent of fallbackAuto\n if (config.fallbackModels && config.fallbackModels.length > 0) {\n return mgr.resolveRefs(config.fallbackModels, target);\n }\n\n // Smart default from config (only when auto-derivation is enabled)\n if (config.fallbackAuto !== false) {\n return mgr.resolveEffective({\n fallbackAuto: true,\n exclude: target,\n });\n }\n\n return Object.freeze([]) as FallbackChain;\n }\n\n /** Attempt a provider call while preserving the actual failure for callers. */\n private async tryCall(\n provider: Provider,\n request: Request,\n signal: AbortSignal,\n providerId?: string,\n model?: string,\n ): Promise<CallAttempt> {\n try {\n return {\n response: await provider.complete(request, { signal }),\n fallbackEligible: false,\n };\n } catch (err) {\n // Record the failure in the tracker\n if (err instanceof ProviderError && providerId && model) {\n this.opts.statusTracker?.recordFailure(\n providerId,\n model,\n err.kind,\n err.status,\n err.describe(),\n { retryAfterMs: err.body?.retryAfterMs },\n );\n }\n return {\n error: err,\n fallbackEligible:\n !signal.aborted && (!(err instanceof ProviderError) || isFallbackWorthy(err.kind)),\n };\n }\n }\n\n /** Build a success result from a provider Response. */\n private buildResult(\n response: Response,\n servingProviderId: string,\n servingModel: string,\n fromFallback: boolean,\n startedAt: number,\n ): OneShotLLMResult {\n const textBlocks = response.content.filter(isTextBlock);\n const text = textBlocks\n .map((b) => b.text)\n .join('\\n')\n .trim();\n return {\n text: text || '(empty response)',\n model: response.model ?? servingModel,\n provider: servingProviderId,\n tokens: {\n input: response.usage?.input ?? 0,\n output: response.usage?.output ?? 0,\n total: (response.usage?.input ?? 0) + (response.usage?.output ?? 0),\n },\n durationMs: Math.round(performance.now() - startedAt),\n fromFallback,\n stopReason: response.stopReason,\n };\n }\n\n /** Build a total-failure error result. */\n private buildErrorResult(\n error: unknown,\n servingProviderId: string,\n servingModel: string,\n fromFallback: boolean,\n startedAt: number,\n ): OneShotLLMResult {\n return {\n text: '',\n model: servingModel,\n provider: servingProviderId,\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: Math.round(performance.now() - startedAt),\n fromFallback,\n error: error instanceof Error ? error.message : String(error ?? 'Unknown error'),\n };\n }\n}\n\n/**\n * Normalize system prompt to TextBlock[].\n */\nfunction asTextBlocks(\n system: string | import('../types/blocks.js').TextBlock[] | undefined,\n): import('../types/blocks.js').TextBlock[] {\n if (!system) return [];\n if (Array.isArray(system)) return system;\n return [{ type: 'text', text: system }];\n}\n", "import type { JSONSchema, Tool } from '../types/tool.js';\nimport type { OneShotLLMInput, OneShotLLMResult, OneShotOrchestratorOptions } from '../types/one-shot-llm.js';\nimport { OneShotOrchestrator } from '../execution/one-shot-llm.js';\n\n/**\n * Tool name for the one-shot LLM tool.\n * Register in ToolRegistry as `llm` so any agent can call it.\n */\nexport const ONE_SHOT_LLM_TOOL_NAME = 'llm';\n\n/**\n * Options for creating the LLM tool.\n * Mirrors OneShotOrchestratorOptions \u2014 the tool wraps an internal orchestrator.\n * When `defaultProvider` and `defaultModel` are not set, callers MUST\n * provide `providerId` and `model` explicitly.\n */\nexport interface CreateOneShotLLMToolOptions {\n buildProvider: OneShotOrchestratorOptions['buildProvider'];\n getConfig: OneShotOrchestratorOptions['getConfig'];\n /** Shared live FallbackProfileManager \u2014 required. */\n fallbackProfileManager: OneShotOrchestratorOptions['fallbackProfileManager'];\n modelRouter?: OneShotOrchestratorOptions['modelRouter'];\n logger?: OneShotOrchestratorOptions['logger'];\n /**\n * Default provider to use when the caller doesn't specify one.\n * When absent, callers MUST provide `providerId` explicitly.\n */\n defaultProvider?: string | undefined;\n /**\n * Default model to use when the caller doesn't specify one.\n * When absent, callers MUST provide `model` explicitly.\n */\n defaultModel?: string | undefined;\n}\n\n/**\n * JSON Schema for the llm tool input.\n */\nconst INPUT_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n system: {\n type: 'string',\n description: 'System prompt guiding the LLM behaviour.',\n },\n userPrompt: {\n type: 'string',\n description: 'Single user turn \u2014 appended as a user-role message.',\n },\n messages: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n role: {\n type: 'string',\n enum: ['system', 'user', 'assistant', 'tool'],\n description: 'Message author role.',\n },\n content: {\n type: 'string',\n description: 'Message text content.',\n },\n },\n required: ['role', 'content'],\n additionalProperties: true,\n },\n description: 'Conversation messages for few-shot examples or multi-turn context. Appended before userPrompt when both are set.',\n },\n model: {\n type: 'string',\n description: 'Model id (e.g. \"deepseek-chat\", \"gpt-4o-mini\"). Defaults to session model.',\n },\n providerId: {\n type: 'string',\n description: 'Provider id (e.g. \"anthropic\", \"openai\"). Defaults to session provider.',\n },\n role: {\n type: 'string',\n description: 'Roster role for model-matrix routing. Overrides model/providerId.',\n },\n fallbackModels: {\n type: 'array',\n items: { type: 'string' },\n description: 'Explicit fallback model chain (e.g. [\"anthropic/claude-haiku\", \"openai/gpt-4o-mini\"]). Resolved named profiles from FallbackProfileManager are passed here.',\n },\n maxTokens: {\n type: 'number',\n description: 'Maximum output tokens (default 1024).',\n },\n responseFormat: {\n oneOf: [\n { type: 'string', enum: ['text', 'json_object'], description: 'Simple response format.' },\n {\n type: 'object',\n properties: {\n type: { type: 'string', enum: ['json_schema'], description: 'Structured JSON output.' },\n json_schema: {\n type: 'object',\n description: 'JSON Schema definition for the structured output.',\n },\n },\n required: ['type'],\n additionalProperties: false,\n },\n ],\n description: 'Response format: \"text\" (default), \"json_object\", or { type: \"json_schema\", json_schema: {...} }.',\n },\n temperature: {\n type: 'number',\n description: 'Sampling temperature.',\n },\n timeoutMs: {\n type: 'number',\n description: 'Hard timeout in ms (default 30s).',\n },\n },\n};\n\n/**\n * Create the `llm` tool \u2014 a general-purpose one-shot LLM invocation tool\n * that any agent can call. Wraps OneShotOrchestrator internally for\n * provider resolution, fallback chain support, and structured results.\n *\n * Usage from an agent:\n * ```\n * llm({\n * system: \"You are a helpful assistant.\",\n * userPrompt: \"Summarize this conversation.\",\n * model: \"deepseek-chat\",\n * maxTokens: 1024,\n * })\n * ```\n *\n * Register with the ToolRegistry and it becomes available everywhere:\n * ```ts\n * toolRegistry.register(createOneShotLLMTool({ buildProvider, getConfig }));\n * ```\n */\nexport function createOneShotLLMTool(opts: CreateOneShotLLMToolOptions): Tool<OneShotLLMInput, OneShotLLMResult> {\n const orchestrator = new OneShotOrchestrator({\n buildProvider: opts.buildProvider,\n getConfig: opts.getConfig,\n fallbackProfileManager: opts.fallbackProfileManager,\n modelRouter: opts.modelRouter,\n logger: opts.logger,\n });\n\n return {\n name: ONE_SHOT_LLM_TOOL_NAME,\n description:\n 'Make a one-shot LLM call with a system prompt and user input. ' +\n 'Supports provider selection, model routing by role, fallback chains, and timeout. ' +\n 'Returns the response text, model info, token usage, and whether a fallback was used. ' +\n 'Use this for summarization, classification, extraction, and any single-turn LLM task.',\n usageHint:\n 'Provide `system` for the instruction and `userPrompt` for the input. ' +\n 'Either set `model`+`providerId`, or have defaults configured on the tool. ' +\n 'Set `fallbackModels` for resilience. ' +\n 'Check `error` on the result for failure details.',\n inputSchema: INPUT_SCHEMA,\n permission: 'auto',\n mutating: false,\n\n async execute(\n input: OneShotLLMInput,\n _ctx,\n { signal }: { signal: AbortSignal },\n ): Promise<OneShotLLMResult> {\n // If the caller didn't provide model/providerId, check for tool-level defaults.\n // This prevents silent fallback to session config which may not be intended.\n if (!input.model && !input.providerId && !opts.defaultModel && !opts.defaultProvider) {\n return {\n text: '',\n model: '',\n provider: '',\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: 0,\n fromFallback: false,\n error:\n 'Either provide `model` and `providerId` in the call, or configure ' +\n 'defaultProvider/defaultModel when creating the tool. The `llm` tool ' +\n 'does not infer provider/model from the session by default.',\n };\n }\n\n // Apply defaults when caller omits model/providerId but defaults are configured.\n const effectiveInput: OneShotLLMInput = {\n ...input,\n signal: input.signal ? AbortSignal.any([input.signal, signal]) : signal,\n model: input.model ?? opts.defaultModel,\n providerId: input.providerId ?? opts.defaultProvider,\n };\n\n return orchestrator.call(effectiveInput);\n },\n };\n}\n", "/**\n * Catalog types for the WrongStack agent fleet.\n *\n * An `AgentDefinition` bundles the runtime `SubagentConfig` (id/name/role/\n * prompt/tools) with two things the bare config lacks:\n * - a per-role `budget` tier (consumed by FLEET_ROSTER_BUDGETS), and\n * - dispatcher `capability` metadata (keywords + summary + phase) used by\n * the smart dispatcher to route a free-form task to the best agent.\n *\n * Phase files (`phase1-discovery.ts` \u2026 `phase9-meta.ts`) each export an\n * `AgentDefinition[]`; `index.ts` aggregates them into `AGENT_CATALOG`.\n * `fleet.ts` derives `FLEET_ROSTER` + `FLEET_ROSTER_BUDGETS` from the catalog.\n */\nimport type { SubagentConfig } from '../../types/multi-agent.js';\n\n/** Lifecycle phase grouping. Drives statusline labels + dispatcher tie-breaks. */\nexport type AgentPhase =\n | 'discovery'\n | 'planning'\n | 'build'\n | 'verify'\n | 'review'\n | 'domain'\n | 'knowledge'\n | 'delivery'\n | 'meta';\n\n/** Per-role budget tier. Same shape as fleet.ts `FleetRosterBudget`. */\nexport interface AgentBudgetTier {\n timeoutMs?: number | undefined;\n maxIterations?: number | undefined;\n maxToolCalls?: number | undefined;\n maxTokens?: number | undefined;\n maxCostUsd?: number | undefined;\n}\n\n/** Dispatcher routing metadata. */\nexport interface AgentCapability {\n phase: AgentPhase;\n /**\n * One-line capability summary. Fed to the LLM dispatcher classifier as the\n * candidate's description, and shown to the user when explaining a routing\n * decision. Keep it concrete and distinct from sibling agents.\n */\n summary: string;\n /**\n * Lowercased signal words/phrases for the heuristic dispatcher. A task whose\n * description contains these scores toward this agent. Order doesn't matter;\n * prefer specific terms (\"graphql\", \"wcag\") over generic ones (\"code\").\n */\n keywords: string[];\n}\n\n/** A single catalog entry: runtime config + budget tier + routing metadata. */\nexport interface AgentDefinition {\n config: SubagentConfig;\n budget: AgentBudgetTier;\n capability: AgentCapability;\n}\n\nconst HOUR = 60 * 60 * 1000;\n\n/**\n * Budget tiers by workload weight. Deliberately generous \u2014 the project's\n * existing roster uses multi-hour ceilings to avoid spurious timeouts on\n * monorepo-scale work, and the auto-extend handshake raises them further when\n * a subagent is still making progress.\n */\nexport const LIGHT_BUDGET: AgentBudgetTier = {\n timeoutMs: 3 * HOUR,\n maxIterations: 3000,\n maxToolCalls: 8000,\n};\nexport const MEDIUM_BUDGET: AgentBudgetTier = {\n timeoutMs: 5 * HOUR,\n maxIterations: 5000,\n maxToolCalls: 14000,\n};\nexport const HEAVY_BUDGET: AgentBudgetTier = {\n timeoutMs: 10 * HOUR,\n maxIterations: 8000,\n maxToolCalls: 20000,\n};\n\n/**\n * Tool allowlist presets. Agents pass the smallest set that covers their job \u2014\n * a planning agent should not hold `write`/`bash`, a reviewer should be\n * read-only. Spread + extend per-agent where a role needs one extra tool.\n */\nexport const TOOLS = {\n /** Pure read/inspect \u2014 safe for analysis and review agents. */\n read: ['read', 'grep', 'glob', 'search', 'tree', 'mailbox'],\n /** Read + structured inspection (logs, diffs, json, dependency audit). */\n inspect: ['read', 'grep', 'glob', 'search', 'tree', 'json', 'diff', 'logs', 'audit', 'mailbox'],\n /** Read + edit (no shell). For agents that write code/docs but don't run it. */\n write: ['read', 'grep', 'glob', 'search', 'tree', 'write', 'edit', 'replace', 'patch', 'mailbox'],\n /** Full build loop: edit + run (lint/format/typecheck/test/bash). */\n build: [\n 'read',\n 'grep',\n 'glob',\n 'search',\n 'tree',\n 'write',\n 'edit',\n 'replace',\n 'patch',\n 'bash',\n 'exec',\n 'lint',\n 'format',\n 'typecheck',\n 'test',\n 'mailbox',\n ],\n /** Version control. */\n vcs: ['read', 'grep', 'glob', 'git', 'diff'],\n /** Dependency management + CVE audit. */\n deps: ['read', 'grep', 'glob', 'install', 'outdated', 'audit', 'json', 'mailbox'],\n /** Documentation authoring. */\n docs: ['read', 'grep', 'glob', 'search', 'tree', 'write', 'edit', 'document', 'mailbox'],\n /** Web research. */\n research: ['read', 'grep', 'glob', 'search', 'fetch', 'mailbox'],\n} as const satisfies Record<string, readonly string[]>;\n", "import { readFileSync, statSync } from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Cache of resolved prompt text, keyed by `<envDir>\\0<id>`. Prompt files do\n * not change during a process lifetime, so the first successful (or failed)\n * lookup is memoized. The key includes the override env var so tests that set\n * `WRONGSTACK_AGENT_INSTRUCTIONS_DIR` still observe fresh resolution.\n */\nconst promptCache = new Map<string, string>();\n\n/**\n * Cache of the ordered candidate directory list, keyed by `<envDir>\\0<cwd-home>`.\n * The list is otherwise identical for every `agentPrompt()` call, so resolving\n * (and sorting via `statSync`) it once per env avoids ~7 redundant `statSync`\n * probes per call. `fleet.ts` + the phase catalogs alone call `agentPrompt()`\n * ~60 times at import time.\n */\nconst candidateCache = new Map<string, string[]>();\n\nexport function agentPrompt(id: string): string {\n const envDir = process.env['WRONGSTACK_AGENT_INSTRUCTIONS_DIR'] ?? '';\n const cacheKey = `${envDir}\\u0000${id}`;\n const cached = promptCache.get(cacheKey);\n if (cached !== undefined) return cached;\n\n const fileName = `${id}.md`;\n let resolved = '';\n for (const dir of agentPromptDirCandidates(envDir)) {\n try {\n resolved = readFileSync(path.join(dir, fileName), 'utf8').trimEnd();\n break;\n } catch {\n // try next candidate\n }\n }\n promptCache.set(cacheKey, resolved);\n return resolved;\n}\n\nfunction agentPromptDirCandidates(envDir: string): string[] {\n const globalRoot = process.env['WRONGSTACK_HOME'] || path.join(os.homedir(), '.wrongstack');\n const candKey = `${envDir}\\u0000${globalRoot}`;\n const cached = candidateCache.get(candKey);\n if (cached !== undefined) return cached;\n\n const here = path.dirname(fileURLToPath(import.meta.url));\n const explicitDir = envDir || undefined;\n const candidates = [\n ...(explicitDir ? [path.resolve(explicitDir)] : []),\n path.join(globalRoot, 'instructions', 'agents'),\n path.resolve(here, '../../../../instructions/agents'),\n path.resolve(here, '../../../instructions/agents'),\n path.resolve(here, '../../instructions/agents'),\n path.resolve(here, '../instructions/agents'),\n path.resolve(here, 'instructions/agents'),\n ];\n const ordered = candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));\n candidateCache.set(candKey, ordered);\n return ordered;\n}\n\nfunction isDirectory(candidate: string): boolean {\n try {\n return statSync(candidate).isDirectory();\n } catch {\n return false;\n }\n}\n", "import { type AgentDefinition, LIGHT_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 1 \u00B7 Discovery \u2014 map the territory before any work begins. */\nexport const DISCOVERY_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'explore',\n name: 'Explore',\n role: 'explore',\n tools: [...TOOLS.read],\n prompt: agentPrompt('explore'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'discovery',\n summary: 'Maps unfamiliar codebases: entry points, structure, architecture, feature flow (read-only).',\n keywords: [\n 'explore',\n 'map',\n 'understand',\n 'where is',\n 'how does',\n 'codebase',\n 'architecture',\n 'structure',\n 'overview',\n 'find file',\n 'entry point',\n 'orient',\n ],\n },\n },\n {\n config: {\n id: 'search',\n name: 'Search',\n role: 'search',\n tools: [...TOOLS.read],\n prompt: agentPrompt('search'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'discovery',\n summary: 'Semantic + lexical code search across repos; finds definitions, references, duplicates, ranks by relevance.',\n keywords: [\n 'search',\n 'find all',\n 'references',\n 'usages',\n 'call sites',\n 'grep',\n 'locate symbol',\n 'duplicate',\n 'where used',\n 'occurrences',\n 'cross-repo',\n ],\n },\n },\n {\n config: {\n id: 'research',\n name: 'Research',\n role: 'research',\n tools: [...TOOLS.research],\n prompt: agentPrompt('research'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'discovery',\n summary: 'Technical research and feasibility: compares libraries/approaches, recommends a path with evidence and tradeoffs.',\n keywords: [\n 'research',\n 'feasibility',\n 'compare libraries',\n 'which library',\n 'best practice',\n 'tradeoff',\n 'investigate',\n 'evaluate approach',\n 'should we use',\n 'pros and cons',\n ],\n },\n },\n];\n", "import { type AgentDefinition, HEAVY_BUDGET, LIGHT_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\nconst PLAN_TOOLS = [...TOOLS.read, 'plan', 'todo'];\n\n/** Phase 2 \u00B7 Planning \u2014 turn intent into requirements, plans, and architecture. */\nexport const PLANNING_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'analyst',\n name: 'Analyst',\n role: 'analyst',\n tools: [...PLAN_TOOLS],\n prompt: agentPrompt('analyst'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'planning',\n summary: 'Requirement analysis: turns vague requests into testable specs with acceptance criteria and open questions.',\n keywords: [\n 'requirements',\n 'analyze requirement',\n 'acceptance criteria',\n 'spec',\n 'specification',\n 'clarify',\n 'scope',\n 'user story',\n 'what should it do',\n ],\n },\n },\n {\n config: {\n id: 'planner',\n name: 'Planner',\n role: 'planner',\n tools: [...PLAN_TOOLS],\n prompt: agentPrompt('planner'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'planning',\n summary: 'Execution planning: decomposes a goal into ordered, dependency-aware, parallelizable steps with checkpoints.',\n keywords: [\n 'plan',\n 'execution plan',\n 'break down',\n 'decompose',\n 'steps',\n 'sequence',\n 'roadmap',\n 'task breakdown',\n 'order of work',\n 'milestones',\n ],\n },\n },\n {\n config: {\n id: 'architect',\n name: 'Architect',\n role: 'architect',\n tools: [...PLAN_TOOLS],\n prompt: agentPrompt('architect'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'planning',\n summary: 'System architecture: designs module boundaries, interfaces, data flow, and records key decisions.',\n keywords: [\n 'architecture',\n 'design system',\n 'module boundaries',\n 'interfaces',\n 'data flow',\n 'component design',\n 'system design',\n 'decision record',\n 'adr',\n 'structure the',\n ],\n },\n },\n {\n config: {\n id: 'critic',\n name: 'Critic',\n role: 'critic',\n tools: [...TOOLS.read],\n prompt: agentPrompt('critic'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'planning',\n summary: 'Adversarial review of plans/designs: finds gaps, risks, and unstated assumptions with ranked fixes.',\n keywords: [\n 'critique',\n 'review plan',\n 'review design',\n 'red team',\n 'poke holes',\n 'risks',\n 'what could go wrong',\n 'second opinion',\n 'challenge',\n 'flaws',\n ],\n },\n },\n {\n config: {\n id: 'refactor-planner',\n name: 'Refactor Planner',\n role: 'refactor-planner',\n tools: [...PLAN_TOOLS, 'diff'],\n prompt: agentPrompt('refactor-planner'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'planning',\n summary: 'Refactoring planner: analyzes code structure, maps dependencies, produces risk-scored phased plans with rollback strategy.',\n keywords: [\n 'refactor',\n 'refactoring',\n 'restructure',\n 'debt',\n 'technical debt',\n 'clean up',\n 'modularize',\n 'decouple',\n 'dependency graph',\n 'code structure',\n ],\n },\n },\n];\n", "import { type AgentDefinition, HEAVY_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 3 \u00B7 Build \u2014 write, refactor, migrate, and fix code. */\nexport const BUILD_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'executor',\n name: 'Executor',\n role: 'executor',\n tools: [...TOOLS.build],\n prompt: agentPrompt('executor'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Implements well-specified tasks: writes code, runs checks, leaves the tree green.',\n keywords: [\n 'implement',\n 'build',\n 'write code',\n 'add feature',\n 'create',\n 'code up',\n 'develop',\n 'apply change',\n 'make it work',\n ],\n },\n },\n {\n config: {\n id: 'refactor',\n name: 'Refactor',\n role: 'refactor',\n tools: [...TOOLS.build],\n prompt: agentPrompt('refactor'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Structural refactoring: extract/split/move/rename/decouple without changing observable behavior.',\n keywords: [\n 'refactor',\n 'restructure',\n 'extract',\n 'split module',\n 'decouple',\n 'rename',\n 'move code',\n 'break dependency',\n 'reorganize',\n ],\n },\n },\n {\n config: {\n id: 'simplifier',\n name: 'Simplifier',\n role: 'simplifier',\n tools: [...TOOLS.build],\n prompt: agentPrompt('simplifier'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Reduces complexity: deletes dead code, collapses needless abstractions, shortens and clarifies code.',\n keywords: [\n 'simplify',\n 'dead code',\n 'remove unused',\n 'reduce complexity',\n 'clean up',\n 'denest',\n 'shorten',\n 'over-engineered',\n 'too complex',\n ],\n },\n },\n {\n config: {\n id: 'migration',\n name: 'Migration',\n role: 'migration',\n tools: [...TOOLS.build, 'install', 'outdated'],\n prompt: agentPrompt('migration'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Framework/language/version upgrades: applies codemods across call sites, staged and verified.',\n keywords: [\n 'migrate',\n 'upgrade',\n 'codemod',\n 'breaking change',\n 'major version',\n 'port to',\n 'convert to',\n 'esm',\n 'modernize',\n ],\n },\n },\n {\n config: {\n id: 'vision',\n name: 'Vision',\n role: 'vision',\n tools: [...TOOLS.write, 'fetch'],\n prompt: agentPrompt('vision'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Screenshot/mockup \u2192 UI code: infers component tree and generates matching, accessible markup.',\n keywords: [\n 'screenshot',\n 'mockup',\n 'design to code',\n 'image to ui',\n 'figma',\n 'replicate this ui',\n 'from this picture',\n 'vision',\n 'clone ui',\n ],\n },\n },\n {\n config: {\n id: 'debugger',\n name: 'Debugger',\n role: 'debugger',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('debugger'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Root-cause bug fixing: reproduces, bisects to the true cause, applies a minimal fix with a regression test.',\n keywords: [\n 'bug',\n 'fix',\n 'debug',\n 'broken',\n 'error',\n 'crash',\n 'root cause',\n 'not working',\n 'failing',\n 'reproduce',\n 'why does',\n ],\n },\n },\n {\n config: {\n id: 'tracer',\n name: 'Tracer',\n role: 'tracer',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('tracer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Runtime tracing: instruments and runs code to observe call order, values, and timing, then cleans up.',\n keywords: [\n 'trace',\n 'runtime',\n 'instrument',\n 'execution path',\n 'what happens at runtime',\n 'call order',\n 'profile execution',\n 'observe behavior',\n 'stack trace',\n ],\n },\n },\n];\n", "import { agentPrompt } from './agent-prompts.js';\nimport { type AgentDefinition, HEAVY_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\n\n/** Phase 4 \u00B7 Verify \u2014 prove the code works under normal, end-to-end, and adverse conditions. */\nexport const VERIFY_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'verifier',\n name: 'Verifier',\n role: 'verifier',\n tools: [...TOOLS.inspect, 'bash', 'exec', 'lint', 'typecheck', 'test', 'git'],\n prompt: agentPrompt('verifier'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Independent verification gate: runs the relevant checks until they pass or returns exact failures that need another implementation pass.',\n keywords: [\n 'verify',\n 'verification',\n 'quality gate',\n 'prove it works',\n 'run checks',\n 'run tests until pass',\n 'test pass',\n 'green build',\n 'typecheck',\n 'lint',\n 'regression check',\n 'acceptance gate',\n ],\n },\n },\n {\n config: {\n id: 'test',\n name: 'Test',\n role: 'test',\n tools: [...TOOLS.build],\n prompt: agentPrompt('test'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Unit + integration testing: writes meaningful tests covering golden path and edge cases, runs the suite.',\n keywords: [\n 'test',\n 'unit test',\n 'integration test',\n 'write tests',\n 'coverage',\n 'test suite',\n 'vitest',\n 'jest',\n 'add tests',\n 'spec',\n ],\n },\n },\n {\n config: {\n id: 'e2e',\n name: 'E2E',\n role: 'e2e',\n tools: [\n ...TOOLS.build,\n 'fetch',\n 'playwright_navigate',\n 'playwright_screenshot',\n 'playwright_click',\n 'playwright_type',\n 'playwright_evaluate',\n 'playwright_select_option',\n 'playwright_hover',\n 'playwright_fill_form',\n 'playwright_wait_for',\n 'playwright_press_key',\n 'playwright_drag',\n ],\n prompt: agentPrompt('e2e'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'End-to-end testing: drives full user journeys across UI/CLI/API boundaries with reproducible failures.',\n keywords: [\n 'e2e',\n 'end to end',\n 'end-to-end',\n 'user journey',\n 'smoke test',\n 'playwright',\n 'browser',\n 'screenshot',\n 'web ui',\n 'headless',\n 'cypress',\n 'full flow',\n 'browser test',\n 'acceptance test',\n 'navigate',\n 'click',\n 'form fill',\n 'dom',\n 'page load',\n ],\n },\n },\n {\n config: {\n id: 'browser',\n name: 'Browser',\n role: 'browser',\n tools: [\n ...TOOLS.read,\n 'fetch',\n 'playwright_navigate',\n 'playwright_screenshot',\n 'playwright_click',\n 'playwright_type',\n 'playwright_evaluate',\n 'playwright_select_option',\n 'playwright_hover',\n 'playwright_fill_form',\n 'playwright_wait_for',\n 'playwright_press_key',\n 'playwright_drag',\n ],\n prompt: agentPrompt('browser'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Browser automation: opens pages, clicks, types, screenshots, extracts data via Playwright headless Chromium.',\n keywords: [\n 'browser',\n 'screenshot',\n 'navigate',\n 'web page',\n 'scrape',\n 'crawl',\n 'headless',\n 'chrome',\n 'open url',\n 'capture',\n 'page title',\n 'extract data',\n 'fill form',\n 'click button',\n 'take screenshot',\n ],\n },\n },\n {\n config: {\n id: 'performance',\n name: 'Performance',\n role: 'performance',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('performance'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Performance analysis: benchmarks/profiles to find the real bottleneck, optimizes, proves speedup with numbers.',\n keywords: [\n 'performance',\n 'slow',\n 'optimize',\n 'bottleneck',\n 'profile',\n 'benchmark',\n 'latency',\n 'throughput',\n 'memory',\n 'speed up',\n 'too slow',\n ],\n },\n },\n {\n config: {\n id: 'chaos',\n name: 'Chaos',\n role: 'chaos',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('chaos'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Resilience testing via fault injection: breaks network/disk/timing to find ungraceful failures and recovery gaps.',\n keywords: [\n 'chaos',\n 'resilience',\n 'fault injection',\n 'failure mode',\n 'fail safe',\n 'retry',\n 'circuit breaker',\n 'graceful degradation',\n 'inject failure',\n 'robustness',\n ],\n },\n },\n {\n config: {\n id: 'security-scanner',\n name: 'Security Scanner',\n role: 'security-scanner',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('security-scanner'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Security scanner: detects hardcoded secrets, injection vectors, insecure patterns, and supply-chain risks with remediation.',\n keywords: [\n 'security',\n 'scan',\n 'vulnerability',\n 'secret',\n 'api key',\n 'hardcoded',\n 'injection',\n 'cve',\n 'audit dependencies',\n 'supply chain',\n 'xss',\n 'sqli',\n 'shell injection',\n 'sensitive data',\n 'credential',\n ],\n },\n },\n {\n config: {\n id: 'bug-hunter',\n name: 'Bug Hunter',\n role: 'bug-hunter',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('bug-hunter'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Bug hunter: scans source code for bugs, anti-patterns, and code smells, producing a file:line-ranked hit list with fixes.',\n keywords: [\n 'bug',\n 'hunt',\n 'scan',\n 'code smell',\n 'anti-pattern',\n 'race condition',\n 'memory leak',\n 'null deref',\n 'type safety',\n 'unhandled error',\n 'find bugs',\n 'audit code',\n 'code quality',\n ],\n },\n },\n {\n config: {\n id: 'audit-log',\n name: 'Audit Log',\n role: 'audit-log',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('audit-log'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Audit log analyzer: parses session JSONL, detects failure patterns, tool anomalies, and cost trends with structured reports.',\n keywords: [\n 'audit',\n 'log',\n 'logs',\n 'session',\n 'trace',\n 'analyze logs',\n 'error patterns',\n 'cost analysis',\n 'tool usage',\n 'token usage',\n 'post-mortem',\n 'trend',\n 'anomaly',\n ],\n },\n },\n];\n", "import { agentPrompt } from './agent-prompts.js';\nimport { type AgentDefinition, MEDIUM_BUDGET, TOOLS } from './types.js';\n\n/** Phase 5 \u00B7 Review \u2014 read-only quality, security, a11y, and compliance gates. */\nexport const REVIEW_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'reviewer',\n name: 'Reviewer',\n role: 'reviewer',\n tools: [...TOOLS.inspect, 'git'],\n prompt: agentPrompt('reviewer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n \"Independent AI reviewer: audits another agent's output, flags uncertainty, correlated-failure risk, and must-fix defects.\",\n keywords: [\n 'reviewer',\n 'independent review',\n 'ai review',\n 'review agent',\n 'quality review',\n 'second opinion',\n 'check another agent',\n 'cross check',\n 'uncertainty',\n 'correlated error',\n 'verify output',\n 'quality control',\n ],\n },\n },\n {\n config: {\n id: 'code-reviewer',\n name: 'Code Reviewer',\n role: 'code-reviewer',\n tools: [...TOOLS.inspect, 'git'],\n prompt: agentPrompt('code-reviewer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n 'Correctness-first code review of diffs/PRs: finds bugs, edge cases, and convention violations with fixes.',\n keywords: [\n 'review',\n 'code review',\n 'review pr',\n 'review diff',\n 'look over',\n 'feedback on code',\n 'quality',\n 'is this correct',\n 'check my code',\n ],\n },\n },\n {\n config: {\n id: 'security-reviewer',\n name: 'Security Reviewer',\n role: 'security-reviewer',\n tools: [...TOOLS.inspect, 'git'],\n prompt: agentPrompt('security-reviewer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n 'Security review: finds injection/authz/secret/crypto issues mapped to OWASP severity with remediation.',\n keywords: [\n 'security review',\n 'security',\n 'vulnerability',\n 'vulnerabilities',\n 'owasp',\n 'injection',\n 'sql injection',\n 'xss',\n 'ssrf',\n 'authz',\n 'secrets',\n 'security audit',\n 'threat',\n 'unsafe',\n ],\n },\n },\n {\n config: {\n id: 'accessibility',\n name: 'Accessibility',\n role: 'accessibility',\n tools: [...TOOLS.read],\n prompt: agentPrompt('accessibility'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n 'WCAG/a11y review of UI: checks semantics, ARIA, keyboard, contrast; maps findings to success criteria.',\n keywords: [\n 'accessibility',\n 'a11y',\n 'wcag',\n 'aria',\n 'screen reader',\n 'keyboard navigation',\n 'contrast',\n 'disabled users',\n 'accessible',\n ],\n },\n },\n {\n config: {\n id: 'compliance',\n name: 'Compliance',\n role: 'compliance',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('compliance'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n 'License/privacy/regulatory review: audits licenses, PII handling, and controls vs GDPR/SOC2.',\n keywords: [\n 'compliance',\n 'license',\n 'gdpr',\n 'soc2',\n 'privacy',\n 'pii',\n 'data retention',\n 'regulatory',\n 'audit log',\n 'legal review',\n ],\n },\n },\n];\n", "import { type AgentDefinition, HEAVY_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 6 \u00B7 Domain \u2014 specialists for the major slices of a system. */\nexport const DOMAIN_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'database',\n name: 'Database',\n role: 'database',\n tools: [...TOOLS.build],\n prompt: agentPrompt('database'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'Schema design, query optimization, and safe reversible migrations for SQL databases.',\n keywords: [\n 'database',\n 'schema',\n 'sql',\n 'migration',\n 'query',\n 'index',\n 'postgres',\n 'mysql',\n 'table',\n 'orm',\n 'slow query',\n ],\n },\n },\n {\n config: {\n id: 'api',\n name: 'API',\n role: 'api',\n tools: [...TOOLS.build, 'fetch'],\n prompt: agentPrompt('api'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'REST + GraphQL API design and implementation: contracts, HTTP/GraphQL semantics, versioning.',\n keywords: [\n 'api',\n 'rest',\n 'graphql',\n 'endpoint',\n 'resolver',\n 'http',\n 'openapi',\n 'swagger',\n 'route',\n 'contract',\n 'webhook',\n ],\n },\n },\n {\n config: {\n id: 'auth',\n name: 'Auth',\n role: 'auth',\n tools: [...TOOLS.build],\n prompt: agentPrompt('auth'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'Authentication and authorization: identity, sessions/tokens, RBAC/ABAC, OAuth/OIDC, done securely.',\n keywords: [\n 'auth',\n 'authentication',\n 'authorization',\n 'login',\n 'session',\n 'jwt',\n 'oauth',\n 'oidc',\n 'rbac',\n 'permissions',\n 'token',\n 'sso',\n ],\n },\n },\n {\n config: {\n id: 'data',\n name: 'Data',\n role: 'data',\n tools: [...TOOLS.build],\n prompt: agentPrompt('data'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'Data engineering: ETL/ELT pipelines, data-quality validation, idempotent transforms, reconciliation.',\n keywords: [\n 'etl',\n 'elt',\n 'pipeline',\n 'data quality',\n 'data engineering',\n 'transform',\n 'ingestion',\n 'batch',\n 'stream',\n 'reconcile',\n 'dataset',\n ],\n },\n },\n {\n config: {\n id: 'frontend',\n name: 'Frontend',\n role: 'frontend',\n tools: [...TOOLS.build, 'fetch'],\n prompt: agentPrompt('frontend'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'UI implementation: components, client state, data fetching, responsive and accessible by default.',\n keywords: [\n 'frontend',\n 'component',\n 'react',\n 'vue',\n 'svelte',\n 'client state',\n 'ui implementation',\n 'css',\n 'responsive',\n 'hook',\n 'render',\n ],\n },\n },\n {\n config: {\n id: 'backend',\n name: 'Backend',\n role: 'backend',\n tools: [...TOOLS.build],\n prompt: agentPrompt('backend'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'Server-side logic: services, business rules, persistence/queue wiring, concurrency and transactions.',\n keywords: [\n 'backend',\n 'server',\n 'service',\n 'business logic',\n 'controller',\n 'handler',\n 'queue',\n 'cache',\n 'transaction',\n 'microservice',\n 'server-side',\n ],\n },\n },\n {\n config: {\n id: 'designer',\n name: 'Designer',\n role: 'designer',\n tools: [...TOOLS.docs],\n prompt: agentPrompt('designer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'UI/UX design: user flows, layout/wireframes, interaction states, and design-system decisions.',\n keywords: [\n 'design',\n 'ux',\n 'ui design',\n 'wireframe',\n 'user flow',\n 'layout',\n 'design system',\n 'interaction',\n 'mockup design',\n 'information architecture',\n ],\n },\n },\n {\n config: {\n id: 'ios',\n name: 'iOS',\n role: 'ios',\n tools: [...TOOLS.build, 'fetch'],\n prompt: agentPrompt('ios'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary:\n 'Apple-platform app development in Swift against the latest Xcode/iOS-SDK line: SwiftUI, UIKit, SwiftData, concurrency, accessibility, and App Store submission.',\n keywords: [\n 'ios',\n 'iphone',\n 'ipad',\n 'ipados',\n 'watchos',\n 'tvos',\n 'visionos',\n 'macos',\n 'swift',\n 'swiftui',\n 'uikit',\n 'xcode',\n 'swiftdata',\n 'app store',\n 'app intents',\n 'swift package manager',\n 'cocoapods',\n 'foundation models',\n ],\n },\n },\n];\n", "import { type AgentDefinition, LIGHT_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 7 \u00B7 Knowledge \u2014 documentation, diagrams, localization, and prompts. */\nexport const KNOWLEDGE_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'document',\n name: 'Document',\n role: 'document',\n tools: [...TOOLS.docs],\n prompt: agentPrompt('document'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'knowledge',\n summary: 'Technical documentation: READMEs, API/reference docs, guides, and verified examples grounded in code.',\n keywords: [\n 'document',\n 'documentation',\n 'readme',\n 'docs',\n 'write up',\n 'guide',\n 'api docs',\n 'explain in writing',\n 'reference',\n 'changelog notes',\n ],\n },\n },\n {\n config: {\n id: 'uml',\n name: 'UML',\n role: 'uml',\n tools: [...TOOLS.read, 'write', 'edit'],\n prompt: agentPrompt('uml'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'knowledge',\n summary: 'Diagram generation from code: class/sequence/component/ER diagrams as Mermaid/PlantUML.',\n keywords: [\n 'uml',\n 'diagram',\n 'mermaid',\n 'plantuml',\n 'sequence diagram',\n 'class diagram',\n 'er diagram',\n 'visualize',\n 'flowchart',\n 'architecture diagram',\n ],\n },\n },\n {\n config: {\n id: 'i18n',\n name: 'I18n',\n role: 'i18n',\n tools: [...TOOLS.write],\n prompt: agentPrompt('i18n'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'knowledge',\n summary: 'Internationalization/localization: string extraction, catalog management, plurals/RTL/format handling.',\n keywords: [\n 'i18n',\n 'internationalization',\n 'localization',\n 'l10n',\n 'translation',\n 'translate ui',\n 'locale',\n 'rtl',\n 'message catalog',\n 'multilingual',\n ],\n },\n },\n {\n config: {\n id: 'prompt',\n name: 'Prompt',\n role: 'prompt',\n tools: [...TOOLS.write],\n prompt: agentPrompt('prompt'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'knowledge',\n summary: 'Prompt engineering: designs/refines/evaluates LLM system prompts and agent instructions.',\n keywords: [\n 'prompt',\n 'prompt engineering',\n 'system prompt',\n 'llm instructions',\n 'few-shot',\n 'refine prompt',\n 'agent instructions',\n 'prompt template',\n ],\n },\n },\n];\n", "import { type AgentDefinition, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 8 \u00B7 Delivery & Ops \u2014 ship it, run it, keep it healthy. */\nexport const DELIVERY_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'git',\n name: 'Git',\n role: 'git',\n tools: [...TOOLS.vcs, 'bash'],\n prompt: agentPrompt('git'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'delivery',\n summary: 'Git automation: focused commits, branch/rebase/conflict handling, PR prep, history investigation.',\n keywords: [\n 'git',\n 'commit',\n 'branch',\n 'rebase',\n 'merge',\n 'pull request',\n 'pr',\n 'conflict',\n 'blame',\n 'bisect',\n 'cherry-pick',\n 'stash',\n ],\n },\n },\n {\n config: {\n id: 'release',\n name: 'Release',\n role: 'release',\n tools: [...TOOLS.vcs, 'bash', 'json'],\n prompt: agentPrompt('release'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'delivery',\n summary: 'Release management: semver bumps, changelogs, and release notes derived from real history.',\n keywords: [\n 'release',\n 'version',\n 'semver',\n 'changelog',\n 'release notes',\n 'tag',\n 'bump version',\n 'publish',\n 'versioning',\n ],\n },\n },\n {\n config: {\n id: 'devops',\n name: 'DevOps',\n role: 'devops',\n tools: [\n ...TOOLS.build,\n 'mcp__ssh__ssh_list_servers',\n 'mcp__ssh__ssh_connection_status',\n 'mcp__ssh__ssh_execute',\n 'mcp__ssh__ssh_execute_sudo',\n 'mcp__ssh__ssh_upload',\n 'mcp__ssh__ssh_download',\n 'mcp__ssh__ssh_sync',\n 'mcp__ssh__ssh_deploy',\n 'mcp__ssh__ssh_health_check',\n 'mcp__ssh__ssh_service_status',\n 'mcp__ssh__ssh_process_manager',\n 'mcp__ssh__ssh_tunnel',\n 'mcp__ssh__ssh_backup_create',\n 'mcp__ssh__ssh_backup_list',\n 'mcp__ssh__ssh_backup_restore',\n 'mcp__ssh__ssh_db_list',\n 'mcp__ssh__ssh_db_query',\n 'mcp__ssh__ssh_profile',\n ],\n prompt: agentPrompt('devops'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'delivery',\n summary: 'CI/CD, containerization, and deployment config: reproducible builds and safe deploys with rollback.',\n keywords: [\n 'devops',\n 'ci',\n 'cd',\n 'ci/cd',\n 'pipeline',\n 'docker',\n 'dockerfile',\n 'kubernetes',\n 'k8s',\n 'deploy',\n 'ssh',\n 'remote ssh',\n 'remote server',\n 'sftp',\n 'tunnel',\n 'bastion',\n 'jump host',\n 'github actions',\n 'container',\n ],\n },\n },\n {\n config: {\n id: 'observability',\n name: 'Observability',\n role: 'observability',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('observability'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'delivery',\n summary: 'Observability: structured logging, metrics, distributed tracing, and alerts/dashboards.',\n keywords: [\n 'observability',\n 'logging',\n 'metrics',\n 'tracing',\n 'telemetry',\n 'opentelemetry',\n 'otel',\n 'prometheus',\n 'monitoring',\n 'alert',\n 'dashboard',\n 'instrument',\n ],\n },\n },\n {\n config: {\n id: 'dependency',\n name: 'Dependency',\n role: 'dependency',\n tools: [...TOOLS.deps, 'bash'],\n prompt: agentPrompt('dependency'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'delivery',\n summary: 'Package management + supply-chain safety: CVE audit, safe upgrades, pruning, install-script review.',\n keywords: [\n 'dependency',\n 'dependencies',\n 'package',\n 'npm',\n 'pnpm',\n 'cve',\n 'vulnerability scan',\n 'upgrade deps',\n 'audit',\n 'supply chain',\n 'outdated',\n 'lockfile',\n ],\n },\n },\n];\n", "import { type AgentDefinition, LIGHT_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 9 \u00B7 Meta \u2014 agents that improve the agent system itself. */\nexport const META_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'skill-manage',\n name: 'Skill Manager',\n role: 'skill-manage',\n tools: [...TOOLS.write],\n prompt: agentPrompt('skill-manage'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'meta',\n summary: 'Skill curation: audits, refines descriptions/triggers, scaffolds, and retires skills.',\n keywords: [\n 'skill',\n 'skills',\n 'curate skill',\n 'skill description',\n 'create skill',\n 'skill library',\n 'skill trigger',\n 'manage skills',\n ],\n },\n },\n {\n config: {\n id: 'self-improving',\n name: 'Self-Improving',\n role: 'self-improving',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('self-improving'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'meta',\n summary: 'Learns from execution logs: mines recurring failures/inefficiencies and proposes evidence-based improvements.',\n keywords: [\n 'self-improving',\n 'learn from',\n 'session logs',\n 'execution analysis',\n 'recurring failure',\n 'improve agents',\n 'post-mortem',\n 'retrospective',\n 'meta-analysis',\n ],\n },\n },\n {\n config: {\n id: 'context',\n name: 'Context',\n role: 'context',\n tools: [...TOOLS.inspect, 'remember', 'forget'],\n prompt: agentPrompt('context'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'meta',\n summary: 'Memory + context-window management: compaction, recall, and curation within a token budget.',\n keywords: [\n 'context',\n 'context window',\n 'memory',\n 'compact',\n 'summarize history',\n 'recall',\n 'token budget',\n 'prune context',\n 'remember',\n 'dfmt',\n ],\n },\n },\n {\n config: {\n id: 'cost',\n name: 'Cost',\n role: 'cost',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('cost'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'meta',\n summary: 'Token/cloud cost optimization: finds spend waste, recommends model routing and trimming with $ estimates.',\n keywords: [\n 'cost',\n 'token cost',\n 'optimize cost',\n 'spend',\n 'cheaper',\n 'model routing',\n 'budget',\n 'expensive',\n 'reduce tokens',\n 'pricing',\n 'cloud cost',\n ],\n },\n },\n {\n config: {\n id: 'tech-stack',\n name: 'Tech Stack Validator',\n role: 'tech-stack',\n tools: ['search', 'fetch', 'read', 'grep', 'glob', 'outdated', 'audit', 'json', 'mailbox'],\n prompt: agentPrompt('tech-stack'),\n },\n budget: {\n timeoutMs: 120_000,\n maxIterations: 10,\n maxToolCalls: 40,\n maxTokens: 60_000,\n maxCostUsd: 0.25,\n },\n capability: {\n phase: 'meta',\n summary: 'Single-shot tech stack validator: checks npm for latest versions, rejects dead/obsolete packages, enforces modern alternatives.',\n keywords: [\n 'tech stack',\n 'version',\n 'package',\n 'library',\n 'framework',\n 'dependency',\n 'install',\n 'upgrade',\n 'latest',\n 'npm',\n 'pnpm add',\n 'outdated',\n 'obsolete',\n 'deprecated',\n 'what version',\n 'which package',\n 'check version',\n 'verify version',\n 'is this current',\n ],\n },\n },\n];\n", "/**\n * Agent catalog aggregator.\n *\n * Collects every phase's `AgentDefinition[]` into:\n * - `ALL_AGENT_DEFINITIONS` \u2014 flat list, catalog order (phase 1 \u2192 9)\n * - `AGENT_CATALOG` \u2014 keyed by role for O(1) lookup\n * - `AGENTS_BY_PHASE` \u2014 grouped for statusline / dispatcher tie-breaks\n *\n * `fleet.ts` derives `FLEET_ROSTER` + `FLEET_ROSTER_BUDGETS` from this, and the\n * dispatcher routes free-form tasks against `capability` metadata here.\n */\nimport type { AgentDefinition, AgentPhase } from './types.js';\nimport { DISCOVERY_AGENTS } from './phase1-discovery.js';\nimport { PLANNING_AGENTS } from './phase2-planning.js';\nimport { BUILD_AGENTS } from './phase3-build.js';\nimport { VERIFY_AGENTS } from './phase4-verify.js';\nimport { REVIEW_AGENTS } from './phase5-review.js';\nimport { DOMAIN_AGENTS } from './phase6-domain.js';\nimport { KNOWLEDGE_AGENTS } from './phase7-knowledge.js';\nimport { DELIVERY_AGENTS } from './phase8-delivery.js';\nimport { META_AGENTS } from './phase9-meta.js';\n\nexport * from './types.js';\nexport {\n DISCOVERY_AGENTS,\n PLANNING_AGENTS,\n BUILD_AGENTS,\n VERIFY_AGENTS,\n REVIEW_AGENTS,\n DOMAIN_AGENTS,\n KNOWLEDGE_AGENTS,\n DELIVERY_AGENTS,\n META_AGENTS,\n};\n\n/** Every catalog agent, in phase order. */\nexport const ALL_AGENT_DEFINITIONS: AgentDefinition[] = [\n ...DISCOVERY_AGENTS,\n ...PLANNING_AGENTS,\n ...BUILD_AGENTS,\n ...VERIFY_AGENTS,\n ...REVIEW_AGENTS,\n ...DOMAIN_AGENTS,\n ...KNOWLEDGE_AGENTS,\n ...DELIVERY_AGENTS,\n ...META_AGENTS,\n];\n\n/** Phase \u2192 its agents, for grouped display and dispatcher fallbacks. */\nexport const AGENTS_BY_PHASE: Record<AgentPhase, AgentDefinition[]> = {\n discovery: DISCOVERY_AGENTS,\n planning: PLANNING_AGENTS,\n build: BUILD_AGENTS,\n verify: VERIFY_AGENTS,\n review: REVIEW_AGENTS,\n domain: DOMAIN_AGENTS,\n knowledge: KNOWLEDGE_AGENTS,\n delivery: DELIVERY_AGENTS,\n meta: META_AGENTS,\n};\n\n/**\n * Role \u2192 definition. Built once at module load. Throws on a duplicate role so\n * a copy-paste collision fails loudly at startup instead of silently shadowing.\n */\nexport const AGENT_CATALOG: Record<string, AgentDefinition> = (() => {\n const map: Record<string, AgentDefinition> = {};\n for (const def of ALL_AGENT_DEFINITIONS) {\n const role = def.config.role;\n if (!role) {\n throw new Error(`Agent \"${def.config.name}\" is missing a role`);\n }\n if (map[role]) {\n throw new Error(`Duplicate agent role in catalog: \"${role}\"`);\n }\n map[role] = def;\n }\n return map;\n})();\n\n/** Role lookup helper. Returns undefined for unknown roles. */\nexport function getAgentDefinition(role: string): AgentDefinition | undefined {\n return AGENT_CATALOG[role];\n}\n", "/**\n * FallbackProfileManager \u2014 centralized, decoupled fallback profile resolution.\n *\n * Every consumer (fallback-model, council orchestrator, one-shot LLM, plugins)\n * resolves its fallback chain through this single manager instead of parsing\n * config.fallbackProfiles independently. This guarantees consistent resolution,\n * provider-health filtering, and a single reload point on config changes.\n *\n * Design:\n * - Stable service identity: `reload()` atomically replaces the manager's\n * immutable config/profile snapshot so injected consumers stay live.\n * - Immutable outputs: every resolved chain is frozen.\n * - Provider-aware: each profile entry is checked against live provider config\n * (has API key?) before inclusion.\n * - Zero coupling: consumers only see `readonly FallbackChainEntry[]` \u2014\n * no awareness of profile names, config shape, or provider internals.\n */\n\nimport type { ProviderModelStatusTracker } from '../coordination/provider-status-tracker.js';\nimport type { Config, ProviderConfig } from '../types/config.js';\nimport { parseModelRef } from './fallback-model.js';\nimport { evaluateModelCalendar } from './model-availability-calendar.js';\n\n// \u2500\u2500 Public types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** One resolved entry in a fallback chain. */\nexport interface FallbackChainEntry {\n /** Resolved provider id. */\n readonly providerId: string;\n /** Resolved model id. */\n readonly model: string;\n /** Whether this entry uses a different provider than the primary. */\n readonly providerSwitched: boolean;\n}\n\n/** Immutable fallback chain returned by the manager. */\nexport type FallbackChain = readonly FallbackChainEntry[];\n\n/**\n * Configuration-level provider health used while resolving fallback chains.\n *\n * This deliberately answers whether the runtime has enough configuration to\n * construct the provider; it does not perform a network probe. Keyless\n * self-hosted endpoints are usable when they declare a `baseUrl`.\n */\nexport interface ProviderHealth {\n readonly providerId: string;\n readonly hasKey: boolean;\n readonly hasEndpoint: boolean;\n readonly hasModels: boolean;\n readonly usable: boolean;\n}\n\n/** @deprecated Use {@link ProviderHealth}. */\nexport type ProviderAvailability = ProviderHealth;\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction hasText(value: unknown): value is string {\n return typeof value === 'string' && value.trim().length > 0;\n}\n\nfunction providerHasKey(entry: ProviderConfig | undefined): boolean {\n if (!entry) return false;\n if (hasText(entry.apiKey)) return true;\n if (Array.isArray(entry.apiKeys) && entry.apiKeys.some((k) => hasText(k?.apiKey))) return true;\n if (Array.isArray(entry.envVars) && entry.envVars.some((v) => hasText(process.env[v])))\n return true;\n return false;\n}\n\nfunction visibleProviderModels(\n config: Config,\n providerId: string,\n providerModels: string[],\n): string[] {\n const entry = config.providers?.[providerId];\n return entry?.models !== undefined ? [...entry.models] : providerModels;\n}\n\nfunction buildProfiles(config: Config): ReadonlyMap<string, readonly string[]> {\n const entries = new Map<string, readonly string[]>();\n for (const [name, chain] of Object.entries(config.fallbackProfiles ?? {})) {\n if (Array.isArray(chain) && chain.length > 0) {\n entries.set(name, Object.freeze([...chain]));\n }\n }\n return entries;\n}\n\n// \u2500\u2500 Manager \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class FallbackProfileManager {\n /** Immutable snapshot of config.fallbackProfiles for the active config. */\n private profiles: ReadonlyMap<string, readonly string[]>;\n /** Active frozen config snapshot for provider lookups. */\n private config: Config;\n /** Optional shared runtime status tracker. */\n private statusTracker: ProviderModelStatusTracker | undefined;\n\n constructor(config: Config, opts?: { statusTracker?: ProviderModelStatusTracker | undefined }) {\n this.config = config;\n this.profiles = buildProfiles(config);\n this.statusTracker = opts?.statusTracker;\n }\n\n /**\n * Bind (or replace) the shared runtime status tracker.\n * Called by the boot path after the tracker is created.\n */\n setStatusTracker(tracker: ProviderModelStatusTracker | undefined): void {\n this.statusTracker = tracker;\n }\n\n // \u2500\u2500 Profile existence \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n hasProfile(name: string): boolean {\n return this.profiles.has(name);\n }\n\n listProfiles(): readonly string[] {\n return Object.freeze([...this.profiles.keys()]);\n }\n\n // \u2500\u2500 Resolution \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Resolve a named fallback profile to a validated, provider-filtered chain.\n *\n * Returns an empty chain when:\n * - The profile doesn't exist.\n * - Every entry's provider is missing, has no key, or has no matching model.\n *\n * @param name - Profile name from config.fallbackProfiles.\n * @param defaultProvider - Used when an entry has no explicit provider.\n * @param exclude - Optional { providerId, model } to skip (avoid self-fallback).\n */\n resolve(\n name: string,\n opts: {\n defaultProvider?: string | undefined;\n exclude?: { providerId: string; model: string } | undefined;\n } = {},\n ): FallbackChain {\n const defaultProvider = opts.defaultProvider ?? this.config.provider;\n const chain = this.profiles.get(name);\n if (!chain) return FREEZER_EMPTY;\n\n const excludeKey = opts.exclude\n ? `${opts.exclude.providerId}/${opts.exclude.model}`\n : undefined;\n\n const resolved: FallbackChainEntry[] = [];\n const seen = new Set<string>();\n\n for (const ref of chain) {\n const parsed = parseModelRef(ref);\n if (!parsed.model) continue;\n\n const providerId = parsed.provider ?? defaultProvider;\n const key = `${providerId}/${parsed.model}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n // Skip self-reference\n if (excludeKey && key === excludeKey) continue;\n\n const health = this.checkProvider(providerId);\n if (!health.usable) continue;\n\n // Skip entries that are blocked by the runtime status tracker\n if (this.statusTracker && !this.statusTracker.isAvailable(providerId, parsed.model)) continue;\n if (\n !evaluateModelCalendar(this.config.modelAvailabilitySchedule, providerId, parsed.model)\n .allowed\n )\n continue;\n\n // Skip entries whose provider has no matching model in its allow-list\n // (provider may restrict which models are available).\n const allowedModels = this.config.providers?.[providerId]?.models;\n if (allowedModels && !allowedModels.includes(parsed.model)) continue;\n\n resolved.push({\n providerId,\n model: parsed.model,\n providerSwitched: providerId !== (opts.exclude?.providerId ?? this.config.provider),\n });\n }\n\n return Object.freeze(resolved);\n }\n\n /**\n * Resolve the effective fallback chain for a session: explicit fallbackModels\n * first, then named profile, then smart default (unless disabled).\n *\n * Mirrors the previous `effectiveFallbackChain()` logic but centralized.\n */\n resolveEffective(\n opts: {\n fallbackModels?: readonly string[] | undefined;\n fallbackProfile?: string | undefined;\n fallbackAuto?: boolean | undefined;\n exclude?: { providerId: string; model: string } | undefined;\n } = {},\n ): FallbackChain {\n // 1. Explicit fallbackModels (already resolved refs)\n // Only return if non-empty; empty chain falls through to next source.\n if (opts.fallbackModels && opts.fallbackModels.length > 0) {\n const resolved = this.resolveRefs(opts.fallbackModels, opts.exclude);\n if (resolved.length > 0) return resolved;\n }\n\n // 2. Named profile \u2014 only return if non-empty\n if (opts.fallbackProfile) {\n const resolved = this.resolve(opts.fallbackProfile, { exclude: opts.exclude });\n if (resolved.length > 0) return resolved;\n }\n\n // 3. Smart default\n if (opts.fallbackAuto !== false) {\n return this.smartDefault(opts.exclude);\n }\n\n return FREEZER_EMPTY;\n }\n\n // \u2500\u2500 Provider availability (read-only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n checkProvider(providerId: string): ProviderHealth {\n const entry = this.config.providers?.[providerId];\n const isPrimary = providerId === this.config.provider;\n const hasKey = providerHasKey(entry) || (isPrimary && hasText(this.config.apiKey));\n const hasEndpoint = hasText(entry?.baseUrl) || (isPrimary && hasText(this.config.baseUrl));\n const hasModels =\n (Array.isArray(entry?.models) && entry.models.length > 0) ||\n (isPrimary && hasText(this.config.model));\n return Object.freeze({\n providerId,\n hasKey,\n hasEndpoint,\n hasModels,\n usable: hasKey || hasEndpoint,\n });\n }\n\n // \u2500\u2500 Rebuild on config change \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Atomically replace the active immutable snapshot while preserving this\n * service identity for every injected consumer.\n */\n reload(newConfig: Config): void {\n this.config = newConfig;\n this.profiles = buildProfiles(newConfig);\n }\n\n // \u2500\u2500 Internal helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Resolve an array of model ref strings (from explicit fallbackModels config).\n * Public so consumers like one-shot-llm can use it directly.\n */\n resolveRefs(\n refs: readonly string[],\n exclude?: { providerId: string; model: string },\n ): FallbackChain {\n const excludeKey = exclude ? `${exclude.providerId}/${exclude.model}` : undefined;\n const resolved: FallbackChainEntry[] = [];\n const seen = new Set<string>();\n\n for (const ref of refs) {\n const parsed = parseModelRef(ref);\n if (!parsed.model) continue;\n\n const providerId = parsed.provider ?? this.config.provider;\n const key = `${providerId}/${parsed.model}`;\n if (seen.has(key)) continue;\n seen.add(key);\n if (excludeKey && key === excludeKey) continue;\n\n // Skip entries blocked by the runtime status tracker\n if (this.statusTracker && !this.statusTracker.isAvailable(providerId, parsed.model)) continue;\n if (\n !evaluateModelCalendar(this.config.modelAvailabilitySchedule, providerId, parsed.model)\n .allowed\n )\n continue;\n\n resolved.push({\n providerId,\n model: parsed.model,\n providerSwitched: providerId !== (exclude?.providerId ?? this.config.provider),\n });\n }\n\n return Object.freeze(resolved);\n }\n\n /**\n * Derive a smart default chain from configured providers when nothing\n * explicit is set. Same-provider alternatives first, then cross-provider.\n * Limited to 4 entries to avoid burning through models on a transient blip.\n */\n private smartDefault(exclude?: { providerId: string; model: string }): FallbackChain {\n const leaderProvider = this.config.provider;\n const leaderModel = this.config.model;\n const providers = this.config.providers ?? {};\n const favoriteSet = new Set(\n (this.config.favoriteModels ?? []).map((ref) => {\n const p = parseModelRef(ref);\n return `${p.provider ?? leaderProvider}/${p.model}`;\n }),\n );\n const hasFavorites = favoriteSet.size > 0;\n const favoritesOnly = this.config.favoriteModelsOnly === true;\n const seen = new Set<string>();\n const favorites: string[] = [];\n const sameProvider: string[] = [];\n const crossProvider: string[] = [];\n\n const excludeKey = exclude ? `${exclude.providerId}/${exclude.model}` : undefined;\n\n const ids = Object.keys(providers).sort((a, b) =>\n a === leaderProvider ? -1 : b === leaderProvider ? 1 : a.localeCompare(b),\n );\n\n for (const id of ids) {\n const entry = providers[id];\n if (!this.checkProvider(id).usable) continue;\n // Skip the entire provider if it's blocked at the provider level\n // (all its models would be blocked too, but we check per-model below)\n const models = visibleProviderModels(this.config, id, entry?.models ?? []);\n for (const model of models) {\n if (id === leaderProvider && model === leaderModel) continue;\n const ref = `${id}/${model}`;\n if (seen.has(ref)) continue;\n seen.add(ref);\n if (excludeKey && ref === excludeKey) continue;\n // Skip models blocked by the runtime status tracker\n if (this.statusTracker && !this.statusTracker.isAvailable(id, model)) continue;\n if (!evaluateModelCalendar(this.config.modelAvailabilitySchedule, id, model).allowed)\n continue;\n if (favoriteSet.has(ref)) {\n favorites.push(ref);\n continue;\n }\n if (favoritesOnly && hasFavorites) continue;\n (id === leaderProvider ? sameProvider : crossProvider).push(ref);\n }\n }\n\n const MAX = 4;\n const all = [...favorites, ...sameProvider, ...crossProvider].slice(0, MAX);\n return Object.freeze(\n all.map((ref) => {\n const p = parseModelRef(ref);\n return {\n providerId: p.provider ?? leaderProvider,\n model: p.model,\n providerSwitched:\n (p.provider ?? leaderProvider) !== (exclude?.providerId ?? leaderProvider),\n } satisfies FallbackChainEntry;\n }),\n );\n }\n}\n\nconst FREEZER_EMPTY: FallbackChain = Object.freeze([]);\n", "/**\n * Cross-provider fallback model extension.\n *\n * Lives in core so EVERY agent surface can reuse it: the CLI leader, the CLI\n * director/host subagent factory, and the runtime light subagent factory (used\n * by standalone SDD runs). It wraps the provider runner and, when the active\n * model 429s / overloads / stream-hangs, rotates through a fallback chain. The\n * chain is recomputed from live config every turn, so changes take effect\n * without a restart; an empty chain makes the wrapper a no-op.\n *\n * Moved here from `@wrongstack/cli` (it only ever depended on core types) so the\n * runtime light factory can wire fallbacks for SDD worker subagents.\n */\n\nimport type { ProviderModelStatusTracker } from '../coordination/provider-status-tracker.js';\nimport type { AgentExtension } from '../extension/extension-points.js';\nimport type { EventBus } from '../kernel/events.js';\nimport { isTextBlock, isToolUseBlock } from '../types/blocks.js';\nimport type { Config } from '../types/config.js';\nimport type { Logger } from '../types/logger.js';\nimport {\n isFallbackWorthy,\n type Provider,\n ProviderError,\n type Response,\n} from '../types/provider.js';\nimport type { FallbackChain, FallbackChainEntry } from './fallback-profile-manager.js';\nimport { FallbackProfileManager } from './fallback-profile-manager.js';\nimport { evaluateModelCalendar, logicalCalendarTarget } from './model-availability-calendar.js';\n\nexport interface FallbackModelDeps {\n /** Returns the live config (re-read each turn so `/model` switches are honored). */\n getConfig: () => Config;\n /** Shared live manager from the runtime container. */\n fallbackProfileManager?: FallbackProfileManager | undefined;\n /** Live named profile selected for this worker (for example by `/setmodel`). */\n getFallbackProfile?: (() => string | undefined) | undefined;\n /** Live task/role-specific chain. Explicit task fallbacks may return a stable list. */\n getFallbackModels?: (() => readonly string[] | undefined) | undefined;\n /**\n * Builds a credential-resolved Provider for a provider id (alias-resolved),\n * WITHOUT persisting anything to config/configStore. Supplied by the boot\n * path, which shares this with the `/model` switch logic. May be async \u2014 the\n * subagent host resolves a provider's real context window asynchronously.\n */\n buildProvider: (providerId: string, modelId?: string | undefined) => Provider | Promise<Provider>;\n /**\n * Called after the active model changes (a fallback hop or the primary\n * restore) so the host can refresh the auto-compaction / context-window\n * denominator \u2014 important when a fallback crosses to a smaller-window model.\n */\n onModelSwitch?: (providerId: string, modelId: string) => void | Promise<void>;\n events: EventBus;\n /** Optional \u2014 warnings about un-buildable fallback providers. */\n logger?: Logger | undefined;\n /**\n * Base cooldown after the configured primary fails with a fallback-worthy\n * error. While active, `beforeRun` leaves the context on the working fallback\n * instead of retrying the primary at the start of every turn. Default: 60s.\n * Set 0 to preserve the legacy \"probe primary every turn\" behavior.\n */\n primaryCooldownMs?: number | undefined;\n /**\n * Maximum exponential cooldown for repeated failed primary probes. Default:\n * 10 minutes. Ignored when `primaryCooldownMs` is 0.\n */\n primaryCooldownMaxMs?: number | undefined;\n /** Test hook for deterministic cooldown assertions. */\n now?: (() => number) | undefined;\n /**\n * Shared provider/model status tracker. When set, the extension records\n * failures and successes in the tracker, and skips blocked entries in\n * the fallback chain.\n */\n statusTracker?: ProviderModelStatusTracker | undefined;\n}\n\ninterface ModelRef {\n provider?: string | undefined;\n model: string;\n}\n\n/** Parse a fallback entry: `model`, `provider/model`, or `provider model`. */\nexport function parseModelRef(ref: string): ModelRef {\n const trimmed = ref.trim();\n const slash = trimmed.indexOf('/');\n if (slash !== -1) {\n // An empty provider (leading slash, e.g. \"/gpt\") means \"use the primary\n // provider\" \u2014 collapse to undefined so the `?? cfg.provider` fallback fires.\n return {\n provider: trimmed.slice(0, slash) || undefined,\n model: trimmed.slice(slash + 1).trim(),\n };\n }\n const parts = trimmed.split(/\\s+/);\n if (parts.length >= 2) {\n return { provider: parts[0], model: parts.slice(1).join(' ') };\n }\n return { model: trimmed };\n}\n\nexport function formatModelRef(ref: ModelRef, defaultProvider?: string | undefined): string {\n const provider = ref.provider ?? defaultProvider;\n return provider ? `${provider}/${ref.model}` : ref.model;\n}\n\nexport function normalizeModelRef(ref: string, defaultProvider?: string | undefined): string {\n const parsed = parseModelRef(ref);\n return formatModelRef(parsed, defaultProvider);\n}\n\nexport function fallbackProfileChain(config: Config, profileName: string | undefined): string[] {\n if (!profileName) return [];\n const mgr = new FallbackProfileManager(config);\n return mgr.resolve(profileName).map((e) => `${e.providerId}/${e.model}`);\n}\n\n/**\n * Check if an error should trigger a fallback. Returns the status for\n * logging, or null if the error doesn't warrant a fallback attempt.\n *\n * Branches on the canonical `ProviderError.kind`: capacity/availability\n * failures (rate limit, overload, server error, stream hang, timeout,\n * network) are worth trying on another provider; request-shaped failures\n * (auth, invalid request, context overflow, content filter) would fail\n * identically anywhere \u2014 or need a different remedy (compaction, key fix) \u2014\n * so they surface instead.\n */\nfunction shouldFallback(err: unknown): number | null {\n if (!(err instanceof ProviderError)) return null;\n return isFallbackWorthy(err.kind) ? err.status : null;\n}\n\nfunction isUsableModelResponse(response: Response): boolean | undefined {\n if (!response?.content) return undefined;\n return response.content.some(\n (block) => isToolUseBlock(block) || (isTextBlock(block) && block.text.trim().length > 0),\n );\n}\n\nfunction ensureUsableModelResponse(\n response: Response,\n providerId: string,\n model: string,\n): Response {\n const usable = isUsableModelResponse(response);\n // undefined content means the caller didn't provide a content field (e.g. test mocks) \u2014 let it through\n if (usable !== false) return response;\n throw new ProviderError(\n `Empty response from ${providerId}/${model}; trying the next configured model`,\n 503,\n true,\n providerId,\n { kind: 'overloaded' },\n );\n}\n\nexport function smartDefaultFallbackChain(config: Config): string[] {\n const mgr = new FallbackProfileManager(config);\n return mgr.resolveEffective({ fallbackAuto: true }).map((e) => `${e.providerId}/${e.model}`);\n}\n\n/**\n * The effective fallback chain for a turn: the explicit `fallbackModels` list\n * when non-empty, otherwise the smart default (unless `fallbackAuto` is off).\n */\nexport function effectiveFallbackChain(config: Config): string[] {\n const mgr = new FallbackProfileManager(config);\n return mgr\n .resolveEffective({\n fallbackModels: config.fallbackModels,\n fallbackAuto: config.fallbackAuto,\n })\n .map((e) => `${e.providerId}/${e.model}`);\n}\n\nconst DEFAULT_PRIMARY_COOLDOWN_MS = 60_000;\nconst DEFAULT_PRIMARY_COOLDOWN_MAX_MS = 10 * 60_000;\n\nfunction sameTarget(\n a: { providerId: string; model: string } | undefined,\n b: { providerId: string; model: string },\n): boolean {\n return !!a && a.providerId === b.providerId && a.model === b.model;\n}\n\nfunction fallbackCandidates(\n config: Config,\n current: { providerId: string; model: string },\n opts: {\n fallbackModels?: readonly string[] | undefined;\n fallbackProfile?: string | undefined;\n sharedManager?: FallbackProfileManager | undefined;\n } = {},\n): FallbackChain {\n const mgr = opts.sharedManager ?? new FallbackProfileManager(config);\n const configuredPrimary = primaryTarget(config);\n const selectedChain = mgr.resolveEffective({\n fallbackModels: opts.fallbackModels ?? config.fallbackModels,\n fallbackProfile: opts.fallbackProfile,\n // A role/profile override is an ordered preference, not a closed world.\n // If every selected entry fails, keep deriving a route back to the known\n // session/default model and other configured providers.\n fallbackAuto: true,\n exclude: current,\n });\n const candidates: FallbackChainEntry[] = [];\n\n if (opts.fallbackProfile !== 'default') {\n candidates.push(...mgr.resolve('default', { exclude: current }));\n }\n\n // Always try the session's configured primary first when we're not already on it.\n if (!sameTarget(configuredPrimary, current)) {\n candidates.push({\n providerId: configuredPrimary.providerId,\n model: configuredPrimary.model,\n providerSwitched: configuredPrimary.providerId !== current.providerId,\n });\n }\n\n // Then try the role-selected or explicit chain.\n candidates.push(...selectedChain);\n\n // Finally try every other configured provider as a last resort.\n const smartDefaults = mgr.resolveEffective({ fallbackAuto: true, exclude: current });\n candidates.push(...smartDefaults);\n\n const seen = new Set<string>();\n return Object.freeze(\n candidates.filter((entry) => {\n const key = `${entry.providerId}/${entry.model}`;\n if (key === `${current.providerId}/${current.model}` || seen.has(key)) return false;\n seen.add(key);\n return true;\n }),\n );\n}\n\nconst primaryTarget = (cfg: Config) => ({ providerId: cfg.provider, model: cfg.model });\n\nfunction maxContextOf(provider: Provider): number {\n const max = provider.capabilities.maxContext;\n return typeof max === 'number' && Number.isFinite(max) ? max : 0;\n}\n\nfunction contextWindowWarning(\n currentProvider: Provider,\n nextProvider: Provider,\n currentTokens: unknown,\n):\n | { fromMaxContext: number; toMaxContext: number; currentTokens?: number | undefined }\n | undefined {\n const fromMaxContext = maxContextOf(currentProvider);\n const toMaxContext = maxContextOf(nextProvider);\n if (fromMaxContext <= 0 || toMaxContext <= 0 || toMaxContext >= fromMaxContext) return undefined;\n return {\n fromMaxContext,\n toMaxContext,\n ...(typeof currentTokens === 'number' && currentTokens > 0 ? { currentTokens } : {}),\n };\n}\n\n/**\n * Build the cross-provider fallback extension. Always returns an extension \u2014\n * the effective chain (`effectiveFallbackChain`) is recomputed every turn from\n * the live config, so a chain that is empty at boot but populated later (via\n * `/fallback add` or the smart default kicking in once a key is added) takes\n * effect WITHOUT a restart. An empty chain makes the wrapper a no-op (it just\n * rethrows the original error).\n *\n * Mechanism (see plan): wraps the provider runner. The inner runner already\n * applies the per-model retry policy (backoff, up to 5 tries for 429), so the\n * fallback only engages AFTER the active model's own retries are exhausted.\n * Because the wrapper resolves within a single provider call, it does not\n * consume the agent loop's `recoveryRetries` budget \u2014 chains longer than two\n * entries work. `beforeRun` keeps the last working fallback while the primary\n * is cooling down, then restores the configured primary for a half-open probe.\n */\nexport function createFallbackModelExtension(deps: FallbackModelDeps): AgentExtension {\n // True when a prior turn left the live context on a fallback model.\n let dirty = false;\n let primaryFailureStreak = 0;\n let blockedPrimary: { providerId: string; model: string } | undefined;\n let primaryBlockedUntil = 0;\n\n const now = () => deps.now?.() ?? Date.now();\n const cooldownBase = () => Math.max(0, deps.primaryCooldownMs ?? DEFAULT_PRIMARY_COOLDOWN_MS);\n const cooldownMax = () =>\n Math.max(cooldownBase(), deps.primaryCooldownMaxMs ?? DEFAULT_PRIMARY_COOLDOWN_MAX_MS);\n const primaryInCooldown = (cfg: Config) =>\n sameTarget(blockedPrimary, primaryTarget(cfg)) && now() < primaryBlockedUntil;\n\n const markPrimaryFailure = (cfg: Config) => {\n const primary = primaryTarget(cfg);\n primaryFailureStreak = sameTarget(blockedPrimary, primary) ? primaryFailureStreak + 1 : 1;\n blockedPrimary = primary;\n const base = cooldownBase();\n if (base <= 0) {\n primaryBlockedUntil = 0;\n return;\n }\n const multiplier = 2 ** Math.max(0, primaryFailureStreak - 1);\n primaryBlockedUntil = now() + Math.min(cooldownMax(), base * multiplier);\n };\n\n const resetPrimaryLadder = (cfg: Config) => {\n if (!sameTarget(blockedPrimary, primaryTarget(cfg))) return;\n primaryFailureStreak = 0;\n blockedPrimary = undefined;\n primaryBlockedUntil = 0;\n };\n\n return {\n name: 'fallback-model',\n\n beforeRun: async (ctx) => {\n if (!dirty) return;\n const cfg = deps.getConfig();\n if (primaryInCooldown(cfg)) return;\n if (\n !evaluateModelCalendar(cfg.modelAvailabilitySchedule, cfg.provider, cfg.model).allowed ||\n (deps.statusTracker && !deps.statusTracker.isAvailable(cfg.provider, cfg.model))\n )\n return;\n try {\n ctx.provider = await deps.buildProvider(cfg.provider, cfg.model);\n ctx.model = cfg.model;\n await deps.onModelSwitch?.(cfg.provider, cfg.model);\n // The next provider call is the half-open primary probe. If it\n // succeeds, the wrapper resets the ladder; if it fails, the catch path\n // marks a longer cooldown and rotates back through the chain.\n primaryBlockedUntil = 0;\n } catch (err) {\n deps.logger?.warn(\n `fallback-model: could not restore primary \"${cfg.provider}/${cfg.model}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n markPrimaryFailure(cfg);\n return;\n }\n dirty = false;\n },\n\n wrapProviderRunner: async (ctx, request, inner) => {\n // \u2500\u2500 Before calling, check if the current provider/model is blocked \u2500\u2500\n const tracker = deps.statusTracker;\n const calendar = evaluateModelCalendar(\n deps.getConfig().modelAvailabilitySchedule,\n ctx.provider.id,\n ctx.model,\n );\n const trackerBlocked = tracker ? !tracker.isAvailable(ctx.provider.id, ctx.model) : false;\n if (trackerBlocked || !calendar.allowed) {\n deps.logger?.warn(\n `provider-status: \"${ctx.provider.id}/${ctx.model}\" is blocked \u2014 trying fallback chain`,\n );\n // Emit active_blocked so the UI can surface a prominent warning\n const status = tracker?.getStatus(ctx.provider.id, ctx.model);\n const logical =\n tracker?.logicalIdentity(ctx.provider.id, ctx.model) ??\n logicalCalendarTarget(ctx.provider.id, ctx.model);\n deps.events.emit('provider.active_blocked', {\n providerId: logical.providerId,\n model: logical.model,\n state: 'blocked',\n fallbackProviderId: '',\n fallbackModel: '',\n lastError:\n calendar.rule?.label ??\n (calendar.rule ? 'Blocked by model availability calendar' : undefined) ??\n status?.lastErrorMessage ??\n 'Rate limit or repeated failures',\n sessionId: ctx.session?.id,\n timestamp: Date.now(),\n });\n // Skipping the blocked primary \u2014 simulate a fallback-worthy error\n const skipErr = new ProviderError(\n `Skipping unavailable \"${ctx.provider.id}/${ctx.model}\" \u2014 try fallback`,\n 429,\n true,\n ctx.provider.id,\n { kind: 'rate_limit' },\n );\n return runFallbackChain(ctx, request, inner, skipErr, true);\n }\n\n try {\n const response = ensureUsableModelResponse(\n await inner(ctx, request),\n ctx.provider.id,\n ctx.model,\n );\n // Record success in the tracker\n tracker?.recordSuccess(ctx.provider.id, ctx.model, {\n sessionId: ctx.session?.id,\n agentId: ctx.agentId,\n });\n const cfg = deps.getConfig();\n if (ctx.provider.id === cfg.provider && ctx.model === cfg.model) {\n resetPrimaryLadder(cfg);\n }\n return response;\n } catch (firstErr) {\n return runFallbackChain(ctx, request, inner, firstErr);\n }\n\n // \u2500\u2500 Shared fallback-chain runner with tracker integration \u2500\u2500\n async function runFallbackChain(\n ctx_: typeof ctx,\n request_: typeof request,\n inner_: typeof inner,\n firstErr_: unknown,\n alreadyTracked = false,\n ): Promise<Response> {\n let lastErr: unknown = firstErr_;\n const cfg = deps.getConfig();\n const current = { providerId: ctx_.provider.id, model: ctx_.model };\n\n // Record the failure in the tracker (real ProviderError, not our synthetic skip)\n if (!alreadyTracked && firstErr_ instanceof ProviderError && tracker) {\n tracker.recordFailure(\n ctx_.provider.id,\n ctx_.model,\n firstErr_.kind,\n firstErr_.status,\n firstErr_.describe(),\n {\n sessionId: ctx_.session?.id,\n agentId: ctx_.agentId,\n retryAfterMs: firstErr_.body?.retryAfterMs,\n },\n );\n }\n\n const chain = fallbackCandidates(cfg, current, {\n fallbackModels: deps.getFallbackModels?.(),\n fallbackProfile: deps.getFallbackProfile?.(),\n sharedManager: deps.fallbackProfileManager,\n });\n\n // Filter blocked entries from the chain via the tracker\n const usableChain = tracker\n ? chain.filter((e) => tracker.isAvailable(e.providerId, e.model))\n : chain;\n\n if (\n !alreadyTracked &&\n shouldFallback(firstErr_) !== null &&\n ctx_.provider.id === cfg.provider &&\n ctx_.model === cfg.model\n ) {\n markPrimaryFailure(cfg);\n }\n\n for (const entry of usableChain) {\n if (\n !evaluateModelCalendar(cfg.modelAvailabilitySchedule, entry.providerId, entry.model)\n .allowed\n )\n continue;\n const status = shouldFallback(lastErr);\n if (status === null) break; // not a fallback-worthy error\n\n const targetProviderId = entry.providerId;\n const targetModel = entry.model;\n if (targetProviderId === ctx_.provider.id && targetModel === ctx_.model) continue;\n if (\n primaryInCooldown(cfg) &&\n targetProviderId === cfg.provider &&\n targetModel === cfg.model\n ) {\n continue;\n }\n\n const from = { providerId: ctx_.provider.id, model: ctx_.model };\n const logicalFrom = tracker?.logicalIdentity(from.providerId, from.model) ?? from;\n\n let nextProvider: Provider;\n try {\n nextProvider = await deps.buildProvider(targetProviderId, targetModel);\n } catch (err) {\n deps.logger?.warn(\n `fallback-model: skipping \"${targetProviderId}/${targetModel}\" \u2014 cannot build provider \"${targetProviderId}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n continue;\n }\n\n const providerSwitched = nextProvider.id !== from.providerId;\n const warning = contextWindowWarning(ctx_.provider, nextProvider, ctx_.lastRequestTokens);\n ctx_.provider = nextProvider;\n ctx_.model = targetModel;\n request_.model = targetModel;\n dirty = true;\n await deps.onModelSwitch?.(targetProviderId, targetModel);\n\n deps.events.emit('provider.fallback', {\n sessionId: ctx_.session?.id,\n from: logicalFrom,\n to: tracker?.logicalIdentity(nextProvider.id, targetModel) ?? {\n providerId: nextProvider.id,\n model: targetModel,\n },\n status,\n providerSwitched,\n ...(warning ? { contextWindowWarning: warning } : {}),\n });\n\n try {\n const response = ensureUsableModelResponse(\n await inner_(ctx_, request_),\n ctx_.provider.id,\n ctx_.model,\n );\n tracker?.recordSuccess(nextProvider.id, targetModel, {\n sessionId: ctx_.session?.id,\n agentId: ctx_.agentId,\n });\n return response;\n } catch (err) {\n // Record fallback failure too\n if (err instanceof ProviderError && tracker) {\n tracker.recordFailure(\n nextProvider.id,\n targetModel,\n err.kind,\n err.status,\n err.describe(),\n {\n sessionId: ctx_.session?.id,\n agentId: ctx_.agentId,\n retryAfterMs: err.body?.retryAfterMs,\n },\n );\n }\n lastErr = err;\n }\n }\n\n throw lastErr;\n }\n },\n };\n}\n", "/**\n * Per-task model matrix resolution.\n *\n * The matrix (Config.modelMatrix) maps a catalog **role**, a **phase** name, or\n * the `*` default to a {@link ModelMatrixEntry} (model + optional provider).\n * At subagent spawn time we resolve the most specific match so different task\n * types can run on different models \u2014 e.g. `security-scanner` on one model,\n * `documentation` on another \u2014 while the leader keeps its own model.\n *\n * Resolution precedence (most \u2192 least specific):\n * 1. exact role (matrix[\"security-scanner\"])\n * 2. the role's phase (matrix[\"review\"])\n * 3. the `*` default (matrix[\"*\"])\n * 4. undefined (caller falls back to the leader model)\n *\n * Set via the `/setmodel` slash command; this module is the single source of\n * truth both that command and the spawn path use to validate + resolve keys.\n */\n\nimport { fallbackProfileChain, parseModelRef } from '../core/fallback-model.js';\nimport type { Config, ModelMatrixEntry, ProviderConfig } from '../types/config.js';\nimport { AGENT_CATALOG, AGENTS_BY_PHASE } from './agents/index.js';\n\n/** All valid phase keys, in catalog order. */\nexport const MATRIX_PHASE_KEYS: readonly string[] = Object.keys(AGENTS_BY_PHASE);\n\n/** Role \u2192 phase lookup, built once from the catalog. */\nconst ROLE_TO_PHASE: Record<string, string> = (() => {\n const map: Record<string, string> = {};\n for (const [phase, defs] of Object.entries(AGENTS_BY_PHASE)) {\n for (const def of defs) {\n const role = def.config.role;\n if (role) map[role] = phase;\n }\n }\n return map;\n})();\n\n/** The phase a catalog role belongs to, or undefined for unknown roles. */\nexport function phaseForRole(role: string | undefined): string | undefined {\n return role ? ROLE_TO_PHASE[role] : undefined;\n}\n\nexport type ModelMatrixResolutionSource = 'role' | 'phase' | 'default';\n\nexport interface ModelMatrixResolution {\n entry: ModelMatrixEntry;\n source: ModelMatrixResolutionSource;\n key: string;\n}\n\n/**\n * Resolve the matrix entry plus the key tier it came from. Use this when the\n * caller needs to distinguish an explicit role/phase pin from the global `*`\n * default.\n */\nexport function resolveModelMatrixResolution(\n matrix: Record<string, ModelMatrixEntry> | undefined,\n role: string | undefined,\n): ModelMatrixResolution | undefined {\n if (!matrix) return undefined;\n if (role && matrix[role]) return { entry: matrix[role], source: 'role', key: role };\n const phase = phaseForRole(role);\n if (phase && matrix[phase]) return { entry: matrix[phase], source: 'phase', key: phase };\n if (matrix['*']) return { entry: matrix['*'], source: 'default', key: '*' };\n return undefined;\n}\n\n/**\n * Resolve the matrix entry for a subagent role. Returns the most specific\n * match (role \u2192 phase \u2192 `*`), or undefined when nothing matches.\n */\nexport function resolveModelMatrix(\n matrix: Record<string, ModelMatrixEntry> | undefined,\n role: string | undefined,\n): ModelMatrixEntry | undefined {\n return resolveModelMatrixResolution(matrix, role)?.entry;\n}\n\nexport interface ResolvedModelTarget {\n provider?: string | undefined;\n model?: string | undefined;\n modelRuntime?: Config['modelRuntime'] | undefined;\n fallbackModels?: string[] | undefined;\n fallbackProfile?: string | undefined;\n}\n\nexport interface ResolvedSubagentModelTarget extends ResolvedModelTarget {\n /** Where the concrete provider/model came from. */\n source: 'matrix' | 'diversity' | 'none';\n /** Matrix tier used before any reviewer diversity adjustment. */\n matrixSource?: ModelMatrixResolutionSource | undefined;\n /** True when a reviewer model was shifted away from the implementation model. */\n diversified?: boolean | undefined;\n}\n\n/**\n * Expand a matrix entry into a concrete primary model plus optional fallback\n * chain. A profile-only matrix entry treats the first profile model as primary\n * and the remaining profile entries as that subagent's fallback chain.\n */\nexport function resolveModelTargetFromEntry(\n config: Config,\n entry: ModelMatrixEntry | undefined,\n): ResolvedModelTarget | undefined {\n if (!entry) return undefined;\n if (entry.model) {\n return {\n provider: entry.provider,\n model: entry.model,\n modelRuntime: entry.modelRuntime,\n fallbackProfile: entry.fallbackProfile,\n fallbackModels: fallbackProfileChain(config, entry.fallbackProfile),\n };\n }\n const chain = fallbackProfileChain(config, entry.fallbackProfile);\n const first = chain[0];\n if (!first) {\n return entry.modelRuntime ? { modelRuntime: entry.modelRuntime } : undefined;\n }\n const parsed = parseModelRef(first);\n return {\n provider: parsed.provider,\n model: parsed.model,\n modelRuntime: entry.modelRuntime,\n fallbackProfile: entry.fallbackProfile,\n fallbackModels: chain.slice(1),\n };\n}\n\nexport interface ModelReference {\n provider?: string | undefined;\n model?: string | undefined;\n}\n\ninterface ConcreteModelReference {\n provider: string;\n model: string;\n}\n\n/**\n * Roles whose output is meant to challenge an implementer. When these roles\n * would otherwise use the same provider/model as the implementation path,\n * WrongStack tries to pick a different available model to reduce correlated\n * model-family mistakes. Exact role/phase `/setmodel` entries still win.\n */\nexport function roleNeedsIndependentReviewModel(role: string | undefined): boolean {\n if (!role) return false;\n return role === 'reviewer' || phaseForRole(role) === 'review';\n}\n\n/**\n * Resolve a subagent's matrix target with the reviewer diversity rule applied.\n *\n * Precedence:\n * 1. Exact role or phase matrix entry.\n * 2. Global `*` matrix entry when it is already different from the\n * implementation model.\n * 3. A different configured provider/model for review roles.\n * 4. The matrix/leader fallback.\n */\nexport function resolveSubagentModelTarget(\n config: Config,\n role: string | undefined,\n opts: { implementationTarget?: ModelReference | undefined } = {},\n): ResolvedSubagentModelTarget | undefined {\n const resolution = resolveModelMatrixResolution(config.modelMatrix, role);\n const matrixTarget = resolveModelTargetFromEntry(config, resolution?.entry);\n const implementationTarget =\n opts.implementationTarget ?? resolveImplementationModelTarget(config);\n\n if (!roleNeedsIndependentReviewModel(role)) {\n if (!matrixTarget) return undefined;\n return {\n ...matrixTarget,\n source: 'matrix',\n matrixSource: resolution?.source,\n };\n }\n\n const matrixRef = materializeTarget(config, matrixTarget);\n\n if (resolution?.source === 'role' || resolution?.source === 'phase') {\n return matrixTarget\n ? { ...matrixTarget, source: 'matrix', matrixSource: resolution.source }\n : undefined;\n }\n\n if (matrixRef && !sameModelReference(matrixRef, implementationTarget)) {\n return {\n ...(matrixTarget ?? {}),\n source: 'matrix',\n matrixSource: resolution?.source,\n };\n }\n\n const diverse = chooseDiverseModelTarget(config, implementationTarget);\n if (diverse) {\n return {\n provider: diverse.provider,\n model: diverse.model,\n modelRuntime: matrixTarget?.modelRuntime,\n fallbackModels: matrixTarget?.fallbackModels,\n fallbackProfile: matrixTarget?.fallbackProfile,\n source: 'diversity',\n matrixSource: resolution?.source,\n diversified: true,\n };\n }\n\n if (!matrixTarget) return undefined;\n return {\n ...matrixTarget,\n source: 'matrix',\n matrixSource: resolution?.source,\n };\n}\n\n/**\n * Resolve the default implementation lane. The generic Executor is the closest\n * stable proxy for \"the implementer\" when a reviewer is spawned without a\n * concrete sibling id.\n */\nexport function resolveImplementationModelTarget(config: Config): ModelReference {\n const target = resolveModelTargetFromEntry(\n config,\n resolveModelMatrix(config.modelMatrix, 'executor'),\n );\n return (\n materializeTarget(config, target) ?? {\n provider: config.provider,\n model: config.model,\n }\n );\n}\n\nexport function sameModelReference(\n a: ModelReference | undefined,\n b: ModelReference | undefined,\n): boolean {\n if (!a?.model || !b?.model) return false;\n const providerA = a.provider ?? '';\n const providerB = b.provider ?? '';\n return providerA === providerB && a.model === b.model;\n}\n\nfunction materializeTarget(\n config: Config,\n target: ResolvedModelTarget | undefined,\n): ModelReference | undefined {\n if (!target?.model) return undefined;\n return {\n provider: target.provider ?? config.provider,\n model: target.model,\n };\n}\n\nfunction chooseDiverseModelTarget(\n config: Config,\n avoid: ModelReference,\n): ConcreteModelReference | undefined {\n const candidates = collectConfiguredModelTargets(config).filter(\n (candidate) => !sameModelReference(candidate, avoid),\n );\n candidates.sort((a, b) => modelDiversityScore(b, avoid) - modelDiversityScore(a, avoid));\n return candidates[0];\n}\n\nfunction collectConfiguredModelTargets(config: Config): ConcreteModelReference[] {\n const seen = new Set<string>();\n const out: ConcreteModelReference[] = [];\n const add = (provider: string | undefined, model: string | undefined) => {\n if (!provider || !model) return;\n const key = `${provider}\\u0000${model}`;\n if (seen.has(key)) return;\n seen.add(key);\n out.push({ provider, model });\n };\n\n add(config.provider, config.model);\n for (const [providerId, provider] of Object.entries(config.providers ?? {})) {\n if (!isProviderAvailable(providerId, provider, config.provider)) continue;\n for (const model of provider.models ?? []) add(providerId, model);\n for (const model of Object.keys(provider.customModels ?? {})) add(providerId, model);\n }\n for (const model of Object.keys(config.models ?? {})) add(config.provider, model);\n return out;\n}\n\nfunction isProviderAvailable(\n providerId: string,\n provider: ProviderConfig,\n leaderProvider: string,\n): boolean {\n if (providerId === leaderProvider) return true;\n if (typeof provider.apiKey === 'string' && provider.apiKey.length > 0) return true;\n if (Array.isArray(provider.apiKeys) && provider.apiKeys.some((key) => key?.apiKey)) return true;\n if (typeof provider.baseUrl === 'string' && provider.baseUrl.length > 0) return true;\n return false;\n}\n\nfunction modelDiversityScore(candidate: ConcreteModelReference, avoid: ModelReference): number {\n let score = 0;\n if (candidate.provider !== avoid.provider) score += 100;\n if (candidate.model !== avoid.model) score += 20;\n if (/opus|gpt-5|o3|o4|gemini.*pro|deepseek-r1/i.test(candidate.model)) score += 10;\n if (/mini|haiku|flash/i.test(candidate.model)) score -= 5;\n return score;\n}\n\nexport type MatrixKeyKind = 'role' | 'phase' | 'default' | 'unknown';\n\n/** Classify a matrix key so `/setmodel` can reject typos before persisting. */\nexport function matrixKeyKind(key: string): MatrixKeyKind {\n if (key === '*') return 'default';\n if (key in AGENT_CATALOG) return 'role';\n if (MATRIX_PHASE_KEYS.includes(key)) return 'phase';\n return 'unknown';\n}\n\n/** True when `key` is a usable matrix key (role, phase, or `*`). */\nexport function isValidMatrixKey(key: string): boolean {\n return matrixKeyKind(key) !== 'unknown';\n}\n", "/**\n * LLM-accessible tools covering every provider/model/fallback configurable area\n * in the system: favorites, fallback chains & profiles, provider management,\n * API key handling, leader model, per-role model assignment, and system view.\n *\n * DESIGN: Every operation that accepts a provider/model reference validates\n * the entry against the user's `favoriteModels` list FIRST. This means all\n * fallback additions, profiles, and role assignments are restricted to\n * user-curated favorites \u2014 the LLM cannot add arbitrary unknown models.\n *\n * Exceptions:\n * - Removing entries (chain, profile, favorites) works on any existing entry.\n * - Listing/viewing works unconditionally.\n * - The active leader model itself is not restricted (it's already set).\n *\n * Tools (8 total):\n * favorite_manage \u2014 List, add, remove favorite models.\n * fallback_chain_manage \u2014 View, add, insert, remove, clear the active chain.\n * fallback_profile_manage \u2014 List, create/update, delete named profiles.\n * agent_model_assign \u2014 Assign model/profile to role/phase/* in the matrix.\n * provider_manage \u2014 List, add, configure, remove provider entries.\n * provider_key_set \u2014 Set API key via env var, direct key, or interactive prompt.\n * leader_model_set \u2014 View/set leader model, derive from profile, toggle settings.\n * system_config_view \u2014 Comprehensive view + validation doctor for full config.\n *\n * Usage from an agent:\n * ```\n * favorite_manage({ action: \"list\" })\n * favorite_manage({ action: \"add\", model: \"anthropic/claude-sonnet-4\" })\n * fallback_chain_manage({ action: \"add\", model: \"anthropic/claude-haiku-3\" })\n * fallback_profile_manage({ action: \"set\", name: \"fast\", chain: [\"openai/gpt-4o-mini\"] })\n * agent_model_assign({ role: \"security-scanner\", provider: \"anthropic\", model: \"claude-haiku-3\" })\n * provider_key_set({ provider: \"openai\", envVar: \"OPENAI_API_KEY\" })\n * leader_model_set({ action: \"show\" })\n * system_config_view({ section: \"all\" })\n * ```\n */\nimport type { Config } from '../types/config.js';\nimport type { Logger } from '../types/logger.js';\nimport type { JSONSchema, Tool } from '../types/tool.js';\nimport { AGENT_CATALOG } from '../coordination/agents/index.js';\nimport { isValidMatrixKey, phaseForRole, resolveSubagentModelTarget } from '../coordination/model-matrix.js';\nimport { normalizeModelRef } from '../core/fallback-model.js';\n\n// \u2500\u2500 Public types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const FAVORITE_MANAGE_TOOL_NAME = 'favorite_manage';\nexport const FALLBACK_CHAIN_MANAGE_TOOL_NAME = 'fallback_chain_manage';\nexport const FALLBACK_PROFILE_MANAGE_TOOL_NAME = 'fallback_profile_manage';\nexport const AGENT_MODEL_ASSIGN_TOOL_NAME = 'agent_model_assign';\n\nexport interface FallbackManageToolOptions {\n /** Returns the live config (re-read each call so changes are honored). */\n getConfig: () => Config;\n /**\n * Persist config mutations. Receives a mutator that receives the config\n * as a mutable JSON object \u2014 the tool sets the relevant fields and the\n * host writes back atomically + mirrors into the in-memory store.\n */\n updateConfig: (mutate: (cfg: Record<string, unknown>) => void) => Promise<void>;\n /**\n * Optional callback for requesting secure interactive input from the user.\n * When provided, tools like `provider_key_set` can use it to prompt the\n * user for secret values (API keys, tokens) without the value passing\n * through the LLM's context. The prompt string is shown to the user and\n * the returned string is the value they entered.\n *\n * When absent, `provider_key_set` returns a `needs_key` status and the\n * host is expected to handle it through other means (env var, CLI command).\n */\n requestInput?: ((prompt: string) => Promise<string>) | undefined;\n /** Optional logger for internal warnings. */\n logger?: Logger | undefined;\n}\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Canonicalize a model reference so equivalent spellings dedupe. */\nfunction normalizeRef(ref: string): string {\n return ref\n .trim()\n .replace(/\\s*\\/\\s*/g, '/')\n .replace(/\\s+/g, ' ');\n}\n\n/**\n * Validate that a model reference is in the user's favorites list (or that\n * favorites are not enforced). Returns `true` when the ref is valid.\n */\nfunction isFavoriteRef(ref: string, config: Config): boolean {\n const favorites = config.favoriteModels ?? [];\n if (favorites.length === 0) {\n // No favorites at all means the constraint is not active \u2014 allow anything\n return true;\n }\n const canonical = normalizeModelRef(ref, config.provider);\n return favorites.some((f) => normalizeModelRef(f, config.provider) === canonical);\n}\n\n/** Build a human-friendly error listing provider/model favorites. */\nfunction notFavoriteError(ref: string, config: Config): string {\n const favorites = config.favoriteModels ?? [];\n return (\n `\"${ref}\" is not in your favorites list. ` +\n (favorites.length === 0\n ? 'Add some favorites first with favorite_manage({ action: \"add\", model: \"<provider/model>\" }).'\n : `Current favorites: ${favorites.join(', ') || '(none)'}. ` +\n 'Use favorite_manage to add this model first.')\n );\n}\n\nfunction modelList(config: Config): string[] {\n return config.favoriteModels ?? [];\n}\n\nfunction profileList(config: Config): Record<string, string[]> {\n return (config.fallbackProfiles ?? {}) as Record<string, string[]>;\n}\n\nfunction chainList(config: Config): string[] {\n return config.fallbackModels ?? [];\n}\n\n// \u2500\u2500 1. FAVORITE_MANAGE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst FAVORITE_MANAGE_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'add', 'remove'],\n description: 'Operation to perform: list (show all), add (add a favorite), remove (remove by index or ref).',\n },\n model: {\n type: 'string',\n description:\n 'Model reference to add/remove (e.g. \"anthropic/claude-haiku-3\", \"openai/gpt-4o-mini\"). ' +\n 'Required for \"add\" and \"remove\" (when removing by ref).',\n },\n index: {\n type: 'number',\n description: '1-based index for removal. Alternative to `model`. Used when action=\"remove\".',\n },\n },\n required: ['action'],\n additionalProperties: false,\n};\n\ninterface FavoriteManageInput {\n action: 'list' | 'add' | 'remove';\n model?: string | undefined;\n index?: number | undefined;\n}\n\ninterface FavoriteManageOutput {\n status: 'ok' | 'error';\n message: string;\n favorites?: string[];\n}\n\nfunction createFavoriteManageTool(opts: FallbackManageToolOptions): Tool<FavoriteManageInput, FavoriteManageOutput> {\n return {\n name: FAVORITE_MANAGE_TOOL_NAME,\n description:\n 'Manage your favorite provider/model list. Favorites are the only models ' +\n 'that can be added to fallback chains and profiles. The LLM uses this tool ' +\n 'to curate which models are available for fallback and role assignment.',\n usageHint: 'Start with \"list\" to see current favorites. Use \"add <provider/model>\" to add. Use \"remove <index|ref>\" to remove.',\n category: 'Config',\n inputSchema: FAVORITE_MANAGE_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const favorites = [...modelList(config)];\n\n if (input.action === 'list') {\n const msg =\n favorites.length === 0\n ? 'No favorites set. Add one with favorite_manage({ action: \"add\", model: \"<provider/model>\" }).'\n : `Favorites (${favorites.length}):\\n` + favorites.map((f, i) => ` ${i + 1}. ${f}`).join('\\n');\n return { status: 'ok', message: msg, favorites: [...favorites] };\n }\n\n if (input.action === 'add') {\n if (!input.model) {\n return { status: 'error', message: 'Provide \"model\" (e.g. \"anthropic/claude-haiku-3\") to add a favorite.' };\n }\n const ref = normalizeRef(input.model);\n const canonical = normalizeModelRef(ref, config.provider);\n if (favorites.some((f) => normalizeModelRef(f, config.provider) === canonical)) {\n return { status: 'error', message: `\"${ref}\" is already a favorite.` };\n }\n favorites.push(ref);\n await opts.updateConfig((cfg) => {\n cfg.favoriteModels = favorites;\n });\n return {\n status: 'ok',\n message: `\u2713 Added favorite: ${ref} (${favorites.length} total)`,\n favorites: [...favorites],\n };\n }\n\n if (input.action === 'remove') {\n if (input.index !== undefined) {\n const idx = input.index - 1;\n if (idx < 0 || idx >= favorites.length) {\n return { status: 'error', message: `Index ${input.index} is out of range (1\u2013${favorites.length}).` };\n }\n const [removed] = favorites.splice(idx, 1);\n await opts.updateConfig((cfg) => {\n cfg.favoriteModels = favorites;\n });\n return { status: 'ok', message: `\u2713 Removed favorite: ${removed}`, favorites: [...favorites] };\n }\n if (input.model) {\n const ref = normalizeRef(input.model);\n const canonical = normalizeModelRef(ref, config.provider);\n const idx = favorites.findIndex((f) => normalizeModelRef(f, config.provider) === canonical);\n if (idx === -1) {\n return { status: 'error', message: `Favorite \"${ref}\" not found. Use \"list\" to see all favorites.` };\n }\n const [removed] = favorites.splice(idx, 1);\n await opts.updateConfig((cfg) => {\n cfg.favoriteModels = favorites;\n });\n return { status: 'ok', message: `\u2713 Removed favorite: ${removed}`, favorites: [...favorites] };\n }\n return { status: 'error', message: 'Provide either \"model\" or \"index\" to remove a favorite.' };\n }\n\n return { status: 'error', message: `Unknown action: \"${input.action}\". Use \"list\", \"add\", or \"remove\".` };\n },\n };\n}\n\n// \u2500\u2500 2. FALLBACK_CHAIN_MANAGE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst FALLBACK_CHAIN_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'add', 'insert', 'remove', 'clear'],\n description:\n 'Operation: list (show chain), add (append), insert (insert at position), ' +\n 'remove (by index or ref), clear (empty the chain).',\n },\n model: {\n type: 'string',\n description:\n 'Model reference for add/insert/remove (e.g. \"anthropic/claude-haiku-3\"). ' +\n 'Must be in your favorites list for add/insert. Required for add, insert, and remove (when removing by ref).',\n },\n index: {\n type: 'number',\n description:\n '1-based insertion position (for action=\"insert\") or removal index (for action=\"remove\"). ' +\n 'For insert: the new entry is placed before this position. Omit to append. ' +\n 'For remove: alternative to model. Omit to remove by model ref.',\n },\n },\n required: ['action'],\n additionalProperties: false,\n};\n\ninterface FallbackChainInput {\n action: 'list' | 'add' | 'insert' | 'remove' | 'clear';\n model?: string | undefined;\n index?: number | undefined;\n}\n\ninterface FallbackChainOutput {\n status: 'ok' | 'error';\n message: string;\n chain?: string[];\n}\n\nfunction createFallbackChainManageTool(opts: FallbackManageToolOptions): Tool<FallbackChainInput, FallbackChainOutput> {\n return {\n name: FALLBACK_CHAIN_MANAGE_TOOL_NAME,\n description:\n 'View or change the active rate-limit fallback chain. When the primary model ' +\n 'is overloaded (429/5xx), the agent rotates through this chain in order. ' +\n 'Every new entry must be a FAVORITE model \u2014 add it via favorite_manage first. ' +\n 'Use insert to place a fallback at a specific position; use remove to delete an entry.',\n usageHint:\n '\"list\" to see the current chain. \"add\" with a favorite model to append. ' +\n '\"insert\" with an index (1-based) to place before that position. ' +\n '\"remove\" with index or model ref. \"clear\" to empty the chain (auto fallback takes over).',\n category: 'Config',\n inputSchema: FALLBACK_CHAIN_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const chain = [...chainList(config)];\n\n if (input.action === 'list') {\n if (chain.length === 0) {\n return {\n status: 'ok',\n message: 'Fallback chain is empty. Add entries with \"add\" or enable auto fallback.',\n chain: [],\n };\n }\n const msg = chain.map((ref, i) => ` ${i + 1}. ${ref}`).join('\\n');\n return { status: 'ok', message: `Fallback chain (${chain.length}):\\n${msg}`, chain: [...chain] };\n }\n\n if (input.action === 'add') {\n if (!input.model) {\n return { status: 'error', message: 'Provide \"model\" (e.g. \"anthropic/claude-haiku-3\") to add to the chain.' };\n }\n const ref = normalizeRef(input.model);\n if (!isFavoriteRef(ref, config)) {\n return { status: 'error', message: notFavoriteError(ref, config) };\n }\n if (chain.some((e) => normalizeRef(e) === ref)) {\n return { status: 'error', message: `\"${ref}\" is already in the chain.` };\n }\n chain.push(ref);\n await opts.updateConfig((cfg) => {\n cfg.fallbackModels = chain;\n });\n return {\n status: 'ok',\n message: `\u2713 Added to chain: ${ref} (position ${chain.length})`,\n chain: [...chain],\n };\n }\n\n if (input.action === 'insert') {\n if (!input.model) {\n return { status: 'error', message: 'Provide \"model\" to insert into the chain.' };\n }\n const ref = normalizeRef(input.model);\n if (!isFavoriteRef(ref, config)) {\n return { status: 'error', message: notFavoriteError(ref, config) };\n }\n if (chain.some((e) => normalizeRef(e) === ref)) {\n return { status: 'error', message: `\"${ref}\" is already in the chain.` };\n }\n let pos = chain.length; // default: append\n if (input.index !== undefined) {\n pos = Math.max(0, Math.min(chain.length, input.index - 1));\n }\n chain.splice(pos, 0, ref);\n await opts.updateConfig((cfg) => {\n cfg.fallbackModels = chain;\n });\n return {\n status: 'ok',\n message: `\u2713 Inserted at position ${pos + 1}: ${ref}`,\n chain: [...chain],\n };\n }\n\n if (input.action === 'remove') {\n if (chain.length === 0) {\n return { status: 'error', message: 'Chain is empty \u2014 nothing to remove.' };\n }\n if (input.index !== undefined) {\n const idx = input.index - 1;\n if (idx < 0 || idx >= chain.length) {\n return { status: 'error', message: `Index ${input.index} is out of range (1\u2013${chain.length}).` };\n }\n const [removed] = chain.splice(idx, 1);\n await opts.updateConfig((cfg) => {\n cfg.fallbackModels = chain;\n });\n return { status: 'ok', message: `\u2713 Removed: ${removed}`, chain: [...chain] };\n }\n if (input.model) {\n const ref = normalizeRef(input.model);\n const idx = chain.findIndex((e) => normalizeRef(e) === ref);\n if (idx === -1) {\n return { status: 'error', message: `\"${ref}\" not found in chain.` };\n }\n const [removed] = chain.splice(idx, 1);\n await opts.updateConfig((cfg) => {\n cfg.fallbackModels = chain;\n });\n return { status: 'ok', message: `\u2713 Removed: ${removed}`, chain: [...chain] };\n }\n return { status: 'error', message: 'Provide \"index\" or \"model\" to remove from the chain.' };\n }\n\n if (input.action === 'clear') {\n if (chain.length === 0) {\n return { status: 'ok', message: 'Chain is already empty.' };\n }\n await opts.updateConfig((cfg) => {\n cfg.fallbackModels = [];\n });\n return { status: 'ok', message: '\u2713 Cleared the fallback chain. Auto fallback will take over when enabled.' };\n }\n\n return { status: 'error', message: `Unknown action: \"${input.action}\".` };\n },\n };\n}\n\n// \u2500\u2500 3. FALLBACK_PROFILE_MANAGE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst FALLBACK_PROFILE_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'set', 'delete'],\n description: 'Operation: list (show all profiles), set (create/update), delete (remove a profile).',\n },\n name: {\n type: 'string',\n description:\n 'Profile name (e.g. \"fast\", \"economy\", \"reliable\"). Required for \"set\" and \"delete\".',\n },\n chain: {\n type: 'array',\n items: { type: 'string' },\n description:\n 'Ordered list of model references for the profile. ' +\n 'Each entry must be a favorite model. Required for \"set\". Example: [\"anthropic/claude-haiku-3\", \"openai/gpt-4o-mini\"].',\n },\n },\n required: ['action'],\n additionalProperties: false,\n};\n\ninterface FallbackProfileInput {\n action: 'list' | 'set' | 'delete';\n name?: string | undefined;\n chain?: string[] | undefined;\n}\n\ninterface FallbackProfileOutput {\n status: 'ok' | 'error';\n message: string;\n profiles?: Record<string, string[]>;\n}\n\nfunction createFallbackProfileManageTool(opts: FallbackManageToolOptions): Tool<FallbackProfileInput, FallbackProfileOutput> {\n return {\n name: FALLBACK_PROFILE_MANAGE_TOOL_NAME,\n description:\n 'Manage named fallback profiles. A profile is a reusable, ordered list of ' +\n 'model references that can be assigned to agent roles. Every entry in a profile ' +\n 'must be a FAVORITE model \u2014 add it via favorite_manage first. ' +\n 'Use /setmodel or agent_model_assign to assign a profile to a role.',\n usageHint:\n '\"list\" to see all profiles. ' +\n '\"set\" with name and chain (array of model refs) to create or replace a profile. ' +\n '\"delete\" with name to remove a profile.',\n category: 'Config',\n inputSchema: FALLBACK_PROFILE_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const profiles = { ...profileList(config) };\n\n if (input.action === 'list') {\n const names = Object.keys(profiles);\n if (names.length === 0) {\n return {\n status: 'ok',\n message: 'No fallback profiles. Create one with \"set\".',\n profiles: {},\n };\n }\n const msg = names\n .sort()\n .map((name) => ` ${name} \u2192 ${profiles[name]?.join(' \u2192 ') || '(empty)'}`)\n .join('\\n');\n return { status: 'ok', message: `Fallback profiles:\\n${msg}`, profiles: { ...profiles } };\n }\n\n if (input.action === 'set') {\n if (!input.name) {\n return { status: 'error', message: 'Provide \"name\" for the profile (e.g. \"fast\").' };\n }\n if (!input.chain || input.chain.length === 0) {\n return { status: 'error', message: 'Provide \"chain\" \u2014 a non-empty array of model references.' };\n }\n // Validate every entry against favorites\n const invalid: string[] = [];\n for (const ref of input.chain) {\n if (!isFavoriteRef(ref, config)) {\n invalid.push(ref);\n }\n }\n if (invalid.length > 0) {\n return {\n status: 'error',\n message:\n `The following entries are not in your favorites list:\\n ${invalid.join('\\n ')}\\n\\n` +\n 'Add them first with favorite_manage({ action: \"add\", model: \"<ref>\" }).',\n };\n }\n profiles[input.name] = [...input.chain];\n await opts.updateConfig((cfg) => {\n cfg.fallbackProfiles = profiles;\n });\n return {\n status: 'ok',\n message: `\u2713 Profile \"${input.name}\" \u2192 ${input.chain.join(' \u2192 ')}`,\n profiles: { ...profiles },\n };\n }\n\n if (input.action === 'delete') {\n if (!input.name) {\n return { status: 'error', message: 'Provide \"name\" of the profile to delete.' };\n }\n if (!(input.name in profiles)) {\n return { status: 'error', message: `Profile \"${input.name}\" not found.` };\n }\n delete profiles[input.name];\n await opts.updateConfig((cfg) => {\n cfg.fallbackProfiles = profiles;\n });\n return {\n status: 'ok',\n message: `\u2713 Deleted profile: ${input.name}`,\n profiles: { ...profiles },\n };\n }\n\n return { status: 'error', message: `Unknown action: \"${input.action}\".` };\n },\n };\n}\n\n// \u2500\u2500 4. AGENT_MODEL_ASSIGN \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst AGENT_MODEL_ASSIGN_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n role: {\n type: 'string',\n description:\n 'Matrix key: a catalog role (e.g. \"security-scanner\", \"bug-hunter\"), a phase ' +\n 'name (e.g. \"review\", \"implementation\"), or \"*\" for the fleet-wide default.',\n },\n provider: {\n type: 'string',\n description:\n 'Provider id (e.g. \"anthropic\", \"openai\"). When omitted, the leader provider is used. ' +\n 'The provider.model combination must be in your favorites list.',\n },\n model: {\n type: 'string',\n description:\n 'Model id (e.g. \"claude-haiku-3\", \"gpt-4o-mini\"). When omitted together with provider, ' +\n 'the role falls back to the leader model. Must be in your favorites list.',\n },\n profile: {\n type: 'string',\n description:\n 'Named fallback profile to assign (e.g. \"fast\", \"economy\"). Alternative to provider+model. ' +\n 'When set, the first profile entry becomes the primary model and the rest are the fallback chain.',\n },\n clear: {\n type: 'boolean',\n description:\n 'Set to true to remove the matrix entry for this role (it will fall through to phase/*/leader).',\n },\n },\n // Flattened from a top-level oneOf \u2014 Anthropic-family endpoints reject\n // top-level combinators (omniroute 400: \"input_schema does not support\n // oneOf, allOf, or anyOf at the top level\"). Combination rules are\n // enforced in the handler instead.\n required: ['role'],\n additionalProperties: false,\n};\n\ninterface AgentModelAssignInput {\n role: string;\n provider?: string | undefined;\n model?: string | undefined;\n profile?: string | undefined;\n clear?: boolean | undefined;\n}\n\ninterface AgentModelAssignOutput {\n status: 'ok' | 'error';\n message: string;\n role?: string;\n}\n\nfunction createAgentModelAssignTool(opts: FallbackManageToolOptions): Tool<AgentModelAssignInput, AgentModelAssignOutput> {\n return {\n name: AGENT_MODEL_ASSIGN_TOOL_NAME,\n description:\n 'Assign a provider/model or a fallback profile to a specific agent role, phase, ' +\n 'or the fleet-wide default. This is the LLM-accessible equivalent of /setmodel set. ' +\n 'The provider+model combination must be in your favorites list (unless only clearing). ' +\n 'Resolution precedence: exact role \u2192 phase \u2192 * \u2192 leader model.',\n usageHint:\n 'Use \"list\" as role to see current assignments. ' +\n 'Set with role + model, or role + provider + model, or role + profile. ' +\n 'Set role + clear=true to remove a matrix entry. ' +\n 'The provider/model must be a favorite.',\n category: 'Config',\n inputSchema: AGENT_MODEL_ASSIGN_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n\n // Reject conflicting combination rules \u2014 only one mode at a time\n const modes = [input.clear ? 'clear' : null, input.profile ? 'profile' : null, input.model ? 'model' : null].filter(Boolean);\n if (modes.length > 1) {\n return {\n status: 'error',\n message: `Conflicting assignment modes: ${modes.join(' + ')}. ` +\n 'Use exactly one: clear=true, profile=\"name\", or model=\"name\" (optionally with provider).',\n };\n }\n\n // Special case: \"list\" role shows current matrix\n if (input.role === 'list') {\n const matrix = (config.modelMatrix ?? {}) as Record<string, unknown>;\n const keys = Object.keys(matrix);\n if (keys.length === 0) {\n return { status: 'ok', message: 'No matrix assignments. All roles use the leader model.' };\n }\n const msg = keys.sort().map((k) => ` ${k} \u2192 ${JSON.stringify(matrix[k])}`).join('\\n');\n return { status: 'ok', message: `Model matrix (${keys.length} entries):\\n${msg}` };\n }\n\n // Validate key\n if (!isValidMatrixKey(input.role)) {\n return {\n status: 'error',\n message:\n `\"${input.role}\" is not a valid matrix key. Use a catalog role (e.g. \"security-scanner\"), ` +\n 'a phase (e.g. \"review\"), or \"*\" for the fleet-wide default.',\n };\n }\n\n // Clear entry\n if (input.clear) {\n const matrix = { ...((config.modelMatrix ?? {}) as Record<string, unknown>) };\n if (!(input.role in matrix)) {\n return { status: 'ok', message: `No matrix entry for \"${input.role}\" to clear.` };\n }\n delete matrix[input.role];\n await opts.updateConfig((cfg) => {\n cfg.modelMatrix = matrix;\n });\n return { status: 'ok', message: `\u2713 Cleared matrix entry for \"${input.role}\".` };\n }\n\n // Show current assignment for this role\n if (!input.model && !input.profile && !input.provider) {\n const matrix = (config.modelMatrix ?? {}) as Record<string, unknown>;\n const entry = matrix[input.role];\n if (!entry) {\n return { status: 'ok', message: `No specific assignment for \"${input.role}\". It uses the leader model or phase/* fallback.` };\n }\n return { status: 'ok', message: `\"${input.role}\" \u2192 ${JSON.stringify(entry)}` };\n }\n\n // Assign profile (no model required)\n if (input.profile && !input.model) {\n const profiles = profileList(config);\n if (!profiles[input.profile]) {\n return { status: 'error', message: `Profile \"${input.profile}\" not found. Create it with fallback_profile_manage first.` };\n }\n const matrix = { ...((config.modelMatrix ?? {}) as Record<string, unknown>) };\n matrix[input.role] = { fallbackProfile: input.profile };\n await opts.updateConfig((cfg) => {\n cfg.modelMatrix = matrix;\n });\n return { status: 'ok', message: `\u2713 \"${input.role}\" \u2192 profile: ${input.profile}` };\n }\n\n // Assign provider+model (must be a favorite)\n if (input.model) {\n const effectiveProvider = input.provider ?? config.provider;\n const ref = `${effectiveProvider}/${input.model}`;\n if (!isFavoriteRef(ref, config)) {\n return { status: 'error', message: notFavoriteError(ref, config) };\n }\n const matrix = { ...((config.modelMatrix ?? {}) as Record<string, unknown>) };\n const previousRuntime = (matrix[input.role] as Record<string, unknown>)?.modelRuntime;\n matrix[input.role] = input.provider\n ? { provider: input.provider, model: input.model, ...(previousRuntime ? { modelRuntime: previousRuntime } : {}) }\n : { model: input.model, ...(previousRuntime ? { modelRuntime: previousRuntime } : {}) };\n await opts.updateConfig((cfg) => {\n cfg.modelMatrix = matrix;\n });\n const display = input.provider ? `${input.provider}/${input.model}` : `${input.model} (leader provider)`;\n return { status: 'ok', message: `\u2713 \"${input.role}\" \u2192 ${display}` };\n }\n\n return { status: 'error', message: 'Provide model, profile, or clear=true for the role assignment.' };\n },\n };\n}\n\n// \u2500\u2500 5. Factory \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// \u2500\u2500 5. PROVIDER_MANAGE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const PROVIDER_MANAGE_TOOL_NAME = 'provider_manage';\n\nconst PROVIDER_MANAGE_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'add', 'configure', 'remove'],\n description:\n 'Operation: list (show all providers), add (add a new provider config), ' +\n 'configure (update fields of an existing provider), remove (delete a provider config).',\n },\n provider: {\n type: 'string',\n description: 'Provider id (e.g. \"openai\", \"anthropic\"). Required for all actions except list.',\n },\n type: {\n type: 'string',\n description: 'Provider type (e.g. \"openai\", \"anthropic\"). Required for \"add\".',\n },\n models: {\n type: 'array',\n items: { type: 'string' },\n description:\n 'Model list to restrict visibility for this provider. Optional for add/configure.',\n },\n baseUrl: {\n type: 'string',\n description: 'Custom base URL (e.g. for self-hosted endpoints). Optional.',\n },\n family: {\n type: 'string',\n description:\n 'Wire-family override (e.g. \"openai\", \"openai-compatible\", \"anthropic\"). ' +\n 'When set, the provider can be constructed without a catalog entry.',\n },\n envVars: {\n type: 'array',\n items: { type: 'string' },\n description: 'Custom env var names to probe when apiKey is missing. Optional.',\n },\n autoDiscoverModels: {\n type: 'boolean',\n description: 'Auto-fetch model list from {baseUrl}/models. Optional.',\n },\n apiKey: {\n type: 'string',\n description:\n '**NOT RECOMMENDED** \u2014 use provider_key_set instead. ' +\n 'The LLM output may contain this value; use env var references for safety.',\n },\n },\n required: ['action'],\n additionalProperties: false,\n};\n\ninterface ProviderManageInput {\n action: 'list' | 'add' | 'configure' | 'remove';\n provider?: string | undefined;\n type?: string | undefined;\n models?: string[] | undefined;\n baseUrl?: string | undefined;\n family?: string | undefined;\n envVars?: string[] | undefined;\n autoDiscoverModels?: boolean | undefined;\n apiKey?: string | undefined;\n}\n\ninterface ProviderManageOutput {\n status: 'ok' | 'error';\n message: string;\n providers?: string[];\n}\n\nfunction createProviderManageTool(opts: FallbackManageToolOptions): Tool<ProviderManageInput, ProviderManageOutput> {\n return {\n name: PROVIDER_MANAGE_TOOL_NAME,\n description:\n 'View or configure provider entries. List all configured providers with their ' +\n 'type, model lists, base URL, and key status. Add new providers, update their ' +\n 'settings, or remove unused ones. API keys should be set via provider_key_set ' +\n 'instead of passing them here \u2014 they are visible in the LLM output.',\n usageHint:\n '\"list\" to see all providers. \"add\" with provider id and type to create. ' +\n '\"configure\" to update models, baseUrl, family, or envVars. ' +\n '\"remove\" to delete a provider. Use provider_key_set for API key management.',\n category: 'Config',\n inputSchema: PROVIDER_MANAGE_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const providers = {\n ...((config.providers ?? {}) as unknown as Record<string, Record<string, unknown>>),\n };\n const leaderProvider: string = config.provider ?? '';\n\n if (input.action === 'list') {\n const ids = Object.keys(providers);\n if (ids.length === 0) {\n return { status: 'ok', message: 'No providers configured.', providers: [] };\n }\n const msg = ids.sort().map((id) => {\n const entry = providers[id] ?? {};\n const type = (entry.type as string) ?? '(unknown)';\n const models = Array.isArray(entry.models) ? (entry.models as string[]).join(', ') : '(all)';\n const hasKey = entry.apiKey ? '\u2713' : entry.apiKeys ? '\u2713' : '\u2717';\n const prefix = id === leaderProvider ? '\u2605 ' : ' ';\n const baseUrl = entry.baseUrl ? ` url:${entry.baseUrl}` : '';\n const family = entry.family ? ` family:${entry.family}` : '';\n return ` ${prefix}${id} (${type}) key:${hasKey} models:[${models}]${baseUrl}${family}`;\n }).join('\\n');\n return {\n status: 'ok',\n message: `Providers (leader: ${leaderProvider}):\\n${msg}`,\n providers: ids,\n };\n }\n\n if (input.action === 'add') {\n if (!input.provider || !input.type) {\n return { status: 'error', message: 'Provide \"provider\" (id) and \"type\" to add a provider.' };\n }\n if (providers[input.provider]) {\n return { status: 'error', message: `Provider \"${input.provider}\" already exists. Use \"configure\" to update.` };\n }\n const entry: Record<string, unknown> = { type: input.type };\n if (input.models) entry.models = input.models;\n if (input.baseUrl) entry.baseUrl = input.baseUrl;\n if (input.family) entry.family = input.family;\n if (input.envVars) entry.envVars = input.envVars;\n if (input.autoDiscoverModels !== undefined) entry.autoDiscoverModels = input.autoDiscoverModels;\n if (input.apiKey) entry.apiKey = input.apiKey;\n providers[input.provider] = entry;\n await opts.updateConfig((cfg) => {\n cfg.providers = providers;\n });\n return { status: 'ok', message: `\u2713 Added provider: ${input.provider} (type: ${input.type})` };\n }\n\n if (input.action === 'configure') {\n if (!input.provider) {\n return { status: 'error', message: 'Provide \"provider\" id to configure.' };\n }\n if (!providers[input.provider]) {\n return { status: 'error', message: `Provider \"${input.provider}\" not found. Use \"add\" first or check \"list\".` };\n }\n const entry: Record<string, unknown> = { ...providers[input.provider] };\n if (input.models !== undefined) entry.models = input.models;\n if (input.baseUrl !== undefined) entry.baseUrl = input.baseUrl || undefined;\n if (input.family !== undefined) entry.family = input.family || undefined;\n if (input.envVars !== undefined) entry.envVars = input.envVars;\n if (input.autoDiscoverModels !== undefined) entry.autoDiscoverModels = input.autoDiscoverModels;\n if (input.apiKey !== undefined) entry.apiKey = input.apiKey || undefined;\n providers[input.provider] = entry;\n await opts.updateConfig((cfg) => {\n cfg.providers = providers;\n });\n const updated = Object.keys({ ...entry }).filter((k) => k !== 'apiKey').join(', ');\n return { status: 'ok', message: `\u2713 Updated ${input.provider}: ${updated}` };\n }\n\n if (input.action === 'remove') {\n if (!input.provider) {\n return { status: 'error', message: 'Provide \"provider\" id to remove.' };\n }\n if (!providers[input.provider]) {\n return { status: 'error', message: `Provider \"${input.provider}\" not found.` };\n }\n if (input.provider === leaderProvider) {\n return { status: 'error', message: `Cannot remove the active leader provider \"${input.provider}\". Switch the leader first.` };\n }\n delete providers[input.provider];\n await opts.updateConfig((cfg) => {\n cfg.providers = providers;\n });\n return { status: 'ok', message: `\u2713 Removed provider: ${input.provider}` };\n }\n\n return { status: 'error', message: `Unknown action: \"${input.action}\".` };\n },\n };\n}\n\n// \u2500\u2500 6. PROVIDER_KEY_SET \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const PROVIDER_KEY_SET_TOOL_NAME = 'provider_key_set';\n\nconst PROVIDER_KEY_SET_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n provider: {\n type: 'string',\n description: 'Provider id (e.g. \"openai\", \"anthropic\"). Required.',\n },\n key: {\n type: 'string',\n description:\n 'The API key value. When provided directly, it is stored as the provider\\'s ' +\n 'primary key. \u26A0\uFE0F This value is visible to the LLM \u2014 for secrets, omit this field ' +\n 'and use envVar instead, or provide the key through the interactive prompt.',\n },\n envVar: {\n type: 'string',\n description:\n 'Environment variable name that contains the key (e.g. \"OPENAI_API_KEY\"). ' +\n 'The key is read from the environment at tool execution time \u2014 the value is never ' +\n 'visible to the LLM. Preferred over passing the key directly.',\n },\n label: {\n type: 'string',\n description:\n 'Optional label for the key entry (e.g. \"work\", \"personal\"). Useful when managing multiple keys.',\n },\n setActive: {\n type: 'boolean',\n description: 'Whether to make this the active key. Default: true.',\n },\n },\n // Flattened from a top-level oneOf \u2014 Anthropic-family endpoints reject\n // top-level combinators (omniroute 400). Combination rules are enforced\n // in the handler instead.\n required: ['provider'],\n additionalProperties: false,\n};\n\ninterface ProviderKeySetInput {\n provider: string;\n key?: string | undefined;\n envVar?: string | undefined;\n label?: string | undefined;\n setActive?: boolean | undefined;\n}\n\ninterface ProviderKeySetOutput {\n status: 'ok' | 'error' | 'needs_key';\n message: string;\n}\n\nfunction createProviderKeySetTool(opts: FallbackManageToolOptions): Tool<ProviderKeySetInput, ProviderKeySetOutput> {\n return {\n name: PROVIDER_KEY_SET_TOOL_NAME,\n description:\n 'Set the API key for a provider. For security, prefer using envVar (reads from ' +\n 'environment variable, value never visible to the LLM) over passing the key directly. ' +\n 'When neither key nor envVar is provided, the tool returns a prompt for interactive key entry \u2014 ' +\n 'the UI will present an input field and the key is stored without LLM visibility.\\n\\n' +\n 'After setting a key, the provider becomes usable for model assignments and fallback chains. ' +\n 'Add its models to favorites with favorite_manage to unlock them for fallback/profile use.',\n usageHint:\n 'Preferred: provider_key_set({ provider: \"openai\", envVar: \"OPENAI_API_KEY\" }). ' +\n 'For interactive input: provider_key_set({ provider: \"openai\" }) \u2014 the UI will prompt. ' +\n 'Direct key: provider_key_set({ provider: \"openai\", key: \"sk-...\" }) \u2014 visible to LLM.',\n category: 'Config',\n inputSchema: PROVIDER_KEY_SET_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const providers = {\n ...((config.providers ?? {}) as unknown as Record<string, Record<string, unknown>>),\n };\n\n // Reject when both key and envVar are supplied \u2014 ambiguous intent\n if (input.key && input.envVar) {\n return {\n status: 'error',\n message: 'Provide either key (direct, visible to LLM) OR envVar (reads from environment, ' +\n 'never visible to LLM), not both. Use envVar for security.',\n };\n }\n\n // If no key or envVar is given, request interactive input\n if (!input.key && !input.envVar) {\n // Interactive input via host callback \u2014 LLM never sees the value\n if (opts.requestInput) {\n try {\n const value = await opts.requestInput(\n `Enter API key for \"${input.provider}\" (will be stored securely, LLM will not see it):`,\n );\n if (!value || value.trim().length === 0) {\n return { status: 'error', message: 'No key was entered. Operation cancelled.' };\n }\n return storeKey(providers, input, value.trim(), opts);\n } catch (err) {\n return {\n status: 'error',\n message: `Interactive input failed or was cancelled: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n }\n // No interactive callback \u2014 return a status the host can intercept\n return {\n status: 'needs_key',\n message:\n `To set the API key for \"${input.provider}\", use provider_key_set ` +\n `with either:\\n` +\n ` 1. envVar: \"${input.provider.toUpperCase()}_API_KEY\" (reads from env, LLM never sees it)\\n` +\n ` 2. key: \"sk-...\" (pass directly, visible to LLM)\\n\\n` +\n `Interactive key entry is handled by the UI \u2014 enter your key through the prompt surface.`,\n };\n }\n\n // Read from environment variable\n if (input.envVar) {\n const envValue = process.env[input.envVar];\n if (!envValue) {\n return {\n status: 'error',\n message: `Environment variable \"${input.envVar}\" is not set or empty. ` +\n `Set it first or use a different envVar.`,\n };\n }\n return storeKey(providers, input, envValue, opts);\n }\n\n // Key provided directly\n if (input.key) {\n return storeKey(providers, input, input.key, opts);\n }\n\n return { status: 'error', message: 'Unexpected \u2014 no key source available.' };\n },\n };\n}\n\nasync function storeKey(\n providers: Record<string, Record<string, unknown>>,\n input: ProviderKeySetInput,\n keyValue: string,\n opts: FallbackManageToolOptions,\n): Promise<ProviderKeySetOutput> {\n const providerId = input.provider;\n\n // Ensure the provider config exists\n if (!providers[providerId]) {\n // Auto-create with a best-guess type (user can configure properly later)\n providers[providerId] = { type: providerId };\n }\n\n const entry = providers[providerId]!;\n const existingKeys = Array.isArray(entry.apiKeys) ? [...(entry.apiKeys as Array<Record<string, unknown>>)] : [];\n const label = input.label ?? 'default';\n\n existingKeys.push({\n label,\n apiKey: keyValue,\n createdAt: new Date().toISOString(),\n });\n\n entry.apiKeys = existingKeys;\n entry.apiKey = undefined; // Clear legacy field after migration to multikey format\n\n if (input.setActive !== false) {\n entry.activeKey = label;\n }\n\n providers[providerId] = entry;\n\n await opts.updateConfig((cfg) => {\n cfg.providers = providers;\n });\n\n const sourceName = input.envVar ? `env:${input.envVar}` : 'direct key';\n return {\n status: 'ok',\n message: `\u2713 API key stored for \"${providerId}\" from ${sourceName}. ` +\n `Now add models to favorites with favorite_manage to use them in fallback chains.`,\n };\n}\n\n// \u2500\u2500 7. LEADER_MODEL_SET \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const LEADER_MODEL_SET_TOOL_NAME = 'leader_model_set';\n\nconst LEADER_MODEL_SET_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['show', 'set', 'profile', 'toggle'],\n description:\n 'Operation: show (current leader + toggles), set (change provider/model), ' +\n 'profile (set from a fallback profile), toggle (change fallbackAuto/favoriteModelsOnly).',\n },\n provider: {\n type: 'string',\n description: 'Provider id for the leader (e.g. \"anthropic\", \"openai\"). Required for \"set\".',\n },\n model: {\n type: 'string',\n description: 'Model id for the leader (e.g. \"claude-sonnet-4-20250514\"). Required for \"set\".',\n },\n profile: {\n type: 'string',\n description: 'Fallback profile name to derive the leader + chain from. Required for \"profile\".',\n },\n toggle: {\n type: 'string',\n enum: ['fallbackAuto', 'favoriteModelsOnly'],\n description: 'Which toggle to change. Required for \"toggle\".',\n },\n value: {\n type: 'boolean',\n description: 'New value for the toggle. Required for \"toggle\".',\n },\n },\n additionalProperties: false,\n};\n\ninterface LeaderModelSetInput {\n action: 'show' | 'set' | 'profile' | 'toggle';\n provider?: string | undefined;\n model?: string | undefined;\n profile?: string | undefined;\n toggle?: 'fallbackAuto' | 'favoriteModelsOnly' | undefined;\n value?: boolean | undefined;\n}\n\ninterface LeaderModelSetOutput {\n status: 'ok' | 'error';\n message: string;\n}\n\nfunction createLeaderModelSetTool(opts: FallbackManageToolOptions): Tool<LeaderModelSetInput, LeaderModelSetOutput> {\n return {\n name: LEADER_MODEL_SET_TOOL_NAME,\n description:\n 'View or change the leader provider/model and system toggles. The leader is the ' +\n 'primary model used for the main agent interactions. ' +\n '\"set\" changes it directly. \"profile\" derives it from a named fallback profile ' +\n '(first entry becomes leader, rest become the fallback chain). ' +\n '\"toggle\" controls fallbackAuto (smart default fallback) and favoriteModelsOnly ' +\n '(restrict auto-fallback to favorites only).',\n usageHint:\n '\"show\" to see current state. \"set\" with provider+model to change. ' +\n '\"profile\" with name to derive from a profile. ' +\n '\"toggle\" with toggle name and value to change a boolean setting.',\n category: 'Config',\n inputSchema: LEADER_MODEL_SET_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n\n if (input.action === 'show') {\n const lines: string[] = [\n ` ${'leader'}: ${config.provider}/${config.model}`,\n ` ${'fallbackAuto'}: ${config.fallbackAuto !== false ? 'on' : 'off'}`,\n ` ${'favoriteModelsOnly'}: ${config.favoriteModelsOnly ? 'on' : 'off'}`,\n '',\n ` ${'fallback models'}: ${(config.fallbackModels ?? []).length > 0 ? (config.fallbackModels ?? []).join(' \u2192 ') : 'empty (auto fallback)'}`,\n ` ${'favorites'}: ${(config.favoriteModels ?? []).length > 0 ? `${(config.favoriteModels ?? []).length} models` : '(none)'}`,\n ` ${'refiner'}: ${config.autonomy?.refinerProvider ? `${config.autonomy.refinerProvider}/${config.autonomy.refinerModel ?? '(default model)'}` : '(same as leader)'}`,\n ];\n return { status: 'ok', message: lines.join('\\n') };\n }\n\n if (input.action === 'set') {\n if (!input.provider || !input.model) {\n return { status: 'error', message: 'Provide \"provider\" and \"model\" for the leader.' };\n }\n await opts.updateConfig((cfg) => {\n cfg.provider = input.provider;\n cfg.model = input.model;\n });\n return { status: 'ok', message: `\u2713 Leader \u2192 ${input.provider}/${input.model}` };\n }\n\n if (input.action === 'profile') {\n if (!input.profile) {\n return { status: 'error', message: 'Provide \"profile\" name to derive the leader from.' };\n }\n const profiles = (config.fallbackProfiles ?? {}) as Record<string, string[]>;\n const chain = profiles[input.profile];\n if (!chain || chain.length === 0) {\n return { status: 'error', message: `Profile \"${input.profile}\" not found or empty.` };\n }\n // Parse first entry as leader provider/model\n const first = chain[0]!;\n const p = parseRefInternal(first);\n const provider = p.provider ?? config.provider;\n const model = p.model;\n if (!model) {\n return { status: 'error', message: `Cannot parse \"${first}\" as a valid model reference.` };\n }\n const rest = chain.slice(1);\n await opts.updateConfig((cfg) => {\n cfg.provider = provider;\n cfg.model = model;\n cfg.fallbackModels = rest;\n });\n return {\n status: 'ok',\n message: `\u2713 Leader \u2192 ${provider}/${model} (profile: ${input.profile})` +\n (rest.length > 0 ? `\\n Fallback chain: ${rest.join(' \u2192 ')}` : ''),\n };\n }\n\n if (input.action === 'toggle') {\n if (!input.toggle || input.value === undefined) {\n return { status: 'error', message: 'Provide \"toggle\" (fallbackAuto | favoriteModelsOnly) and \"value\" (boolean).' };\n }\n await opts.updateConfig((cfg) => {\n if (input.toggle === 'fallbackAuto') {\n cfg.fallbackAuto = input.value;\n } else if (input.toggle === 'favoriteModelsOnly') {\n cfg.favoriteModelsOnly = input.value;\n }\n });\n return {\n status: 'ok',\n message: `\u2713 ${input.toggle} \u2192 ${input.value ? 'on' : 'off'}`,\n };\n }\n\n return { status: 'error', message: `Unknown action: \"${input.action}\".` };\n },\n };\n}\n\ninterface ParsedRef {\n provider?: string;\n model: string;\n}\n\nfunction parseRefInternal(ref: string): ParsedRef {\n const trimmed = ref.trim();\n const slash = trimmed.indexOf('/');\n if (slash !== -1) {\n const p = trimmed.slice(0, slash);\n const m = trimmed.slice(slash + 1).trim();\n if (p) return { provider: p, model: m };\n return { model: m };\n }\n const parts = trimmed.split(/\\s+/);\n if (parts.length >= 2) {\n return { provider: parts[0]!, model: parts.slice(1).join(' ') };\n }\n return { model: trimmed };\n}\n\n// \u2500\u2500 8. SYSTEM_CONFIG_VIEW \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const SYSTEM_CONFIG_VIEW_TOOL_NAME = 'system_config_view';\n\nconst SYSTEM_CONFIG_VIEW_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n section: {\n type: 'string',\n enum: ['all', 'providers', 'models', 'fallbacks', 'matrix', 'agents', 'refiner', 'doctor'],\n description:\n 'Which section to show: all (everything), providers (configured providers + keys), ' +\n 'models (favorites + leader), fallbacks (chain + profiles + toggles), ' +\n 'matrix (per-role assignments), agents (every catalog agent with resolved model), ' +\n 'refiner (goal refinement config), doctor (validate config and show issues/warnings). ' +\n 'Default: all.',\n },\n },\n additionalProperties: false,\n};\n\ninterface SystemConfigViewInput {\n section?: 'all' | 'providers' | 'models' | 'fallbacks' | 'matrix' | 'agents' | 'refiner' | 'doctor' | undefined;\n}\n\ninterface SystemConfigViewOutput {\n status: 'ok';\n message: string;\n}\n\nfunction createSystemConfigViewTool(opts: FallbackManageToolOptions): Tool<SystemConfigViewInput, SystemConfigViewOutput> {\n return {\n name: SYSTEM_CONFIG_VIEW_TOOL_NAME,\n description:\n 'Get a comprehensive view of all provider, model, fallback, and matrix configuration. ' +\n 'Shows the complete state across all configurable areas so you can see what is available ' +\n 'and make informed decisions when assigning models, creating fallback profiles, or ' +\n 'managing providers. Use the section parameter to focus on specific areas.',\n usageHint:\n '\"section: all\" for everything. \"section: providers\" for configured providers and key status. ' +\n '\"section: models\" for leader model and favorites. ' +\n '\"section: fallbacks\" for chains, profiles, and toggles. ' +\n '\"section: matrix\" for per-role assignments. ' +\n '\"section: refiner\" for goal refinement config.',\n category: 'Config',\n inputSchema: SYSTEM_CONFIG_VIEW_SCHEMA,\n permission: 'auto',\n mutating: false,\n riskTier: 'safe',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const section = input.section ?? 'all';\n const sections: string[] = [];\n const addSection = (title: string, content: string) => {\n sections.push(`\u2500\u2500 ${title} \u2500\u2500\\n${content}`);\n };\n\n // Always show provider/model header\n addSection(\n 'Leader',\n ` ${config.provider}/${config.model}`,\n );\n\n if (section === 'all' || section === 'providers') {\n const providers = (config.providers ?? {}) as unknown as Record<string, Record<string, unknown>>;\n const ids = Object.keys(providers);\n if (ids.length === 0) {\n addSection('Providers', ' (none configured)');\n } else {\n const lines = ids.sort().map((id) => {\n const e = providers[id] ?? {};\n const type = (e.type as string) ?? '?';\n const models = Array.isArray(e.models) ? `[${(e.models as string[]).join(', ')}]` : '(all)';\n const hasKey = e.apiKey || (Array.isArray(e.apiKeys) && e.apiKeys.length > 0) ? '\u2713' : '\u2717';\n const baseUrl = e.baseUrl ? ` url:${e.baseUrl}` : '';\n const family = e.family ? ` family:${e.family}` : '';\n const envVars = Array.isArray(e.envVars) ? ` env:[${(e.envVars as string[]).join(', ')}]` : '';\n return ` ${id === config.provider ? '\u2605' : ' '} ${id} (${type}) key:${hasKey} models:${models}${baseUrl}${family}${envVars}`;\n });\n addSection('Providers', lines.join('\\n'));\n }\n }\n\n if (section === 'all' || section === 'models') {\n const favorites = config.favoriteModels ?? [];\n addSection(\n 'Favorites',\n favorites.length > 0\n ? favorites.map((f, i) => ` ${i + 1}. ${f}`).join('\\n')\n : ' (none \u2014 use favorite_manage to add)',\n );\n addSection(\n 'Settings',\n ` fallbackAuto: ${config.fallbackAuto !== false ? 'on' : 'off'}\\n` +\n ` favoriteModelsOnly: ${config.favoriteModelsOnly ? 'on' : 'off'}`,\n );\n }\n\n if (section === 'all' || section === 'fallbacks') {\n const fallbackModels = config.fallbackModels ?? [];\n const profiles = (config.fallbackProfiles ?? {}) as Record<string, string[]>;\n addSection(\n 'Fallback Chain',\n fallbackModels.length > 0\n ? fallbackModels.map((f, i) => ` ${i + 1}. ${f}`).join('\\n')\n : ' (empty \u2014 auto fallback applies when fallbackAuto is on)',\n );\n const profileNames = Object.keys(profiles);\n addSection(\n 'Fallback Profiles',\n profileNames.length > 0\n ? profileNames.sort().map((n) => ` ${n} \u2192 ${profiles[n]?.join(' \u2192 ') ?? '(empty)'}`).join('\\n')\n : ' (none)',\n );\n }\n\n if (section === 'all' || section === 'matrix') {\n const matrix = (config.modelMatrix ?? {}) as Record<string, Record<string, unknown>>;\n const keys = Object.keys(matrix);\n addSection(\n 'Model Matrix (role assignments)',\n keys.length > 0\n ? keys.sort().map((k) => ` ${k} \u2192 ${JSON.stringify(matrix[k])}`).join('\\n')\n : ' (empty \u2014 all roles use the leader model)',\n );\n }\n\n if (section === 'all' || section === 'agents') {\n const roleNames = Object.keys(AGENT_CATALOG).sort();\n const lines = roleNames.map((role) => {\n const phase = phaseForRole(role) ?? '?';\n const target = resolveSubagentModelTarget(config, role);\n const model = target?.provider\n ? `${target.provider}/${target.model ?? '(default)'}`\n : `${config.provider}/${config.model ?? '(leader)'}`;\n const src = target?.diversified\n ? ' (diversified)'\n : target?.source === 'matrix'\n ? ` (matrix:${target.matrixSource ?? '?'})`\n : '';\n return ` ${role.padEnd(24)} ${phase.padEnd(14)} ${model}${src}`;\n });\n addSection(\n `Agent Models (${roleNames.length} roles)`,\n lines.length > 0\n ? ` ${'ROLE'.padEnd(24)} ${'PHASE'.padEnd(14)} RESOLVED MODEL\\n` + lines.join('\\n')\n : ' (no agents in catalog)',\n );\n }\n\n if (section === 'all' || section === 'doctor') {\n const issues: string[] = [];\n const warnings: string[] = [];\n const ok: string[] = [];\n const providers = (config.providers ?? {}) as unknown as Record<string, Record<string, unknown>>;\n const favorites = config.favoriteModels ?? [];\n const profiles = (config.fallbackProfiles ?? {}) as Record<string, string[]>;\n const chain = config.fallbackModels ?? [];\n const matrix = (config.modelMatrix ?? {}) as Record<string, Record<string, unknown>>;\n\n // 1. Check favorites against provider model lists\n for (const fav of favorites) {\n const p = parseRefInternal(fav);\n const provId = p.provider ?? config.provider;\n const model = p.model;\n const prov = providers[provId];\n if (!prov) {\n warnings.push(`Favorite \"${fav}\" references unknown provider \"${provId}\"`);\n continue;\n }\n const provModels = prov.models as string[] | undefined;\n if (provModels && provModels.length > 0 && !provModels.includes(model)) {\n warnings.push(`Favorite \"${fav}\" \u2014 model \"${model}\" not in ${provId} model list (${provModels.join(', ')})`);\n } else {\n ok.push(`Favorite \"${fav}\" \u2014 provider ${provId} is configured`);\n }\n }\n\n // 2. Check fallback chain entries\n for (const entry of chain) {\n const p = parseRefInternal(entry);\n const provId = p.provider ?? config.provider;\n if (!providers[provId] && provId !== config.provider) {\n issues.push(`Chain entry \"${entry}\" references unknown provider \"${provId}\"`);\n } else {\n ok.push(`Chain entry \"${entry}\" \u2014 provider OK`);\n }\n }\n\n // 3. Check fallback profile entries\n for (const [pname, pchain] of Object.entries(profiles)) {\n if (!pchain || pchain.length === 0) {\n warnings.push(`Profile \"${pname}\" is empty`);\n continue;\n }\n for (const entry of pchain) {\n const p = parseRefInternal(entry);\n const provId = p.provider ?? config.provider;\n if (!providers[provId] && provId !== config.provider) {\n issues.push(`Profile \"${pname}\" entry \"${entry}\" references unknown provider \"${provId}\"`);\n }\n }\n }\n\n // 4. Check matrix assignments\n for (const [key, entry] of Object.entries(matrix)) {\n const eProvider = (entry.provider as string) ?? config.provider;\n const eModel = entry.model as string | undefined;\n if (eModel) {\n const provData = providers[eProvider];\n if (!provData && eProvider !== config.provider) {\n issues.push(`Matrix \"${key}\" references unknown provider \"${eProvider}\"`);\n }\n const provModels = provData?.models as string[] | undefined;\n if (provModels && provModels.length > 0 && !provModels.includes(eModel)) {\n warnings.push(`Matrix \"${key}\" \u2014 model \"${eModel}\" not in ${eProvider} model list`);\n }\n }\n // Check fallbackProfile reference\n const eProfile = entry.fallbackProfile as string | undefined;\n if (eProfile && !profiles[eProfile]) {\n issues.push(`Matrix \"${key}\" references unknown fallback profile \"${eProfile}\"`);\n }\n }\n\n // 5. Check leader provider\n if (!providers[config.provider] && Object.keys(providers).length > 0) {\n warnings.push(`Leader provider \"${config.provider}\" has no explicit config entry`);\n }\n\n // 6. Summary\n const summary = ` \u2713 ${ok.length} checks passed\\n` +\n ` \u26A0 ${warnings.length} warnings\\n` +\n ` \u2717 ${issues.length} issues`;\n const lines: string[] = [summary, ''];\n if (warnings.length > 0) {\n lines.push('\u2500\u2500 Warnings \u2500\u2500');\n lines.push(...warnings.map((w) => ` \u26A0 ${w}`));\n lines.push('');\n }\n if (issues.length > 0) {\n lines.push('\u2500\u2500 Issues \u2500\u2500');\n lines.push(...issues.map((i) => ` \u2717 ${i}`));\n lines.push('');\n }\n if (warnings.length === 0 && issues.length === 0 && ok.length > 0) {\n lines.push(' All checks passed \u2014 configuration is healthy.');\n }\n addSection('Configuration Doctor', lines.join('\\n'));\n }\n\n if (section === 'all' || section === 'refiner') {\n const ref = config.autonomy;\n addSection(\n 'Goal Refinement',\n ` refinerProvider: ${ref?.refinerProvider ?? '(same as leader)'}\\n` +\n ` refinerModel: ${ref?.refinerModel ?? '(default for provider)'}\\n` +\n ` refinerFallbackProfile: ${ref?.refinerFallbackProfile ?? '(none)'}`,\n );\n }\n\n return { status: 'ok', message: sections.join('\\n\\n') };\n },\n };\n}\n\n// \u2500\u2500 Factory \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Create all 8 provider/model/fallback management tools that LLMs can call.\n *\n * Register them all in the tool registry:\n * ```ts\n * const tools = createFallbackManageTools({ getConfig, updateConfig });\n * for (const tool of tools) toolRegistry.register(tool);\n * ```\n */\nexport function createFallbackManageTools(opts: FallbackManageToolOptions): Tool[] {\n return [\n createFavoriteManageTool(opts),\n createFallbackChainManageTool(opts),\n createFallbackProfileManageTool(opts),\n createAgentModelAssignTool(opts),\n createProviderManageTool(opts),\n createProviderKeySetTool(opts),\n createLeaderModelSetTool(opts),\n createSystemConfigViewTool(opts),\n ];\n}\n"],
5
- "mappings": ";AAIO,SAAS,cAAiB,OAA6B,OAAmB;AAC/E,MAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,UAAM,MAAM,IAAI,MAAM,QAAQ,YAAY,KAAK,mBAAmB,8BAA8B;AAChG,QAAI,OAAO;AACX,UAAM;AAAA,EACR;AACA,SAAO;AACT;;;ACPO,SAAS,eAAe,KAAsB;AACnD,SAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AACxD;;;ACKO,IAAM,mBAAmB;AAAA;AAAA,EAE9B,iBAAiB;AAAA;AAAA,EAGjB,kBAAkB;AAAA;AAAA,EAGlB,YAAY;AAAA;AAAA,EAGZ,SAAS;AAAA;AAAA,EAGT,UAAU;AAAA;AAAA,EAGV,0BAA0B;AAAA;AAAA,EAG1B,cAAc;AAAA;AAAA,EAGd,cAAc;AAAA;AAAA,EAGd,cAAc;AAAA;AAAA,EAGd,WAAW;AAAA;AAAA,EAGX,iBAAiB;AAAA;AAAA,EAGjB,aAAa;AAAA;AAAA,EAGb,cAAc;AAAA;AAAA,EAGd,eAAe;AAAA;AAAA,EAGf,WAAW;AAAA;AAAA,EAGX,gBAAgB;AAAA;AAAA,EAGhB,yBAAyB;AAAA;AAAA,EAGzB,yBAAyB;AAAA;AAAA,EAGzB,4BAA4B;AAAA;AAAA,EAG5B,mBAAmB;AAAA;AAAA,EAGnB,mBAAmB;AAAA;AAAA,EAGnB,eAAe;AAAA;AAAA,EAGf,iBAAiB;AACnB;AASO,IAAM,0BAAqD;AAAA,EAChE,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AACnB;AAoBO,IAAM,6BAAwD;AAAA,EACnE,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA;AAAA;AAAA,EAGjB,iBAAiB;AAAA,EACjB,iBAAiB;AACnB;;;ACxHO,IAAM,mBAAmB,OAAwB;AAAA,EACtD,MAAM;AAAA,EACN,aAAa;AAAA,EACb,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM,CAAC,MAAM,2CAA2C,GAAG;AAAA,EAC3D,YAAY;AACd;AAGO,IAAM,eAAe,OAAwB;AAAA,EAClD,MAAM;AAAA,EACN,aACE;AAAA,EACF,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM,CAAC,MAAM,qCAAqC;AAAA,EAClD,gBAAgB,CAAC,gCAAgC,cAAc;AAAA,EAC/D,YAAY;AACd;AAMO,IAAM,iBAAiB,OAAwB;AAAA,EACpD,MAAM;AAAA,EACN,aAAa;AAAA,EACb,WAAW;AAAA,EACX,KAAK;AAAA,EACL,YAAY;AACd;AAOO,IAAM,oBAAoB,OAAwB;AAAA,EACvD,MAAM;AAAA,EACN,aAAa;AAAA,EACb,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM,CAAC,MAAM,2CAA2C;AAAA,EACxD,gBAAgB,CAAC,sBAAsB;AAAA,EACvC,YAAY;AACd;AAMO,IAAM,cAAc,OAAwB;AAAA,EACjD,MAAM;AAAA,EACN,aAAa;AAAA,EACb,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM,CAAC,MAAM,oCAAoC;AAAA,EACjD,YAAY;AACd;AAMO,IAAM,gBAAgB,OAAwB;AAAA,EACnD,MAAM;AAAA,EACN,aAAa;AAAA,EACb,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM,CAAC,MAAM,sCAAsC;AAAA,EACnD,gBAAgB,CAAC,iBAAiB;AAAA,EAClC,YAAY;AACd;AAMO,IAAM,cAAc,OAAwB;AAAA,EACjD,MAAM;AAAA,EACN,aAAa;AAAA,EACb,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM,CAAC,MAAM,oCAAoC;AAAA,EACjD,gBAAgB,CAAC,mBAAmB,eAAe;AAAA,EACnD,YAAY;AACd;AAMO,IAAM,YAAY,OAAwB;AAAA,EAC/C,MAAM;AAAA,EACN,aAAa;AAAA,EACb,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM,CAAC,MAAM,kCAAkC;AAAA,EAC/C,gBAAgB,CAAC,qBAAqB,yBAAyB,cAAc,mBAAmB;AAAA,EAChG,YAAY;AACd;AAMO,IAAM,mBAAmB,OAAwB;AAAA,EACtD,MAAM;AAAA,EACN,aAAa;AAAA,EACb,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM,CAAC,MAAM,0CAA0C;AAAA,EACvD,gBAAgB,CAAC,qBAAqB;AAAA,EACtC,YAAY;AACd;AAGO,IAAM,iBAAiB,OAAwB;AAAA,EACpD,MAAM;AAAA,EACN,aAAa;AAAA,EACb,WAAW;AAAA,EACX,KAAK;AAAA,EACL,YAAY;AAAA;AACd;AAMO,IAAM,kBAAkB,OAAwB;AAAA,EACrD,MAAM;AAAA,EACN,aAAa;AAAA,EACb,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM,CAAC,MAAM,yBAAyB;AAAA,EACtC,KAAK,EAAE,WAAW,MAAM;AAAA,EACxB,gBAAgB,CAAC,cAAc;AAAA,EAC/B,cAAc;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,YAAY;AACd;AAQO,IAAM,mBAAmB,OAAwB;AAAA,EACtD,MAAM;AAAA,EACN,aACE;AAAA,EACF,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM,CAAC,MAAM,yCAAyC;AAAA,EACtD,YAAY;AACd;AAOO,IAAM,sBAAsB,OAAwB;AAAA,EACzD,MAAM;AAAA,EACN,aAAa;AAAA,EACb,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM,CAAC,2BAA2B,IAAI;AAAA,EACtC,KAAK;AAAA,IACH,uBAAuB;AAAA,IACvB,kBAAkB;AAAA,IAClB,2BAA2B;AAAA,EAC7B;AAAA,EACA,gBAAgB,CAAC,iBAAiB;AAAA,EAClC,cAAc,CAAC,kBAAkB;AAAA,EACjC,YAAY;AACd;AAOO,IAAM,mBAAmB,OAAwB;AAAA,EACtD,MAAM;AAAA,EACN,aACE;AAAA,EACF,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM,CAAC,MAAM,iBAAiB;AAAA,EAC9B,KAAK;AAAA,IACH,sBAAsB;AAAA,IACtB,yBAAyB;AAAA,EAC3B;AAAA,EACA,YAAY;AAAA,EACZ,kBAAkB;AACpB;AAGO,IAAM,aAAa,OAAwC;AAAA,EAChE,YAAY,EAAE,GAAG,iBAAiB,GAAG,SAAS,MAAM;AAAA,EACpD,QAAQ,EAAE,GAAG,aAAa,GAAG,SAAS,MAAM;AAAA,EAC5C,UAAU,EAAE,GAAG,eAAe,GAAG,SAAS,MAAM;AAAA,EAChD,gBAAgB,EAAE,GAAG,kBAAkB,GAAG,SAAS,MAAM;AAAA,EACzD,OAAO,EAAE,GAAG,YAAY,GAAG,SAAS,MAAM;AAAA,EAC1C,SAAS,EAAE,GAAG,cAAc,GAAG,SAAS,MAAM;AAAA,EAC9C,OAAO,EAAE,GAAG,YAAY,GAAG,SAAS,MAAM;AAAA,EAC1C,KAAK,EAAE,GAAG,UAAU,GAAG,SAAS,MAAM;AAAA,EACtC,eAAe,EAAE,GAAG,iBAAiB,GAAG,SAAS,MAAM;AAAA,EACvD,UAAU,EAAE,GAAG,eAAe,GAAG,SAAS,MAAM;AAAA,EAChD,cAAc,EAAE,GAAG,gBAAgB,GAAG,SAAS,MAAM;AAAA,EACrD,kBAAkB,EAAE,GAAG,oBAAoB,GAAG,SAAS,MAAM;AAAA,EAC7D,YAAY,EAAE,GAAG,iBAAiB,GAAG,SAAS,MAAM;AAAA,EACpD,KAAK,EAAE,GAAG,iBAAiB,GAAG,SAAS,MAAM;AAC/C;;;AC/OA,YAAYA,SAAQ;;;ACApB,SAAS,mBAAmB;AAC5B,YAAY,QAAQ;AAGpB,YAAY,UAAU;;;ACuEf,SAAS,YAAY,GAAiC;AAC3D,SAAO,EAAE,SAAS;AACpB;;;ACrEO,SAAS,SAAS,GAAW,KAAqB;AACvD,SAAO,EAAE,UAAU,MAAM,IAAI,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AACrD;;;ACcO,IAAM,cAAc;AAAA;AAAA,EAEzB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,qBAAqB;AAAA,EACrB,0BAA0B;AAAA,EAC1B,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA;AAAA,EAE3B,gBAAgB;AAAA,EAChB,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,cAAc;AAAA,EACd,oBAAoB;AAAA;AAAA,EAEpB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,yBAAyB;AAAA;AAAA,EAEzB,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,2BAA2B;AAAA;AAAA,EAE3B,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,eAAe;AAAA,EACf,kBAAkB;AAAA;AAAA,EAElB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,sBAAsB;AAAA;AAAA,EAEtB,+BAA+B;AAAA,EAC/B,2BAA2B;AAAA,EAC3B,+BAA+B;AAAA,EAC/B,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,kBAAkB;AAAA;AAAA,EAElB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,wBAAwB;AAAA;AAAA,EAExB,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,eAAe;AAAA;AAAA,EAEf,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,SAAS;AACX;AAwBO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,MAQT;AACD,UAAM,KAAK,SAAS,EAAE,OAAO,KAAK,MAAM,CAAC;AACzC,SAAK,OAAO;AACZ,SAAK,OAAO,KAAK;AACjB,SAAK,YAAY,KAAK;AACtB,SAAK,WAAW,KAAK,YAAY;AACjC,SAAK,cAAc,KAAK,eAAe;AACvC,SAAK,UAAU,KAAK;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAmB;AACjB,UAAM,MAAM,KAAK,UAAU,IAAI,cAAc,KAAK,OAAO,CAAC,KAAK;AAC/D,WAAO,GAAG,KAAK,IAAI,KAAK,KAAK,OAAO,GAAG,GAAG;AAAA,EAC5C;AACF;AAEA,SAAS,cAAc,KAAsC;AAC3D,QAAM,QAAQ,OAAO,QAAQ,GAAG,EAC7B,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS,EACjC,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC,EAAE;AACtC,SAAO,MAAM,SAAS,IAAI,IAAI,MAAM,KAAK,GAAG,CAAC,MAAM;AACrD;;;AH/HA,eAAsB,YACpB,YACA,SACA,OAA2B,CAAC,GACb;AACf,QAAM,MAAW,aAAQ,UAAU;AACnC,QAAS,SAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AACvC,QAAM,MAAW,UAAK,KAAK,IAAS,cAAS,UAAU,CAAC,IAAI,YAAY,CAAC,EAAE,SAAS,KAAK,CAAC,MAAM;AAIhG,MAAI;AACF,QAAI,OAAO,YAAY,UAAU;AAC/B,YAAS,aAAU,KAAK,SAAS,EAAE,MAAM,MAAM,UAAU,KAAK,YAAY,OAAO,CAAC;AAAA,IACpF,OAAO;AACL,YAAS,aAAU,KAAK,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,IACjD;AACA,QAAI;AACF,YAAM,KAAK,MAAS,QAAK,KAAK,IAAI;AAClC,UAAI;AACF,cAAM,GAAG,KAAK;AAAA,MAChB,UAAE;AACA,cAAM,GAAG,MAAM;AAAA,MACjB;AAAA,IACF,QAAQ;AAAA,IAER;AAGA,QAAI;AACJ,QAAI;AACF,YAAMC,QAAO,MAAS,QAAK,UAAU;AACrC,aAAOA,MAAK,OAAO;AAAA,IACrB,QAAQ;AACN,aAAO,KAAK;AAAA,IACd;AACA,QAAI,SAAS,QAAW;AACtB,YAAS,SAAM,KAAK,IAAI;AAAA,IAC1B;AACA,UAAM,gBAAgB,KAAK,UAAU;AASrC,QAAI,SAAS,UAAa,QAAQ,aAAa,SAAS;AACtD,UAAI;AACF,cAAS,SAAM,YAAY,IAAI;AAAA,MACjC,QAAQ;AAAA,MAGR;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,QAAI;AACF,YAAS,UAAO,GAAG;AAAA,IACrB,QAAQ;AAAA,IAER;AACA,UAAM;AAAA,EACR;AACF;AA+JA,IAAM,yBAAyB,oBAAI,IAAI,CAAC,SAAS,SAAS,UAAU,WAAW,CAAC;AAEhF,eAAe,gBAAgB,MAAc,IAA2B;AACtE,MAAI,QAAQ,aAAa,SAAS;AAChC,UAAS,UAAO,MAAM,EAAE;AACxB;AAAA,EACF;AACA,QAAM,SAAS,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG;AACpC,MAAI;AACJ,WAAS,IAAI,GAAG,KAAK,OAAO,QAAQ,KAAK;AACvC,QAAI;AACF,YAAS,UAAO,MAAM,EAAE;AACxB;AAAA,IACF,SAAS,KAAK;AACZ,gBAAU;AACV,YAAM,OAAQ,KAA+B;AAC7C,UAAI,CAAC,QAAQ,CAAC,uBAAuB,IAAI,IAAI,KAAK,MAAM,OAAO,QAAQ;AACrE,cAAM;AAAA,MACR;AACA,YAAM,IAAI,QAAQ,CAACC,aAAY,WAAWA,UAAS,OAAO,CAAC,CAAC,CAAC;AAAA,IAC/D;AAAA,EACF;AACA,QAAM;AACR;;;ADhQA,eAAsB,mBAAmB,UAAuC;AAC9E,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,MAAS,aAAS,UAAU,MAAM,CAAC;AAC7D,WAAO,aAAa,MAAM,IAAI,SAAS,CAAC;AAAA,EAC1C,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAWA,eAAsB,oBAAoB,UAAkB,OAAkC;AAC5F,QAAM,YAAY,UAAU,KAAK,UAAU,OAAO,MAAM,CAAC,GAAG,EAAE,MAAM,IAAM,CAAC;AAC7E;AAEA,eAAsB,qBACpB,UACA,SACqB;AACrB,QAAM,SAAS,MAAM,mBAAmB,QAAQ;AAChD,QAAM,YAAY,MAAM,QAAQ,MAAM;AACtC,QAAM,OAAO,aAAa,aAAa,SAAS,IAAI,YAAY;AAChE,QAAM,oBAAoB,UAAU,IAAI;AACxC,SAAO;AACT;AAgBO,SAAS,YAAY,MAAkBC,OAAgB,OAA4B;AACxF,MAAIA,MAAK,WAAW,GAAG;AACrB,QAAI,CAAC,aAAa,KAAK,EAAG,OAAM,IAAI,MAAM,qCAAqC;AAC/E,WAAO;AAAA,EACT;AACA,QAAM,SAAS,iBAAiB,MAAMA,KAAI;AAC1C,QAAM,OAAO,gBAAgBA,KAAI;AACjC,MAAI,OAAO,SAAS,UAAU;AAC5B,QAAI,CAAC,MAAM,QAAQ,MAAM,EAAG,OAAM,IAAI,MAAM,8BAA8B,IAAI,sBAAsB;AACpG,WAAO,IAAI,IAAI;AAAA,EACjB,OAAO;AACL,QAAI,CAAC,aAAa,MAAM,EAAG,OAAM,IAAI,MAAM,uBAAuB,IAAI,uBAAuB;AAC7F,WAAO,IAAI,IAAI;AAAA,EACjB;AACA,SAAO;AACT;AA0BO,SAAS,aAAa,OAAqC;AAChE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,gBAAgBC,OAAiC;AACxD,QAAM,UAAUA,MAAKA,MAAK,SAAS,CAAC;AAEpC,MAAI,YAAY,OAAW,OAAM,IAAI,MAAM,yBAAyB;AACpE,SAAO;AACT;AAEA,SAAS,iBAAiB,MAAkBA,OAAwC;AAClF,MAAI,UAAkC;AACtC,WAAS,IAAI,GAAG,IAAIA,MAAK,SAAS,GAAG,KAAK,GAAG;AAC3C,UAAM,UAAUA,MAAK,CAAC;AACtB,UAAM,cAAcA,MAAK,IAAI,CAAC;AAE9B,QAAI,YAAY,OAAW,OAAM,IAAI,MAAM,iCAAiC;AAC5E,UAAM,gBAAgB,OAAO,gBAAgB,WAAW,CAAC,IAAI,CAAC;AAE9D,QAAI,OAAO,YAAY,UAAU;AAC/B,UAAI,CAAC,MAAM,QAAQ,OAAO,EAAG,OAAM,IAAI,MAAM,mCAAmC,OAAO,sBAAsB;AAC7G,UAAI,CAAC,aAAa,QAAQ,OAAO,CAAC,KAAK,CAAC,MAAM,QAAQ,QAAQ,OAAO,CAAC,EAAG,SAAQ,OAAO,IAAI;AAC5F,gBAAU,QAAQ,OAAO;AAAA,IAC3B,OAAO;AACL,UAAI,CAAC,aAAa,OAAO,EAAG,OAAM,IAAI,MAAM,4BAA4B,OAAO,uBAAuB;AACtG,UAAI,CAAC,aAAa,QAAQ,OAAO,CAAC,KAAK,CAAC,MAAM,QAAQ,QAAQ,OAAO,CAAC,EAAG,SAAQ,OAAO,IAAI;AAC5F,gBAAU,QAAQ,OAAO;AAAA,IAC3B;AAAA,EACF;AACA,SAAO;AACT;;;AK5DO,SAAS,qBAAqB,MAAyC;AAC5E,QAAM,EAAE,WAAW,YAAY,SAAS,IAAI;AAE5C,QAAM,cAA0B;AAAA,IAC9B,MAAM;AAAA,IACN,YAAY;AAAA,MACV,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,MAAM,CAAC,QAAQ,UAAU,UAAU,WAAW,WAAW,YAAY,YAAY;AAAA,QACjF,aAAa;AAAA,MACf;AAAA;AAAA,MAEA,OAAO;AAAA,QACL,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA;AAAA,MAEA,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,UAAU,CAAC,QAAQ;AAAA,EACrB;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aACE;AAAA,IACF,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOV,UAAU;AAAA,IACV,cAAc,CAAC,iBAAiB,aAAa;AAAA,IAC7C;AAAA,IACA,MAAM,QAAQ,KAAK;AACjB,YAAM,QAAQ;AACd,aAAO,mBAAmB,OAAO,EAAE,WAAW,YAAY,SAAS,CAAC;AAAA,IACtE;AAAA,EACF;AACF;AAIA,eAAe,mBACb,OACA,MACiB;AACjB,QAAM,EAAE,QAAQ,OAAO,OAAO,IAAI;AAElC,UAAQ,QAAQ;AAAA,IACd,KAAK;AAAS,aAAO,WAAW,IAAI;AAAA,IACpC,KAAK;AAAU,aAAO,aAAa,SAAS,IAAI,IAAI;AAAA,IACpD,KAAK;AAAU,aAAO,SAAS,UAAU,QAAQ,IAAI,IAAI;AAAA,IACzD,KAAK;AAAW,aAAO,SAAS,WAAW,QAAQ,IAAI,IAAI;AAAA,IAC3D,KAAK;AAAW,aAAO,SAAS,WAAW,QAAQ,IAAI,IAAI;AAAA,IAC3D,KAAK;AAAY,aAAO,SAAS,YAAY,QAAQ,IAAI,IAAI;AAAA,IAC7D,KAAK;AAAc,aAAO,SAAS,cAAc,QAAQ,IAAI,IAAI;AAAA,IACjE;AACE,aAAO,mBAAmB,MAAM;AAAA,EACpC;AACF;AAIA,eAAe,WAAW,MAAqG;AAC7H,QAAM,aAAa,MAAM,wBAAwB,IAAI;AACrD,QAAM,OAAO,KAAK,SAAS,SAAS;AAEpC,MAAI,OAAO,KAAK,UAAU,EAAE,WAAW,GAAG;AACxC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,UAAU,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAEpD,aAAW,CAAC,MAAM,GAAG,KAAK,OAAO,QAAQ,UAAU,GAAG;AACpD,UAAM,WAAW,QAAQ,IAAI,IAAI;AACjC,UAAM,YAAY,WAAW,KAAK,SAAS,SAAS,YAAY;AAChE,UAAM,WAAW,WAAW,MAAM,SAAS,KAAK,IAAI,IAAI,mBAAc;AACtE,UAAM,UAAU,IAAI,YAAY,QAC5B,GAAG,IAAI,UAAU,CAAC,OAClB,GAAG,MAAM,gBAAW,CAAC;AACzB,UAAM,KAAK,KAAK,KAAK,IAAI,CAAC,KAAK,OAAO,GAAG,QAAQ,GAAG,SAAS,EAAE;AAC/D,QAAI,IAAI,YAAa,OAAM,KAAK,OAAO,IAAI,IAAI,WAAW,CAAC,EAAE;AAAA,EAC/D;AAEA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,IAAI,gFAAgF,CAAC;AAChG,QAAM,KAAK,IAAI,gFAAgF,CAAC;AAChG,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,eAAe,aACb,OACA,MACiB;AACjB,QAAM,aAAa,MAAM,wBAAwB,IAAI;AACrD,QAAM,MAAM,WAAW;AACvB,QAAM,IAAI,MAAM,YAAY;AAE5B,QAAM,kBAAkB,IAAI,IAAI,OAAO,KAAK,UAAU,CAAC;AAGvD,QAAM,oBAAoB,OAAO,QAAQ,UAAU,EAAE;AAAA,IACnD,CAAC,CAAC,MAAM,GAAG,MACT,KAAK,YAAY,EAAE,SAAS,CAAC,MAC5B,IAAI,eAAe,IAAI,YAAY,EAAE,SAAS,CAAC;AAAA,EACpD;AAEA,QAAM,sBAAsB,OAAO,QAAQ,GAAG,EAC3C,OAAO,CAAC,CAAC,IAAI,MAAM,CAAC,gBAAgB,IAAI,IAAI,CAAC,EAC7C;AAAA,IACC,CAAC,CAAC,MAAM,GAAG,MACT,KAAK,YAAY,EAAE,SAAS,CAAC,MAC5B,IAAI,eAAe,IAAI,YAAY,EAAE,SAAS,CAAC;AAAA,EACpD;AAEF,QAAM,QAAkB,CAAC;AAEzB,MAAI,kBAAkB,SAAS,GAAG;AAChC,UAAM,KAAK,KAAK,+BAA+B,IAAI,QAAQ,IAAI;AAC/D,eAAW,CAAC,MAAM,GAAG,KAAK,mBAAmB;AAC3C,YAAM,KAAK,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,eAAe,IAAI,SAAS,EAAE;AAAA,IACnE;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,oBAAoB,SAAS,GAAG;AAClC,UAAM,KAAK,KAAK,8BAA8B,IAAI,QAAQ,IAAI;AAC9D,eAAW,CAAC,MAAM,GAAG,KAAK,qBAAqB;AAC7C,YAAM,OAAO,IAAI,eAAe,SAAS,IAAI,0BAAqB,IAAI;AACtE,YAAM,KAAK,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,eAAe,IAAI,SAAS,GAAG,IAAI,EAAE;AAAA,IAC1E;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,kBAAkB,WAAW,KAAK,oBAAoB,WAAW,GAAG;AACtE,WAAO,qBAAqB,KAAK;AAAA,EACnC;AAEA,QAAM,QAAQ,kBAAkB,SAAS,oBAAoB;AAC7D,QAAM,KAAK,IAAI,KAAK,KAAK,UAAU,UAAU,IAAI,MAAM,EAAE,+CAA+C,CAAC;AACzG,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,eAAe,UACb,MACA,MACiB;AACjB,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,MAAM,WAAW;AACvB,QAAM,aAAa,KAAK,UAAU,EAAE,cAAc,CAAC;AAGnD,QAAM,MAAM,WAAW,IAAI,KAAK,IAAI,IAAI;AACxC,MAAI,CAAC,KAAK;AACR,UAAM,QAAQ,OAAO,KAAK,GAAG,EAAE,KAAK,IAAI;AACxC,WAAO,mBAAmB,IAAI,yBAAyB,KAAK;AAAA,EAC9D;AAGA,QAAM,qBAAqB,KAAK,YAAY,CAAC,SAAS;AACpD,UAAM,UAAU,kBAAkB,KAAK,UAAU,IAAI,KAAK,aAAa,CAAC;AACxE,gBAAY,MAAM,CAAC,cAAc,IAAI,GAAG,EAAE,GAAG,QAAQ,IAAI,GAAG,GAAG,KAAK,SAAS,KAAK,CAAC;AAAA,EACrF,CAAC;AAGD,MAAI;AACF,UAAM,OAAO,KAAK,SAAS,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACjE,QAAI,QAAQ,KAAK,UAAU,aAAa;AACtC,aAAO,GAAG,MAAM,QAAG,CAAC,YAAY,IAAI,yBAAyB,KAAK,SAAS;AAAA,IAC7E;AACA,UAAM,KAAK,SAAS,MAAM,EAAE,GAAG,KAAK,SAAS,KAAK,CAAC;AACnD,UAAM,UAAU,KAAK,SAAS,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACpE,WAAO,GAAG,MAAM,4BAAuB,CAAC,KAAK,IAAI,IAAI,UAAU,KAAK,QAAQ,SAAS,wBAAwB,GAAG;AAAA,EAClH,SAAS,KAAK;AACZ,WAAO,GAAG,IAAI,wBAAmB,CAAC,KAAK,IAAI,MAAM,eAAe,GAAG,CAAC;AAAA,EACtE;AACF;AAEA,eAAe,WACb,MACA,MACiB;AACjB,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,aAAa,KAAK,UAAU,EAAE,cAAc,CAAC;AACnD,MAAI,CAAC,WAAW,IAAI,GAAG;AACrB,WAAO,WAAW,IAAI,8EAA8E,IAAI;AAAA,EAC1G;AAGA,QAAM,qBAAqB,KAAK,YAAY,CAAC,SAAS;AACpD,UAAM,UAAU,kBAAkB,KAAK,UAAU,IAAI,KAAK,aAAa,CAAC;AACxE,UAAM,WAAW,cAAc,QAAQ,IAAI,CAAC;AAC5C,gBAAY,MAAM,CAAC,cAAc,IAAI,GAAG,EAAE,GAAG,UAAU,SAAS,MAAM,CAAC;AAAA,EACzE,CAAC;AAGD,MAAI;AACF,UAAM,KAAK,SAAS,KAAK,IAAI;AAC7B,WAAO,GAAG,OAAO,iBAAY,CAAC,KAAK,IAAI;AAAA,EACzC,QAAQ;AACN,WAAO,GAAG,OAAO,iBAAY,CAAC,KAAK,IAAI;AAAA,EACzC;AACF;AAEA,eAAe,WACb,MACA,MACiB;AACjB,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,aAAa,KAAK,UAAU,EAAE,cAAc,CAAC;AACnD,MAAI,CAAC,WAAW,IAAI,GAAG;AACrB,WAAO,WAAW,IAAI,uEAAuE,IAAI;AAAA,EACnG;AAEA,MAAI;AACF,UAAM,KAAK,SAAS,QAAQ,IAAI;AAChC,UAAM,UAAU,KAAK,SAAS,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACpE,WAAO,GAAG,MAAM,kBAAa,CAAC,KAAK,IAAI,IAAI,UAAU,KAAK,QAAQ,SAAS,wBAAwB,GAAG;AAAA,EACxG,SAAS,KAAK;AACZ,WAAO,GAAG,IAAI,uBAAkB,CAAC,SAAS,IAAI,MAAM,eAAe,GAAG,CAAC;AAAA,EACzE;AACF;AAQA,eAAe,YACb,MACA,MACiB;AACjB,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,CAAC,KAAK,SAAS,gBAAgB;AACjC,WAAO,4EAA4E,IAAI;AAAA,EACzF;AACA,QAAM,OAAO,KAAK,SAAS,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACjE,MAAI,CAAC,MAAM;AACT,WAAO,WAAW,IAAI,uEAAuE,IAAI;AAAA,EACnG;AACA,MAAI,KAAK,UAAU,aAAa;AAC9B,WAAO,WAAW,IAAI,8BAA8B,KAAK,KAAK;AAAA,EAChE;AACA,MAAI,KAAK,SAAS,cAAc,IAAI,GAAG;AACrC,WAAO,GAAG,MAAM,QAAG,CAAC,YAAY,IAAI;AAAA,EACtC;AACA,OAAK,SAAS,eAAe,IAAI;AACjC,QAAM,UAAU,KAAK,SAAS,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACpE,SAAO,GAAG,MAAM,kBAAa,CAAC,KAAK,IAAI,YAAO,SAAS,aAAa,CAAC,+EAA+E,IAAI;AAC1J;AAMA,eAAe,cACb,MACA,MACiB;AACjB,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,CAAC,KAAK,SAAS,kBAAkB;AACnC,WAAO,8EAA8E,IAAI;AAAA,EAC3F;AACA,MAAI,CAAC,KAAK,SAAS,cAAc,IAAI,GAAG;AACtC,WAAO,WAAW,IAAI;AAAA,EACxB;AACA,QAAM,QAAQ,KAAK,SAAS,iBAAiB,IAAI;AACjD,SAAO,GAAG,OAAO,oBAAe,CAAC,KAAK,IAAI,YAAO,KAAK;AACxD;AAIA,eAAe,wBAAwB,MAAiG;AACtI,QAAM,aAAa,MAAM,mBAAmB,KAAK,UAAU;AAC3D,MAAI,kBAAkB,WAAW,UAAU,EAAG,QAAO,WAAW;AAChE,SAAO,KAAK,UAAU,EAAE,cAAc,CAAC;AACzC;AAEA,SAAS,kBAAkB,OAA0D;AACnF,SAAO,CAAC,CAAC,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AACrE;AAIA,SAAS,KAAK,GAAY;AAAE,SAAO,UAAU,CAAC;AAAW;AACzD,SAAS,IAAI,GAAY;AAAE,SAAO,UAAU,CAAC;AAAW;AACxD,SAAS,MAAM,GAAW;AAAE,SAAO,WAAW,CAAC;AAAW;AAC1D,SAAS,OAAO,GAAU;AAAE,SAAO,WAAW,CAAC;AAAW;AAC1D,SAAS,IAAI,GAAa;AAAE,SAAO,WAAW,CAAC;AAAW;AAE1D,SAAS,MAAM,OAAuB;AACpC,UAAQ,OAAO;AAAA,IACb,KAAK;AAAgB,aAAO,MAAM,kBAAa;AAAA,IAC/C,KAAK;AAAgB,aAAO;AAAA,IAC5B,KAAK;AAAgB,aAAO;AAAA,IAC5B,KAAK;AAAgB,aAAO,IAAI,qBAAgB;AAAA,IAChD,KAAK;AAAgB,aAAO,IAAI,eAAU;AAAA,IAC1C;AAAoB,aAAO,IAAI,KAAK;AAAA,EACtC;AACF;;;AC5XA,IAAM,gBAAgB;AAGf,IAAM,2BAAsD,OAAO,OAAO;AAAA,EAC/E,cAAc;AAAA,IACZ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aACE;AAAA,IACF,MAAM,CAAC,YAAY,eAAe,UAAU;AAAA,EAC9C,CAAC;AAAA,EACD,cAAc;AAAA,IACZ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aACE;AAAA,IACF,aAAa;AAAA,IACb,MAAM,CAAC,QAAQ,eAAe,eAAe;AAAA,EAC/C,CAAC;AAAA,EACD,cAAc;AAAA,IACZ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aACE;AAAA,IACF,MAAM,CAAC,QAAQ,YAAY,YAAY;AAAA,EACzC,CAAC;AAAA,EACD,cAAc;AAAA,IACZ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aACE;AAAA,IACF,aAAa;AAAA,IACb,MAAM,CAAC,YAAY,SAAS,aAAa;AAAA,EAC3C,CAAC;AAAA,EACD,cAAc;AAAA,IACZ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aACE;AAAA,IACF,MAAM,CAAC,eAAe,iBAAiB,YAAY;AAAA,EACrD,CAAC;AAAA,EACD,cAAc;AAAA,IACZ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aACE;AAAA,IACF,MAAM,CAAC,SAAS,aAAa,eAAe;AAAA,EAC9C,CAAC;AACH,CAAC;AAGM,IAAM,yBAAN,MAAM,wBAAuB;AAAA,EACjB;AAAA,EAEjB,YAAY,WAAsC,CAAC,GAAG;AACpD,UAAM,UAAU,oBAAI,IAA4B;AAChD,eAAW,WAAW,UAAU;AAC9B,YAAM,aAAa,cAAc,OAAO;AACxC,UAAI,QAAQ,IAAI,WAAW,EAAE,GAAG;AAC9B,cAAM,IAAI,MAAM,iDAAiD,WAAW,EAAE,IAAI;AAAA,MACpF;AACA,cAAQ,IAAI,WAAW,IAAI,UAAU;AAAA,IACvC;AACA,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,IAAI,IAAqB;AACvB,WAAO,KAAK,KAAK,IAAI,EAAE;AAAA,EACzB;AAAA,EAEA,IAAI,IAAwC;AAC1C,WAAO,KAAK,KAAK,IAAI,EAAE;AAAA,EACzB;AAAA,EAEA,QAAQ,IAA4B;AAClC,UAAM,UAAU,KAAK,IAAI,EAAE;AAC3B,QAAI,CAAC,QAAS,OAAM,IAAI,MAAM,4CAA4C,EAAE,IAAI;AAChF,WAAO;AAAA,EACT;AAAA,EAEA,OAAkC;AAChC,WAAO,OAAO,OAAO,CAAC,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC;AAAA,EAC9C;AAAA;AAAA,EAGA,KAAK,SAAyB,OAA0C,CAAC,GAA2B;AAClG,UAAM,aAAa,cAAc,OAAO;AACxC,QAAI,KAAK,IAAI,WAAW,EAAE,KAAK,KAAK,YAAY,MAAM;AACpD,YAAM,IAAI,MAAM,oCAAoC,WAAW,EAAE,mBAAmB;AAAA,IACtF;AACA,WAAO,IAAI,wBAAuB;AAAA,MAChC,GAAG,KAAK,KAAK,EAAE,OAAO,CAAC,UAAU,MAAM,OAAO,WAAW,EAAE;AAAA,MAC3D;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,IAAM,mCAAmC,IAAI;AAAA,EAClD;AACF;AAUA,SAAS,cAAc,SAAyC;AAC9D,QAAM,KAAK,QAAQ,GAAG,KAAK;AAC3B,QAAM,OAAO,QAAQ,KAAK,KAAK;AAC/B,QAAM,cAAc,QAAQ,YAAY,KAAK;AAC7C,QAAM,cAAc,QAAQ,YAAY,KAAK;AAC7C,MAAI,CAAC,cAAc,KAAK,EAAE,GAAG;AAC3B,UAAM,IAAI,MAAM,+CAA+C,QAAQ,EAAE,IAAI;AAAA,EAC/E;AACA,MAAI,CAAC,KAAM,OAAM,IAAI,MAAM,oCAAoC,EAAE,oBAAoB;AACrF,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,MAAM,oCAAoC,EAAE,2BAA2B;AAAA,EACnF;AACA,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,MAAM,oCAAoC,EAAE,4BAA4B;AAAA,EACpF;AACA,MACE,QAAQ,kBAAkB,WACzB,CAAC,OAAO,SAAS,QAAQ,aAAa,KAAK,QAAQ,iBAAiB,IACrE;AACA,UAAM,IAAI,MAAM,oCAAoC,EAAE,kCAAkC;AAAA,EAC1F;AACA,QAAM,OAAO,OAAO;AAAA,IAClB,CAAC,GAAG,IAAI,KAAK,QAAQ,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC;AAAA,EAC5E;AACA,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,QAAQ,kBAAkB,SAAY,EAAE,eAAe,QAAQ,cAAc,IAAI,CAAC;AAAA,IACtF,GAAI,QAAQ,gBAAgB,SAAY,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC;AAAA,IAChF,GAAI,KAAK,SAAS,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA,EACpC,CAAC;AACH;;;AC1IA,IAAM,gBAAgB;AACtB,IAAM,sBAAwD,oBAAI,IAAI;AAAA,EACpE;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,kCAAkC;AACxC,IAAM,oCAAoC;AAC1C,IAAM,mCAAmC;AACzC,IAAM,mCAAmC;AACzC,IAAM,sCAAsC;AAC5C,IAAM,qCAAqC;AAG3C,IAAM,2BAA4D,OAAO,OAAO;AAAA,EACrF,OAAO,OAAO;AAAA,IACZ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,OAAO,OAAO;AAAA,MACnB,OAAO,OAAO,EAAE,SAAS,YAAY,QAAQ,OAAO,OAAO,EAAE,MAAM,UAAU,CAAC,EAAE,CAAC;AAAA,MACjF,OAAO,OAAO,EAAE,SAAS,WAAW,QAAQ,OAAO,OAAO,EAAE,MAAM,SAAS,CAAC,EAAE,CAAC;AAAA,MAC/E,OAAO,OAAO,EAAE,SAAS,WAAW,QAAQ,OAAO,OAAO,EAAE,MAAM,UAAU,CAAC,EAAE,CAAC;AAAA,IAClF,CAAC;AAAA,IACD,OAAO,OAAO,OAAO,EAAE,MAAM,WAAW,CAAC;AAAA,IACzC,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,cAAc;AAAA,EAChB,CAAC;AAAA,EACD,OAAO,OAAO;AAAA,IACZ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,OAAO,OAAO;AAAA,MACnB,OAAO,OAAO,EAAE,SAAS,YAAY,QAAQ,OAAO,OAAO,EAAE,MAAM,UAAU,CAAC,EAAE,CAAC;AAAA,MACjF,OAAO,OAAO,EAAE,SAAS,WAAW,QAAQ,OAAO,OAAO,EAAE,MAAM,SAAS,CAAC,EAAE,CAAC;AAAA,IACjF,CAAC;AAAA,IACD,OAAO;AAAA,IACP,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,EACpB,CAAC;AAAA,EACD,OAAO,OAAO;AAAA,IACZ,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO,OAAO,OAAO;AAAA,MACnB,OAAO,OAAO,EAAE,SAAS,WAAW,QAAQ,OAAO,OAAO,EAAE,MAAM,SAAS,CAAC,EAAE,CAAC;AAAA,MAC/E,OAAO,OAAO,EAAE,SAAS,YAAY,QAAQ,OAAO,OAAO,EAAE,MAAM,oBAAoB,CAAC,EAAE,CAAC;AAAA,MAC3F,OAAO,OAAO,EAAE,SAAS,cAAc,QAAQ,OAAO,OAAO,EAAE,MAAM,WAAW,CAAC,EAAE,CAAC;AAAA,MACpF,OAAO,OAAO,EAAE,SAAS,WAAW,QAAQ,OAAO,OAAO,EAAE,MAAM,UAAU,CAAC,EAAE,CAAC;AAAA,IAClF,CAAC;AAAA,IACD,OAAO,OAAO,OAAO,EAAE,MAAM,YAAY,CAAC;AAAA,IAC1C,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,EACpB,CAAC;AACH,CAAC;AAGM,IAAM,yBAAN,MAAM,wBAAuB;AAAA,EACjB;AAAA,EACA;AAAA,EAEjB,YACE,WAA4C,CAAC,GAC7C,WAAmC,kCACnC;AACA,SAAK,WAAW;AAChB,UAAM,UAAU,oBAAI,IAAoC;AACxD,eAAW,WAAW,UAAU;AAC9B,YAAM,aAAa,wBAAwB,SAAS,QAAQ;AAC5D,UAAI,QAAQ,IAAI,WAAW,EAAE,GAAG;AAC9B,cAAM,IAAI,MAAM,iDAAiD,WAAW,EAAE,IAAI;AAAA,MACpF;AACA,cAAQ,IAAI,WAAW,IAAI,UAAU;AAAA,IACvC;AACA,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,IAAI,IAAqB;AACvB,WAAO,KAAK,KAAK,IAAI,EAAE;AAAA,EACzB;AAAA,EAEA,IAAI,IAAgD;AAClD,WAAO,KAAK,KAAK,IAAI,EAAE;AAAA,EACzB;AAAA,EAEA,QAAQ,IAAoC;AAC1C,UAAM,UAAU,KAAK,IAAI,EAAE;AAC3B,QAAI,CAAC,QAAS,OAAM,IAAI,MAAM,4CAA4C,EAAE,IAAI;AAChF,WAAO;AAAA,EACT;AAAA,EAEA,OAA0C;AACxC,WAAO,OAAO,OAAO,CAAC,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC;AAAA,EAC9C;AAAA;AAAA,EAGA,KACE,SACA,OAGI,CAAC,GACmB;AACxB,UAAM,WAAW,KAAK,YAAY,KAAK;AACvC,UAAM,aAAa,wBAAwB,SAAS,QAAQ;AAC5D,QAAI,KAAK,IAAI,WAAW,EAAE,KAAK,KAAK,YAAY,MAAM;AACpD,YAAM,IAAI,MAAM,oCAAoC,WAAW,EAAE,mBAAmB;AAAA,IACtF;AACA,WAAO,IAAI;AAAA,MACT;AAAA,QACE,GAAG,KAAK,KAAK,EAAE,OAAO,CAAC,UAAU,MAAM,OAAO,WAAW,EAAE;AAAA,QAC3D;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,mCAAmC,IAAI;AAAA,EAClD;AACF;AASO,SAAS,sBACd,SACA,OAII,CAAC,GACmB;AACxB,QAAM,WAAW,KAAK,YAAY;AAClC,MAAI,WAAW,OAAO,YAAY,SAAU,QAAO,wBAAwB,SAAS,QAAQ;AAC5F,QAAM,KAAK,WAAW,KAAK,kBAAkB;AAC7C,UAAQ,KAAK,YAAY,kCAAkC,QAAQ,EAAE;AACvE;AAEO,SAAS,wBACd,SACA,WAAmC,kCACX;AACxB,QAAM,KAAK,QAAQ,GAAG,KAAK;AAC3B,MAAI,CAAC,cAAc,KAAK,EAAE,GAAG;AAC3B,UAAM,IAAI,MAAM,+CAA+C,QAAQ,EAAE,IAAI;AAAA,EAC/E;AACA,MAAI,QAAQ,MAAM,WAAW,GAAG;AAC9B,UAAM,IAAI,MAAM,oCAAoC,EAAE,+BAA+B;AAAA,EACvF;AAEA,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,QAAQ,QAAQ,MAAM,IAAI,CAAC,SAAS;AACxC,UAAM,UAAU,SAAS,QAAQ,KAAK,QAAQ,KAAK,CAAC;AACpD,UAAM,iBAAiB,KAAK,IAAI,KAAK;AACrC,QAAI,kBAAkB,QAAQ,IAAI,cAAc,GAAG;AACjD,YAAM,IAAI,MAAM,8CAA8C,cAAc,IAAI;AAAA,IAClF;AACA,UAAM,SAAS,aAAa,kBAAkB,QAAQ,IAAI,OAAO;AACjE,UAAM,QAAQ,KAAK,OAAO,KAAK,KAAK,QAAQ;AAC5C,UAAM,SAAS,KAAK,UAAU,QAAQ,iBAAiB;AACvD,QAAI,CAAC,OAAO,SAAS,MAAM,KAAK,UAAU,GAAG;AAC3C,YAAM,IAAI,MAAM,iCAAiC,MAAM,0BAA0B;AAAA,IACnF;AACA,WAAO,OAAO,OAAO;AAAA,MACnB,IAAI;AAAA,MACJ;AAAA,MACA,SAAS,QAAQ;AAAA,MACjB,GAAI,KAAK,SAAS,EAAE,QAAQ,aAAa,KAAK,QAAQ,SAAS,MAAM,GAAG,EAAE,IAAI,CAAC;AAAA,MAC/E;AAAA,MACA,MAAM,KAAK,QAAQ,QAAQ,eAAe;AAAA,IAC5C,CAAC;AAAA,EACH,CAAC;AAED,QAAM,iBAAiB;AAAA,IACrB,QAAQ,kBAAkB;AAAA,IAC1B;AAAA,IACA;AAAA,EACF;AACA,QAAM,mBAAmB;AAAA,IACvB,QAAQ,oBAAoB;AAAA,IAC5B;AAAA,IACA;AAAA,EACF;AACA,QAAM,eAAe,QAAQ,gBAAgB;AAC7C,MAAI,CAAC,oBAAoB,IAAI,YAAY,GAAG;AAC1C,UAAM,IAAI,MAAM,oCAAoC,EAAE,6BAA6B;AAAA,EACrF;AACA,QAAM,iBAAiB;AAAA,IACrB,QAAQ,kBAAkB;AAAA,IAC1B;AAAA,IACA;AAAA,EACF;AACA,QAAM,iBAAiB;AAAA,IACrB,QAAQ,kBAAkB;AAAA,IAC1B;AAAA,IACA;AAAA,EACF;AACA,QAAM,mBAAmB;AAAA,IACvB,QAAQ,oBAAoB;AAAA,IAC5B;AAAA,IACA;AAAA,EACF;AACA,QAAM,mBAAmB;AAAA,IACvB,QAAQ,oBAAoB;AAAA,IAC5B;AAAA,IACA;AAAA,EACF;AACA,MAAI,mBAAmB,kBAAkB;AACvC,UAAM,IAAI;AAAA,MACR,oCAAoC,EAAE;AAAA,IACxC;AAAA,EACF;AAEA,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA,MAAM,QAAQ,MAAM,KAAK,KAAK;AAAA,IAC9B,aAAa,QAAQ,aAAa,KAAK,KAAK;AAAA,IAC5C,OAAO,OAAO,OAAO,KAAK;AAAA,IAC1B,OAAO,QAAQ,QAAQ,aAAa,QAAQ,OAAO,OAAO,IAAI;AAAA,IAC9D;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAEA,SAAS,aAAa,MAAc,MAA2B;AAC7D,MAAI,CAAC,cAAc,KAAK,IAAI,GAAG;AAC7B,UAAM,IAAI,MAAM,4CAA4C,IAAI,IAAI;AAAA,EACtE;AACA,MAAI,KAAK;AACT,MAAI,SAAS;AACb,SAAO,KAAK,IAAI,EAAE,EAAG,MAAK,GAAG,IAAI,IAAI,QAAQ;AAC7C,OAAK,IAAI,EAAE;AACX,SAAO;AACT;AAEA,SAAS,aAAa,QAA4B,OAAmC;AACnF,QAAM,aAAa,aAAa,OAAO,UAAU;AACjD,QAAM,QAAQ,aAAa,OAAO,KAAK;AACvC,QAAM,OAAO,aAAa,OAAO,IAAI;AACrC,QAAM,kBAAkB,aAAa,OAAO,eAAe;AAC3D,QAAM,iBAAiB,OAAO;AAAA,IAC5B,CAAC,GAAG,IAAI,KAAK,OAAO,kBAAkB,CAAC,GAAG,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC;AAAA,EACrF;AACA,MACE,CAAC,cACD,CAAC,SACD,CAAC,QACD,CAAC,mBACD,eAAe,WAAW,GAC1B;AACA,UAAM,IAAI,MAAM,2BAA2B,KAAK,mBAAmB;AAAA,EACrE;AACA,SAAO,OAAO,OAAO;AAAA,IACnB,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,IACnC,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IACzB,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,IACvB,GAAI,kBAAkB,EAAE,gBAAgB,IAAI,CAAC;AAAA,IAC7C,GAAI,eAAe,SAAS,IAAI,EAAE,eAAe,IAAI,CAAC;AAAA,EACxD,CAAC;AACH;AAEA,SAAS,aAAa,OAA+C;AACnE,QAAM,UAAU,OAAO,KAAK;AAC5B,SAAO,WAAW;AACpB;AAEA,SAAS,SAAS,OAAe,OAAe,WAA2B;AACzE,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,SAAS,KAAK,QAAQ,GAAG;AACtD,UAAM,IAAI,MAAM,oCAAoC,SAAS,KAAK,KAAK,qBAAqB;AAAA,EAC9F;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,OAAe,OAAe,WAA2B;AAChF,MAAI,CAAC,OAAO,cAAc,KAAK,KAAK,SAAS,GAAG;AAC9C,UAAM,IAAI;AAAA,MACR,oCAAoC,SAAS,KAAK,KAAK;AAAA,IACzD;AAAA,EACF;AACA,SAAO;AACT;;;ACvTA,SAAS,cAAc,gBAAgB;AACvC,YAAYC,WAAU;AACtB,SAAS,qBAAqB;AAO9B,IAAM,YAAY,oBAAI,IAAoB;AAG1C,IAAI;AAEG,SAAS,2BAA2B,cAA8B;AACvE,QAAM,SAAS,UAAU,IAAI,YAAY;AACzC,MAAI,WAAW,OAAW,QAAO;AAEjC,MAAI,WAAW;AACf,aAAW,QAAQ,0BAA0B,GAAG;AAC9C,QAAI;AACF,iBAAW,aAAkB,WAAK,MAAM,YAAY,GAAG,MAAM,EAAE,QAAQ;AACvE;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,YAAU,IAAI,cAAc,QAAQ;AACpC,SAAO;AACT;AAEO,SAAS,0BACd,UACA,QACQ;AACR,SAAO,SAAS;AAAA,IAAQ;AAAA,IAAoC,CAAC,OAAO,QAClE,OAAO,OAAO,QAAQ,GAAG,IAAK,OAAO,GAAG,KAAK,KAAM;AAAA,EACrD;AACF;AAEA,SAAS,4BAAsC;AAC7C,MAAI,mBAAmB,OAAW,QAAO;AACzC,QAAM,OAAY,cAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,QAAM,aAAa;AAAA,IACZ,cAAQ,MAAM,oBAAoB;AAAA,IAClC,cAAQ,MAAM,iBAAiB;AAAA,IAC/B,cAAQ,MAAM,cAAc;AAAA,EACnC;AACA,mBAAiB,WAAW,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;AAC5F,SAAO;AACT;AAEA,SAAS,YAAY,WAA4B;AAC/C,MAAI;AACF,WAAO,SAAS,SAAS,EAAE,YAAY;AAAA,EACzC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AC9CO,IAAM,4BAA4B;AAClC,IAAM,4BAA4B;AAGlC,SAAS,8BAA8B,SAAiC;AAC7E,QAAM,WAAW,oBAAoB,yBAAyB;AAC9D,SAAO,0BAA0B,UAAU;AAAA,IACzC,oBAAoB,QAAQ;AAAA,EAC9B,CAAC;AACH;AAGO,SAAS,gCAAwC;AACtD,SAAO,oBAAoB,yBAAyB;AACtD;AAGO,SAAS,2BACd,UACA,OAAiD,CAAC,GAC1C;AACR,QAAM,OAAO,SAAS,SAAS,KAAK;AACpC,MAAI,CAAC,KAAM,OAAM,IAAI,MAAM,yDAAyD;AACpF,QAAM,UAAU,iBAAiB,SAAS,OAAO;AACjD,SAAO;AAAA,IACL;AAAA,IACA,aAAa,IAAI;AAAA,IACjB,SAAS,SAAS,KAAK,IAAI;AAAA,EAAa,SAAS,QAAQ,KAAK,CAAC,KAAK;AAAA,IACpE,QAAQ,SAAS,IAAI;AAAA,EAAoB,KAAK,UAAU,OAAO,CAAC,KAAK;AAAA,IACrE,KAAK,kBACD,sBAAsB,KAAK,eAAe,KAC1C;AAAA,IACJ;AAAA,EACF,EACG,OAAO,OAAO,EACd,KAAK,MAAM;AAChB;AAGO,SAAS,4BACd,UACA,MACA,OAAiD,CAAC,GAC1C;AACR,SAAO;AAAA,IACL,2BAA2B,UAAU,IAAI;AAAA,IACzC;AAAA,IACA,YAAY,KAAK,EAAE;AAAA,IACnB,eAAe,KAAK,KAAK;AAAA,IACzB,eAAe,KAAK,OAAO;AAAA,IAC3B;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAGO,SAAS,4BACd,UACA,OACA,OAGI,CAAC,GACG;AACR,QAAM,UAAU,MAAM,IAAI,CAAC,UAAU;AAAA,IACnC,QAAQ,KAAK;AAAA,IACb,SAAS,KAAK;AAAA,IACd,QAAQ,KAAK;AAAA,IACb,GAAI,KAAK,WAAW,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;AAAA,IACnD,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,IAC7C,GAAI,KAAK,YAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,EACxD,EAAE;AACF,SAAO;AAAA,IACL,2BAA2B,UAAU,EAAE,iBAAiB,KAAK,gBAAgB,CAAC;AAAA,IAC9E;AAAA,IACA,KAAK,QAAQ,KAAK,IAAI,+BAA+B,KAAK,OAAO,KAAK,CAAC,KAAK;AAAA,IAC5E,KAAK,UAAU,OAAO;AAAA,IACtB;AAAA,EACF,EACG,OAAO,OAAO,EACd,KAAK,MAAM;AAChB;AAEA,SAAS,iBAAiB,SAAgE;AACxF,MAAI,CAAC,QAAS,QAAO,CAAC;AACtB,QAAM,OAAO,oBAAI,IAAY;AAC7B,SAAO,QAAQ,IAAI,CAAC,WAAW;AAC7B,UAAM,KAAK,OAAO,GAAG,KAAK;AAC1B,UAAM,QAAQ,OAAO,MAAM,KAAK;AAChC,QAAI,CAAC,GAAI,OAAM,IAAI,MAAM,0DAA0D;AACnF,QAAI,CAAC,MAAO,OAAM,IAAI,MAAM,uCAAuC,EAAE,kBAAkB;AACvF,QAAI,KAAK,IAAI,EAAE,EAAG,OAAM,IAAI,MAAM,oDAAoD,EAAE,IAAI;AAC5F,SAAK,IAAI,EAAE;AACX,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,GAAI,OAAO,aAAa,KAAK,IAAI,EAAE,aAAa,OAAO,YAAY,KAAK,EAAE,IAAI,CAAC;AAAA,IACjF;AAAA,EACF,CAAC;AACH;AAEA,SAAS,oBAAoBC,OAAsB;AACjD,QAAM,OAAO,2BAA2BA,KAAI;AAC5C,MAAI,CAAC,KAAM,OAAM,IAAI,MAAM,4CAA4CA,KAAI,EAAE;AAC7E,SAAO;AACT;;;ACnDO,SAAS,oBAAoB,OAAkD;AACpF,gBAAc,KAAK;AAEnB,QAAM,WAAW,IAAI,IAAI,MAAM,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,CAAU,CAAC;AAC5E,QAAM,aAAsC,CAAC;AAC7C,QAAM,eAAe,oBAAI,IAAY;AACrC,aAAW,QAAQ,MAAM,OAAO;AAC9B,QAAI,CAAC,SAAS,IAAI,KAAK,MAAM,KAAK,aAAa,IAAI,KAAK,MAAM,EAAG;AACjE,iBAAa,IAAI,KAAK,MAAM;AAC5B,eAAW,KAAK,IAAI;AAAA,EACtB;AAEA,MAAI,WAAW,SAAS,MAAM,MAAM,SAAS,MAAM,gBAAgB;AACjE,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,gBAAgB,WAAW;AAAA,MAC3B,WAAW,MAAM,MAAM;AAAA,IACzB;AAAA,EACF;AAEA,QAAM,OAAO,WAAW;AAAA,IACtB,CAAC,SACC,KAAK,aAAa,MAAM,mBAAmB,SAAS,IAAI,KAAK,MAAM,GAAG,SAAS;AAAA,EACnF;AACA,MAAI,MAAM;AACR,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,UAAU,KAAK;AAAA,MACf,QAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAEA,QAAM,iBAAiB,oBAAI,IAAoB;AAC/C,MAAI,aAAa;AACjB,aAAW,QAAQ,YAAY;AAC7B,UAAM,SAAS,SAAS,IAAI,KAAK,MAAM,GAAG,UAAU;AACpD,kBAAc;AACd,mBAAe,IAAI,KAAK,WAAW,eAAe,IAAI,KAAK,QAAQ,KAAK,KAAK,MAAM;AAAA,EACrF;AAEA,MAAI;AACJ,MAAI,YAAY;AAChB,aAAW,CAAC,UAAU,MAAM,KAAK,gBAAgB;AAC/C,QAAI,CAAC,UAAU,SAAS,OAAO,QAAQ;AACrC,eAAS,EAAE,UAAU,OAAO;AAC5B,kBAAY;AAAA,IACd,WAAW,WAAW,OAAO,QAAQ;AACnC,kBAAY;AAAA,IACd;AAAA,EACF;AAEA,QAAM,WACJ,WAAW,UACX,CAAC,aACD,OAAO,SAAS,MAAM,mBAAmB;AAE3C,MAAI,CAAC,YAAY,CAAC,QAAQ;AACxB,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ,YAAY,QAAQ;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,aAAa,MAAM,iBAAiB;AAC7C,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,UAAU,OAAO;AAAA,MACjB,eAAe,OAAO;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,UAAU,OAAO;AAAA,IACjB,eAAe,OAAO;AAAA,IACtB;AAAA,EACF;AACF;AAEA,SAAS,cAAc,OAAqC;AAC1D,MAAI,MAAM,MAAM,WAAW,GAAG;AAC5B,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AACA,kBAAgB,MAAM,gBAAgB,gBAAgB;AACtD,kBAAgB,MAAM,kBAAkB,kBAAkB;AAE1D,QAAM,UAAU,oBAAI,IAAY;AAChC,aAAW,QAAQ,MAAM,OAAO;AAC9B,QAAI,CAAC,KAAK,GAAG,KAAK,EAAG,OAAM,IAAI,MAAM,iDAAiD;AACtF,QAAI,QAAQ,IAAI,KAAK,EAAE,GAAG;AACxB,YAAM,IAAI,MAAM,2CAA2C,KAAK,EAAE,IAAI;AAAA,IACxE;AACA,YAAQ,IAAI,KAAK,EAAE;AACnB,QAAI,KAAK,WAAW,WAAc,CAAC,OAAO,SAAS,KAAK,MAAM,KAAK,KAAK,UAAU,IAAI;AACpF,YAAM,IAAI,MAAM,iDAAiD,KAAK,EAAE,IAAI;AAAA,IAC9E;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,OAAe,OAAqB;AAC3D,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,SAAS,KAAK,QAAQ,GAAG;AACtD,UAAM,IAAI,MAAM,wBAAwB,KAAK,qBAAqB;AAAA,EACpE;AACF;;;AC/IO,IAAM,4BAA4B;AAClC,IAAM,kCAAkC;AACxC,IAAM,0BAA0B;AAmDhC,IAAM,sBAAN,MAA0B;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,MAAkC;AAC5C,SAAK,SAAS,KAAK;AACnB,SAAK,WAAW,KAAK,YAAY;AACjC,SAAK,WAAW,KAAK,YAAY;AACjC,SAAK,iBAAiB,KAAK;AAC3B,SAAK,iBAAiB;AAAA,MACpB,KAAK,kBAAkB;AAAA,IACzB;AACA,SAAK,kBAAkB,KAAK,iBAAiB,KAAK,KAAK;AACvD,SAAK,yBAAyB,KAAK;AACnC,SAAK,aAAa,KAAK;AACvB,SAAK,cAAc,KAAK;AAAA,EAC1B;AAAA,EAEA,MAAM,IAAI,UAAmD;AAC3D,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,UAAU,sBAAsB,SAAS,SAAS;AAAA,MACtD,UAAU,KAAK;AAAA,MACf,UAAU,KAAK;AAAA,MACf,gBAAgB,KAAK;AAAA,IACvB,CAAC;AACD,6BAAyB,UAAU,KAAK,eAAe;AAEvD,UAAM,gBAAgB,YAAY,QAAQ,QAAQ,gBAAgB;AAClE,UAAM,SAAS,SAAS,SACpB,YAAY,IAAI,CAAC,SAAS,QAAQ,aAAa,CAAC,IAChD;AACJ,UAAM,QAA0B;AAAA,MAC9B,OAAO;AAAA,MACP,aAAa;AAAA,MACb,cAAc;AAAA,MACd,aAAa;AAAA,IACf;AAEA,UAAM,QAAQ,MAAM;AAAA,MAClB,QAAQ;AAAA,MACR,KAAK,IAAI,KAAK,gBAAgB,QAAQ,MAAM,MAAM;AAAA,MAClD,OAAO,MAAM,MAAM;AACjB,YAAI;AACF,iBAAO,MAAM,KAAK,SAAS,UAAU,SAAS,MAAM,GAAG,QAAQ,KAAK;AAAA,QACtE,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,QAAQ,KAAK;AAAA,YACb,SAAS,KAAK;AAAA,YACd,QAAQ,OAAO,UAAU,cAAc;AAAA,YACvC,OAAO,aAAa,KAAK;AAAA,UAC3B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,UAAM,WAAW,qBAAqB,OAAO,OAAO;AACpD,UAAM,SAAS,MACZ,OAAO,CAAC,SAAS,KAAK,WAAW,YAAY,KAAK,WAAW,SAAS,EACtE,IAAI,CAAC,SAAS,GAAG,KAAK,MAAM,KAAK,KAAK,SAAS,KAAK,MAAM,EAAE;AAE/D,QAAI,SAAS,QAAQ,SAAS;AAC5B,aAAO,eAAe;AAAA,QACpB,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AACA,QAAI,cAAc,SAAS;AACzB,aAAO,eAAe;AAAA,QACpB,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ,CAAC,GAAG,QAAQ,mCAAmC;AAAA,MACzD,CAAC;AAAA,IACH;AAEA,QAAI,CAAC,SAAS,WAAW,SAAS,QAAQ,WAAW,GAAG;AACtD,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,SACZ,UACA,SACA,MACA,WACA,QACA,OAC4B;AAC5B,QAAI,OAAO,QAAS,QAAO,cAAc,IAAI;AAC7C,QAAI;AACJ,QAAI;AACF,gBAAU,KAAK,SAAS,QAAQ,KAAK,OAAO;AAAA,IAC9C,SAAS,OAAO;AACd,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,SAAS,KAAK;AAAA,QACd,QAAQ;AAAA,QACR,OAAO,aAAa,KAAK;AAAA,MAC3B;AAAA,IACF;AACA,UAAM,SAAS,MAAM,KAAK,SAAS;AAAA,MACjC,QAAQ,8BAA8B,OAAO;AAAA,MAC7C,YAAY,4BAA4B,UAAU,MAAM;AAAA,QACtD,iBAAiB,SAAS,SAAS,SAAS,KAAK,kBAAkB;AAAA,MACrE,CAAC;AAAA,MACD,QAAQ,KAAK;AAAA,MACb,WAAW,QAAQ;AAAA,MACnB,WAAW,QAAQ;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,WAAW,aAAa,MAAM;AACpC,QAAI,OAAO,OAAO;AAChB,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,SAAS,KAAK;AAAA,QACd,QAAQ,OAAO,UAAU,cAAc;AAAA,QACvC,GAAG;AAAA,QACH,OAAO,OAAO;AAAA,MAChB;AAAA,IACF;AACA,UAAM,SAAS,UAAU,OAAO,MAAM,UAAU,KAAK,eAAe;AACpE,QAAI,CAAC,OAAO,IAAI;AACd,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,SAAS,KAAK;AAAA,QACd,QAAQ;AAAA,QACR,GAAG;AAAA,QACH,OAAO,OAAO;AAAA,MAChB;AAAA,IACF;AACA,WAAO;AAAA,MACL,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK;AAAA,MACd,QAAQ;AAAA,MACR,GAAG,OAAO;AAAA,MACV,GAAG;AAAA,IACL;AAAA,EACF;AAAA,EAEA,MAAc,sBACZ,UACA,SACA,OACA,QACA,OACA,WACA,UACA,QACwB;AACxB,UAAM,aAAa,MAAM;AAAA,MACvB,CAAC,SACC,KAAK,WAAW,WAAW,OAAO,KAAK,aAAa;AAAA,IACxD;AACA,UAAM,aAAa,oBAAoB;AAAA,MACrC,OAAO,QAAQ,MAAM,IAAI,CAAC,UAAU;AAAA,QAClC,IAAI,KAAK;AAAA,QACT,QAAQ,KAAK;AAAA,QACb,MAAM,KAAK;AAAA,MACb,EAAE;AAAA,MACF,OAAO,WAAW,IAAI,CAAC,UAAU,EAAE,QAAQ,KAAK,QAAQ,UAAU,KAAK,SAAS,EAAE;AAAA,MAClF,iBAAiB,KAAK;AAAA,MACtB,gBAAgB,QAAQ;AAAA,MACxB,kBAAkB,QAAQ;AAAA,IAC5B,CAAC;AAED,QAAI,WAAW,WAAW,aAAa;AACrC,aAAO,eAAe;AAAA,QACpB,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AACA,QAAI,WAAW,WAAW,UAAU;AAClC,aAAO,eAAe;AAAA,QACpB,QAAQ;AAAA,QACR,UAAU,WAAW;AAAA,QACrB,QAAQ,mCAAmC,WAAW,MAAM;AAAA,QAC5D,YAAY,WAAW;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AACA,QAAI,WAAW,WAAW,WAAW;AACnC,aAAO,eAAe;AAAA,QACpB,QAAQ;AAAA,QACR,UAAU,WAAW;AAAA,QACrB,QAAQ,YAAY,UAAU,WAAW,QAAQ;AAAA,QACjD,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AACA,QAAI,CAAC,QAAQ,OAAO;AAClB,aAAO,eAAe;AAAA,QACpB,QAAQ;AAAA,QACR,QAAQ,6BAA6B,WAAW,MAAM;AAAA,QACtD,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,SAAS,MAAM,KAAK;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,WAAW;AAAA,MACX;AAAA,MACA;AAAA,IACF;AACA,QAAI,CAAC,OAAO,IAAI;AACd,aAAO,eAAe;AAAA,QACpB,QAAQ,OAAO,UAAU,cAAc;AAAA,QACvC,QAAQ,OAAO;AAAA,QACf,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ,CAAC,GAAG,QAAQ,OAAO,KAAK;AAAA,QAChC,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,QAAI,OAAO,MAAM,aAAa,KAAK,iBAAiB;AAClD,aAAO,eAAe;AAAA,QACpB,QAAQ;AAAA,QACR,UAAU,KAAK;AAAA,QACf,QAAQ,OAAO,MAAM,aAAa;AAAA,QAClC,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,WAAO,eAAe;AAAA,MACpB,QAAQ;AAAA,MACR,UAAU,OAAO,MAAM;AAAA,MACvB,QAAQ,YAAY,UAAU,OAAO,MAAM,QAAQ;AAAA,MACnD,QAAQ,OAAO,MAAM;AAAA,MACrB,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,oBACZ,UACA,SACA,OACA,QACA,OACA,WACA,UACA,QACwB;AACxB,UAAM,QAAQ,MAAM;AAAA,MAClB,CAAC,SACC,KAAK,WAAW,WAAW,OAAO,KAAK,WAAW;AAAA,IACtD;AACA,QAAI,MAAM,SAAS,QAAQ,MAAM,SAAS,QAAQ,gBAAgB;AAChE,aAAO,eAAe;AAAA,QACpB,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AACA,QAAI,CAAC,QAAQ,OAAO;AAClB,YAAM,QAAQ,MAAM,CAAC;AACrB,UAAI,CAAC,OAAO;AACV,eAAO,eAAe;AAAA,UACpB,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,YAAY;AAAA,UACZ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AACA,aAAO,eAAe;AAAA,QACpB,QAAQ;AAAA,QACR,QAAQ,MAAM;AAAA,QACd,QAAQ,MAAM;AAAA,QACd,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,SAAS,MAAM,KAAK;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,CAAC,OAAO,IAAI;AACd,aAAO,eAAe;AAAA,QACpB,QAAQ,OAAO,UAAU,cAAc;AAAA,QACvC,QAAQ,OAAO;AAAA,QACf,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ,CAAC,GAAG,QAAQ,OAAO,KAAK;AAAA,QAChC,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AACA,WAAO,eAAe;AAAA,MACpB,QAAQ;AAAA,MACR,QAAQ,OAAO,MAAM;AAAA,MACrB,QAAQ,OAAO,MAAM;AAAA,MACrB,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,UACZ,UACA,SACA,OACA,QACA,QACA,QACA,OAC0E;AAC1E,UAAM,SAAS,MAAM,KAAK,SAAS;AAAA,MACjC,QAAQ,8BAA8B;AAAA,MACtC,YAAY,4BAA4B,UAAU,OAAO;AAAA,QACvD;AAAA,QACA,iBAAiB,SAAS,SAAS,SAAS,KAAK,kBAAkB;AAAA,MACrE,CAAC;AAAA,MACD;AAAA,MACA,WAAW,QAAQ;AAAA,MACnB,WAAW,QAAQ;AAAA,MACnB;AAAA,MACA;AAAA,IACF,CAAC;AACD,QAAI,OAAO,MAAO,QAAO,EAAE,IAAI,OAAO,OAAO,OAAO,MAAM;AAC1D,WAAO,WAAW,OAAO,MAAM,UAAU,KAAK,eAAe;AAAA,EAC/D;AAAA,EAEA,MAAc,SAAS,OASO;AAC5B,UAAM,kBACJ,MAAM,cAAc,UAAa,KAAK,aAClC,KAAK,WAAW,MAAM,SAAS,IAC/B,KAAK,gBAAgB,KAAK,aAAa,KAAK,WAAW,CAAC,IAAI,KAAK;AAEvE,UAAM,iBAAiB,KAAK,qBAAqB,MAAM,MAAM;AAE7D,QAAI;AACF,YAAM,SAAS,MAAM,gBAAgB,KAAK;AAAA,QACxC,QAAQ,MAAM;AAAA,QACd,YAAY,MAAM;AAAA,QAClB,gBAAgB,EAAE,MAAM,cAAc;AAAA,QACtC,WAAW,MAAM;AAAA,QACjB,WAAW,MAAM;AAAA,QACjB,QAAQ,MAAM;AAAA,QACd,GAAI,gBAAgB,aAAa,EAAE,YAAY,eAAe,WAAW,IAAI,CAAC;AAAA,QAC9E,GAAI,gBAAgB,QAAQ,EAAE,OAAO,eAAe,MAAM,IAAI,CAAC;AAAA,QAC/D,GAAI,gBAAgB,OAAO,EAAE,MAAM,eAAe,KAAK,IAAI,CAAC;AAAA,QAC5D,GAAI,gBAAgB,kBAAkB,eAAe,eAAe,SAAS,IACzE,EAAE,gBAAgB,CAAC,GAAG,eAAe,cAAc,EAAE,IACrD,CAAC;AAAA,MACP,CAAC;AACD,eAAS,MAAM,OAAO,MAAM;AAC5B,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,MAAM,SAAS;AACrB,aAAO,gBAAgB,aAAa,KAAK,CAAC;AAAA,IAC5C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,qBACN,QACgC;AAChC,QAAI,CAAC,OAAQ,QAAO;AACpB,QAAI,CAAC,OAAO,gBAAiB,QAAO;AAEpC,UAAM,MAAM,KAAK;AACjB,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,QAAQ,IAAI,QAAQ,OAAO,eAAe;AAChD,QAAI,MAAM,WAAW,EAAG,QAAO;AAG/B,UAAM,WAAW;AAAA,MACf,GAAG,MAAM,IAAI,CAAC,MAAM,GAAG,EAAE,UAAU,IAAI,EAAE,KAAK,EAAE;AAAA,MAChD,GAAI,OAAO,kBAAkB,CAAC;AAAA,IAChC;AAEA,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,UAAU,SAAS,OAAO,CAAC,QAAQ;AACvC,UAAI,KAAK,IAAI,GAAG,EAAG,QAAO;AAC1B,WAAK,IAAI,GAAG;AACZ,aAAO;AAAA,IACT,CAAC;AAED,WAAO;AAAA,MACL,GAAI,OAAO,aAAa,EAAE,YAAY,OAAO,WAAW,IAAI,CAAC;AAAA,MAC7D,GAAI,OAAO,QAAQ,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC;AAAA,MAC9C,GAAI,OAAO,OAAO,EAAE,MAAM,OAAO,KAAK,IAAI,CAAC;AAAA,MAC3C,gBAAgB;AAAA,IAClB;AAAA,EACF;AACF;AAEA,SAAS,UACP,MACA,UACA,iBAC+D;AAC/D,QAAM,SAAS,YAAY,IAAI;AAC/B,MAAI,CAAC,OAAO,OAAO,CAAC,SAAS,WAAW,SAAS,QAAQ,WAAW,IAAI;AAGtE,UAAM,WAAW,KAAK,KAAK;AAC3B,QAAI,SAAU,QAAO,EAAE,IAAI,MAAM,MAAM,EAAE,QAAQ,SAAS,EAAE;AAC5D,WAAO,EAAE,IAAI,OAAO,OAAO,oCAAoC;AAAA,EACjE;AACA,MAAI,CAAC,OAAO,GAAI,QAAO;AACvB,QAAM,YAAY,eAAe,OAAO,MAAM,WAAW,CAAC;AAC1D,MAAI,SAAS,WAAW,SAAS,QAAQ,SAAS,GAAG;AACnD,UAAM,WAAW,eAAe,OAAO,MAAM,UAAU,CAAC;AACxD,UAAM,UAAU,oBAAI,IAAI,CAAC,GAAG,SAAS,QAAQ,IAAI,CAAC,WAAW,OAAO,GAAG,KAAK,CAAC,GAAG,eAAe,CAAC;AAChG,QAAI,CAAC,YAAY,CAAC,QAAQ,IAAI,QAAQ,GAAG;AACvC,aAAO,EAAE,IAAI,OAAO,OAAO,iDAAiD;AAAA,IAC9E;AACA,WAAO,EAAE,IAAI,MAAM,MAAM,EAAE,UAAU,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC,EAAG,EAAE;AAAA,EAC7E;AACA,QAAM,SAAS,eAAe,OAAO,MAAM,QAAQ,CAAC;AACpD,MAAI,CAAC,OAAQ,QAAO,EAAE,IAAI,OAAO,OAAO,6CAA6C;AACrF,SAAO,EAAE,IAAI,MAAM,MAAM,EAAE,QAAQ,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC,EAAG,EAAE;AAC3E;AAEA,SAAS,WACP,MACA,UACA,iBACiE;AACjE,QAAM,SAAS,YAAY,IAAI;AAC/B,MAAI,CAAC,OAAO,OAAO,CAAC,SAAS,WAAW,SAAS,QAAQ,WAAW,IAAI;AAEtE,UAAM,WAAW,KAAK,KAAK;AAC3B,QAAI,SAAU,QAAO,EAAE,IAAI,MAAM,OAAO,EAAE,QAAQ,SAAS,EAAE;AAC7D,WAAO,EAAE,IAAI,OAAO,OAAO,oCAAoC;AAAA,EACjE;AACA,MAAI,CAAC,OAAO,GAAI,QAAO;AACvB,QAAM,YAAY,eAAe,OAAO,MAAM,WAAW,CAAC;AAC1D,MAAI,SAAS,WAAW,SAAS,QAAQ,SAAS,GAAG;AACnD,UAAM,WAAW,eAAe,OAAO,MAAM,UAAU,CAAC;AACxD,UAAM,UAAU,oBAAI,IAAI,CAAC,GAAG,SAAS,QAAQ,IAAI,CAAC,WAAW,OAAO,GAAG,KAAK,CAAC,GAAG,eAAe,CAAC;AAChG,QAAI,CAAC,YAAY,CAAC,QAAQ,IAAI,QAAQ,GAAG;AACvC,aAAO,EAAE,IAAI,OAAO,OAAO,iDAAiD;AAAA,IAC9E;AACA,WAAO,EAAE,IAAI,MAAM,OAAO,EAAE,UAAU,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC,EAAG,EAAE;AAAA,EAC9E;AACA,QAAM,SAAS,eAAe,OAAO,MAAM,QAAQ,CAAC;AACpD,MAAI,CAAC,OAAQ,QAAO,EAAE,IAAI,OAAO,OAAO,6CAA6C;AACrF,SAAO,EAAE,IAAI,MAAM,OAAO,EAAE,QAAQ,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC,EAAG,EAAE;AAC5E;AAEA,SAAS,YACP,MAC6E;AAC7E,QAAM,UAAU,KAAK,KAAK;AAC1B,QAAM,QAAQ,QAAQ,QAAQ,GAAG;AACjC,QAAM,OAAO,QAAQ,YAAY,GAAG;AACpC,MAAI,QAAQ,KAAK,OAAO,MAAO,QAAO,EAAE,IAAI,OAAO,OAAO,qCAAqC;AAC/F,MAAI;AACF,UAAM,QAAiB,KAAK,MAAM,QAAQ,MAAM,OAAO,OAAO,CAAC,CAAC;AAChE,QAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AAC/D,aAAO,EAAE,IAAI,OAAO,OAAO,uCAAuC;AAAA,IACpE;AACA,WAAO,EAAE,IAAI,MAAM,MAAwC;AAAA,EAC7D,SAAS,OAAO;AACd,WAAO,EAAE,IAAI,OAAO,OAAO,8BAA8B,aAAa,KAAK,CAAC,GAAG;AAAA,EACjF;AACF;AAEA,SAAS,eAAe,OAaN;AAChB,QAAM,iBAAiB,MAAM,MAAM,OAAO,CAAC,SAAS,KAAK,WAAW,OAAO,EAAE;AAC7E,SAAO;AAAA,IACL,QAAQ,MAAM;AAAA,IACd,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,IAC/C,GAAI,MAAM,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;AAAA,IACrD,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,IAC/C,YAAY,MAAM;AAAA,IAClB,OAAO,OAAO,OAAO,CAAC,GAAG,MAAM,KAAK,CAAC;AAAA,IACrC,qBAAqB,MAAM,QAAQ,MAAM;AAAA,IACzC;AAAA,IACA,qBAAqB,oBAAoB,MAAM,OAAO,MAAM,OAAO;AAAA,IACnE,WAAW,MAAM,aAAa;AAAA,IAC9B,OAAO,YAAY,MAAM,OAAO,MAAM,SAAS;AAAA,IAC/C,GAAI,MAAM,SAAS,SAAS,IAAI,EAAE,UAAU,OAAO,OAAO,CAAC,GAAG,MAAM,QAAQ,CAAC,EAAE,IAAI,CAAC;AAAA,IACpF,GAAI,MAAM,OAAO,SAAS,IAAI,EAAE,QAAQ,OAAO,OAAO,CAAC,GAAG,MAAM,MAAM,CAAC,EAAE,IAAI,CAAC;AAAA,EAChF;AACF;AAEA,SAAS,aAAa,QAAoF;AACxG,SAAO;AAAA,IACL,GAAI,OAAO,WAAW,EAAE,UAAU,OAAO,SAAS,IAAI,CAAC;AAAA,IACvD,GAAI,OAAO,QAAQ,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC;AAAA,IAC9C,GAAI,OAAO,eAAe,EAAE,cAAc,KAAK,IAAI,CAAC;AAAA,IACpD,YAAY,OAAO;AAAA,EACrB;AACF;AAEA,SAAS,SAAS,OAAyB,QAAgC;AACzE,QAAM,SAAS;AACf,QAAM,eAAe,OAAO,OAAO;AACnC,QAAM,gBAAgB,OAAO,OAAO;AACpC,QAAM,eAAe,OAAO,OAAO;AACrC;AAEA,SAAS,YAAY,OAAyB,WAAiC;AAC7E,SAAO,OAAO,OAAO,EAAE,GAAG,OAAO,YAAY,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,SAAS,EAAE,CAAC;AACpF;AAEA,SAAS,cAAc,MAA8C;AACnE,SAAO,EAAE,QAAQ,KAAK,IAAI,SAAS,KAAK,SAAS,QAAQ,aAAa,OAAO,aAAa;AAC5F;AAEA,SAAS,oBACP,OACA,SACQ;AACR,QAAM,OAAO,MACV,OAAO,CAAC,SAAS,KAAK,WAAW,OAAO,EACxC;AAAA,IAAI,CAAC,SACJ,QAAQ,iBAAiB,aACrB,KAAK,WACL,GAAG,KAAK,YAAY,EAAE,IAAI,KAAK,SAAS,EAAE;AAAA,EAChD,EACC,OAAO,OAAO;AACjB,SAAO,IAAI,IAAI,IAAI,EAAE;AACvB;AAEA,SAAS,qBACP,OACA,SACU;AACV,MAAI,QAAQ,iBAAiB,OAAQ,QAAO,CAAC;AAC7C,QAAM,QAAQ,MAAM,OAAO,CAAC,SAAS,KAAK,WAAW,OAAO;AAC5D,QAAM,WAAW,oBAAoB,OAAO,OAAO;AACnD,MAAI,MAAM,SAAS,KAAK,WAAW,MAAM,QAAQ;AAC/C,WAAO;AAAA,MACL,gCAAgC,QAAQ,YAAY,kBAAkB,QAAQ,8BAA8B,MAAM,MAAM;AAAA,IAC1H;AAAA,EACF;AACA,SAAO,CAAC;AACV;AAEA,SAAS,YAAY,UAA2B,UAAkD;AAChG,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO,SAAS,SAAS,KAAK,CAAC,WAAW,OAAO,GAAG,KAAK,MAAM,QAAQ,GAAG,MAAM,KAAK;AACvF;AAEA,SAAS,yBAAyB,UAA2B,iBAA+B;AAC1F,MAAI,SAAS,SAAS,KAAK,CAAC,WAAW,OAAO,GAAG,KAAK,MAAM,eAAe,GAAG;AAC5E,UAAM,IAAI,MAAM,mCAAmC,eAAe,gBAAgB;AAAA,EACpF;AACF;AAEA,SAAS,oBAAoB,OAAuB;AAClD,MAAI,CAAC,OAAO,cAAc,KAAK,KAAK,SAAS,KAAK,QAAQ,yBAAyB;AACjF,UAAM,IAAI;AAAA,MACR,iEAAiE,uBAAuB;AAAA,IAC1F;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAe,cACb,OACA,aACA,QACc;AACd,QAAM,UAAU,IAAI,MAAS,MAAM,MAAM;AACzC,MAAI,OAAO;AACX,QAAM,MAAM,YAA2B;AACrC,WAAO,MAAM;AACX,YAAM,QAAQ;AACd,UAAI,SAAS,MAAM,OAAQ;AAC3B,YAAM,OAAO,MAAM,KAAK;AACxB,UAAI,SAAS,OAAW,SAAQ,KAAK,IAAI,MAAM,OAAO,MAAM,KAAK;AAAA,IACnE;AAAA,EACF;AACA,QAAM,QAAQ,IAAI,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,aAAa,MAAM,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,CAAC;AAC1F,SAAO;AACT;AAEA,SAAS,gBAAgB,OAAiC;AACxD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,QAAQ,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,EAAE;AAAA,IACxC,YAAY;AAAA,IACZ,cAAc;AAAA,IACd;AAAA,EACF;AACF;AAEA,SAAS,eAAe,OAAoC;AAC1D,SAAO,OAAO,UAAU,YAAY,MAAM,KAAK,IAAI,MAAM,KAAK,IAAI;AACpE;AAEA,SAAS,aAAa,OAAwB;AAC5C,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;;;AC7xBO,IAAM,oBAAoB;AAC1B,IAAM,2BAA2B;AACjC,IAAM,6BAA6B;AACnC,IAAM,4BAA4B;AAoBzC,IAAM,eAA2B;AAAA,EAC/B,MAAM;AAAA,EACN,YAAY;AAAA,IACV,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aAAa;AAAA,MACb,WAAW;AAAA,IACb;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,WAAW;AAAA,IACb;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,UAAU;AAAA,MACV,OAAO;AAAA,QACL,MAAM;AAAA,QACN,YAAY;AAAA,UACV,IAAI,EAAE,MAAM,UAAU,aAAa,oBAAoB;AAAA,UACvD,OAAO,EAAE,MAAM,UAAU,aAAa,+BAA+B;AAAA,UACrE,aAAa,EAAE,MAAM,UAAU,aAAa,qCAAqC;AAAA,QACnF;AAAA,QACA,UAAU,CAAC,MAAM,OAAO;AAAA,QACxB,sBAAsB;AAAA,MACxB;AAAA,MACA,aAAa;AAAA,IACf;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,UAAU,CAAC,UAAU;AAAA,EACrB,sBAAsB;AACxB;AAGO,SAAS,kBACd,MACuC;AACvC,QAAM,eAAe,IAAI,oBAAoB;AAAA,IAC3C,GAAG;AAAA,IACH,wBAAwB,KAAK;AAAA,EAC/B,CAAC;AACD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aACE;AAAA,IAEF,WACE;AAAA,IAGF,UAAU;AAAA,IACV,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,UAAU;AAAA,IACV,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,MAAM,QAAQ,OAAO,MAAM,EAAE,OAAO,GAAG;AACrC,YAAM,WAA4B;AAAA,QAChC,UAAU,MAAM;AAAA,QAChB,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,QAClD,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,QAClD,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,QAClD;AAAA,MACF;AACA,aAAO,aAAa,IAAI,QAAQ;AAAA,IAClC;AAAA,IACA,UAAU;AAAA,EACZ;AACF;AAEA,SAAS,yBAAyB,OAAmC;AACnE,QAAM,SAAmB,CAAC;AAC1B,QAAM,WAAW,MAAM,UAAU,KAAK,KAAK;AAC3C,MAAI,CAAC,SAAU,QAAO,KAAK,+BAA+B;AAC1D,MAAI,SAAS,SAAS,4BAA4B;AAChD,WAAO,KAAK,gCAAgC,0BAA0B,cAAc;AAAA,EACtF;AACA,OAAK,MAAM,SAAS,UAAU,KAAK,2BAA2B;AAC5D,WAAO,KAAK,+BAA+B,yBAAyB,cAAc;AAAA,EACpF;AACA,OAAK,MAAM,SAAS,UAAU,KAAK,0BAA0B;AAC3D,WAAO,KAAK,0CAA0C,wBAAwB,SAAS;AAAA,EACzF;AACA,QAAM,MAAM,oBAAI,IAAY;AAC5B,aAAW,UAAU,MAAM,WAAW,CAAC,GAAG;AACxC,UAAM,KAAK,OAAO,GAAG,KAAK;AAC1B,QAAI,CAAC,GAAI,QAAO,KAAK,0CAA0C;AAC/D,QAAI,CAAC,OAAO,MAAM,KAAK,EAAG,QAAO,KAAK,WAAW,MAAM,SAAS,sBAAsB;AACtF,QAAI,IAAI,IAAI,EAAE,EAAG,QAAO,KAAK,wBAAwB,EAAE,IAAI;AAC3D,QAAI,IAAI,EAAE;AAAA,EACZ;AACA,SAAO;AACT;;;AC9GO,SAAS,sBACd,YACA,OAIA;AACA,MAAI,eAAe,YAAa,QAAO,EAAE,YAAY,MAAM;AAC3D,QAAM,QAAQ,MAAM,QAAQ,GAAG;AAC/B,SAAO,QAAQ,KAAK,QAAQ,MAAM,SAAS,IACvC,EAAE,YAAY,MAAM,MAAM,GAAG,KAAK,GAAG,OAAO,MAAM,MAAM,QAAQ,CAAC,EAAE,IACnE,EAAE,YAAY,MAAM;AAC1B;AAEA,IAAM,WAAmC;AAAA,EACvC,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;AAEA,SAAS,YAAY,OAAmC;AACtD,QAAM,QAAQ,oBAAoB,KAAK,KAAK;AAC5C,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,OAAO,OAAO,MAAM,CAAC,CAAC;AAC5B,QAAM,SAAS,OAAO,MAAM,CAAC,CAAC;AAC9B,MAAI,OAAO,MAAM,SAAS,GAAI,QAAO;AACrC,SAAO,OAAO,KAAK;AACrB;AAEA,SAAS,QAAQ,MAAY,UAAgE;AAC3F,MAAI;AACF,UAAM,QAAQ,IAAI,KAAK,eAAe,SAAS;AAAA,MAC7C,UAAU;AAAA,MACV,SAAS;AAAA,MACT,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,WAAW;AAAA,IACb,CAAC,EAAE,cAAc,IAAI;AACrB,UAAM,UAAU,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,SAAS,GAAG;AAC/D,UAAM,OAAO,OAAO,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,MAAM,GAAG,KAAK;AACrE,UAAM,SAAS,OAAO,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,QAAQ,GAAG,KAAK;AACzE,QAAI,CAAC,WAAW,SAAS,OAAO,MAAM,UAAa,CAAC,OAAO,SAAS,OAAO,MAAM;AAC/E,aAAO;AACT,WAAO,EAAE,KAAK,SAAS,OAAO,GAAG,QAAQ,OAAO,KAAK,OAAO;AAAA,EAC9D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,cAAc,MAAyB,YAAoB,OAAwB;AAC1F,MAAI,KAAK,YAAY,KAAK,aAAa,WAAY,QAAO;AAC1D,MAAI,KAAK,SAAS,KAAK,UAAU,MAAO,QAAO;AAC/C,SAAO,QAAQ,KAAK,YAAY,KAAK,KAAK;AAC5C;AAEA,SAAS,YAAY,MAAyB,KAAa,QAAyB;AAClF,QAAM,QAAQ,YAAY,KAAK,KAAK;AACpC,QAAM,MAAM,YAAY,KAAK,GAAG;AAChC,MAAI,UAAU,UAAa,QAAQ,OAAW,QAAO;AACrD,QAAM,OAAO,KAAK,MAAM,SAAS,IAAI,IAAI,KAAK,IAAI,IAAI;AACtD,MAAI,UAAU,IAAK,QAAO,CAAC,QAAQ,KAAK,IAAI,GAAG;AAC/C,MAAI,QAAQ,IAAK,SAAQ,CAAC,QAAQ,KAAK,IAAI,GAAG,MAAM,UAAU,SAAS,SAAS;AAEhF,MAAI,UAAU,MAAO,QAAO,CAAC,QAAQ,KAAK,IAAI,GAAG;AACjD,QAAM,eAAe,MAAM,KAAK;AAChC,SAAO,SAAS,QAAQ,CAAC,QAAQ,KAAK,IAAI,WAAW;AACvD;AAEO,SAAS,sBACd,OACA,YACA,OACA,KAAK,oBAAI,KAAK,GACS;AACvB,GAAC,EAAE,YAAY,MAAM,IAAI,sBAAsB,YAAY,KAAK;AAChE,QAAM,aAAkC,CAAC;AACzC,MAAI,eAAe;AACnB,aAAW,QAAQ,SAAS,CAAC,GAAG;AAC9B,QAAI,KAAK,YAAY,SAAS,CAAC,cAAc,MAAM,YAAY,KAAK,EAAG;AACvE,UAAM,QAAQ,QAAQ,IAAI,KAAK,QAAQ;AACvC,QAAI,CAAC,SAAS,YAAY,KAAK,KAAK,MAAM,UAAa,YAAY,KAAK,GAAG,MAAM;AAC/E;AACF,QAAI,KAAK,SAAS,cAAc;AAC9B,iBAAW,KAAK,IAAI;AACpB,UAAI,YAAY,MAAM,MAAM,KAAK,MAAM,MAAM,EAAG,gBAAe;AAAA,IACjE,WAAW,YAAY,MAAM,MAAM,KAAK,MAAM,MAAM,GAAG;AACrD,aAAO,EAAE,SAAS,OAAO,KAAK;AAAA,IAChC;AAAA,EACF;AACA,MAAI,WAAW,SAAS,KAAK,CAAC,aAAc,QAAO,EAAE,SAAS,OAAO,MAAM,WAAW,CAAC,EAAE;AACzF,SAAO,EAAE,SAAS,KAAK;AACzB;;;AC2NA,IAAM,sBACJ;AAGF,IAAM,oBAAoB;AAC1B,IAAM,qBACJ;AAQK,SAAS,sBACd,QACA,MACA,SACmB;AACnB,QAAM,OAAO,MAAM;AACnB,QAAM,OAAO,CAAC,SAAS,MAAM,SAAS,MAAM,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AAChF,MAAI,WAAW,EAAG,QAAO;AACzB,MAAI,WAAW,IAAK,QAAO;AAC3B,MAAI,WAAW,IAAK,QAAO;AAC3B,MAAI,WAAW,OAAO,mBAAmB,KAAK,IAAI,EAAG,QAAO;AAC5D,MAAI,SAAS,sBAAsB,WAAW,IAAK,QAAO;AAC1D,MAAI,SAAS,sBAAsB,WAAW,IAAK,QAAO;AAC1D,MAAI,UAAU,IAAK,QAAO;AAC1B,MACE,SAAS,0BACT,SAAS,sBACT,WAAW,OACX,WAAW,KACX;AACA,WAAO;AAAA,EACT;AACA,MAAI,SAAS,oBAAoB,kBAAkB,KAAK,IAAI,EAAG,QAAO;AACtE,MAAI,WAAW,OAAQ,UAAU,OAAO,oBAAoB,KAAK,IAAI,GAAI;AACvE,WAAO;AAAA,EACT;AACA,MAAI,UAAU,IAAK,QAAO;AAC1B,SAAO;AACT;AAgDO,SAAS,iBAAiB,MAAkC;AACjE,SAAO,wBAAwB,IAAI;AACrC;AAEA,IAAM,0BAA8D;AAAA,EAClE,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,aAAa;AAAA,EACb,MAAM;AAAA,EACN,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,SAAS;AACX;AAEO,IAAM,gBAAN,cAA4B,gBAAgB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EAEhB,YACE,SACA,QACA,WACA,YACA,OAKI,CAAC,GACL;AACA,UAAM,OAAO,KAAK,QAAQ,sBAAsB,QAAQ,KAAK,MAAM,OAAO;AAC1E,UAAM;AAAA,MACJ;AAAA,MACA,MAAM,WAAW,IAAI;AAAA,MACrB,WAAW;AAAA,MACX,UAAU,UAAU,MAAM,UAAU;AAAA,MACpC,aAAa;AAAA,MACb,SAAS,EAAE,YAAY,OAAO;AAAA,MAC9B,OAAO,KAAK;AAAA,IACd,CAAC;AACD,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,YAAY;AACjB,SAAK,aAAa;AAClB,SAAK,OAAO;AACZ,SAAK,OAAO,KAAK;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcS,WAAmB;AAC1B,UAAM,OAAO,eAAe,KAAK,QAAQ,KAAK,MAAM,IAAI;AACxD,UAAM,OAAO,GAAG,KAAK,UAAU,IAAI,IAAI;AACvC,UAAM,SAAS,KAAK,MAAM,SAAS,KAAK;AACxC,UAAM,QAAQ,KAAK,MAAM,YACrB,SAAS,KAAK,KAAK,UAAU,MAAM,GAAG,EAAE,CAAC,GAAG,KAAK,KAAK,UAAU,SAAS,KAAK,WAAM,EAAE,MACtF;AACJ,QAAI,UAAU,OAAO,SAAS,GAAG;AAC/B,aAAO,GAAG,IAAI,KAAK,SAAS,QAAQ,GAAG,CAAC,GAAG,KAAK;AAAA,IAClD;AACA,WAAO,GAAG,IAAI,GAAG,KAAK;AAAA,EACxB;AACF;AAqBA,SAAS,eAAe,QAAgB,MAAuB;AAC7D,MAAI,WAAW,EAAG,QAAO;AACzB,MAAI,WAAW,IAAK,QAAO,gBAAgB,MAAM;AACjD,MAAI,SAAS,sBAAsB,WAAW,IAAK,QAAO,eAAe,MAAM;AAC/E,MAAI,SAAS,sBAAsB,WAAW,IAAK,QAAO,iBAAiB,MAAM;AACjF,MAAI,SAAS,0BAA0B,WAAW,IAAK,QAAO,gBAAgB,MAAM;AACpF,MAAI,SAAS,sBAAsB,WAAW,IAAK,QAAO,cAAc,MAAM;AAC9E,MAAI,SAAS,qBAAqB,WAAW,IAAK,QAAO,cAAc,MAAM;AAC7E,MAAI,SAAS,iBAAkB,QAAO,qBAAqB,MAAM;AACjE,MAAI,SAAS,2BAA2B,WAAW,IAAK,QAAO,oBAAoB,MAAM;AACzF,MAAI,WAAW,IAAK,QAAO,YAAY,MAAM;AAC7C,MAAI,UAAU,OAAO,SAAS,IAAK,QAAO,QAAQ,MAAM;AACxD,MAAI,KAAM,QAAO,GAAG,IAAI,KAAK,MAAM;AACnC,SAAO,QAAQ,MAAM;AACvB;AAuDA,IAAM,eAAqD;AAAA,EACzD,SAAS,YAAY;AAAA,EACrB,SAAS,YAAY;AAAA,EACrB,YAAY,YAAY;AAAA,EACxB,iBAAiB,YAAY;AAAA,EAC7B,MAAM,YAAY;AAAA,EAClB,YAAY,YAAY;AAAA,EACxB,kBAAkB,YAAY;AAAA,EAC9B,QAAQ,YAAY;AAAA,EACpB,aAAa,YAAY;AAAA,EACzB,gBAAgB,YAAY;AAAA,EAC5B,iBAAiB,YAAY;AAAA,EAC7B,SAAS,YAAY;AACvB;AAEA,SAAS,WAAW,MAAoC;AACtD,SAAO,aAAa,IAAI;AAC1B;;;ACllBA,IAAM,qBAAqB;AAK3B,IAAM,qBAAqB;AAyBpB,IAAM,sBAAN,MAA0B;AAAA,EACd;AAAA,EAEjB,YAAY,MAAkC;AAC5C,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,KAAK,OAAmD;AAC5D,UAAM,YAAY,YAAY,IAAI;AAClC,UAAM,SAAS,KAAK,KAAK,UAAU;AAGnC,UAAM,SAAS,KAAK,cAAc,OAAO,MAAM;AAC/C,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,MAAM,SAAS,OAAO,SAAS;AAAA,QACtC,UAAU,MAAM,cAAc,OAAO,YAAY;AAAA,QACjD,QAAQ,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,EAAE;AAAA,QACxC,YAAY,KAAK,MAAM,YAAY,IAAI,IAAI,SAAS;AAAA,QACpD,cAAc;AAAA,QACd,OAAO;AAAA,MACT;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,KAAK,KAAK,cAAc,OAAO,YAAY,OAAO,KAAK;AAAA,IAC1E,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,OAAO;AAAA,QACd,UAAU,OAAO;AAAA,QACjB,QAAQ,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,EAAE;AAAA,QACxC,YAAY,KAAK,MAAM,YAAY,IAAI,IAAI,SAAS;AAAA,QACpD,cAAc;AAAA,QACd,OAAO,0BAA0B,OAAO,UAAU,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MAC1G;AAAA,IACF;AAGA,UAAM,UAAU,KAAK,aAAa,OAAO,OAAO,KAAK;AACrD,UAAM,SAAS,KAAK,cAAc,KAAK;AAGvC,UAAM,QAAQ,KAAK,qBAAqB,OAAO,QAAQ,MAAM;AAG7D,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,oBAAoB,SAAS;AACjC,QAAI,eAAe,OAAO;AAC1B,QAAI,eAAe;AACnB,QAAI;AACJ,QAAI,mBAAmB;AAGvB,QACG,WAAW,CAAC,QAAQ,YAAY,OAAO,YAAY,OAAO,KAAK,KAChE,CAAC,sBAAsB,OAAO,2BAA2B,OAAO,YAAY,OAAO,KAAK,EACrF,SACH;AACA,WAAK,KAAK,QAAQ;AAAA,QAChB,sBAAsB,OAAO,UAAU,IAAI,OAAO,KAAK;AAAA,MACzD;AAAA,IAEF,OAAO;AACL,YAAM,iBAAiB,MAAM,KAAK;AAAA,QAChC;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AACA,YAAM,SAAS,eAAe;AAC9B,kBAAY,eAAe;AAC3B,yBAAmB,eAAe;AAElC,UAAI,QAAQ;AACV,iBAAS,cAAc,OAAO,YAAY,OAAO,KAAK;AACtD,4BAAoB,SAAS;AAC7B,uBAAe,OAAO;AACtB,eAAO,KAAK,YAAY,QAAQ,mBAAmB,cAAc,OAAO,SAAS;AAAA,MACnF;AAEA,UAAI,CAAC,oBAAoB,MAAM,WAAW,GAAG;AAC3C,eAAO,KAAK,iBAAiB,WAAW,OAAO,YAAY,OAAO,OAAO,OAAO,SAAS;AAAA,MAC3F;AAAA,IACF;AAIA,UAAM,cAAc,UAChB,MAAM,OAAO,CAAC,MAAM,QAAQ,YAAY,EAAE,YAAY,EAAE,KAAK,CAAC,IAC9D;AAEJ,eAAW,SAAS,aAAa;AAC/B,UACE,CAAC,sBAAsB,OAAO,2BAA2B,MAAM,YAAY,MAAM,KAAK,EACnF;AAEH;AACF,UAAI,MAAM,eAAe,SAAS,MAAM,MAAM,UAAU,OAAO,MAAO;AAEtE,UAAI;AACJ,UAAI;AACF,qBAAa,MAAM,KAAK,KAAK,cAAc,MAAM,YAAY,MAAM,KAAK;AAAA,MAC1E,SAAS,KAAK;AACZ,oBAAY;AACZ;AAAA,MACF;AAEA,0BAAoB,WAAW;AAC/B,qBAAe,MAAM;AACrB,YAAM,UAAU,MAAM,KAAK;AAAA,QACzB;AAAA,QACA,KAAK,aAAa,OAAO,MAAM,KAAK;AAAA,QACpC;AAAA,QACA,MAAM;AAAA,QACN,MAAM;AAAA,MACR;AACA,UAAI,QAAQ,UAAU;AACpB,iBAAS,cAAc,MAAM,YAAY,MAAM,KAAK;AACpD,uBAAe;AACf,eAAO,KAAK,YAAY,QAAQ,UAAU,mBAAmB,cAAc,MAAM,SAAS;AAAA,MAC5F;AAEA,kBAAY,QAAQ;AACpB,yBAAmB,QAAQ;AAC3B,UAAI,CAAC,iBAAkB;AAAA,IACzB;AAGA,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,cACN,OACA,QACmD;AAEnD,QAAI,MAAM,QAAQ,KAAK,KAAK,aAAa;AACvC,YAAM,OAAO,KAAK,KAAK,YAAY,YAAY,MAAM,MAAM,EAAE;AAC7D,UAAI,MAAM;AACR,eAAO,EAAE,YAAY,KAAK,UAAU,OAAO,KAAK,MAAM;AAAA,MACxD;AAAA,IACF;AAGA,QAAI,MAAM,cAAc,MAAM,OAAO;AACnC,aAAO,EAAE,YAAY,MAAM,YAAY,OAAO,MAAM,MAAM;AAAA,IAC5D;AAGA,QAAI,MAAM,OAAO;AACf,aAAO,EAAE,YAAY,OAAO,UAAU,OAAO,MAAM,MAAM;AAAA,IAC3D;AAGA,QAAI,MAAM,YAAY;AACpB,aAAO,EAAE,YAAY,MAAM,YAAY,OAAO,OAAO,MAAM;AAAA,IAC7D;AAGA,QAAI,OAAO,YAAY,OAAO,OAAO;AACnC,aAAO,EAAE,YAAY,OAAO,UAAU,OAAO,OAAO,MAAM;AAAA,IAC5D;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,OAAwB,OAAwB;AACnE,UAAM,WAAsB,CAAC,GAAI,MAAM,YAAY,CAAC,CAAE;AACtD,QAAI,MAAM,YAAY;AACpB,eAAS,KAAK,EAAE,MAAM,QAAQ,SAAS,MAAM,WAAW,CAAC;AAAA,IAC3D;AAEA,UAAM,SAAS,aAAa,MAAM,MAAM;AAExC,WAAO;AAAA,MACL;AAAA,MACA,GAAI,OAAO,SAAS,IAAI,EAAE,OAAO,IAAI,CAAC;AAAA,MACtC;AAAA,MACA,WAAW,MAAM,aAAa;AAAA,MAC9B,GAAI,MAAM,gBAAgB,SAAY,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,MAC5E,GAAI,MAAM,iBAAiB,EAAE,gBAAgB,MAAM,eAAe,IAAI,CAAC;AAAA,IACzE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,cAAc,OAAqC;AACzD,UAAM,gBAAgB,YAAY,QAAQ,MAAM,aAAa,kBAAkB;AAC/E,WAAO,MAAM,SAAS,YAAY,IAAI,CAAC,MAAM,QAAQ,aAAa,CAAC,IAAI;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,qBACN,OACA,QACA,QACe;AACf,UAAM,MAAM,KAAK,KAAK;AAGtB,QAAI,MAAM,kBAAkB,MAAM,eAAe,SAAS,GAAG;AAC3D,aAAO,IAAI,YAAY,MAAM,gBAAgB,MAAM;AAAA,IACrD;AAGA,QAAI,OAAO,kBAAkB,OAAO,eAAe,SAAS,GAAG;AAC7D,aAAO,IAAI,YAAY,OAAO,gBAAgB,MAAM;AAAA,IACtD;AAGA,QAAI,OAAO,iBAAiB,OAAO;AACjC,aAAO,IAAI,iBAAiB;AAAA,QAC1B,cAAc;AAAA,QACd,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAEA,WAAO,OAAO,OAAO,CAAC,CAAC;AAAA,EACzB;AAAA;AAAA,EAGA,MAAc,QACZ,UACA,SACA,QACA,YACA,OACsB;AACtB,QAAI;AACF,aAAO;AAAA,QACL,UAAU,MAAM,SAAS,SAAS,SAAS,EAAE,OAAO,CAAC;AAAA,QACrD,kBAAkB;AAAA,MACpB;AAAA,IACF,SAAS,KAAK;AAEZ,UAAI,eAAe,iBAAiB,cAAc,OAAO;AACvD,aAAK,KAAK,eAAe;AAAA,UACvB;AAAA,UACA;AAAA,UACA,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI,SAAS;AAAA,UACb,EAAE,cAAc,IAAI,MAAM,aAAa;AAAA,QACzC;AAAA,MACF;AACA,aAAO;AAAA,QACL,OAAO;AAAA,QACP,kBACE,CAAC,OAAO,YAAY,EAAE,eAAe,kBAAkB,iBAAiB,IAAI,IAAI;AAAA,MACpF;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGQ,YACN,UACA,mBACA,cACA,cACA,WACkB;AAClB,UAAM,aAAa,SAAS,QAAQ,OAAO,WAAW;AACtD,UAAM,OAAO,WACV,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,IAAI,EACT,KAAK;AACR,WAAO;AAAA,MACL,MAAM,QAAQ;AAAA,MACd,OAAO,SAAS,SAAS;AAAA,MACzB,UAAU;AAAA,MACV,QAAQ;AAAA,QACN,OAAO,SAAS,OAAO,SAAS;AAAA,QAChC,QAAQ,SAAS,OAAO,UAAU;AAAA,QAClC,QAAQ,SAAS,OAAO,SAAS,MAAM,SAAS,OAAO,UAAU;AAAA,MACnE;AAAA,MACA,YAAY,KAAK,MAAM,YAAY,IAAI,IAAI,SAAS;AAAA,MACpD;AAAA,MACA,YAAY,SAAS;AAAA,IACvB;AAAA,EACF;AAAA;AAAA,EAGQ,iBACN,OACA,mBACA,cACA,cACA,WACkB;AAClB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,MACP,UAAU;AAAA,MACV,QAAQ,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,EAAE;AAAA,MACxC,YAAY,KAAK,MAAM,YAAY,IAAI,IAAI,SAAS;AAAA,MACpD;AAAA,MACA,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,SAAS,eAAe;AAAA,IACjF;AAAA,EACF;AACF;AAKA,SAAS,aACP,QAC0C;AAC1C,MAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,MAAI,MAAM,QAAQ,MAAM,EAAG,QAAO;AAClC,SAAO,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,CAAC;AACxC;;;AClYO,IAAM,yBAAyB;AA8BtC,IAAMC,gBAA2B;AAAA,EAC/B,MAAM;AAAA,EACN,YAAY;AAAA,IACV,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,YAAY;AAAA,MACV,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,MACN,OAAO;AAAA,QACL,MAAM;AAAA,QACN,YAAY;AAAA,UACV,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,MAAM,CAAC,UAAU,QAAQ,aAAa,MAAM;AAAA,YAC5C,aAAa;AAAA,UACf;AAAA,UACA,SAAS;AAAA,YACP,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,QACF;AAAA,QACA,UAAU,CAAC,QAAQ,SAAS;AAAA,QAC5B,sBAAsB;AAAA,MACxB;AAAA,MACA,aAAa;AAAA,IACf;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,YAAY;AAAA,MACV,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,gBAAgB;AAAA,MACd,MAAM;AAAA,MACN,OAAO,EAAE,MAAM,SAAS;AAAA,MACxB,aAAa;AAAA,IACf;AAAA,IACA,WAAW;AAAA,MACT,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,gBAAgB;AAAA,MACd,OAAO;AAAA,QACL,EAAE,MAAM,UAAU,MAAM,CAAC,QAAQ,aAAa,GAAG,aAAa,0BAA0B;AAAA,QACxF;AAAA,UACE,MAAM;AAAA,UACN,YAAY;AAAA,YACV,MAAM,EAAE,MAAM,UAAU,MAAM,CAAC,aAAa,GAAG,aAAa,0BAA0B;AAAA,YACtF,aAAa;AAAA,cACX,MAAM;AAAA,cACN,aAAa;AAAA,YACf;AAAA,UACF;AAAA,UACA,UAAU,CAAC,MAAM;AAAA,UACjB,sBAAsB;AAAA,QACxB;AAAA,MACF;AAAA,MACA,aAAa;AAAA,IACf;AAAA,IACA,aAAa;AAAA,MACX,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,WAAW;AAAA,MACT,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,EACF;AACF;AAsBO,SAAS,qBAAqB,MAA4E;AAC/G,QAAM,eAAe,IAAI,oBAAoB;AAAA,IAC3C,eAAe,KAAK;AAAA,IACpB,WAAW,KAAK;AAAA,IAChB,wBAAwB,KAAK;AAAA,IAC7B,aAAa,KAAK;AAAA,IAClB,QAAQ,KAAK;AAAA,EACf,CAAC;AAED,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aACE;AAAA,IAIF,WACE;AAAA,IAIF,aAAaA;AAAA,IACb,YAAY;AAAA,IACZ,UAAU;AAAA,IAEV,MAAM,QACJ,OACA,MACA,EAAE,OAAO,GACkB;AAG3B,UAAI,CAAC,MAAM,SAAS,CAAC,MAAM,cAAc,CAAC,KAAK,gBAAgB,CAAC,KAAK,iBAAiB;AACpF,eAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO;AAAA,UACP,UAAU;AAAA,UACV,QAAQ,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,EAAE;AAAA,UACxC,YAAY;AAAA,UACZ,cAAc;AAAA,UACd,OACE;AAAA,QAGJ;AAAA,MACF;AAGA,YAAM,iBAAkC;AAAA,QACtC,GAAG;AAAA,QACH,QAAQ,MAAM,SAAS,YAAY,IAAI,CAAC,MAAM,QAAQ,MAAM,CAAC,IAAI;AAAA,QACjE,OAAO,MAAM,SAAS,KAAK;AAAA,QAC3B,YAAY,MAAM,cAAc,KAAK;AAAA,MACvC;AAEA,aAAO,aAAa,KAAK,cAAc;AAAA,IACzC;AAAA,EACF;AACF;;;ACzIA,IAAM,OAAO,KAAK,KAAK;AAQhB,IAAM,eAAgC;AAAA,EAC3C,WAAW,IAAI;AAAA,EACf,eAAe;AAAA,EACf,cAAc;AAChB;AACO,IAAM,gBAAiC;AAAA,EAC5C,WAAW,IAAI;AAAA,EACf,eAAe;AAAA,EACf,cAAc;AAChB;AACO,IAAM,eAAgC;AAAA,EAC3C,WAAW,KAAK;AAAA,EAChB,eAAe;AAAA,EACf,cAAc;AAChB;AAOO,IAAM,QAAQ;AAAA;AAAA,EAEnB,MAAM,CAAC,QAAQ,QAAQ,QAAQ,UAAU,QAAQ,SAAS;AAAA;AAAA,EAE1D,SAAS,CAAC,QAAQ,QAAQ,QAAQ,UAAU,QAAQ,QAAQ,QAAQ,QAAQ,SAAS,SAAS;AAAA;AAAA,EAE9F,OAAO,CAAC,QAAQ,QAAQ,QAAQ,UAAU,QAAQ,SAAS,QAAQ,WAAW,SAAS,SAAS;AAAA;AAAA,EAEhG,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA;AAAA,EAEA,KAAK,CAAC,QAAQ,QAAQ,QAAQ,OAAO,MAAM;AAAA;AAAA,EAE3C,MAAM,CAAC,QAAQ,QAAQ,QAAQ,WAAW,YAAY,SAAS,QAAQ,SAAS;AAAA;AAAA,EAEhF,MAAM,CAAC,QAAQ,QAAQ,QAAQ,UAAU,QAAQ,SAAS,QAAQ,YAAY,SAAS;AAAA;AAAA,EAEvF,UAAU,CAAC,QAAQ,QAAQ,QAAQ,UAAU,SAAS,SAAS;AACjE;;;AC3HA,SAAS,gBAAAC,eAAc,YAAAC,iBAAgB;AACvC,YAAY,QAAQ;AACpB,YAAYC,WAAU;AACtB,SAAS,iBAAAC,sBAAqB;AAQ9B,IAAM,cAAc,oBAAI,IAAoB;AAS5C,IAAM,iBAAiB,oBAAI,IAAsB;AAE1C,SAAS,YAAY,IAAoB;AAC9C,QAAM,SAAS,QAAQ,IAAI,mCAAmC,KAAK;AACnE,QAAM,WAAW,GAAG,MAAM,KAAS,EAAE;AACrC,QAAM,SAAS,YAAY,IAAI,QAAQ;AACvC,MAAI,WAAW,OAAW,QAAO;AAEjC,QAAM,WAAW,GAAG,EAAE;AACtB,MAAI,WAAW;AACf,aAAW,OAAO,yBAAyB,MAAM,GAAG;AAClD,QAAI;AACF,iBAAWH,cAAkB,WAAK,KAAK,QAAQ,GAAG,MAAM,EAAE,QAAQ;AAClE;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,cAAY,IAAI,UAAU,QAAQ;AAClC,SAAO;AACT;AAEA,SAAS,yBAAyB,QAA0B;AAC1D,QAAM,aAAa,QAAQ,IAAI,iBAAiB,KAAU,WAAQ,WAAQ,GAAG,aAAa;AAC1F,QAAM,UAAU,GAAG,MAAM,KAAS,UAAU;AAC5C,QAAM,SAAS,eAAe,IAAI,OAAO;AACzC,MAAI,WAAW,OAAW,QAAO;AAEjC,QAAM,OAAY,cAAQG,eAAc,YAAY,GAAG,CAAC;AACxD,QAAM,cAAc,UAAU;AAC9B,QAAM,aAAa;AAAA,IACjB,GAAI,cAAc,CAAM,cAAQ,WAAW,CAAC,IAAI,CAAC;AAAA,IAC5C,WAAK,YAAY,gBAAgB,QAAQ;AAAA,IACzC,cAAQ,MAAM,iCAAiC;AAAA,IAC/C,cAAQ,MAAM,8BAA8B;AAAA,IAC5C,cAAQ,MAAM,2BAA2B;AAAA,IACzC,cAAQ,MAAM,wBAAwB;AAAA,IACtC,cAAQ,MAAM,qBAAqB;AAAA,EAC1C;AACA,QAAM,UAAU,WAAW,KAAK,CAAC,GAAG,MAAM,OAAO,CAACC,aAAY,CAAC,CAAC,IAAI,OAAO,CAACA,aAAY,CAAC,CAAC,CAAC;AAC3F,iBAAe,IAAI,SAAS,OAAO;AACnC,SAAO;AACT;AAEA,SAASA,aAAY,WAA4B;AAC/C,MAAI;AACF,WAAOH,UAAS,SAAS,EAAE,YAAY;AAAA,EACzC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AClEO,IAAM,mBAAsC;AAAA,EACjD;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,IAAI;AAAA,MACrB,QAAQ,YAAY,SAAS;AAAA,IAC/B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,IAAI;AAAA,MACrB,QAAQ,YAAY,QAAQ;AAAA,IAC9B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,QAAQ;AAAA,MACzB,QAAQ,YAAY,UAAU;AAAA,IAChC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACnFA,IAAM,aAAa,CAAC,GAAG,MAAM,MAAM,QAAQ,MAAM;AAG1C,IAAM,kBAAqC;AAAA,EAChD;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,UAAU;AAAA,MACrB,QAAQ,YAAY,SAAS;AAAA,IAC/B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,UAAU;AAAA,MACrB,QAAQ,YAAY,SAAS;AAAA,IAC/B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,UAAU;AAAA,MACrB,QAAQ,YAAY,WAAW;AAAA,IACjC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,IAAI;AAAA,MACrB,QAAQ,YAAY,QAAQ;AAAA,IAC9B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,YAAY,MAAM;AAAA,MAC7B,QAAQ,YAAY,kBAAkB;AAAA,IACxC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACpIO,IAAM,eAAkC;AAAA,EAC7C;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,KAAK;AAAA,MACtB,QAAQ,YAAY,UAAU;AAAA,IAChC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,KAAK;AAAA,MACtB,QAAQ,YAAY,UAAU;AAAA,IAChC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,KAAK;AAAA,MACtB,QAAQ,YAAY,YAAY;AAAA,IAClC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,OAAO,WAAW,UAAU;AAAA,MAC7C,QAAQ,YAAY,WAAW;AAAA,IACjC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,OAAO,OAAO;AAAA,MAC/B,QAAQ,YAAY,QAAQ;AAAA,IAC9B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,OAAO,MAAM;AAAA,MAC9B,QAAQ,YAAY,UAAU;AAAA,IAChC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,OAAO,MAAM;AAAA,MAC9B,QAAQ,YAAY,QAAQ;AAAA,IAC9B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AClLO,IAAM,gBAAmC;AAAA,EAC9C;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,SAAS,QAAQ,QAAQ,QAAQ,aAAa,QAAQ,KAAK;AAAA,MAC5E,QAAQ,YAAY,UAAU;AAAA,IAChC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SACE;AAAA,MACF,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,KAAK;AAAA,MACtB,QAAQ,YAAY,MAAM;AAAA,IAC5B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SACE;AAAA,MACF,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO;AAAA,QACL,GAAG,MAAM;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,QAAQ,YAAY,KAAK;AAAA,IAC3B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SACE;AAAA,MACF,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO;AAAA,QACL,GAAG,MAAM;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,QAAQ,YAAY,SAAS;AAAA,IAC/B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SACE;AAAA,MACF,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,OAAO,MAAM;AAAA,MAC9B,QAAQ,YAAY,aAAa;AAAA,IACnC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SACE;AAAA,MACF,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,OAAO,MAAM;AAAA,MAC9B,QAAQ,YAAY,OAAO;AAAA,IAC7B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SACE;AAAA,MACF,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,OAAO;AAAA,MACxB,QAAQ,YAAY,kBAAkB;AAAA,IACxC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SACE;AAAA,MACF,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,OAAO;AAAA,MACxB,QAAQ,YAAY,YAAY;AAAA,IAClC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SACE;AAAA,MACF,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,OAAO;AAAA,MACxB,QAAQ,YAAY,WAAW;AAAA,IACjC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SACE;AAAA,MACF,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC5SO,IAAM,gBAAmC;AAAA,EAC9C;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,SAAS,KAAK;AAAA,MAC/B,QAAQ,YAAY,UAAU;AAAA,IAChC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SACE;AAAA,MACF,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,SAAS,KAAK;AAAA,MAC/B,QAAQ,YAAY,eAAe;AAAA,IACrC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SACE;AAAA,MACF,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,SAAS,KAAK;AAAA,MAC/B,QAAQ,YAAY,mBAAmB;AAAA,IACzC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SACE;AAAA,MACF,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,IAAI;AAAA,MACrB,QAAQ,YAAY,eAAe;AAAA,IACrC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SACE;AAAA,MACF,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,OAAO;AAAA,MACxB,QAAQ,YAAY,YAAY;AAAA,IAClC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SACE;AAAA,MACF,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC5IO,IAAM,gBAAmC;AAAA,EAC9C;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,KAAK;AAAA,MACtB,QAAQ,YAAY,UAAU;AAAA,IAChC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,OAAO,OAAO;AAAA,MAC/B,QAAQ,YAAY,KAAK;AAAA,IAC3B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,KAAK;AAAA,MACtB,QAAQ,YAAY,MAAM;AAAA,IAC5B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,KAAK;AAAA,MACtB,QAAQ,YAAY,MAAM;AAAA,IAC5B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,OAAO,OAAO;AAAA,MAC/B,QAAQ,YAAY,UAAU;AAAA,IAChC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,KAAK;AAAA,MACtB,QAAQ,YAAY,SAAS;AAAA,IAC/B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,IAAI;AAAA,MACrB,QAAQ,YAAY,UAAU;AAAA,IAChC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,OAAO,OAAO;AAAA,MAC/B,QAAQ,YAAY,KAAK;AAAA,IAC3B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SACE;AAAA,MACF,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACjOO,IAAM,mBAAsC;AAAA,EACjD;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,IAAI;AAAA,MACrB,QAAQ,YAAY,UAAU;AAAA,IAChC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,MAAM,SAAS,MAAM;AAAA,MACtC,QAAQ,YAAY,KAAK;AAAA,IAC3B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,KAAK;AAAA,MACtB,QAAQ,YAAY,MAAM;AAAA,IAC5B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,KAAK;AAAA,MACtB,QAAQ,YAAY,QAAQ;AAAA,IAC9B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACvGO,IAAM,kBAAqC;AAAA,EAChD;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,KAAK,MAAM;AAAA,MAC5B,QAAQ,YAAY,KAAK;AAAA,IAC3B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,KAAK,QAAQ,MAAM;AAAA,MACpC,QAAQ,YAAY,SAAS;AAAA,IAC/B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO;AAAA,QACL,GAAG,MAAM;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,QAAQ,YAAY,QAAQ;AAAA,IAC9B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,OAAO,MAAM;AAAA,MAC9B,QAAQ,YAAY,eAAe;AAAA,IACrC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,MAAM,MAAM;AAAA,MAC7B,QAAQ,YAAY,YAAY;AAAA,IAClC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACrKO,IAAM,cAAiC;AAAA,EAC5C;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,KAAK;AAAA,MACtB,QAAQ,YAAY,cAAc;AAAA,IACpC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,OAAO;AAAA,MACxB,QAAQ,YAAY,gBAAgB;AAAA,IACtC;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,SAAS,YAAY,QAAQ;AAAA,MAC9C,QAAQ,YAAY,SAAS;AAAA,IAC/B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,GAAG,MAAM,OAAO;AAAA,MACxB,QAAQ,YAAY,MAAM;AAAA,IAC5B;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,UAAU,SAAS,QAAQ,QAAQ,QAAQ,YAAY,SAAS,QAAQ,SAAS;AAAA,MACzF,QAAQ,YAAY,YAAY;AAAA,IAClC;AAAA,IACA,QAAQ;AAAA,MACN,WAAW;AAAA,MACX,eAAe;AAAA,MACf,cAAc;AAAA,MACd,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAAA,IACA,YAAY;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AChHO,IAAM,wBAA2C;AAAA,EACtD,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAGO,IAAM,kBAAyD;AAAA,EACpE,WAAW;AAAA,EACX,UAAU;AAAA,EACV,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,UAAU;AAAA,EACV,MAAM;AACR;AAMO,IAAM,iBAAkD,MAAM;AACnE,QAAM,MAAuC,CAAC;AAC9C,aAAW,OAAO,uBAAuB;AACvC,UAAM,OAAO,IAAI,OAAO;AACxB,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,UAAU,IAAI,OAAO,IAAI,qBAAqB;AAAA,IAChE;AACA,QAAI,IAAI,IAAI,GAAG;AACb,YAAM,IAAI,MAAM,qCAAqC,IAAI,GAAG;AAAA,IAC9D;AACA,QAAI,IAAI,IAAI;AAAA,EACd;AACA,SAAO;AACT,GAAG;;;ACpBH,SAAS,QAAQ,OAAiC;AAChD,SAAO,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS;AAC5D;AAEA,SAAS,eAAe,OAA4C;AAClE,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,QAAQ,MAAM,MAAM,EAAG,QAAO;AAClC,MAAI,MAAM,QAAQ,MAAM,OAAO,KAAK,MAAM,QAAQ,KAAK,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAG,QAAO;AAC1F,MAAI,MAAM,QAAQ,MAAM,OAAO,KAAK,MAAM,QAAQ,KAAK,CAAC,MAAM,QAAQ,QAAQ,IAAI,CAAC,CAAC,CAAC;AACnF,WAAO;AACT,SAAO;AACT;AAEA,SAAS,sBACP,QACA,YACA,gBACU;AACV,QAAM,QAAQ,OAAO,YAAY,UAAU;AAC3C,SAAO,OAAO,WAAW,SAAY,CAAC,GAAG,MAAM,MAAM,IAAI;AAC3D;AAEA,SAAS,cAAc,QAAwD;AAC7E,QAAM,UAAU,oBAAI,IAA+B;AACnD,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,OAAO,oBAAoB,CAAC,CAAC,GAAG;AACzE,QAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,SAAS,GAAG;AAC5C,cAAQ,IAAI,MAAM,OAAO,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;AAAA,IAC7C;AAAA,EACF;AACA,SAAO;AACT;AAIO,IAAM,yBAAN,MAA6B;AAAA;AAAA,EAE1B;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAER,YAAY,QAAgB,MAAmE;AAC7F,SAAK,SAAS;AACd,SAAK,WAAW,cAAc,MAAM;AACpC,SAAK,gBAAgB,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAAiB,SAAuD;AACtE,SAAK,gBAAgB;AAAA,EACvB;AAAA;AAAA,EAIA,WAAW,MAAuB;AAChC,WAAO,KAAK,SAAS,IAAI,IAAI;AAAA,EAC/B;AAAA,EAEA,eAAkC;AAChC,WAAO,OAAO,OAAO,CAAC,GAAG,KAAK,SAAS,KAAK,CAAC,CAAC;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,QACE,MACA,OAGI,CAAC,GACU;AACf,UAAM,kBAAkB,KAAK,mBAAmB,KAAK,OAAO;AAC5D,UAAM,QAAQ,KAAK,SAAS,IAAI,IAAI;AACpC,QAAI,CAAC,MAAO,QAAO;AAEnB,UAAM,aAAa,KAAK,UACpB,GAAG,KAAK,QAAQ,UAAU,IAAI,KAAK,QAAQ,KAAK,KAChD;AAEJ,UAAM,WAAiC,CAAC;AACxC,UAAM,OAAO,oBAAI,IAAY;AAE7B,eAAW,OAAO,OAAO;AACvB,YAAM,SAAS,cAAc,GAAG;AAChC,UAAI,CAAC,OAAO,MAAO;AAEnB,YAAM,aAAa,OAAO,YAAY;AACtC,YAAM,MAAM,GAAG,UAAU,IAAI,OAAO,KAAK;AACzC,UAAI,KAAK,IAAI,GAAG,EAAG;AACnB,WAAK,IAAI,GAAG;AAGZ,UAAI,cAAc,QAAQ,WAAY;AAEtC,YAAM,SAAS,KAAK,cAAc,UAAU;AAC5C,UAAI,CAAC,OAAO,OAAQ;AAGpB,UAAI,KAAK,iBAAiB,CAAC,KAAK,cAAc,YAAY,YAAY,OAAO,KAAK,EAAG;AACrF,UACE,CAAC,sBAAsB,KAAK,OAAO,2BAA2B,YAAY,OAAO,KAAK,EACnF;AAEH;AAIF,YAAM,gBAAgB,KAAK,OAAO,YAAY,UAAU,GAAG;AAC3D,UAAI,iBAAiB,CAAC,cAAc,SAAS,OAAO,KAAK,EAAG;AAE5D,eAAS,KAAK;AAAA,QACZ;AAAA,QACA,OAAO,OAAO;AAAA,QACd,kBAAkB,gBAAgB,KAAK,SAAS,cAAc,KAAK,OAAO;AAAA,MAC5E,CAAC;AAAA,IACH;AAEA,WAAO,OAAO,OAAO,QAAQ;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,iBACE,OAKI,CAAC,GACU;AAGf,QAAI,KAAK,kBAAkB,KAAK,eAAe,SAAS,GAAG;AACzD,YAAM,WAAW,KAAK,YAAY,KAAK,gBAAgB,KAAK,OAAO;AACnE,UAAI,SAAS,SAAS,EAAG,QAAO;AAAA,IAClC;AAGA,QAAI,KAAK,iBAAiB;AACxB,YAAM,WAAW,KAAK,QAAQ,KAAK,iBAAiB,EAAE,SAAS,KAAK,QAAQ,CAAC;AAC7E,UAAI,SAAS,SAAS,EAAG,QAAO;AAAA,IAClC;AAGA,QAAI,KAAK,iBAAiB,OAAO;AAC/B,aAAO,KAAK,aAAa,KAAK,OAAO;AAAA,IACvC;AAEA,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,cAAc,YAAoC;AAChD,UAAM,QAAQ,KAAK,OAAO,YAAY,UAAU;AAChD,UAAM,YAAY,eAAe,KAAK,OAAO;AAC7C,UAAM,SAAS,eAAe,KAAK,KAAM,aAAa,QAAQ,KAAK,OAAO,MAAM;AAChF,UAAM,cAAc,QAAQ,OAAO,OAAO,KAAM,aAAa,QAAQ,KAAK,OAAO,OAAO;AACxF,UAAM,YACH,MAAM,QAAQ,OAAO,MAAM,KAAK,MAAM,OAAO,SAAS,KACtD,aAAa,QAAQ,KAAK,OAAO,KAAK;AACzC,WAAO,OAAO,OAAO;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,UAAU;AAAA,IACpB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,WAAyB;AAC9B,SAAK,SAAS;AACd,SAAK,WAAW,cAAc,SAAS;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,YACE,MACA,SACe;AACf,UAAM,aAAa,UAAU,GAAG,QAAQ,UAAU,IAAI,QAAQ,KAAK,KAAK;AACxE,UAAM,WAAiC,CAAC;AACxC,UAAM,OAAO,oBAAI,IAAY;AAE7B,eAAW,OAAO,MAAM;AACtB,YAAM,SAAS,cAAc,GAAG;AAChC,UAAI,CAAC,OAAO,MAAO;AAEnB,YAAM,aAAa,OAAO,YAAY,KAAK,OAAO;AAClD,YAAM,MAAM,GAAG,UAAU,IAAI,OAAO,KAAK;AACzC,UAAI,KAAK,IAAI,GAAG,EAAG;AACnB,WAAK,IAAI,GAAG;AACZ,UAAI,cAAc,QAAQ,WAAY;AAGtC,UAAI,KAAK,iBAAiB,CAAC,KAAK,cAAc,YAAY,YAAY,OAAO,KAAK,EAAG;AACrF,UACE,CAAC,sBAAsB,KAAK,OAAO,2BAA2B,YAAY,OAAO,KAAK,EACnF;AAEH;AAEF,eAAS,KAAK;AAAA,QACZ;AAAA,QACA,OAAO,OAAO;AAAA,QACd,kBAAkB,gBAAgB,SAAS,cAAc,KAAK,OAAO;AAAA,MACvE,CAAC;AAAA,IACH;AAEA,WAAO,OAAO,OAAO,QAAQ;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,aAAa,SAAgE;AACnF,UAAM,iBAAiB,KAAK,OAAO;AACnC,UAAM,cAAc,KAAK,OAAO;AAChC,UAAM,YAAY,KAAK,OAAO,aAAa,CAAC;AAC5C,UAAM,cAAc,IAAI;AAAA,OACrB,KAAK,OAAO,kBAAkB,CAAC,GAAG,IAAI,CAAC,QAAQ;AAC9C,cAAM,IAAI,cAAc,GAAG;AAC3B,eAAO,GAAG,EAAE,YAAY,cAAc,IAAI,EAAE,KAAK;AAAA,MACnD,CAAC;AAAA,IACH;AACA,UAAM,eAAe,YAAY,OAAO;AACxC,UAAM,gBAAgB,KAAK,OAAO,uBAAuB;AACzD,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,YAAsB,CAAC;AAC7B,UAAM,eAAyB,CAAC;AAChC,UAAM,gBAA0B,CAAC;AAEjC,UAAM,aAAa,UAAU,GAAG,QAAQ,UAAU,IAAI,QAAQ,KAAK,KAAK;AAExE,UAAM,MAAM,OAAO,KAAK,SAAS,EAAE;AAAA,MAAK,CAAC,GAAG,MAC1C,MAAM,iBAAiB,KAAK,MAAM,iBAAiB,IAAI,EAAE,cAAc,CAAC;AAAA,IAC1E;AAEA,eAAW,MAAM,KAAK;AACpB,YAAM,QAAQ,UAAU,EAAE;AAC1B,UAAI,CAAC,KAAK,cAAc,EAAE,EAAE,OAAQ;AAGpC,YAAM,SAAS,sBAAsB,KAAK,QAAQ,IAAI,OAAO,UAAU,CAAC,CAAC;AACzE,iBAAW,SAAS,QAAQ;AAC1B,YAAI,OAAO,kBAAkB,UAAU,YAAa;AACpD,cAAM,MAAM,GAAG,EAAE,IAAI,KAAK;AAC1B,YAAI,KAAK,IAAI,GAAG,EAAG;AACnB,aAAK,IAAI,GAAG;AACZ,YAAI,cAAc,QAAQ,WAAY;AAEtC,YAAI,KAAK,iBAAiB,CAAC,KAAK,cAAc,YAAY,IAAI,KAAK,EAAG;AACtE,YAAI,CAAC,sBAAsB,KAAK,OAAO,2BAA2B,IAAI,KAAK,EAAE;AAC3E;AACF,YAAI,YAAY,IAAI,GAAG,GAAG;AACxB,oBAAU,KAAK,GAAG;AAClB;AAAA,QACF;AACA,YAAI,iBAAiB,aAAc;AACnC,SAAC,OAAO,iBAAiB,eAAe,eAAe,KAAK,GAAG;AAAA,MACjE;AAAA,IACF;AAEA,UAAM,MAAM;AACZ,UAAM,MAAM,CAAC,GAAG,WAAW,GAAG,cAAc,GAAG,aAAa,EAAE,MAAM,GAAG,GAAG;AAC1E,WAAO,OAAO;AAAA,MACZ,IAAI,IAAI,CAAC,QAAQ;AACf,cAAM,IAAI,cAAc,GAAG;AAC3B,eAAO;AAAA,UACL,YAAY,EAAE,YAAY;AAAA,UAC1B,OAAO,EAAE;AAAA,UACT,mBACG,EAAE,YAAY,qBAAqB,SAAS,cAAc;AAAA,QAC/D;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,IAAM,gBAA+B,OAAO,OAAO,CAAC,CAAC;;;AC9R9C,SAAS,cAAc,KAAuB;AACnD,QAAM,UAAU,IAAI,KAAK;AACzB,QAAM,QAAQ,QAAQ,QAAQ,GAAG;AACjC,MAAI,UAAU,IAAI;AAGhB,WAAO;AAAA,MACL,UAAU,QAAQ,MAAM,GAAG,KAAK,KAAK;AAAA,MACrC,OAAO,QAAQ,MAAM,QAAQ,CAAC,EAAE,KAAK;AAAA,IACvC;AAAA,EACF;AACA,QAAM,QAAQ,QAAQ,MAAM,KAAK;AACjC,MAAI,MAAM,UAAU,GAAG;AACrB,WAAO,EAAE,UAAU,MAAM,CAAC,GAAG,OAAO,MAAM,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE;AAAA,EAC/D;AACA,SAAO,EAAE,OAAO,QAAQ;AAC1B;AAEO,SAAS,eAAe,KAAe,iBAA8C;AAC1F,QAAM,WAAW,IAAI,YAAY;AACjC,SAAO,WAAW,GAAG,QAAQ,IAAI,IAAI,KAAK,KAAK,IAAI;AACrD;AAEO,SAAS,kBAAkB,KAAa,iBAA8C;AAC3F,QAAM,SAAS,cAAc,GAAG;AAChC,SAAO,eAAe,QAAQ,eAAe;AAC/C;AAEO,SAAS,qBAAqB,QAAgB,aAA2C;AAC9F,MAAI,CAAC,YAAa,QAAO,CAAC;AAC1B,QAAM,MAAM,IAAI,uBAAuB,MAAM;AAC7C,SAAO,IAAI,QAAQ,WAAW,EAAE,IAAI,CAAC,MAAM,GAAG,EAAE,UAAU,IAAI,EAAE,KAAK,EAAE;AACzE;AA8DA,IAAM,kCAAkC,KAAK;;;ACzJtC,IAAM,oBAAuC,OAAO,KAAK,eAAe;AAG/E,IAAM,iBAAyC,MAAM;AACnD,QAAM,MAA8B,CAAC;AACrC,aAAW,CAAC,OAAO,IAAI,KAAK,OAAO,QAAQ,eAAe,GAAG;AAC3D,eAAW,OAAO,MAAM;AACtB,YAAM,OAAO,IAAI,OAAO;AACxB,UAAI,KAAM,KAAI,IAAI,IAAI;AAAA,IACxB;AAAA,EACF;AACA,SAAO;AACT,GAAG;AAGI,SAAS,aAAa,MAA8C;AACzE,SAAO,OAAO,cAAc,IAAI,IAAI;AACtC;AAeO,SAAS,6BACd,QACA,MACmC;AACnC,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,QAAQ,OAAO,IAAI,EAAG,QAAO,EAAE,OAAO,OAAO,IAAI,GAAG,QAAQ,QAAQ,KAAK,KAAK;AAClF,QAAM,QAAQ,aAAa,IAAI;AAC/B,MAAI,SAAS,OAAO,KAAK,EAAG,QAAO,EAAE,OAAO,OAAO,KAAK,GAAG,QAAQ,SAAS,KAAK,MAAM;AACvF,MAAI,OAAO,GAAG,EAAG,QAAO,EAAE,OAAO,OAAO,GAAG,GAAG,QAAQ,WAAW,KAAK,IAAI;AAC1E,SAAO;AACT;AAMO,SAAS,mBACd,QACA,MAC8B;AAC9B,SAAO,6BAA6B,QAAQ,IAAI,GAAG;AACrD;AAwBO,SAAS,4BACd,QACA,OACiC;AACjC,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,MAAM,OAAO;AACf,WAAO;AAAA,MACL,UAAU,MAAM;AAAA,MAChB,OAAO,MAAM;AAAA,MACb,cAAc,MAAM;AAAA,MACpB,iBAAiB,MAAM;AAAA,MACvB,gBAAgB,qBAAqB,QAAQ,MAAM,eAAe;AAAA,IACpE;AAAA,EACF;AACA,QAAM,QAAQ,qBAAqB,QAAQ,MAAM,eAAe;AAChE,QAAM,QAAQ,MAAM,CAAC;AACrB,MAAI,CAAC,OAAO;AACV,WAAO,MAAM,eAAe,EAAE,cAAc,MAAM,aAAa,IAAI;AAAA,EACrE;AACA,QAAM,SAAS,cAAc,KAAK;AAClC,SAAO;AAAA,IACL,UAAU,OAAO;AAAA,IACjB,OAAO,OAAO;AAAA,IACd,cAAc,MAAM;AAAA,IACpB,iBAAiB,MAAM;AAAA,IACvB,gBAAgB,MAAM,MAAM,CAAC;AAAA,EAC/B;AACF;AAkBO,SAAS,gCAAgC,MAAmC;AACjF,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,SAAS,cAAc,aAAa,IAAI,MAAM;AACvD;AAYO,SAAS,2BACd,QACA,MACA,OAA8D,CAAC,GACtB;AACzC,QAAM,aAAa,6BAA6B,OAAO,aAAa,IAAI;AACxE,QAAM,eAAe,4BAA4B,QAAQ,YAAY,KAAK;AAC1E,QAAM,uBACJ,KAAK,wBAAwB,iCAAiC,MAAM;AAEtE,MAAI,CAAC,gCAAgC,IAAI,GAAG;AAC1C,QAAI,CAAC,aAAc,QAAO;AAC1B,WAAO;AAAA,MACL,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,cAAc,YAAY;AAAA,IAC5B;AAAA,EACF;AAEA,QAAM,YAAY,kBAAkB,QAAQ,YAAY;AAExD,MAAI,YAAY,WAAW,UAAU,YAAY,WAAW,SAAS;AACnE,WAAO,eACH,EAAE,GAAG,cAAc,QAAQ,UAAU,cAAc,WAAW,OAAO,IACrE;AAAA,EACN;AAEA,MAAI,aAAa,CAAC,mBAAmB,WAAW,oBAAoB,GAAG;AACrE,WAAO;AAAA,MACL,GAAI,gBAAgB,CAAC;AAAA,MACrB,QAAQ;AAAA,MACR,cAAc,YAAY;AAAA,IAC5B;AAAA,EACF;AAEA,QAAM,UAAU,yBAAyB,QAAQ,oBAAoB;AACrE,MAAI,SAAS;AACX,WAAO;AAAA,MACL,UAAU,QAAQ;AAAA,MAClB,OAAO,QAAQ;AAAA,MACf,cAAc,cAAc;AAAA,MAC5B,gBAAgB,cAAc;AAAA,MAC9B,iBAAiB,cAAc;AAAA,MAC/B,QAAQ;AAAA,MACR,cAAc,YAAY;AAAA,MAC1B,aAAa;AAAA,IACf;AAAA,EACF;AAEA,MAAI,CAAC,aAAc,QAAO;AAC1B,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ;AAAA,IACR,cAAc,YAAY;AAAA,EAC5B;AACF;AAOO,SAAS,iCAAiC,QAAgC;AAC/E,QAAM,SAAS;AAAA,IACb;AAAA,IACA,mBAAmB,OAAO,aAAa,UAAU;AAAA,EACnD;AACA,SACE,kBAAkB,QAAQ,MAAM,KAAK;AAAA,IACnC,UAAU,OAAO;AAAA,IACjB,OAAO,OAAO;AAAA,EAChB;AAEJ;AAEO,SAAS,mBACd,GACA,GACS;AACT,MAAI,CAAC,GAAG,SAAS,CAAC,GAAG,MAAO,QAAO;AACnC,QAAM,YAAY,EAAE,YAAY;AAChC,QAAM,YAAY,EAAE,YAAY;AAChC,SAAO,cAAc,aAAa,EAAE,UAAU,EAAE;AAClD;AAEA,SAAS,kBACP,QACA,QAC4B;AAC5B,MAAI,CAAC,QAAQ,MAAO,QAAO;AAC3B,SAAO;AAAA,IACL,UAAU,OAAO,YAAY,OAAO;AAAA,IACpC,OAAO,OAAO;AAAA,EAChB;AACF;AAEA,SAAS,yBACP,QACA,OACoC;AACpC,QAAM,aAAa,8BAA8B,MAAM,EAAE;AAAA,IACvD,CAAC,cAAc,CAAC,mBAAmB,WAAW,KAAK;AAAA,EACrD;AACA,aAAW,KAAK,CAAC,GAAG,MAAM,oBAAoB,GAAG,KAAK,IAAI,oBAAoB,GAAG,KAAK,CAAC;AACvF,SAAO,WAAW,CAAC;AACrB;AAEA,SAAS,8BAA8B,QAA0C;AAC/E,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,MAAgC,CAAC;AACvC,QAAM,MAAM,CAAC,UAA8B,UAA8B;AACvE,QAAI,CAAC,YAAY,CAAC,MAAO;AACzB,UAAM,MAAM,GAAG,QAAQ,KAAS,KAAK;AACrC,QAAI,KAAK,IAAI,GAAG,EAAG;AACnB,SAAK,IAAI,GAAG;AACZ,QAAI,KAAK,EAAE,UAAU,MAAM,CAAC;AAAA,EAC9B;AAEA,MAAI,OAAO,UAAU,OAAO,KAAK;AACjC,aAAW,CAAC,YAAY,QAAQ,KAAK,OAAO,QAAQ,OAAO,aAAa,CAAC,CAAC,GAAG;AAC3E,QAAI,CAAC,oBAAoB,YAAY,UAAU,OAAO,QAAQ,EAAG;AACjE,eAAW,SAAS,SAAS,UAAU,CAAC,EAAG,KAAI,YAAY,KAAK;AAChE,eAAW,SAAS,OAAO,KAAK,SAAS,gBAAgB,CAAC,CAAC,EAAG,KAAI,YAAY,KAAK;AAAA,EACrF;AACA,aAAW,SAAS,OAAO,KAAK,OAAO,UAAU,CAAC,CAAC,EAAG,KAAI,OAAO,UAAU,KAAK;AAChF,SAAO;AACT;AAEA,SAAS,oBACP,YACA,UACA,gBACS;AACT,MAAI,eAAe,eAAgB,QAAO;AAC1C,MAAI,OAAO,SAAS,WAAW,YAAY,SAAS,OAAO,SAAS,EAAG,QAAO;AAC9E,MAAI,MAAM,QAAQ,SAAS,OAAO,KAAK,SAAS,QAAQ,KAAK,CAAC,QAAQ,KAAK,MAAM,EAAG,QAAO;AAC3F,MAAI,OAAO,SAAS,YAAY,YAAY,SAAS,QAAQ,SAAS,EAAG,QAAO;AAChF,SAAO;AACT;AAEA,SAAS,oBAAoB,WAAmC,OAA+B;AAC7F,MAAI,QAAQ;AACZ,MAAI,UAAU,aAAa,MAAM,SAAU,UAAS;AACpD,MAAI,UAAU,UAAU,MAAM,MAAO,UAAS;AAC9C,MAAI,4CAA4C,KAAK,UAAU,KAAK,EAAG,UAAS;AAChF,MAAI,oBAAoB,KAAK,UAAU,KAAK,EAAG,UAAS;AACxD,SAAO;AACT;AAKO,SAAS,cAAc,KAA4B;AACxD,MAAI,QAAQ,IAAK,QAAO;AACxB,MAAI,OAAO,cAAe,QAAO;AACjC,MAAI,kBAAkB,SAAS,GAAG,EAAG,QAAO;AAC5C,SAAO;AACT;AAGO,SAAS,iBAAiB,KAAsB;AACrD,SAAO,cAAc,GAAG,MAAM;AAChC;;;ACrRO,IAAM,4BAA4B;AAClC,IAAM,kCAAkC;AACxC,IAAM,oCAAoC;AAC1C,IAAM,+BAA+B;AA6B5C,SAAS,aAAa,KAAqB;AACzC,SAAO,IACJ,KAAK,EACL,QAAQ,aAAa,GAAG,EACxB,QAAQ,QAAQ,GAAG;AACxB;AAMA,SAAS,cAAc,KAAa,QAAyB;AAC3D,QAAM,YAAY,OAAO,kBAAkB,CAAC;AAC5C,MAAI,UAAU,WAAW,GAAG;AAE1B,WAAO;AAAA,EACT;AACA,QAAM,YAAY,kBAAkB,KAAK,OAAO,QAAQ;AACxD,SAAO,UAAU,KAAK,CAAC,MAAM,kBAAkB,GAAG,OAAO,QAAQ,MAAM,SAAS;AAClF;AAGA,SAAS,iBAAiB,KAAa,QAAwB;AAC7D,QAAM,YAAY,OAAO,kBAAkB,CAAC;AAC5C,SACE,IAAI,GAAG,uCACN,UAAU,WAAW,IAClB,iGACA,sBAAsB,UAAU,KAAK,IAAI,KAAK,QAAQ;AAG9D;AAEA,SAAS,UAAU,QAA0B;AAC3C,SAAO,OAAO,kBAAkB,CAAC;AACnC;AAEA,SAAS,YAAY,QAA0C;AAC7D,SAAQ,OAAO,oBAAoB,CAAC;AACtC;AAEA,SAAS,UAAU,QAA0B;AAC3C,SAAO,OAAO,kBAAkB,CAAC;AACnC;AAIA,IAAM,yBAAqC;AAAA,EACzC,MAAM;AAAA,EACN,YAAY;AAAA,IACV,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,MAAM,CAAC,QAAQ,OAAO,QAAQ;AAAA,MAC9B,aAAa;AAAA,IACf;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aACE;AAAA,IAEJ;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,UAAU,CAAC,QAAQ;AAAA,EACnB,sBAAsB;AACxB;AAcA,SAAS,yBAAyB,MAAkF;AAClH,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aACE;AAAA,IAGF,WAAW;AAAA,IACX,UAAU;AAAA,IACV,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM,QAAQ,OAAO;AACnB,YAAM,SAAS,KAAK,UAAU;AAC9B,YAAM,YAAY,CAAC,GAAG,UAAU,MAAM,CAAC;AAEvC,UAAI,MAAM,WAAW,QAAQ;AAC3B,cAAM,MACJ,UAAU,WAAW,IACjB,kGACA,cAAc,UAAU,MAAM;AAAA,IAAS,UAAU,IAAI,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI;AAClG,eAAO,EAAE,QAAQ,MAAM,SAAS,KAAK,WAAW,CAAC,GAAG,SAAS,EAAE;AAAA,MACjE;AAEA,UAAI,MAAM,WAAW,OAAO;AAC1B,YAAI,CAAC,MAAM,OAAO;AAChB,iBAAO,EAAE,QAAQ,SAAS,SAAS,uEAAuE;AAAA,QAC5G;AACA,cAAM,MAAM,aAAa,MAAM,KAAK;AACpC,cAAM,YAAY,kBAAkB,KAAK,OAAO,QAAQ;AACxD,YAAI,UAAU,KAAK,CAAC,MAAM,kBAAkB,GAAG,OAAO,QAAQ,MAAM,SAAS,GAAG;AAC9E,iBAAO,EAAE,QAAQ,SAAS,SAAS,IAAI,GAAG,2BAA2B;AAAA,QACvE;AACA,kBAAU,KAAK,GAAG;AAClB,cAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,cAAI,iBAAiB;AAAA,QACvB,CAAC;AACD,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,SAAS,0BAAqB,GAAG,KAAK,UAAU,MAAM;AAAA,UACtD,WAAW,CAAC,GAAG,SAAS;AAAA,QAC1B;AAAA,MACF;AAEA,UAAI,MAAM,WAAW,UAAU;AAC7B,YAAI,MAAM,UAAU,QAAW;AAC7B,gBAAM,MAAM,MAAM,QAAQ;AAC1B,cAAI,MAAM,KAAK,OAAO,UAAU,QAAQ;AACtC,mBAAO,EAAE,QAAQ,SAAS,SAAS,SAAS,MAAM,KAAK,4BAAuB,UAAU,MAAM,KAAK;AAAA,UACrG;AACA,gBAAM,CAAC,OAAO,IAAI,UAAU,OAAO,KAAK,CAAC;AACzC,gBAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,gBAAI,iBAAiB;AAAA,UACvB,CAAC;AACD,iBAAO,EAAE,QAAQ,MAAM,SAAS,4BAAuB,OAAO,IAAI,WAAW,CAAC,GAAG,SAAS,EAAE;AAAA,QAC9F;AACA,YAAI,MAAM,OAAO;AACf,gBAAM,MAAM,aAAa,MAAM,KAAK;AACpC,gBAAM,YAAY,kBAAkB,KAAK,OAAO,QAAQ;AACxD,gBAAM,MAAM,UAAU,UAAU,CAAC,MAAM,kBAAkB,GAAG,OAAO,QAAQ,MAAM,SAAS;AAC1F,cAAI,QAAQ,IAAI;AACd,mBAAO,EAAE,QAAQ,SAAS,SAAS,aAAa,GAAG,gDAAgD;AAAA,UACrG;AACA,gBAAM,CAAC,OAAO,IAAI,UAAU,OAAO,KAAK,CAAC;AACzC,gBAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,gBAAI,iBAAiB;AAAA,UACvB,CAAC;AACD,iBAAO,EAAE,QAAQ,MAAM,SAAS,4BAAuB,OAAO,IAAI,WAAW,CAAC,GAAG,SAAS,EAAE;AAAA,QAC9F;AACA,eAAO,EAAE,QAAQ,SAAS,SAAS,0DAA0D;AAAA,MAC/F;AAEA,aAAO,EAAE,QAAQ,SAAS,SAAS,oBAAoB,MAAM,MAAM,qCAAqC;AAAA,IAC1G;AAAA,EACF;AACF;AAIA,IAAM,wBAAoC;AAAA,EACxC,MAAM;AAAA,EACN,YAAY;AAAA,IACV,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,MAAM,CAAC,QAAQ,OAAO,UAAU,UAAU,OAAO;AAAA,MACjD,aACE;AAAA,IAEJ;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aACE;AAAA,IAEJ;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aACE;AAAA,IAGJ;AAAA,EACF;AAAA,EACA,UAAU,CAAC,QAAQ;AAAA,EACnB,sBAAsB;AACxB;AAcA,SAAS,8BAA8B,MAAgF;AACrH,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aACE;AAAA,IAIF,WACE;AAAA,IAGF,UAAU;AAAA,IACV,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM,QAAQ,OAAO;AACnB,YAAM,SAAS,KAAK,UAAU;AAC9B,YAAM,QAAQ,CAAC,GAAG,UAAU,MAAM,CAAC;AAEnC,UAAI,MAAM,WAAW,QAAQ;AAC3B,YAAI,MAAM,WAAW,GAAG;AACtB,iBAAO;AAAA,YACL,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,OAAO,CAAC;AAAA,UACV;AAAA,QACF;AACA,cAAM,MAAM,MAAM,IAAI,CAAC,KAAK,MAAM,KAAK,IAAI,CAAC,KAAK,GAAG,EAAE,EAAE,KAAK,IAAI;AACjE,eAAO,EAAE,QAAQ,MAAM,SAAS,mBAAmB,MAAM,MAAM;AAAA,EAAO,GAAG,IAAI,OAAO,CAAC,GAAG,KAAK,EAAE;AAAA,MACjG;AAEA,UAAI,MAAM,WAAW,OAAO;AAC1B,YAAI,CAAC,MAAM,OAAO;AAChB,iBAAO,EAAE,QAAQ,SAAS,SAAS,yEAAyE;AAAA,QAC9G;AACA,cAAM,MAAM,aAAa,MAAM,KAAK;AACpC,YAAI,CAAC,cAAc,KAAK,MAAM,GAAG;AAC/B,iBAAO,EAAE,QAAQ,SAAS,SAAS,iBAAiB,KAAK,MAAM,EAAE;AAAA,QACnE;AACA,YAAI,MAAM,KAAK,CAAC,MAAM,aAAa,CAAC,MAAM,GAAG,GAAG;AAC9C,iBAAO,EAAE,QAAQ,SAAS,SAAS,IAAI,GAAG,6BAA6B;AAAA,QACzE;AACA,cAAM,KAAK,GAAG;AACd,cAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,cAAI,iBAAiB;AAAA,QACvB,CAAC;AACD,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,SAAS,0BAAqB,GAAG,cAAc,MAAM,MAAM;AAAA,UAC3D,OAAO,CAAC,GAAG,KAAK;AAAA,QAClB;AAAA,MACF;AAEA,UAAI,MAAM,WAAW,UAAU;AAC7B,YAAI,CAAC,MAAM,OAAO;AAChB,iBAAO,EAAE,QAAQ,SAAS,SAAS,4CAA4C;AAAA,QACjF;AACA,cAAM,MAAM,aAAa,MAAM,KAAK;AACpC,YAAI,CAAC,cAAc,KAAK,MAAM,GAAG;AAC/B,iBAAO,EAAE,QAAQ,SAAS,SAAS,iBAAiB,KAAK,MAAM,EAAE;AAAA,QACnE;AACA,YAAI,MAAM,KAAK,CAAC,MAAM,aAAa,CAAC,MAAM,GAAG,GAAG;AAC9C,iBAAO,EAAE,QAAQ,SAAS,SAAS,IAAI,GAAG,6BAA6B;AAAA,QACzE;AACA,YAAI,MAAM,MAAM;AAChB,YAAI,MAAM,UAAU,QAAW;AAC7B,gBAAM,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,QAAQ,MAAM,QAAQ,CAAC,CAAC;AAAA,QAC3D;AACA,cAAM,OAAO,KAAK,GAAG,GAAG;AACxB,cAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,cAAI,iBAAiB;AAAA,QACvB,CAAC;AACD,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,SAAS,+BAA0B,MAAM,CAAC,KAAK,GAAG;AAAA,UAClD,OAAO,CAAC,GAAG,KAAK;AAAA,QAClB;AAAA,MACF;AAEA,UAAI,MAAM,WAAW,UAAU;AAC7B,YAAI,MAAM,WAAW,GAAG;AACtB,iBAAO,EAAE,QAAQ,SAAS,SAAS,2CAAsC;AAAA,QAC3E;AACA,YAAI,MAAM,UAAU,QAAW;AAC7B,gBAAM,MAAM,MAAM,QAAQ;AAC1B,cAAI,MAAM,KAAK,OAAO,MAAM,QAAQ;AAClC,mBAAO,EAAE,QAAQ,SAAS,SAAS,SAAS,MAAM,KAAK,4BAAuB,MAAM,MAAM,KAAK;AAAA,UACjG;AACA,gBAAM,CAAC,OAAO,IAAI,MAAM,OAAO,KAAK,CAAC;AACrC,gBAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,gBAAI,iBAAiB;AAAA,UACvB,CAAC;AACD,iBAAO,EAAE,QAAQ,MAAM,SAAS,mBAAc,OAAO,IAAI,OAAO,CAAC,GAAG,KAAK,EAAE;AAAA,QAC7E;AACA,YAAI,MAAM,OAAO;AACf,gBAAM,MAAM,aAAa,MAAM,KAAK;AACpC,gBAAM,MAAM,MAAM,UAAU,CAAC,MAAM,aAAa,CAAC,MAAM,GAAG;AAC1D,cAAI,QAAQ,IAAI;AACd,mBAAO,EAAE,QAAQ,SAAS,SAAS,IAAI,GAAG,wBAAwB;AAAA,UACpE;AACA,gBAAM,CAAC,OAAO,IAAI,MAAM,OAAO,KAAK,CAAC;AACrC,gBAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,gBAAI,iBAAiB;AAAA,UACvB,CAAC;AACD,iBAAO,EAAE,QAAQ,MAAM,SAAS,mBAAc,OAAO,IAAI,OAAO,CAAC,GAAG,KAAK,EAAE;AAAA,QAC7E;AACA,eAAO,EAAE,QAAQ,SAAS,SAAS,uDAAuD;AAAA,MAC5F;AAEA,UAAI,MAAM,WAAW,SAAS;AAC5B,YAAI,MAAM,WAAW,GAAG;AACtB,iBAAO,EAAE,QAAQ,MAAM,SAAS,0BAA0B;AAAA,QAC5D;AACA,cAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,cAAI,iBAAiB,CAAC;AAAA,QACxB,CAAC;AACD,eAAO,EAAE,QAAQ,MAAM,SAAS,gFAA2E;AAAA,MAC7G;AAEA,aAAO,EAAE,QAAQ,SAAS,SAAS,oBAAoB,MAAM,MAAM,KAAK;AAAA,IAC1E;AAAA,EACF;AACF;AAIA,IAAM,0BAAsC;AAAA,EAC1C,MAAM;AAAA,EACN,YAAY;AAAA,IACV,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,MAAM,CAAC,QAAQ,OAAO,QAAQ;AAAA,MAC9B,aAAa;AAAA,IACf;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aACE;AAAA,IACJ;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,EAAE,MAAM,SAAS;AAAA,MACxB,aACE;AAAA,IAEJ;AAAA,EACF;AAAA,EACA,UAAU,CAAC,QAAQ;AAAA,EACnB,sBAAsB;AACxB;AAcA,SAAS,gCAAgC,MAAoF;AAC3H,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aACE;AAAA,IAIF,WACE;AAAA,IAGF,UAAU;AAAA,IACV,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM,QAAQ,OAAO;AACnB,YAAM,SAAS,KAAK,UAAU;AAC9B,YAAM,WAAW,EAAE,GAAG,YAAY,MAAM,EAAE;AAE1C,UAAI,MAAM,WAAW,QAAQ;AAC3B,cAAM,QAAQ,OAAO,KAAK,QAAQ;AAClC,YAAI,MAAM,WAAW,GAAG;AACtB,iBAAO;AAAA,YACL,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,UAAU,CAAC;AAAA,UACb;AAAA,QACF;AACA,cAAM,MAAM,MACT,KAAK,EACL,IAAI,CAAC,SAAS,KAAK,IAAI,WAAM,SAAS,IAAI,GAAG,KAAK,UAAK,KAAK,SAAS,EAAE,EACvE,KAAK,IAAI;AACZ,eAAO,EAAE,QAAQ,MAAM,SAAS;AAAA,EAAuB,GAAG,IAAI,UAAU,EAAE,GAAG,SAAS,EAAE;AAAA,MAC1F;AAEA,UAAI,MAAM,WAAW,OAAO;AAC1B,YAAI,CAAC,MAAM,MAAM;AACf,iBAAO,EAAE,QAAQ,SAAS,SAAS,gDAAgD;AAAA,QACrF;AACA,YAAI,CAAC,MAAM,SAAS,MAAM,MAAM,WAAW,GAAG;AAC5C,iBAAO,EAAE,QAAQ,SAAS,SAAS,gEAA2D;AAAA,QAChG;AAEA,cAAM,UAAoB,CAAC;AAC3B,mBAAW,OAAO,MAAM,OAAO;AAC7B,cAAI,CAAC,cAAc,KAAK,MAAM,GAAG;AAC/B,oBAAQ,KAAK,GAAG;AAAA,UAClB;AAAA,QACF;AACA,YAAI,QAAQ,SAAS,GAAG;AACtB,iBAAO;AAAA,YACL,QAAQ;AAAA,YACR,SACE;AAAA,IAA4D,QAAQ,KAAK,MAAM,CAAC;AAAA;AAAA;AAAA,UAEpF;AAAA,QACF;AACA,iBAAS,MAAM,IAAI,IAAI,CAAC,GAAG,MAAM,KAAK;AACtC,cAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,cAAI,mBAAmB;AAAA,QACzB,CAAC;AACD,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,SAAS,mBAAc,MAAM,IAAI,YAAO,MAAM,MAAM,KAAK,UAAK,CAAC;AAAA,UAC/D,UAAU,EAAE,GAAG,SAAS;AAAA,QAC1B;AAAA,MACF;AAEA,UAAI,MAAM,WAAW,UAAU;AAC7B,YAAI,CAAC,MAAM,MAAM;AACf,iBAAO,EAAE,QAAQ,SAAS,SAAS,2CAA2C;AAAA,QAChF;AACA,YAAI,EAAE,MAAM,QAAQ,WAAW;AAC7B,iBAAO,EAAE,QAAQ,SAAS,SAAS,YAAY,MAAM,IAAI,eAAe;AAAA,QAC1E;AACA,eAAO,SAAS,MAAM,IAAI;AAC1B,cAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,cAAI,mBAAmB;AAAA,QACzB,CAAC;AACD,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,SAAS,2BAAsB,MAAM,IAAI;AAAA,UACzC,UAAU,EAAE,GAAG,SAAS;AAAA,QAC1B;AAAA,MACF;AAEA,aAAO,EAAE,QAAQ,SAAS,SAAS,oBAAoB,MAAM,MAAM,KAAK;AAAA,IAC1E;AAAA,EACF;AACF;AAIA,IAAM,4BAAwC;AAAA,EAC5C,MAAM;AAAA,EACN,YAAY;AAAA,IACV,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aACE;AAAA,IAEJ;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aACE;AAAA,IAEJ;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aACE;AAAA,IAEJ;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,IAEJ;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aACE;AAAA,IACJ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,CAAC,MAAM;AAAA,EACjB,sBAAsB;AACxB;AAgBA,SAAS,2BAA2B,MAAsF;AACxH,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aACE;AAAA,IAIF,WACE;AAAA,IAIF,UAAU;AAAA,IACV,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM,QAAQ,OAAO;AACnB,YAAM,SAAS,KAAK,UAAU;AAG9B,YAAM,QAAQ,CAAC,MAAM,QAAQ,UAAU,MAAM,MAAM,UAAU,YAAY,MAAM,MAAM,QAAQ,UAAU,IAAI,EAAE,OAAO,OAAO;AAC3H,UAAI,MAAM,SAAS,GAAG;AACpB,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,SAAS,iCAAiC,MAAM,KAAK,KAAK,CAAC;AAAA,QAE7D;AAAA,MACF;AAGA,UAAI,MAAM,SAAS,QAAQ;AACzB,cAAM,SAAU,OAAO,eAAe,CAAC;AACvC,cAAM,OAAO,OAAO,KAAK,MAAM;AAC/B,YAAI,KAAK,WAAW,GAAG;AACrB,iBAAO,EAAE,QAAQ,MAAM,SAAS,yDAAyD;AAAA,QAC3F;AACA,cAAM,MAAM,KAAK,KAAK,EAAE,IAAI,CAAC,MAAM,KAAK,CAAC,WAAM,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,IAAI;AACrF,eAAO,EAAE,QAAQ,MAAM,SAAS,iBAAiB,KAAK,MAAM;AAAA,EAAe,GAAG,GAAG;AAAA,MACnF;AAGA,UAAI,CAAC,iBAAiB,MAAM,IAAI,GAAG;AACjC,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,SACE,IAAI,MAAM,IAAI;AAAA,QAElB;AAAA,MACF;AAGA,UAAI,MAAM,OAAO;AACf,cAAM,SAAS,EAAE,GAAK,OAAO,eAAe,CAAC,EAA+B;AAC5E,YAAI,EAAE,MAAM,QAAQ,SAAS;AAC3B,iBAAO,EAAE,QAAQ,MAAM,SAAS,wBAAwB,MAAM,IAAI,cAAc;AAAA,QAClF;AACA,eAAO,OAAO,MAAM,IAAI;AACxB,cAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,cAAI,cAAc;AAAA,QACpB,CAAC;AACD,eAAO,EAAE,QAAQ,MAAM,SAAS,oCAA+B,MAAM,IAAI,KAAK;AAAA,MAChF;AAGA,UAAI,CAAC,MAAM,SAAS,CAAC,MAAM,WAAW,CAAC,MAAM,UAAU;AACrD,cAAM,SAAU,OAAO,eAAe,CAAC;AACvC,cAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,YAAI,CAAC,OAAO;AACV,iBAAO,EAAE,QAAQ,MAAM,SAAS,+BAA+B,MAAM,IAAI,mDAAmD;AAAA,QAC9H;AACA,eAAO,EAAE,QAAQ,MAAM,SAAS,IAAI,MAAM,IAAI,YAAO,KAAK,UAAU,KAAK,CAAC,GAAG;AAAA,MAC/E;AAGA,UAAI,MAAM,WAAW,CAAC,MAAM,OAAO;AACjC,cAAM,WAAW,YAAY,MAAM;AACnC,YAAI,CAAC,SAAS,MAAM,OAAO,GAAG;AAC5B,iBAAO,EAAE,QAAQ,SAAS,SAAS,YAAY,MAAM,OAAO,6DAA6D;AAAA,QAC3H;AACA,cAAM,SAAS,EAAE,GAAK,OAAO,eAAe,CAAC,EAA+B;AAC5E,eAAO,MAAM,IAAI,IAAI,EAAE,iBAAiB,MAAM,QAAQ;AACtD,cAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,cAAI,cAAc;AAAA,QACpB,CAAC;AACD,eAAO,EAAE,QAAQ,MAAM,SAAS,WAAM,MAAM,IAAI,qBAAgB,MAAM,OAAO,GAAG;AAAA,MAClF;AAGA,UAAI,MAAM,OAAO;AACf,cAAM,oBAAoB,MAAM,YAAY,OAAO;AACnD,cAAM,MAAM,GAAG,iBAAiB,IAAI,MAAM,KAAK;AAC/C,YAAI,CAAC,cAAc,KAAK,MAAM,GAAG;AAC/B,iBAAO,EAAE,QAAQ,SAAS,SAAS,iBAAiB,KAAK,MAAM,EAAE;AAAA,QACnE;AACA,cAAM,SAAS,EAAE,GAAK,OAAO,eAAe,CAAC,EAA+B;AAC5E,cAAM,kBAAmB,OAAO,MAAM,IAAI,GAA+B;AACzE,eAAO,MAAM,IAAI,IAAI,MAAM,WACvB,EAAE,UAAU,MAAM,UAAU,OAAO,MAAM,OAAO,GAAI,kBAAkB,EAAE,cAAc,gBAAgB,IAAI,CAAC,EAAG,IAC9G,EAAE,OAAO,MAAM,OAAO,GAAI,kBAAkB,EAAE,cAAc,gBAAgB,IAAI,CAAC,EAAG;AACxF,cAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,cAAI,cAAc;AAAA,QACpB,CAAC;AACD,cAAM,UAAU,MAAM,WAAW,GAAG,MAAM,QAAQ,IAAI,MAAM,KAAK,KAAK,GAAG,MAAM,KAAK;AACpF,eAAO,EAAE,QAAQ,MAAM,SAAS,WAAM,MAAM,IAAI,YAAO,OAAO,GAAG;AAAA,MACnE;AAEA,aAAO,EAAE,QAAQ,SAAS,SAAS,iEAAiE;AAAA,IACtG;AAAA,EACF;AACF;AAMO,IAAM,4BAA4B;AAEzC,IAAM,yBAAqC;AAAA,EACzC,MAAM;AAAA,EACN,YAAY;AAAA,IACV,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,MAAM,CAAC,QAAQ,OAAO,aAAa,QAAQ;AAAA,MAC3C,aACE;AAAA,IAEJ;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,OAAO,EAAE,MAAM,SAAS;AAAA,MACxB,aACE;AAAA,IACJ;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aACE;AAAA,IAEJ;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,OAAO,EAAE,MAAM,SAAS;AAAA,MACxB,aAAa;AAAA,IACf;AAAA,IACA,oBAAoB;AAAA,MAClB,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aACE;AAAA,IAEJ;AAAA,EACF;AAAA,EACA,UAAU,CAAC,QAAQ;AAAA,EACnB,sBAAsB;AACxB;AAoBA,SAAS,yBAAyB,MAAkF;AAClH,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aACE;AAAA,IAIF,WACE;AAAA,IAGF,UAAU;AAAA,IACV,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM,QAAQ,OAAO;AACnB,YAAM,SAAS,KAAK,UAAU;AAC9B,YAAM,YAAY;AAAA,QAChB,GAAK,OAAO,aAAa,CAAC;AAAA,MAC5B;AACA,YAAM,iBAAyB,OAAO,YAAY;AAElD,UAAI,MAAM,WAAW,QAAQ;AAC3B,cAAM,MAAM,OAAO,KAAK,SAAS;AACjC,YAAI,IAAI,WAAW,GAAG;AACpB,iBAAO,EAAE,QAAQ,MAAM,SAAS,4BAA4B,WAAW,CAAC,EAAE;AAAA,QAC5E;AACA,cAAM,MAAM,IAAI,KAAK,EAAE,IAAI,CAAC,OAAO;AACjC,gBAAM,QAAQ,UAAU,EAAE,KAAK,CAAC;AAChC,gBAAM,OAAQ,MAAM,QAAmB;AACvC,gBAAM,SAAS,MAAM,QAAQ,MAAM,MAAM,IAAK,MAAM,OAAoB,KAAK,IAAI,IAAI;AACrF,gBAAM,SAAS,MAAM,SAAS,WAAM,MAAM,UAAU,WAAM;AAC1D,gBAAM,SAAS,OAAO,iBAAiB,YAAO;AAC9C,gBAAM,UAAU,MAAM,UAAU,QAAQ,MAAM,OAAO,KAAK;AAC1D,gBAAM,SAAS,MAAM,SAAS,WAAW,MAAM,MAAM,KAAK;AAC1D,iBAAO,KAAK,MAAM,GAAG,EAAE,KAAK,IAAI,SAAS,MAAM,YAAY,MAAM,IAAI,OAAO,GAAG,MAAM;AAAA,QACvF,CAAC,EAAE,KAAK,IAAI;AACZ,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,SAAS,sBAAsB,cAAc;AAAA,EAAO,GAAG;AAAA,UACvD,WAAW;AAAA,QACb;AAAA,MACF;AAEA,UAAI,MAAM,WAAW,OAAO;AAC1B,YAAI,CAAC,MAAM,YAAY,CAAC,MAAM,MAAM;AAClC,iBAAO,EAAE,QAAQ,SAAS,SAAS,wDAAwD;AAAA,QAC7F;AACA,YAAI,UAAU,MAAM,QAAQ,GAAG;AAC7B,iBAAO,EAAE,QAAQ,SAAS,SAAS,aAAa,MAAM,QAAQ,+CAA+C;AAAA,QAC/G;AACA,cAAM,QAAiC,EAAE,MAAM,MAAM,KAAK;AAC1D,YAAI,MAAM,OAAQ,OAAM,SAAS,MAAM;AACvC,YAAI,MAAM,QAAS,OAAM,UAAU,MAAM;AACzC,YAAI,MAAM,OAAQ,OAAM,SAAS,MAAM;AACvC,YAAI,MAAM,QAAS,OAAM,UAAU,MAAM;AACzC,YAAI,MAAM,uBAAuB,OAAW,OAAM,qBAAqB,MAAM;AAC7E,YAAI,MAAM,OAAQ,OAAM,SAAS,MAAM;AACvC,kBAAU,MAAM,QAAQ,IAAI;AAC5B,cAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,cAAI,YAAY;AAAA,QAClB,CAAC;AACD,eAAO,EAAE,QAAQ,MAAM,SAAS,0BAAqB,MAAM,QAAQ,WAAW,MAAM,IAAI,IAAI;AAAA,MAC9F;AAEA,UAAI,MAAM,WAAW,aAAa;AAChC,YAAI,CAAC,MAAM,UAAU;AACnB,iBAAO,EAAE,QAAQ,SAAS,SAAS,sCAAsC;AAAA,QAC3E;AACA,YAAI,CAAC,UAAU,MAAM,QAAQ,GAAG;AAC9B,iBAAO,EAAE,QAAQ,SAAS,SAAS,aAAa,MAAM,QAAQ,gDAAgD;AAAA,QAChH;AACA,cAAM,QAAiC,EAAE,GAAG,UAAU,MAAM,QAAQ,EAAE;AACtE,YAAI,MAAM,WAAW,OAAW,OAAM,SAAS,MAAM;AACrD,YAAI,MAAM,YAAY,OAAW,OAAM,UAAU,MAAM,WAAW;AAClE,YAAI,MAAM,WAAW,OAAW,OAAM,SAAS,MAAM,UAAU;AAC/D,YAAI,MAAM,YAAY,OAAW,OAAM,UAAU,MAAM;AACvD,YAAI,MAAM,uBAAuB,OAAW,OAAM,qBAAqB,MAAM;AAC7E,YAAI,MAAM,WAAW,OAAW,OAAM,SAAS,MAAM,UAAU;AAC/D,kBAAU,MAAM,QAAQ,IAAI;AAC5B,cAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,cAAI,YAAY;AAAA,QAClB,CAAC;AACD,cAAM,UAAU,OAAO,KAAK,EAAE,GAAG,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,MAAM,QAAQ,EAAE,KAAK,IAAI;AACjF,eAAO,EAAE,QAAQ,MAAM,SAAS,kBAAa,MAAM,QAAQ,KAAK,OAAO,GAAG;AAAA,MAC5E;AAEA,UAAI,MAAM,WAAW,UAAU;AAC7B,YAAI,CAAC,MAAM,UAAU;AACnB,iBAAO,EAAE,QAAQ,SAAS,SAAS,mCAAmC;AAAA,QACxE;AACA,YAAI,CAAC,UAAU,MAAM,QAAQ,GAAG;AAC9B,iBAAO,EAAE,QAAQ,SAAS,SAAS,aAAa,MAAM,QAAQ,eAAe;AAAA,QAC/E;AACA,YAAI,MAAM,aAAa,gBAAgB;AACrC,iBAAO,EAAE,QAAQ,SAAS,SAAS,6CAA6C,MAAM,QAAQ,8BAA8B;AAAA,QAC9H;AACA,eAAO,UAAU,MAAM,QAAQ;AAC/B,cAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,cAAI,YAAY;AAAA,QAClB,CAAC;AACD,eAAO,EAAE,QAAQ,MAAM,SAAS,4BAAuB,MAAM,QAAQ,GAAG;AAAA,MAC1E;AAEA,aAAO,EAAE,QAAQ,SAAS,SAAS,oBAAoB,MAAM,MAAM,KAAK;AAAA,IAC1E;AAAA,EACF;AACF;AAIO,IAAM,6BAA6B;AAE1C,IAAM,0BAAsC;AAAA,EAC1C,MAAM;AAAA,EACN,YAAY;AAAA,IACV,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,KAAK;AAAA,MACH,MAAM;AAAA,MACN,aACE;AAAA,IAGJ;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aACE;AAAA,IAGJ;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aACE;AAAA,IACJ;AAAA,IACA,WAAW;AAAA,MACT,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAIA,UAAU,CAAC,UAAU;AAAA,EACrB,sBAAsB;AACxB;AAeA,SAAS,yBAAyB,MAAkF;AAClH,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aACE;AAAA,IAMF,WACE;AAAA,IAGF,UAAU;AAAA,IACV,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM,QAAQ,OAAO;AACnB,YAAM,SAAS,KAAK,UAAU;AAC9B,YAAM,YAAY;AAAA,QAChB,GAAK,OAAO,aAAa,CAAC;AAAA,MAC5B;AAGA,UAAI,MAAM,OAAO,MAAM,QAAQ;AAC7B,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,SAAS;AAAA,QAEX;AAAA,MACF;AAGA,UAAI,CAAC,MAAM,OAAO,CAAC,MAAM,QAAQ;AAE/B,YAAI,KAAK,cAAc;AACrB,cAAI;AACF,kBAAM,QAAQ,MAAM,KAAK;AAAA,cACvB,sBAAsB,MAAM,QAAQ;AAAA,YACtC;AACA,gBAAI,CAAC,SAAS,MAAM,KAAK,EAAE,WAAW,GAAG;AACvC,qBAAO,EAAE,QAAQ,SAAS,SAAS,2CAA2C;AAAA,YAChF;AACA,mBAAO,SAAS,WAAW,OAAO,MAAM,KAAK,GAAG,IAAI;AAAA,UACtD,SAAS,KAAK;AACZ,mBAAO;AAAA,cACL,QAAQ;AAAA,cACR,SAAS,8CAA8C,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,YACzG;AAAA,UACF;AAAA,QACF;AAEA,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,SACE,2BAA2B,MAAM,QAAQ;AAAA,gBAExB,MAAM,SAAS,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA,QAGjD;AAAA,MACF;AAGA,UAAI,MAAM,QAAQ;AAChB,cAAM,WAAW,QAAQ,IAAI,MAAM,MAAM;AACzC,YAAI,CAAC,UAAU;AACb,iBAAO;AAAA,YACL,QAAQ;AAAA,YACR,SAAS,yBAAyB,MAAM,MAAM;AAAA,UAEhD;AAAA,QACF;AACA,eAAO,SAAS,WAAW,OAAO,UAAU,IAAI;AAAA,MAClD;AAGA,UAAI,MAAM,KAAK;AACb,eAAO,SAAS,WAAW,OAAO,MAAM,KAAK,IAAI;AAAA,MACnD;AAEA,aAAO,EAAE,QAAQ,SAAS,SAAS,6CAAwC;AAAA,IAC7E;AAAA,EACF;AACF;AAEA,eAAe,SACb,WACA,OACA,UACA,MAC+B;AAC/B,QAAM,aAAa,MAAM;AAGzB,MAAI,CAAC,UAAU,UAAU,GAAG;AAE1B,cAAU,UAAU,IAAI,EAAE,MAAM,WAAW;AAAA,EAC7C;AAEA,QAAM,QAAQ,UAAU,UAAU;AAClC,QAAM,eAAe,MAAM,QAAQ,MAAM,OAAO,IAAI,CAAC,GAAI,MAAM,OAA0C,IAAI,CAAC;AAC9G,QAAM,QAAQ,MAAM,SAAS;AAE7B,eAAa,KAAK;AAAA,IAChB;AAAA,IACA,QAAQ;AAAA,IACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC,CAAC;AAED,QAAM,UAAU;AAChB,QAAM,SAAS;AAEf,MAAI,MAAM,cAAc,OAAO;AAC7B,UAAM,YAAY;AAAA,EACpB;AAEA,YAAU,UAAU,IAAI;AAExB,QAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,QAAI,YAAY;AAAA,EAClB,CAAC;AAED,QAAM,aAAa,MAAM,SAAS,OAAO,MAAM,MAAM,KAAK;AAC1D,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,SAAS,8BAAyB,UAAU,UAAU,UAAU;AAAA,EAElE;AACF;AAIO,IAAM,6BAA6B;AAE1C,IAAM,0BAAsC;AAAA,EAC1C,MAAM;AAAA,EACN,YAAY;AAAA,IACV,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,MAAM,CAAC,QAAQ,OAAO,WAAW,QAAQ;AAAA,MACzC,aACE;AAAA,IAEJ;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,MAAM,CAAC,gBAAgB,oBAAoB;AAAA,MAC3C,aAAa;AAAA,IACf;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,sBAAsB;AACxB;AAgBA,SAAS,yBAAyB,MAAkF;AAClH,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aACE;AAAA,IAMF,WACE;AAAA,IAGF,UAAU;AAAA,IACV,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM,QAAQ,OAAO;AACnB,YAAM,SAAS,KAAK,UAAU;AAE9B,UAAI,MAAM,WAAW,QAAQ;AAC3B,cAAM,QAAkB;AAAA,UACtB,KAAK,QAAQ,KAAK,OAAO,QAAQ,IAAI,OAAO,KAAK;AAAA,UACjD,KAAK,cAAc,KAAK,OAAO,iBAAiB,QAAQ,OAAO,KAAK;AAAA,UACpE,KAAK,oBAAoB,KAAK,OAAO,qBAAqB,OAAO,KAAK;AAAA,UACtE;AAAA,UACA,KAAK,iBAAiB,MAAM,OAAO,kBAAkB,CAAC,GAAG,SAAS,KAAK,OAAO,kBAAkB,CAAC,GAAG,KAAK,UAAK,IAAI,uBAAuB;AAAA,UACzI,KAAK,WAAW,MAAM,OAAO,kBAAkB,CAAC,GAAG,SAAS,IAAI,IAAI,OAAO,kBAAkB,CAAC,GAAG,MAAM,YAAY,QAAQ;AAAA,UAC3H,KAAK,SAAS,KAAK,OAAO,UAAU,kBAAkB,GAAG,OAAO,SAAS,eAAe,IAAI,OAAO,SAAS,gBAAgB,iBAAiB,KAAK,kBAAkB;AAAA,QACtK;AACA,eAAO,EAAE,QAAQ,MAAM,SAAS,MAAM,KAAK,IAAI,EAAE;AAAA,MACnD;AAEA,UAAI,MAAM,WAAW,OAAO;AAC1B,YAAI,CAAC,MAAM,YAAY,CAAC,MAAM,OAAO;AACnC,iBAAO,EAAE,QAAQ,SAAS,SAAS,iDAAiD;AAAA,QACtF;AACA,cAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,cAAI,WAAW,MAAM;AACrB,cAAI,QAAQ,MAAM;AAAA,QACpB,CAAC;AACD,eAAO,EAAE,QAAQ,MAAM,SAAS,wBAAc,MAAM,QAAQ,IAAI,MAAM,KAAK,GAAG;AAAA,MAChF;AAEA,UAAI,MAAM,WAAW,WAAW;AAC9B,YAAI,CAAC,MAAM,SAAS;AAClB,iBAAO,EAAE,QAAQ,SAAS,SAAS,oDAAoD;AAAA,QACzF;AACA,cAAM,WAAY,OAAO,oBAAoB,CAAC;AAC9C,cAAM,QAAQ,SAAS,MAAM,OAAO;AACpC,YAAI,CAAC,SAAS,MAAM,WAAW,GAAG;AAChC,iBAAO,EAAE,QAAQ,SAAS,SAAS,YAAY,MAAM,OAAO,wBAAwB;AAAA,QACtF;AAEA,cAAM,QAAQ,MAAM,CAAC;AACrB,cAAM,IAAI,iBAAiB,KAAK;AAChC,cAAM,WAAW,EAAE,YAAY,OAAO;AACtC,cAAM,QAAQ,EAAE;AAChB,YAAI,CAAC,OAAO;AACV,iBAAO,EAAE,QAAQ,SAAS,SAAS,iBAAiB,KAAK,gCAAgC;AAAA,QAC3F;AACA,cAAM,OAAO,MAAM,MAAM,CAAC;AAC1B,cAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,cAAI,WAAW;AACf,cAAI,QAAQ;AACZ,cAAI,iBAAiB;AAAA,QACvB,CAAC;AACD,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,SAAS,wBAAc,QAAQ,IAAI,KAAK,cAAc,MAAM,OAAO,OAChE,KAAK,SAAS,IAAI;AAAA,oBAAuB,KAAK,KAAK,UAAK,CAAC,KAAK;AAAA,QACnE;AAAA,MACF;AAEA,UAAI,MAAM,WAAW,UAAU;AAC7B,YAAI,CAAC,MAAM,UAAU,MAAM,UAAU,QAAW;AAC9C,iBAAO,EAAE,QAAQ,SAAS,SAAS,8EAA8E;AAAA,QACnH;AACA,cAAM,KAAK,aAAa,CAAC,QAAQ;AAC/B,cAAI,MAAM,WAAW,gBAAgB;AACnC,gBAAI,eAAe,MAAM;AAAA,UAC3B,WAAW,MAAM,WAAW,sBAAsB;AAChD,gBAAI,qBAAqB,MAAM;AAAA,UACjC;AAAA,QACF,CAAC;AACD,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,SAAS,UAAK,MAAM,MAAM,WAAM,MAAM,QAAQ,OAAO,KAAK;AAAA,QAC5D;AAAA,MACF;AAEA,aAAO,EAAE,QAAQ,SAAS,SAAS,oBAAoB,MAAM,MAAM,KAAK;AAAA,IAC1E;AAAA,EACF;AACF;AAOA,SAAS,iBAAiB,KAAwB;AAChD,QAAM,UAAU,IAAI,KAAK;AACzB,QAAM,QAAQ,QAAQ,QAAQ,GAAG;AACjC,MAAI,UAAU,IAAI;AAChB,UAAM,IAAI,QAAQ,MAAM,GAAG,KAAK;AAChC,UAAM,IAAI,QAAQ,MAAM,QAAQ,CAAC,EAAE,KAAK;AACxC,QAAI,EAAG,QAAO,EAAE,UAAU,GAAG,OAAO,EAAE;AACtC,WAAO,EAAE,OAAO,EAAE;AAAA,EACpB;AACA,QAAM,QAAQ,QAAQ,MAAM,KAAK;AACjC,MAAI,MAAM,UAAU,GAAG;AACrB,WAAO,EAAE,UAAU,MAAM,CAAC,GAAI,OAAO,MAAM,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE;AAAA,EAChE;AACA,SAAO,EAAE,OAAO,QAAQ;AAC1B;AAIO,IAAM,+BAA+B;AAE5C,IAAM,4BAAwC;AAAA,EAC5C,MAAM;AAAA,EACN,YAAY;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,MAAM,CAAC,OAAO,aAAa,UAAU,aAAa,UAAU,UAAU,WAAW,QAAQ;AAAA,MACzF,aACE;AAAA,IAKJ;AAAA,EACF;AAAA,EACA,sBAAsB;AACxB;AAWA,SAAS,2BAA2B,MAAsF;AACxH,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aACE;AAAA,IAIF,WACE;AAAA,IAKF,UAAU;AAAA,IACV,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,UAAU;AAAA,IACV,MAAM;AAAA,IACN,MAAM,QAAQ,OAAO;AACnB,YAAM,SAAS,KAAK,UAAU;AAC9B,YAAM,UAAU,MAAM,WAAW;AACjC,YAAM,WAAqB,CAAC;AAC5B,YAAM,aAAa,CAAC,OAAe,YAAoB;AACrD,iBAAS,KAAK,gBAAM,KAAK;AAAA,EAAQ,OAAO,EAAE;AAAA,MAC5C;AAGA;AAAA,QACE;AAAA,QACA,KAAK,OAAO,QAAQ,IAAI,OAAO,KAAK;AAAA,MACtC;AAEA,UAAI,YAAY,SAAS,YAAY,aAAa;AAChD,cAAM,YAAa,OAAO,aAAa,CAAC;AACxC,cAAM,MAAM,OAAO,KAAK,SAAS;AACjC,YAAI,IAAI,WAAW,GAAG;AACpB,qBAAW,aAAa,qBAAqB;AAAA,QAC/C,OAAO;AACL,gBAAM,QAAQ,IAAI,KAAK,EAAE,IAAI,CAAC,OAAO;AACnC,kBAAM,IAAI,UAAU,EAAE,KAAK,CAAC;AAC5B,kBAAM,OAAQ,EAAE,QAAmB;AACnC,kBAAM,SAAS,MAAM,QAAQ,EAAE,MAAM,IAAI,IAAK,EAAE,OAAoB,KAAK,IAAI,CAAC,MAAM;AACpF,kBAAM,SAAS,EAAE,UAAW,MAAM,QAAQ,EAAE,OAAO,KAAK,EAAE,QAAQ,SAAS,IAAK,WAAM;AACtF,kBAAM,UAAU,EAAE,UAAU,QAAQ,EAAE,OAAO,KAAK;AAClD,kBAAM,SAAS,EAAE,SAAS,WAAW,EAAE,MAAM,KAAK;AAClD,kBAAM,UAAU,MAAM,QAAQ,EAAE,OAAO,IAAI,SAAU,EAAE,QAAqB,KAAK,IAAI,CAAC,MAAM;AAC5F,mBAAO,KAAK,OAAO,OAAO,WAAW,WAAM,GAAG,IAAI,EAAE,KAAK,IAAI,SAAS,MAAM,WAAW,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO;AAAA,UAC5H,CAAC;AACD,qBAAW,aAAa,MAAM,KAAK,IAAI,CAAC;AAAA,QAC1C;AAAA,MACF;AAEA,UAAI,YAAY,SAAS,YAAY,UAAU;AAC7C,cAAM,YAAY,OAAO,kBAAkB,CAAC;AAC5C;AAAA,UACE;AAAA,UACA,UAAU,SAAS,IACf,UAAU,IAAI,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,IACrD;AAAA,QACN;AACA;AAAA,UACE;AAAA,UACA,mBAAmB,OAAO,iBAAiB,QAAQ,OAAO,KAAK;AAAA,wBACtC,OAAO,qBAAqB,OAAO,KAAK;AAAA,QACnE;AAAA,MACF;AAEA,UAAI,YAAY,SAAS,YAAY,aAAa;AAChD,cAAM,iBAAiB,OAAO,kBAAkB,CAAC;AACjD,cAAM,WAAY,OAAO,oBAAoB,CAAC;AAC9C;AAAA,UACE;AAAA,UACA,eAAe,SAAS,IACpB,eAAe,IAAI,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,IAC1D;AAAA,QACN;AACA,cAAM,eAAe,OAAO,KAAK,QAAQ;AACzC;AAAA,UACE;AAAA,UACA,aAAa,SAAS,IAClB,aAAa,KAAK,EAAE,IAAI,CAAC,MAAM,KAAK,CAAC,WAAM,SAAS,CAAC,GAAG,KAAK,UAAK,KAAK,SAAS,EAAE,EAAE,KAAK,IAAI,IAC7F;AAAA,QACN;AAAA,MACF;AAEA,UAAI,YAAY,SAAS,YAAY,UAAU;AAC7C,cAAM,SAAU,OAAO,eAAe,CAAC;AACvC,cAAM,OAAO,OAAO,KAAK,MAAM;AAC/B;AAAA,UACE;AAAA,UACA,KAAK,SAAS,IACV,KAAK,KAAK,EAAE,IAAI,CAAC,MAAM,KAAK,CAAC,WAAM,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,IAAI,IACzE;AAAA,QACN;AAAA,MACF;AAEA,UAAI,YAAY,SAAS,YAAY,UAAU;AAC7C,cAAM,YAAY,OAAO,KAAK,aAAa,EAAE,KAAK;AAClD,cAAM,QAAQ,UAAU,IAAI,CAAC,SAAS;AACpC,gBAAM,QAAQ,aAAa,IAAI,KAAK;AACpC,gBAAM,SAAS,2BAA2B,QAAQ,IAAI;AACtD,gBAAM,QAAQ,QAAQ,WAClB,GAAG,OAAO,QAAQ,IAAI,OAAO,SAAS,WAAW,KACjD,GAAG,OAAO,QAAQ,IAAI,OAAO,SAAS,UAAU;AACpD,gBAAM,MAAM,QAAQ,cAChB,mBACA,QAAQ,WAAW,WACjB,YAAY,OAAO,gBAAgB,GAAG,MACtC;AACN,iBAAO,KAAK,KAAK,OAAO,EAAE,CAAC,IAAI,MAAM,OAAO,EAAE,CAAC,IAAI,KAAK,GAAG,GAAG;AAAA,QAChE,CAAC;AACD;AAAA,UACE,iBAAiB,UAAU,MAAM;AAAA,UACjC,MAAM,SAAS,IACX,KAAK,OAAO,OAAO,EAAE,CAAC,IAAI,QAAQ,OAAO,EAAE,CAAC;AAAA,IAAsB,MAAM,KAAK,IAAI,IACjF;AAAA,QACN;AAAA,MACF;AAEA,UAAI,YAAY,SAAS,YAAY,UAAU;AAC7C,cAAM,SAAmB,CAAC;AAC1B,cAAM,WAAqB,CAAC;AAC5B,cAAM,KAAe,CAAC;AACtB,cAAM,YAAa,OAAO,aAAa,CAAC;AACxC,cAAM,YAAY,OAAO,kBAAkB,CAAC;AAC5C,cAAM,WAAY,OAAO,oBAAoB,CAAC;AAC9C,cAAM,QAAQ,OAAO,kBAAkB,CAAC;AACxC,cAAM,SAAU,OAAO,eAAe,CAAC;AAGvC,mBAAW,OAAO,WAAW;AAC3B,gBAAM,IAAI,iBAAiB,GAAG;AAC9B,gBAAM,SAAS,EAAE,YAAY,OAAO;AACpC,gBAAM,QAAQ,EAAE;AAChB,gBAAM,OAAO,UAAU,MAAM;AAC7B,cAAI,CAAC,MAAM;AACT,qBAAS,KAAK,aAAa,GAAG,kCAAkC,MAAM,GAAG;AACzE;AAAA,UACF;AACA,gBAAM,aAAa,KAAK;AACxB,cAAI,cAAc,WAAW,SAAS,KAAK,CAAC,WAAW,SAAS,KAAK,GAAG;AACtE,qBAAS,KAAK,aAAa,GAAG,mBAAc,KAAK,YAAY,MAAM,gBAAgB,WAAW,KAAK,IAAI,CAAC,GAAG;AAAA,UAC7G,OAAO;AACL,eAAG,KAAK,aAAa,GAAG,qBAAgB,MAAM,gBAAgB;AAAA,UAChE;AAAA,QACF;AAGA,mBAAW,SAAS,OAAO;AACzB,gBAAM,IAAI,iBAAiB,KAAK;AAChC,gBAAM,SAAS,EAAE,YAAY,OAAO;AACpC,cAAI,CAAC,UAAU,MAAM,KAAK,WAAW,OAAO,UAAU;AACpD,mBAAO,KAAK,gBAAgB,KAAK,kCAAkC,MAAM,GAAG;AAAA,UAC9E,OAAO;AACL,eAAG,KAAK,gBAAgB,KAAK,sBAAiB;AAAA,UAChD;AAAA,QACF;AAGA,mBAAW,CAAC,OAAO,MAAM,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACtD,cAAI,CAAC,UAAU,OAAO,WAAW,GAAG;AAClC,qBAAS,KAAK,YAAY,KAAK,YAAY;AAC3C;AAAA,UACF;AACA,qBAAW,SAAS,QAAQ;AAC1B,kBAAM,IAAI,iBAAiB,KAAK;AAChC,kBAAM,SAAS,EAAE,YAAY,OAAO;AACpC,gBAAI,CAAC,UAAU,MAAM,KAAK,WAAW,OAAO,UAAU;AACpD,qBAAO,KAAK,YAAY,KAAK,YAAY,KAAK,kCAAkC,MAAM,GAAG;AAAA,YAC3F;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,gBAAM,YAAa,MAAM,YAAuB,OAAO;AACvD,gBAAM,SAAS,MAAM;AACrB,cAAI,QAAQ;AACV,kBAAM,WAAW,UAAU,SAAS;AACpC,gBAAI,CAAC,YAAY,cAAc,OAAO,UAAU;AAC9C,qBAAO,KAAK,WAAW,GAAG,kCAAkC,SAAS,GAAG;AAAA,YAC1E;AACA,kBAAM,aAAa,UAAU;AAC7B,gBAAI,cAAc,WAAW,SAAS,KAAK,CAAC,WAAW,SAAS,MAAM,GAAG;AACvE,uBAAS,KAAK,WAAW,GAAG,mBAAc,MAAM,YAAY,SAAS,aAAa;AAAA,YACpF;AAAA,UACF;AAEA,gBAAM,WAAW,MAAM;AACvB,cAAI,YAAY,CAAC,SAAS,QAAQ,GAAG;AACnC,mBAAO,KAAK,WAAW,GAAG,0CAA0C,QAAQ,GAAG;AAAA,UACjF;AAAA,QACF;AAGA,YAAI,CAAC,UAAU,OAAO,QAAQ,KAAK,OAAO,KAAK,SAAS,EAAE,SAAS,GAAG;AACpE,mBAAS,KAAK,oBAAoB,OAAO,QAAQ,gCAAgC;AAAA,QACnF;AAGA,cAAM,UAAU,YAAO,GAAG,MAAM;AAAA,WACvB,SAAS,MAAM;AAAA,WACf,OAAO,MAAM;AACtB,cAAM,QAAkB,CAAC,SAAS,EAAE;AACpC,YAAI,SAAS,SAAS,GAAG;AACvB,gBAAM,KAAK,oCAAgB;AAC3B,gBAAM,KAAK,GAAG,SAAS,IAAI,CAAC,MAAM,YAAO,CAAC,EAAE,CAAC;AAC7C,gBAAM,KAAK,EAAE;AAAA,QACf;AACA,YAAI,OAAO,SAAS,GAAG;AACrB,gBAAM,KAAK,kCAAc;AACzB,gBAAM,KAAK,GAAG,OAAO,IAAI,CAAC,MAAM,YAAO,CAAC,EAAE,CAAC;AAC3C,gBAAM,KAAK,EAAE;AAAA,QACf;AACA,YAAI,SAAS,WAAW,KAAK,OAAO,WAAW,KAAK,GAAG,SAAS,GAAG;AACjE,gBAAM,KAAK,sDAAiD;AAAA,QAC9D;AACA,mBAAW,wBAAwB,MAAM,KAAK,IAAI,CAAC;AAAA,MACrD;AAEA,UAAI,YAAY,SAAS,YAAY,WAAW;AAC9C,cAAM,MAAM,OAAO;AACnB;AAAA,UACE;AAAA,UACA,sBAAsB,KAAK,mBAAmB,kBAAkB;AAAA,kBAC7C,KAAK,gBAAgB,wBAAwB;AAAA,4BACnC,KAAK,0BAA0B,QAAQ;AAAA,QACtE;AAAA,MACF;AAEA,aAAO,EAAE,QAAQ,MAAM,SAAS,SAAS,KAAK,MAAM,EAAE;AAAA,IACxD;AAAA,EACF;AACF;AAaO,SAAS,0BAA0B,MAAyC;AACjF,SAAO;AAAA,IACL,yBAAyB,IAAI;AAAA,IAC7B,8BAA8B,IAAI;AAAA,IAClC,gCAAgC,IAAI;AAAA,IACpC,2BAA2B,IAAI;AAAA,IAC/B,yBAAyB,IAAI;AAAA,IAC7B,yBAAyB,IAAI;AAAA,IAC7B,yBAAyB,IAAI;AAAA,IAC7B,2BAA2B,IAAI;AAAA,EACjC;AACF;",
4
+ "sourcesContent": ["/** 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", "/**\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", "/**\n * Well-known tool capabilities used for authorization decisions.\n *\n * These are the preferred values for `Tool.capabilities`.\n * New capabilities should be added here with clear documentation.\n *\n * Philosophy (2026-06+):\n * - Prefer capabilities over exact tool name matching.\n * - Subagent guards and future policies should primarily key off capabilities.\n * - Name-based denylists are legacy and will be phased down.\n */\nexport const ToolCapabilities = {\n /** Can execute arbitrary commands in the user's shell (the `bash` tool). */\n SHELL_ARBITRARY: 'shell.arbitrary',\n\n /** Can execute a restricted set of commands (the `exec` tool). */\n SHELL_RESTRICTED: 'shell.restricted',\n\n /** Can run a restricted project formatter/linter-style command. */\n SHELL_EXEC: 'shell.exec',\n\n /** Can read files inside the project (and possibly outside via symlinks if not guarded). */\n FS_READ: 'fs.read',\n\n /** Can write / modify / delete files inside the project. */\n FS_WRITE: 'fs.write',\n\n /** Can write files outside the current project root (very high risk). */\n FS_WRITE_OUTSIDE_PROJECT: 'fs.write.outside-project',\n\n /** Can perform outbound network requests. */\n NET_OUTBOUND: 'net.outbound',\n\n /** Can mutate in-memory session todos only. */\n SESSION_TODO: 'session.todo',\n\n /** Can mutate in-memory session mode only. */\n SESSION_MODE: 'session.mode',\n\n /** Can inspect registered tool metadata. */\n TOOL_META: 'tool.meta',\n\n /** Can invoke arbitrary registered tools through a meta-tool. */\n TOOL_MUTATE_ANY: 'tool.mutate.any',\n\n /** Can read persistent memory. */\n MEMORY_READ: 'memory.read',\n\n /** Can write persistent memory. */\n MEMORY_WRITE: 'memory.write',\n\n /** Can delete persistent memory. */\n MEMORY_DELETE: 'memory.delete',\n\n /** Proxies tools from external MCP servers (unknown capability). */\n MCP_PROXY: 'mcp.proxy',\n\n /** Can spawn or manage subagents / multi-agent tasks. */\n SUBAGENT_SPAWN: 'subagent.spawn',\n\n /** Can inspect fleet/subagent coordination state without mutating it. */\n COORDINATION_FLEET_READ: 'coordination.fleet.read',\n\n /** Can publish attributed, schema-checked events onto the fleet bus. */\n COORDINATION_FLEET_EMIT: 'coordination.fleet.emit',\n\n /** Can submit a task-local structured result to the parent Director. */\n COORDINATION_RESULT_SUBMIT: 'coordination.result.submit',\n\n /** Can read or write inter-agent mailbox messages. */\n COORDINATION_MAIL: 'coordination.mail',\n\n /** Can schedule, inspect, or cancel in-session cron jobs. */\n COORDINATION_CRON: 'coordination.cron',\n\n /** Can mutate global or session configuration / trust state. */\n CONFIG_MUTATE: 'config.mutate',\n\n /** Can install packages or run package managers with side effects. */\n PACKAGE_INSTALL: 'package.install',\n} as const;\n\nexport type ToolCapability = (typeof ToolCapabilities)[keyof typeof ToolCapabilities];\n\n/**\n * Set of capabilities that are considered dangerous for subagents by default.\n * Subagents should not receive these capabilities unless the leader explicitly\n * allows the specific tool at spawn time.\n */\nexport const DANGEROUS_FOR_SUBAGENTS: readonly ToolCapability[] = [\n ToolCapabilities.SHELL_ARBITRARY,\n ToolCapabilities.SHELL_RESTRICTED,\n ToolCapabilities.SHELL_EXEC,\n ToolCapabilities.FS_WRITE,\n ToolCapabilities.FS_WRITE_OUTSIDE_PROJECT,\n ToolCapabilities.TOOL_MUTATE_ANY,\n ToolCapabilities.MEMORY_WRITE,\n ToolCapabilities.MEMORY_DELETE,\n ToolCapabilities.MCP_PROXY,\n ToolCapabilities.SUBAGENT_SPAWN,\n ToolCapabilities.CONFIG_MUTATE,\n ToolCapabilities.PACKAGE_INSTALL,\n];\n\n/**\n * Wide capability allowlist for subagents that the user has authorized to act\n * with full developer power (the CLI fleet host applies this to any subagent\n * that isn't given an explicit, narrower grant). It covers everything needed to\n * do real work end-to-end \u2014 read, write/edit inside the project, outbound\n * network, all shell/build/install capabilities, session todos, tool metadata, and read-only\n * memory lookup \u2014 so a delegated coding or build agent runs the same toolchain\n * the leader would, without per-tool confirmation it cannot answer.\n *\n * Deliberately EXCLUDED (require an explicit per-spawn `allowedCapabilities`\n * grant, because they escape the task's blast radius rather than perform it):\n * - `fs.write.outside-project` \u2014 writing outside the repo (e.g. ~/.ssh).\n * - `tool.mutate.any` \u2014 arbitrary meta-tool dispatch.\n * - `memory.write` / `memory.delete` \u2014 persistent memory mutation.\n * - `mcp.proxy` \u2014 third-party MCP tools (also hard-blocked by name).\n * - `subagent.spawn` \u2014 recursive delegation (the baseline prompt forbids it).\n * - `config.mutate` \u2014 rewriting trust/config is privilege escalation, not work.\n */\nexport const WIDE_SUBAGENT_CAPABILITIES: readonly ToolCapability[] = [\n ToolCapabilities.FS_READ,\n ToolCapabilities.FS_WRITE,\n ToolCapabilities.NET_OUTBOUND,\n ToolCapabilities.SESSION_TODO,\n ToolCapabilities.TOOL_META,\n ToolCapabilities.MEMORY_READ,\n ToolCapabilities.SHELL_ARBITRARY,\n ToolCapabilities.SHELL_RESTRICTED,\n ToolCapabilities.SHELL_EXEC,\n ToolCapabilities.PACKAGE_INSTALL,\n // Read-only fleet visibility (fleet_status) \u2014 peer awareness has no blast\n // radius and every fleet worker should coordinate around its peers.\n ToolCapabilities.COORDINATION_FLEET_READ,\n ToolCapabilities.COORDINATION_RESULT_SUBMIT,\n];\n\n/**\n * Check if a tool (or its capabilities array) includes any dangerous capability\n * for subagent execution.\n */\nexport function hasDangerousCapabilityForSubagents(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n): boolean {\n if (!toolOrCaps) return false;\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n return caps.some((c) => DANGEROUS_FOR_SUBAGENTS.includes(c as ToolCapability));\n}\n\n/**\n * Check if a tool declares a specific capability (or any of the provided ones).\n */\nexport function hasCapability(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n capability: ToolCapability | ToolCapability[],\n): boolean {\n if (!toolOrCaps) return false;\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n const toCheck = Array.isArray(capability) ? capability : [capability];\n return toCheck.some((c) => caps.includes(c));\n}\n\n/**\n * Returns the intersection of a tool's capabilities with the dangerous set.\n * Useful for logging and audit trails.\n */\nexport function getDangerousCapabilities(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n): ToolCapability[] {\n if (!toolOrCaps) return [];\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n return caps.filter((c): c is ToolCapability =>\n DANGEROUS_FOR_SUBAGENTS.includes(c as ToolCapability),\n );\n}\n", "import type { MCPServerConfig } from '../types/config.js';\n\n/**\n * Built-in MCP server presets available to all WrongStack users out of the box.\n * These servers must be explicitly enabled in config (disabled by default).\n *\n * To enable: set `mcpServers: { serverName: { enabled: true } }` in your config.\n *\n * Some servers require environment variables or additional config \u2014 see notes below.\n *\n * Transport types:\n * stdio \u2014 spawns a local npm package binary via child_process\n * sse \u2014 HTTP SSE endpoint (client POSTs requests)\n * streamable-http \u2014 session-based HTTP with NDJSON responses\n */\n\n/** Filesystem access: read, write, list, search, tree. Good for exploring projects. */\nexport const filesystemServer = (): MCPServerConfig => ({\n name: 'filesystem',\n description: 'Read, write, and navigate the local filesystem (read-heavy tools)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-filesystem', '.'],\n permission: 'confirm',\n});\n\n/** GitHub API: issues, PRs, repos, search, file operations. Requires GITHUB_PERSONAL_ACCESS_TOKEN. */\nexport const githubServer = (): MCPServerConfig => ({\n name: 'github',\n description:\n 'GitHub API \u2014 issues, PRs, repos, search, file ops (requires GITHUB_PERSONAL_ACCESS_TOKEN)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-github'],\n passthroughEnv: ['GITHUB_PERSONAL_ACCESS_TOKEN', 'GITHUB_TOKEN'],\n permission: 'confirm',\n});\n\n/**\n * Context7 \u2014 codebase-aware documentation and Q&A using context from your code.\n * Live documentation for any library, grounded in your actual versions.\n */\nexport const context7Server = (): MCPServerConfig => ({\n name: 'context7',\n description: 'Codebase-aware documentation and Q&A (context7.ai)',\n transport: 'streamable-http',\n url: 'https://mcp.context7.com/mcp',\n permission: 'confirm',\n});\n\n/**\n * Brave Search \u2014 web search via Brave Browser's API.\n * Requires BRAVE_SEARCH_API_KEY. Free tier: 2,000 queries/month.\n * Sign up at https://api.search.brave.com/\n */\nexport const braveSearchServer = (): MCPServerConfig => ({\n name: 'brave-search',\n description: 'Web search (Brave). Requires BRAVE_SEARCH_API_KEY \u2014 free tier 2k queries/month',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-brave-search'],\n passthroughEnv: ['BRAVE_SEARCH_API_KEY'],\n permission: 'confirm',\n});\n\n/**\n * Block (Block, Inc.) \u2014 Postgres database access via SQL.\n * Useful for running queries against a connected database during development.\n */\nexport const blockServer = (): MCPServerConfig => ({\n name: 'block',\n description: 'Postgres database access via SQL (Block MCP server)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-block'],\n permission: 'confirm',\n});\n\n/**\n * EverArt \u2014 AI image generation via various providers.\n * Requires EVERART_API_KEY.\n */\nexport const everArtServer = (): MCPServerConfig => ({\n name: 'everart',\n description: 'AI image generation (EverArt). Requires EVERART_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-everart'],\n passthroughEnv: ['EVERART_API_KEY'],\n permission: 'confirm',\n});\n\n/**\n * Slack \u2014 messaging, channels, search.\n * Requires SLACK_BOT_TOKEN and either SLACK_TEAM_ID or SLACK_USER_TOKEN.\n */\nexport const slackServer = (): MCPServerConfig => ({\n name: 'slack',\n description: 'Slack \u2014 messaging, channels, search. Requires SLACK_BOT_TOKEN + SLACK_TEAM_ID',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-slack'],\n passthroughEnv: ['SLACK_BOT_TOKEN', 'SLACK_TEAM_ID'],\n permission: 'confirm',\n});\n\n/**\n * AWS knowledge base \u2014 EC2, S3, Lambda, IAM, CloudFormation, cost management.\n * Requires AWS access key + secret in environment.\n */\nexport const awsServer = (): MCPServerConfig => ({\n name: 'aws',\n description: 'AWS \u2014 EC2, S3, Lambda, IAM, CloudFormation, costs. Requires AWS credentials',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-aws'],\n passthroughEnv: ['AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'AWS_REGION', 'AWS_SESSION_TOKEN'],\n permission: 'confirm',\n});\n\n/**\n * Google Maps \u2014 directions, distance matrix, geocoding, places.\n * Requires GOOGLE_MAPS_API_KEY.\n */\nexport const googleMapsServer = (): MCPServerConfig => ({\n name: 'google-maps',\n description: 'Google Maps \u2014 directions, geocoding, places. Requires GOOGLE_MAPS_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-google-maps'],\n passthroughEnv: ['GOOGLE_MAPS_API_KEY'],\n permission: 'confirm',\n});\n\n/** Sentinel \u2014 security vulnerability scanning (sentinel-labs). */\nexport const sentinelServer = (): MCPServerConfig => ({\n name: 'sentinel',\n description: 'Security vulnerability scanning (Sentinel)',\n transport: 'streamable-http',\n url: 'https://mcp.sentinel.ai',\n permission: 'deny', // security tool \u2014 require explicit confirmation\n});\n\n/**\n * Z.AI Vision MCP \u2014 image understanding fallback for text-only models.\n * Requires Z_AI_API_KEY. Tools are read-only and safe to run automatically.\n */\nexport const zaiVisionServer = (): MCPServerConfig => ({\n name: 'zai-vision',\n description: 'Z.AI Vision MCP \u2014 image analysis and screenshot understanding',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@z_ai/mcp-server@latest'],\n env: { Z_AI_MODE: 'ZAI' },\n passthroughEnv: ['Z_AI_API_KEY'],\n allowedTools: [\n 'image_analysis',\n 'extract_text_from_screenshot',\n 'diagnose_error_screenshot',\n 'understand_technical_diagram',\n 'analyze_data_visualization',\n 'ui_diff_check',\n ],\n permission: 'auto',\n});\n\n/**\n * Playwright \u2014 browser automation: navigate, click, type, screenshot, evaluate JS.\n * Spawns a headless Chromium browser via @modelcontextprotocol/server-playwright.\n * Tools can read and interact with live web pages \u2014 permission defaults to\n * `confirm` because form submission / DOM mutation is possible.\n */\nexport const playwrightServer = (): MCPServerConfig => ({\n name: 'playwright',\n description:\n 'Browser automation \u2014 navigate, screenshot, click, type, evaluate JS (headless Chromium)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-playwright'],\n permission: 'confirm',\n});\n\n/**\n * MiniMax Token Plan MCP \u2014 search + understand_image.\n * This preset exposes only the read-only image understanding tool by default.\n * Requires MINIMAX_API_KEY and uvx on PATH.\n */\nexport const miniMaxVisionServer = (): MCPServerConfig => ({\n name: 'minimax-vision',\n description: 'MiniMax MCP \u2014 image understanding via understand_image',\n transport: 'stdio',\n command: 'uvx',\n args: ['minimax-coding-plan-mcp', '-y'],\n env: {\n MINIMAX_MCP_BASE_PATH: './.wrongstack/minimax-output',\n MINIMAX_API_HOST: 'https://api.minimax.io',\n MINIMAX_API_RESOURCE_MODE: 'url',\n },\n passthroughEnv: ['MINIMAX_API_KEY'],\n allowedTools: ['understand_image'],\n permission: 'auto',\n});\n\n/**\n * SSH Manager \u2014 remote SSH execution, file transfer, tunnels, health checks, and deployment ops.\n * Server credentials are intentionally NOT embedded here. Configure hosts via mcp-ssh-manager's\n * env/TOML config (for example SSH_SERVER_<NAME>_HOST, USER, KEYPATH/PASSWORD) or ssh-agent.\n */\nexport const sshManagerServer = (): MCPServerConfig => ({\n name: 'ssh',\n description:\n 'Remote SSH management \u2014 execute commands, transfer files, tunnels, health checks (mcp-ssh-manager)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', 'mcp-ssh-manager'],\n env: {\n MCP_SSH_COMPACT_JSON: 'true',\n MCP_SSH_DEFAULT_TIMEOUT: '120000',\n },\n permission: 'confirm',\n requestTimeoutMs: 180_000,\n});\n\n/** Everything bundled \u2014 full set of built-in servers. Useful for `wstack mcp add --all`. */\nexport const allServers = (): Record<string, MCPServerConfig> => ({\n filesystem: { ...filesystemServer(), enabled: false },\n github: { ...githubServer(), enabled: false },\n context7: { ...context7Server(), enabled: false },\n 'brave-search': { ...braveSearchServer(), enabled: false },\n block: { ...blockServer(), enabled: false },\n everart: { ...everArtServer(), enabled: false },\n slack: { ...slackServer(), enabled: false },\n aws: { ...awsServer(), enabled: false },\n 'google-maps': { ...googleMapsServer(), enabled: false },\n sentinel: { ...sentinelServer(), enabled: false },\n 'zai-vision': { ...zaiVisionServer(), enabled: false },\n 'minimax-vision': { ...miniMaxVisionServer(), enabled: false },\n playwright: { ...playwrightServer(), enabled: false },\n ssh: { ...sshManagerServer(), enabled: false },\n});\n", "import * as fs from 'node:fs/promises';\nimport { atomicWrite } from './atomic-write.js';\n\nexport type JsonObject = Record<string, unknown>;\nexport type JsonPathSegment = string | number;\nexport type JsonPath = readonly JsonPathSegment[];\n\nexport async function readJsonObjectFile(filePath: string): Promise<JsonObject> {\n try {\n const parsed = JSON.parse(await fs.readFile(filePath, 'utf8')) as unknown;\n return isJsonObject(parsed) ? parsed : {};\n } catch {\n return {};\n }\n}\n\nexport async function jsonObjectFileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function writeJsonObjectFile(filePath: string, value: JsonObject): Promise<void> {\n await atomicWrite(filePath, JSON.stringify(value, null, 2), { mode: 0o600 });\n}\n\nexport async function updateJsonObjectFile(\n filePath: string,\n mutator: (config: JsonObject) => void | JsonObject | Promise<void | JsonObject>,\n): Promise<JsonObject> {\n const config = await readJsonObjectFile(filePath);\n const maybeNext = await mutator(config);\n const next = maybeNext && isJsonObject(maybeNext) ? maybeNext : config;\n await writeJsonObjectFile(filePath, next);\n return next;\n}\n\nexport function getJsonPath(root: unknown, path: JsonPath): unknown {\n let current = root;\n for (const segment of path) {\n if (typeof segment === 'number') {\n if (!Array.isArray(current)) return undefined;\n current = current[segment];\n continue;\n }\n if (!isJsonObject(current)) return undefined;\n current = current[segment];\n }\n return current;\n}\n\nexport function setJsonPath(root: JsonObject, path: JsonPath, value: unknown): JsonObject {\n if (path.length === 0) {\n if (!isJsonObject(value)) throw new Error('Root config value must be an object');\n return value;\n }\n const parent = ensureJsonParent(root, path);\n const leaf = lastPathSegment(path);\n if (typeof leaf === 'number') {\n if (!Array.isArray(parent)) throw new Error(`Cannot set numeric segment ${leaf} on non-array parent`);\n parent[leaf] = value;\n } else {\n if (!isJsonObject(parent)) throw new Error(`Cannot set property ${leaf} on non-object parent`);\n parent[leaf] = value;\n }\n return root;\n}\n\nexport function removeJsonPath(root: JsonObject, path: JsonPath): boolean {\n if (path.length === 0) return false;\n const parent = getJsonPath(root, path.slice(0, -1));\n const leaf = lastPathSegment(path);\n if (typeof leaf === 'number') {\n if (!Array.isArray(parent) || leaf < 0 || leaf >= parent.length) return false;\n parent.splice(leaf, 1);\n return true;\n }\n if (!isJsonObject(parent) || !(leaf in parent)) return false;\n delete parent[leaf];\n return true;\n}\n\nexport async function setJsonPathInFile(filePath: string, path: JsonPath, value: unknown): Promise<JsonObject> {\n return updateJsonObjectFile(filePath, (config) => setJsonPath(config, path, value));\n}\n\nexport async function removeJsonPathInFile(filePath: string, path: JsonPath): Promise<JsonObject> {\n return updateJsonObjectFile(filePath, (config) => {\n removeJsonPath(config, path);\n });\n}\n\nexport function isJsonObject(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction lastPathSegment(path: JsonPath): JsonPathSegment {\n const segment = path[path.length - 1];\n /* v8 ignore next -- defensive: callers guard path.length === 0 before here */\n if (segment === undefined) throw new Error('Invalid empty JSON path');\n return segment;\n}\n\nfunction ensureJsonParent(root: JsonObject, path: JsonPath): JsonObject | unknown[] {\n let current: JsonObject | unknown[] = root;\n for (let i = 0; i < path.length - 1; i += 1) {\n const segment = path[i];\n const nextSegment = path[i + 1];\n /* v8 ignore next -- defensive: sparse-array paths are never produced by callers */\n if (segment === undefined) throw new Error('Invalid empty JSON path segment');\n const nextContainer = typeof nextSegment === 'number' ? [] : {};\n\n if (typeof segment === 'number') {\n if (!Array.isArray(current)) throw new Error(`Cannot traverse numeric segment ${segment} on non-array parent`);\n if (!isJsonObject(current[segment]) && !Array.isArray(current[segment])) current[segment] = nextContainer;\n current = current[segment] as JsonObject | unknown[];\n } else {\n if (!isJsonObject(current)) throw new Error(`Cannot traverse property ${segment} on non-object parent`);\n if (!isJsonObject(current[segment]) && !Array.isArray(current[segment])) current[segment] = nextContainer;\n current = current[segment] as JsonObject | unknown[];\n }\n }\n return current;\n}\n", "import { randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport { watch as watchDir } from 'node:fs';\nimport type { FSWatcher } from 'node:fs';\nimport * as path from 'node:path';\nimport { FsError } from '../types/errors.js';\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 \u2014 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 // P3 #20 (before-release.md): on Windows, fs.rename (MoveFileExW) does\n // not preserve Unix permission bits \u2014 the chmod above applies to the tmp\n // file, but the rename may reset the destination's mode to the Windows\n // default. Re-apply the mode after rename on win32 so an edited file\n // keeps its executable bit (or any non-default permission). On POSIX,\n // rename preserves metadata so this is a no-op (chmod is idempotent and\n // cheap), but we gate it on win32 to avoid the extra stat+chmod on the\n // common path.\n if (mode !== undefined && process.platform === 'win32') {\n try {\n await fs.chmod(targetPath, mode);\n } catch {\n // Best-effort: a transient EPERM (antivirus lock) should not fail\n // the write \u2014 the content is already on disk.\n }\n }\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 // A lock holder can be scheduled out for several seconds when the full test\n // suite (or a busy workstation) is spawning many child processes. Five\n // seconds was short enough to turn ordinary contention into a dropped\n // best-effort index write. Keep the wait bounded, but leave enough headroom\n // for the holder to resume and release before stale-lock recovery applies.\n const timeoutMs = opts.timeoutMs ?? 15_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 // If fs.open succeeded but handle.writeFile threw (e.g. ENOSPC, EIO),\n // `handle` owns an open exclusive lock file. Close the handle and remove\n // the orphan lock so the next iteration (or a peer) can acquire it\n // without timing out on the stale-lock window or dead-looping on EEXIST.\n if (handle) {\n await handle.close().catch(() => {});\n await fs.unlink(lockPath).catch(() => {});\n handle = undefined;\n }\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' && code !== 'EPERM') 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 const elapsed = Date.now() - started;\n if (elapsed >= timeoutMs) {\n throw new FsError({\n message: `Timed out waiting for file lock: ${targetPath}`,\n code: 'FS_ATOMIC_WRITE_FAILED',\n path: targetPath,\n context: { timeoutMs },\n });\n }\n // Wait for the lock to be released, using a filesystem watcher for\n // nearly-instant wake-up instead of polling. The watcher is best-effort:\n // a safety timeout fires at most every 100ms so we don't busy-wait.\n await waitForLockRelease(lockPath, timeoutMs - elapsed);\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/**\n * Watch a lock file's parent directory for the file being removed (unlinked),\n * which signals that the lock holder has released it. A safety timeout caps\n * the wait so the overall `withFileLock` timeout is always respected.\n *\n * Uses a bounded safety interval (up to 100ms) so even if `fs.watch` is\n * unavailable or misses the event, we never busy-wait at 25ms fixed polling.\n */\nasync function waitForLockRelease(lockPath: string, remainingMs: number): Promise<void> {\n const parentDir = path.dirname(lockPath);\n const lockName = path.basename(lockPath);\n const intervalMs = Math.min(remainingMs, 100);\n\n return new Promise<void>((resolve) => {\n let settled = false;\n let watcher: FSWatcher | null = null;\n\n // Safety timer \u2014 always fires, even if fs.watch is unavailable.\n const timer = setTimeout(() => {\n settled = true;\n watcher?.close();\n resolve();\n }, intervalMs);\n\n try {\n watcher = watchDir(parentDir, (eventType, filename) => {\n if (settled) return;\n // 'rename' fires on unlink on most platforms; 'change' is a\n // conservative fallback for environments that only emit 'change'.\n if (filename === lockName && (eventType === 'rename' || eventType === 'change')) {\n settled = true;\n clearTimeout(timer);\n watcher?.close();\n resolve();\n }\n });\n } catch {\n // fs.watch not supported (e.g. some container environments, network\n // filesystems). Clear the safety timer and fall back to a single\n // short delay \u2014 the caller's loop will retry on the next iteration.\n clearTimeout(timer);\n if (!settled) {\n settled = true;\n setTimeout(resolve, Math.min(remainingMs, 25));\n }\n return;\n }\n\n // Re-check lock existence after setting up the watch to close the race\n // where the lock was released between our last EEXIST check and now.\n fs.access(lockPath).then(\n () => {\n // Lock still exists \u2014 the watch (or safety timer) will resolve.\n },\n () => {\n // Lock was already released \u2014 respond immediately.\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n watcher?.close();\n resolve();\n }\n },\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 \u2014 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", "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` \u2014 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` \u2014 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` \u2014 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 \u2014 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}\n", "/**\n * String utilities shared across the WrongStack codebase.\n */\n\n/**\n * Truncate a string to at most `max` characters, appending an ellipsis if it\n * was longer. Returns the original string unchanged when it fits.\n */\nexport function truncate(s: string, max: number): string {\n return s.length <= max ? s : `${s.slice(0, max - 1)}\u2026`;\n}\n", "import { toErrorMessage } from '../utils/index.js';\n\n/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// \u2500\u2500 Error codes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n PARSE_FAILED: 'PARSE_FAILED',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` \u2014 no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// \u2500\u2500 Base error class \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// \u2500\u2500 Specific error classes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Tool execution errors \u2014 thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors \u2014 thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = toErrorMessage(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors \u2014 spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n/**\n * HTTP fetch error \u2014 thrown when a network request returns a non-OK status.\n * Carries the response status so {@link classifyToolError} can branch on it\n * (429 \u2192 transient, 404 \u2192 not_found, 401 \u2192 permission) without duck-typing\n * the error via `'response' in err`.\n *\n * P3 #18 (before-release.md): the previous `'response' in err` check caught\n * any Error with a `response` property, including custom errors, proxy\n * objects, or mocked errors in tests. `instanceof FetchError` is reliable.\n *\n * Tools and providers that make HTTP requests and need the executor to\n * classify their failures should throw `new FetchError({ status, message })`\n * instead of a bare `Error` with an ad-hoc `response` field.\n */\nexport class FetchError extends WrongStackError {\n readonly status: number;\n\n constructor(opts: {\n message: string;\n status: number;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: opts.status === 429 || opts.status >= 500,\n context: { status: opts.status, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FetchError';\n this.status = opts.status;\n }\n}\n\n/**\n * Tool input validation error \u2014 thrown when a tool's input fails a validation\n * check that the JSON Schema cannot express (e.g. `old_string === new_string`\n * in edit, or a cross-field invariant). Use this instead of a bare\n * `throw new Error('...validation...')` so {@link classifyToolError} can\n * match on `instanceof` rather than a locale-dependent message substring.\n *\n * P2 #6 (before-release.md): the previous `err.message.includes('validation')`\n * check misclassified any error whose message happened to contain \"validation\"\n * (e.g. a third-party \"input validation timeout\") as a VALIDATION error.\n *\n * Named `ToolValidationError` (not `ValidationError`) to avoid colliding with\n * the existing `ValidationError` interface exported by json-schema-validate.ts\n * (a validation-result shape, not an Error subclass).\n */\nexport class ToolValidationError extends WrongStackError {\n constructor(opts: {\n message: string;\n /** Field path or tool name that failed validation, for diagnostics. */\n field?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { field: opts.field, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolValidationError';\n }\n}\n\n/**\n * Response / payload parse error \u2014 thrown when an upstream HTTP response,\n * file, or data structure is well-formed at the transport layer (HTTP 200,\n * valid JSON) but is missing required fields or has an unexpected shape.\n *\n * Distinct from `ConfigError(CONFIG_PARSE_FAILED)` (which is specifically\n * for config-file parsing) and `FetchError` (which covers HTTP non-OK\n * responses). `ParseError` fills the gap: the request succeeded but the\n * response body couldn't be interpreted.\n *\n * Common sites: OAuth token responses missing `access_token`, device-code\n * responses missing `device_code`, registry responses with unexpected\n * schemas.\n */\nexport class ParseError extends WrongStackError {\n readonly source?: string | undefined;\n\n constructor(opts: {\n message: string;\n /**\n * What was being parsed \u2014 e.g. `'oauth-token-response'`,\n * `'device-code-response'`. Lets consumers distinguish parse failures\n * from different upstream APIs without parsing the message.\n */\n source?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.PARSE_FAILED,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { source: opts.source, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ParseError';\n this.source = opts.source;\n }\n}\n\n// \u2500\u2500 Type guards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isToolValidationError(err: unknown): err is ToolValidationError {\n return err instanceof ToolValidationError;\n}\n\nexport function isFetchError(err: unknown): err is FetchError {\n return err instanceof FetchError;\n}\n\nexport function isParseError(err: unknown): err is ParseError {\n return err instanceof ParseError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n", "import { expectDefined } from '../utils/expect-defined.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { ToolCapabilities } from '../security/capabilities.js';\n/**\n * `mcp_control` \u2014 LLM-driven MCP server lifecycle management.\n *\n * The model calls this tool to:\n * list \u2014 see all known servers (running or not) without starting any\n * search \u2014 filter the server catalog by name or description keyword\n * enable \u2014 start a server and register its tools\n * disable \u2014 stop a server and unregister its tools\n * restart \u2014 stop then re-start a running server\n *\n * This is the primary mechanism by which the LLM autonomously extends its\n * own capabilities at runtime \u2014 e.g. \"I need GitHub access, let me enable it.\"\n */\nimport { allServers } from '../infrastructure/mcp-servers.js';\nimport { readJsonObjectFile, setJsonPath, updateJsonObjectFile } from '../utils/config-json.js';\nimport type { Config, JSONSchema, MCPServerConfig, Tool } from '../index.js';\nexport interface MCPRegistryHandle {\n start(cfg: MCPServerConfig): Promise<void>;\n stop(name: string): Promise<void>;\n restart(name: string): Promise<void>;\n describe(): {\n name: string;\n state: string;\n toolCount: number;\n enabled: boolean;\n tools?: string[];\n }[];\n list(): { name: string; state: string; toolCount: number; tools?: string[] }[];\n /**\n * Register all cached tools for a server without restarting it.\n * No-op if the server is not connected or tools are already active.\n * Used in token-saving mode to temporarily expose MCP tools.\n */\n activateServer?(name: string): void;\n /**\n * Unregister all tools for a server without disconnecting it.\n * Returns the number of tools that were deactivated.\n * Used in token-saving mode to hide MCP tools after use.\n */\n deactivateServer?(name: string): number;\n /**\n * Check whether a server's tools are currently registered.\n */\n isActivated?(name: string): boolean;\n}\n\nexport interface CreateMcpControlToolOptions {\n /**\n * Read the current config object. The tool never mutates this directly \u2014\n * writes go to the global config file via `configPath`.\n */\n getConfig: () => Config;\n /**\n * Path to the active profile config for atomic config writes.\n */\n configPath: string;\n /**\n * Live MCP registry for runtime start/stop/restart. The tool calls these\n * immediately so the LLM sees the result of its action in the same turn.\n */\n registry: MCPRegistryHandle;\n}\n\nexport function createMcpControlTool(opts: CreateMcpControlToolOptions): Tool {\n const { getConfig, configPath, registry } = opts;\n\n const inputSchema: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'search', 'enable', 'disable', 'restart', 'activate', 'deactivate'],\n description: 'The management action to perform. activate/deactivate toggle tool registration ephemerally without disconnecting.',\n },\n /** Filter for `search`. Matches server name or description case-insensitively. */\n query: {\n type: 'string',\n description: 'Search term for `search` action. Matches server name or description.',\n },\n /** Target server name for `enable`, `disable`, `restart`, `activate`, `deactivate`. */\n server: {\n type: 'string',\n description: 'Server name (e.g. \"github\", \"filesystem\", \"brave-search\").',\n },\n },\n required: ['action'],\n };\n\n return {\n name: 'mcp_control',\n description:\n 'Manage MCP server lifecycle: list available servers, search by name or capability, enable or disable servers at runtime, restart running servers. Use activate/deactivate to ephemerally toggle tool registration without disconnecting \u2014 ideal for token-saving mode where MCP tools are lazy-loaded on demand. NOTE: `enable`/`restart` start a server process, which for the built-in stdio presets runs `npx -y <package>` \u2014 i.e. it fetches and executes an npm package from the network. Treat it as code execution.',\n category: 'mcp',\n permission: 'confirm',\n mutating: true,\n // `enable`/`restart` spawn a server process that, for the stdio presets,\n // fetches and runs an npm package (`npx -y <pkg>`) \u2014 effectively remote\n // code execution. Marking the tool destructive preserves risk metadata for\n // UI/audit surfaces; YOLO itself still auto-approves unless an explicit\n // deny rule blocks the call. Read-only actions (list/search) ride the same\n // tool but are cheap to confirm/trust once when YOLO is off.\n riskTier: 'destructive',\n capabilities: [ToolCapabilities.CONFIG_MUTATE],\n inputSchema,\n async execute(raw) {\n const input = raw as { action: string; query?: string | undefined; server?: string | undefined };\n return mcpControlDispatch(input, { getConfig, configPath, registry });\n },\n };\n}\n\n// \u2500\u2500 Dispatch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function mcpControlDispatch(\n input: { action: string; query?: string | undefined; server?: string | undefined },\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n const { action, query, server } = input;\n\n switch (action) {\n case 'list': return renderList(deps);\n case 'search': return renderSearch(query ?? '', deps);\n case 'enable': return server ? runEnable(server, deps) : '`server` is required for enable.';\n case 'disable': return server ? runDisable(server, deps) : '`server` is required for disable.';\n case 'restart': return server ? runRestart(server, deps) : '`server` is required for restart.';\n case 'activate': return server ? runActivate(server, deps) : '`server` is required for activate.';\n case 'deactivate': return server ? runDeactivate(server, deps) : '`server` is required for deactivate.';\n default:\n return `Unknown action \"${action}\". Use one of: list, search, enable, disable, restart, activate, deactivate.`;\n }\n}\n\n// \u2500\u2500 Actions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function renderList(deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle }): Promise<string> {\n const configured = await getConfiguredMcpServers(deps);\n const live = deps.registry.describe();\n\n if (Object.keys(configured).length === 0) {\n return [\n 'No MCP servers configured.',\n ' Use `mcp_control({ action: \"search\" })` to see available presets,',\n ' then `mcp_control({ action: \"enable\", server: \"<name>\" })` to add one.',\n ].join('\\n');\n }\n\n const lines: string[] = [];\n const liveMap = new Map(live.map((s) => [s.name, s]));\n\n for (const [name, cfg] of Object.entries(configured)) {\n const liveInfo = liveMap.get(name);\n const toolCount = liveInfo ? ` (${liveInfo.toolCount} tools)` : '';\n const stateStr = liveInfo ? badge(liveInfo.state) : dim('\u25CB not loaded');\n const enabled = cfg.enabled === false\n ? `${dim('disabled')} `\n : `${green('\u25CF enabled')} `;\n lines.push(` ${bold(name)} ${enabled}${stateStr}${toolCount}`);\n if (cfg.description) lines.push(` ${dim(cfg.description)}`);\n }\n\n lines.push('');\n lines.push(dim(' Use `mcp_control({ action: \"search\", query: \"<keyword>\" })` to find servers.'));\n lines.push(dim(' Use `mcp_control({ action: \"enable\", server: \"<name>\" })` to start a server.'));\n return lines.join('\\n');\n}\n\nasync function renderSearch(\n query: string,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n const configured = await getConfiguredMcpServers(deps);\n const all = allServers();\n const q = query.toLowerCase();\n\n const configuredNames = new Set(Object.keys(configured));\n\n // Match against configured servers first, then remaining presets\n const configuredEntries = Object.entries(configured).filter(\n ([name, cfg]) =>\n name.toLowerCase().includes(q) ||\n (cfg.description ?? '').toLowerCase().includes(q),\n );\n\n const unconfiguredEntries = Object.entries(all)\n .filter(([name]) => !configuredNames.has(name))\n .filter(\n ([name, cfg]) =>\n name.toLowerCase().includes(q) ||\n (cfg.description ?? '').toLowerCase().includes(q),\n );\n\n const lines: string[] = [];\n\n if (configuredEntries.length > 0) {\n lines.push(bold('Configured servers matching \"') + query + '\":');\n for (const [name, cfg] of configuredEntries) {\n lines.push(` ${bold(name)} ${cfg.description ?? cfg.transport}`);\n }\n lines.push('');\n }\n\n if (unconfiguredEntries.length > 0) {\n lines.push(bold('Available presets matching \"') + query + '\":');\n for (const [name, cfg] of unconfiguredEntries) {\n const warn = cfg.permission === 'deny' ? red(' \u26A0 confirm required') : '';\n lines.push(` ${bold(name)} ${cfg.description ?? cfg.transport}${warn}`);\n }\n lines.push('');\n }\n\n if (configuredEntries.length === 0 && unconfiguredEntries.length === 0) {\n return `No servers match \"${query}\". Try a shorter keyword or \\`mcp_control({ action: \"list\" })\\`.`;\n }\n\n const total = configuredEntries.length + unconfiguredEntries.length;\n lines.push(dim(` ${total} server${total !== 1 ? 's' : ''} shown. Run \\`enable\\` on one to activate it.`));\n return lines.join('\\n');\n}\n\nasync function runEnable(\n name: string | undefined,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for enable. Example: { action: \"enable\", server: \"github\" }';\n\n const all = allServers();\n const configured = deps.getConfig().mcpServers ?? {};\n\n // Resolve the target config \u2014 it may be a preset not yet in config\n const cfg = configured[name] ?? all[name];\n if (!cfg) {\n const known = Object.keys(all).join(', ');\n return `Unknown server \"${name}\". Available presets: ${known}`;\n }\n\n // Write to config (add or update) using the shared JSON path helper.\n await updateJsonObjectFile(deps.configPath, (full) => {\n const current = isMcpServerRecord(full.mcpServers) ? full.mcpServers : {};\n setJsonPath(full, ['mcpServers', name], { ...current[name], ...cfg, enabled: true });\n });\n\n // Start the server in the registry\n try {\n const live = deps.registry.describe().find((s) => s.name === name);\n if (live && live.state === 'connected') {\n return `${green('\u25CF')} Server \"${name}\" is already running (${live.toolCount} tools registered).`;\n }\n await deps.registry.start({ ...cfg, enabled: true });\n const updated = deps.registry.describe().find((s) => s.name === name);\n return `${green('\u2713 Enabled and started')} \"${name}\"${updated ? ` (${updated.toolCount} tools registered).` : '.'}`;\n } catch (err) {\n return `${red('\u2717 Failed to start')} \"${name}\": ${toErrorMessage(err)}`;\n }\n}\n\nasync function runDisable(\n name: string | undefined,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for disable. Example: { action: \"disable\", server: \"github\" }';\n\n const configured = deps.getConfig().mcpServers ?? {};\n if (!configured[name]) {\n return `Server \"${name}\" is not in config. Add it with \\`mcp_control({ action: \"enable\", server: \"${name}\" })\\`.`;\n }\n\n // Write to config using the shared JSON path helper.\n await updateJsonObjectFile(deps.configPath, (full) => {\n const current = isMcpServerRecord(full.mcpServers) ? full.mcpServers : {};\n const existing = expectDefined(current[name]);\n setJsonPath(full, ['mcpServers', name], { ...existing, enabled: false });\n });\n\n // Stop the running server\n try {\n await deps.registry.stop(name);\n return `${yellow('\u25CB Disabled')} \"${name}\". It will not be started on next boot.`;\n } catch {\n return `${yellow('\u25CB Disabled')} \"${name}\" (it was not running). Config updated.`;\n }\n}\n\nasync function runRestart(\n name: string | undefined,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for restart. Example: { action: \"restart\", server: \"github\" }';\n\n const configured = deps.getConfig().mcpServers ?? {};\n if (!configured[name]) {\n return `Server \"${name}\" is not configured. Use \\`mcp_control({ action: \"enable\", server: \"${name}\" })\\` first.`;\n }\n\n try {\n await deps.registry.restart(name);\n const updated = deps.registry.describe().find((s) => s.name === name);\n return `${green('\u2713 Restarted')} \"${name}\"${updated ? ` (${updated.toolCount} tools registered).` : '.'}`;\n } catch (err) {\n return `${red('\u2717 Restart failed')} for \"${name}\": ${toErrorMessage(err)}`;\n }\n}\n\n/**\n * Ephemerally activate a server's tools without writing to config or\n * restarting the connection. The server must already be connected (lazy mode).\n * Calls `registry.activateServer()` when available; falls back to a message\n * if the registry doesn't support ephemeral activation.\n */\nasync function runActivate(\n name: string | undefined,\n deps: { registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for activate.';\n if (!deps.registry.activateServer) {\n return `Registry does not support ephemeral activation. Use \\`enable\\` to start \"${name}\" instead.`;\n }\n const live = deps.registry.describe().find((s) => s.name === name);\n if (!live) {\n return `Server \"${name}\" is not registered. Use \\`mcp_control({ action: \"enable\", server: \"${name}\" })\\` first.`;\n }\n if (live.state !== 'connected') {\n return `Server \"${name}\" is not connected (state: ${live.state}). Use \\`enable\\` to start it first.`;\n }\n if (deps.registry.isActivated?.(name)) {\n return `${green('\u25CF')} Server \"${name}\" tools are already active. Use \\`deactivate\\` to hide them.`;\n }\n deps.registry.activateServer(name);\n const updated = deps.registry.describe().find((s) => s.name === name);\n return `${green('\u2713 Activated')} \"${name}\" \u2014 ${updated?.toolCount ?? 0} tool(s) now registered. Use \\`mcp_control({ action: \"deactivate\", server: \"${name}\" })\\` to hide them when done.`;\n}\n\n/**\n * Ephemerally deactivate a server's tools without disconnecting.\n * Calls `registry.deactivateServer()` when available.\n */\nasync function runDeactivate(\n name: string | undefined,\n deps: { registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for deactivate.';\n if (!deps.registry.deactivateServer) {\n return `Registry does not support ephemeral deactivation. Use \\`disable\\` to stop \"${name}\" instead.`;\n }\n if (!deps.registry.isActivated?.(name)) {\n return `Server \"${name}\" tools are not currently active.`;\n }\n const count = deps.registry.deactivateServer(name);\n return `${yellow('\u25CB Deactivated')} \"${name}\" \u2014 ${count} tool(s) unregistered. Server stays connected.`;\n}\n\n// \u2500\u2500 Config helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function getConfiguredMcpServers(deps: { getConfig: () => Config; configPath: string }): Promise<Record<string, MCPServerConfig>> {\n const diskConfig = await readJsonObjectFile(deps.configPath);\n if (isMcpServerRecord(diskConfig.mcpServers)) return diskConfig.mcpServers;\n return deps.getConfig().mcpServers ?? {};\n}\n\nfunction isMcpServerRecord(value: unknown): value is Record<string, MCPServerConfig> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\n// \u2500\u2500 Colour helpers (no dep on core color \u2014 inline) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bold(s: string) { return `\\x1b[1m${s}\\x1b[0m`; }\nfunction dim(s: string) { return `\\x1b[2m${s}\\x1b[0m`; }\nfunction green(s: string) { return `\\x1b[32m${s}\\x1b[0m`; }\nfunction yellow(s: string){ return `\\x1b[33m${s}\\x1b[0m`; }\nfunction red(s: string) { return `\\x1b[31m${s}\\x1b[0m`; }\n\nfunction badge(state: string): string {\n switch (state) {\n case 'connected': return green('\u25CF connected');\n case 'connecting': return `\\x1b[36m\u25D0 connecting\\x1b[0m`;\n case 'reconnecting': return `\\x1b[36m\u25D1 reconnecting\\x1b[0m`;\n case 'disconnected': return dim('\u25CB disconnected');\n case 'failed': return red('\u2717 failed');\n default: return dim(state);\n }\n}\n", "import type { CouncilPersona } from '../types/council.js';\n\nconst PERSONA_ID_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\n/** Provider-neutral personas shipped with every Council installation. */\nexport const BUILTIN_COUNCIL_PERSONAS: readonly CouncilPersona[] = Object.freeze([\n freezePersona({\n id: 'executor',\n name: 'Executor',\n description: 'Tests whether a proposal is practical and keeps useful work moving.',\n instruction:\n 'Evaluate operational feasibility, concrete progress, and the cost of delay. Favor decisive action when evidence supports it, but reject action whose prerequisites are missing.',\n tags: ['delivery', 'feasibility', 'progress'],\n }),\n freezePersona({\n id: 'skeptic',\n name: 'Skeptic',\n description: 'Challenges assumptions and looks for concrete failure modes.',\n instruction:\n 'Identify unsupported assumptions, unsafe premises, irreversible consequences, and credible failure modes. Oppose or refuse only when you can name a concrete reason.',\n defaultVeto: true,\n tags: ['risk', 'assumptions', 'failure-modes'],\n }),\n freezePersona({\n id: 'auditor',\n name: 'Auditor',\n description: 'Evaluates cost, waste, evidence quality, and expected value.',\n instruction:\n 'Compare resource cost, opportunity cost, evidence quality, reversibility, and expected value. Prefer the option that achieves the objective with the least avoidable waste.',\n tags: ['cost', 'evidence', 'efficiency'],\n }),\n freezePersona({\n id: 'security',\n name: 'Security Reviewer',\n description: 'Examines trust boundaries, abuse cases, and security impact.',\n instruction:\n 'Evaluate trust boundaries, attacker-controlled inputs, privilege changes, data exposure, abuse cases, and recovery options. Treat unmitigated high-impact security risk as grounds to refuse.',\n defaultVeto: true,\n tags: ['security', 'trust', 'abuse-cases'],\n }),\n freezePersona({\n id: 'maintainer',\n name: 'Maintainer',\n description: 'Evaluates complexity, compatibility, and long-term ownership.',\n instruction:\n 'Evaluate behavioral compatibility, conceptual complexity, testability, migration cost, and future maintenance. Prefer the smallest design that remains clear and extensible.',\n tags: ['maintenance', 'compatibility', 'simplicity'],\n }),\n freezePersona({\n id: 'user-advocate',\n name: 'User Advocate',\n description: 'Evaluates the decision from the affected user\u2019s perspective.',\n instruction:\n 'Evaluate usability, surprise, accessibility, failure recovery, and whether the outcome solves the user\u2019s stated need. Prefer understandable behavior with safe recovery paths.',\n tags: ['users', 'usability', 'accessibility'],\n }),\n]);\n\n/** Immutable registry of trusted Council persona definitions. */\nexport class CouncilPersonaRegistry {\n private readonly byId: ReadonlyMap<string, CouncilPersona>;\n\n constructor(personas: readonly CouncilPersona[] = []) {\n const entries = new Map<string, CouncilPersona>();\n for (const persona of personas) {\n const normalized = freezePersona(persona);\n if (entries.has(normalized.id)) {\n throw new Error(`CouncilPersonaRegistry: duplicate persona id \"${normalized.id}\".`);\n }\n entries.set(normalized.id, normalized);\n }\n this.byId = entries;\n }\n\n has(id: string): boolean {\n return this.byId.has(id);\n }\n\n get(id: string): CouncilPersona | undefined {\n return this.byId.get(id);\n }\n\n require(id: string): CouncilPersona {\n const persona = this.get(id);\n if (!persona) throw new Error(`CouncilPersonaRegistry: unknown persona \"${id}\".`);\n return persona;\n }\n\n list(): readonly CouncilPersona[] {\n return Object.freeze([...this.byId.values()]);\n }\n\n /** Return a new registry; the current registry is never mutated. */\n with(persona: CouncilPersona, opts: { replace?: boolean | undefined } = {}): CouncilPersonaRegistry {\n const normalized = freezePersona(persona);\n if (this.has(normalized.id) && opts.replace !== true) {\n throw new Error(`CouncilPersonaRegistry: persona \"${normalized.id}\" already exists.`);\n }\n return new CouncilPersonaRegistry([\n ...this.list().filter((entry) => entry.id !== normalized.id),\n normalized,\n ]);\n }\n}\n\nexport const DEFAULT_COUNCIL_PERSONA_REGISTRY = new CouncilPersonaRegistry(\n BUILTIN_COUNCIL_PERSONAS,\n);\n\nexport function createCouncilPersonaRegistry(\n additional: readonly CouncilPersona[] = [],\n): CouncilPersonaRegistry {\n let registry = DEFAULT_COUNCIL_PERSONA_REGISTRY;\n for (const persona of additional) registry = registry.with(persona);\n return registry;\n}\n\nfunction freezePersona(persona: CouncilPersona): CouncilPersona {\n const id = persona.id.trim();\n const name = persona.name.trim();\n const description = persona.description.trim();\n const instruction = persona.instruction.trim();\n if (!PERSONA_ID_RE.test(id)) {\n throw new Error(`CouncilPersonaRegistry: invalid persona id \"${persona.id}\".`);\n }\n if (!name) throw new Error(`CouncilPersonaRegistry: persona \"${id}\" requires a name.`);\n if (!description) {\n throw new Error(`CouncilPersonaRegistry: persona \"${id}\" requires a description.`);\n }\n if (!instruction) {\n throw new Error(`CouncilPersonaRegistry: persona \"${id}\" requires an instruction.`);\n }\n if (\n persona.defaultWeight !== undefined &&\n (!Number.isFinite(persona.defaultWeight) || persona.defaultWeight <= 0)\n ) {\n throw new Error(`CouncilPersonaRegistry: persona \"${id}\" has an invalid default weight.`);\n }\n const tags = Object.freeze(\n [...new Set((persona.tags ?? []).map((tag) => tag.trim()).filter(Boolean))],\n );\n return Object.freeze({\n id,\n name,\n description,\n instruction,\n ...(persona.defaultWeight !== undefined ? { defaultWeight: persona.defaultWeight } : {}),\n ...(persona.defaultVeto !== undefined ? { defaultVeto: persona.defaultVeto } : {}),\n ...(tags.length > 0 ? { tags } : {}),\n });\n}\n", "import type {\n CouncilDistinctness,\n CouncilModelTarget,\n CouncilProfileConfig,\n ResolvedCouncilProfile,\n ResolvedCouncilSeat,\n} from '../types/council.js';\nimport {\n type CouncilPersonaRegistry,\n DEFAULT_COUNCIL_PERSONA_REGISTRY,\n} from './council-personas.js';\n\nconst PROFILE_ID_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nconst DISTINCTNESS_VALUES: ReadonlySet<CouncilDistinctness> = new Set([\n 'none',\n 'model',\n 'provider',\n]);\n\nexport const DEFAULT_COUNCIL_QUORUM_FRACTION = 0.5;\nexport const DEFAULT_COUNCIL_APPROVAL_FRACTION = 0.5;\nexport const DEFAULT_COUNCIL_VOTER_MAX_TOKENS = 300;\nexport const DEFAULT_COUNCIL_JUDGE_MAX_TOKENS = 500;\nexport const DEFAULT_COUNCIL_PER_CALL_TIMEOUT_MS = 30_000;\nexport const DEFAULT_COUNCIL_OVERALL_TIMEOUT_MS = 90_000;\n\n/** Model-agnostic profiles. Roles are routing hints, never provider/model pins. */\nexport const BUILTIN_COUNCIL_PROFILES: readonly CouncilProfileConfig[] = Object.freeze([\n Object.freeze({\n id: 'balanced',\n name: 'Balanced',\n description: 'Three complementary lenses plus an independent judge for general decisions.',\n seats: Object.freeze([\n Object.freeze({ persona: 'executor', target: Object.freeze({ role: 'planner' }) }),\n Object.freeze({ persona: 'skeptic', target: Object.freeze({ role: 'critic' }) }),\n Object.freeze({ persona: 'auditor', target: Object.freeze({ role: 'analyst' }) }),\n ]),\n judge: Object.freeze({ role: 'reviewer' }),\n quorumFraction: 0.5,\n approvalFraction: 0.5,\n distinctness: 'model',\n }),\n Object.freeze({\n id: 'fast',\n name: 'Fast',\n description: 'Two-seat panel without a judge for quick, low-cost decisions.',\n seats: Object.freeze([\n Object.freeze({ persona: 'executor', target: Object.freeze({ role: 'planner' }) }),\n Object.freeze({ persona: 'skeptic', target: Object.freeze({ role: 'critic' }) }),\n ]),\n judge: false,\n quorumFraction: 0.5,\n approvalFraction: 0.5,\n distinctness: 'none',\n voterMaxTokens: 200,\n perCallTimeoutMs: 20_000,\n overallTimeoutMs: 30_000,\n }),\n Object.freeze({\n id: 'risk-review',\n name: 'Risk Review',\n description: 'Security, assumptions, maintenance, and cost review for high-impact choices.',\n seats: Object.freeze([\n Object.freeze({ persona: 'skeptic', target: Object.freeze({ role: 'critic' }) }),\n Object.freeze({ persona: 'security', target: Object.freeze({ role: 'security-reviewer' }) }),\n Object.freeze({ persona: 'maintainer', target: Object.freeze({ role: 'reviewer' }) }),\n Object.freeze({ persona: 'auditor', target: Object.freeze({ role: 'analyst' }) }),\n ]),\n judge: Object.freeze({ role: 'architect' }),\n quorumFraction: 0.75,\n approvalFraction: 0.5,\n distinctness: 'provider',\n judgeMaxTokens: 700,\n overallTimeoutMs: 120_000,\n }),\n]);\n\n/** Immutable registry of normalized Council profiles. */\nexport class CouncilProfileRegistry {\n private readonly byId: ReadonlyMap<string, ResolvedCouncilProfile>;\n private readonly personas: CouncilPersonaRegistry;\n\n constructor(\n profiles: readonly CouncilProfileConfig[] = [],\n personas: CouncilPersonaRegistry = DEFAULT_COUNCIL_PERSONA_REGISTRY,\n ) {\n this.personas = personas;\n const entries = new Map<string, ResolvedCouncilProfile>();\n for (const profile of profiles) {\n const normalized = normalizeCouncilProfile(profile, personas);\n if (entries.has(normalized.id)) {\n throw new Error(`CouncilProfileRegistry: duplicate profile id \"${normalized.id}\".`);\n }\n entries.set(normalized.id, normalized);\n }\n this.byId = entries;\n }\n\n has(id: string): boolean {\n return this.byId.has(id);\n }\n\n get(id: string): ResolvedCouncilProfile | undefined {\n return this.byId.get(id);\n }\n\n require(id: string): ResolvedCouncilProfile {\n const profile = this.get(id);\n if (!profile) throw new Error(`CouncilProfileRegistry: unknown profile \"${id}\".`);\n return profile;\n }\n\n list(): readonly ResolvedCouncilProfile[] {\n return Object.freeze([...this.byId.values()]);\n }\n\n /** Return a new registry; the current registry is never mutated. */\n with(\n profile: CouncilProfileConfig,\n opts: {\n replace?: boolean | undefined;\n personas?: CouncilPersonaRegistry | undefined;\n } = {},\n ): CouncilProfileRegistry {\n const personas = opts.personas ?? this.personas;\n const normalized = normalizeCouncilProfile(profile, personas);\n if (this.has(normalized.id) && opts.replace !== true) {\n throw new Error(`CouncilProfileRegistry: profile \"${normalized.id}\" already exists.`);\n }\n return new CouncilProfileRegistry(\n [\n ...this.list().filter((entry) => entry.id !== normalized.id),\n profile,\n ],\n personas,\n );\n }\n}\n\nexport const DEFAULT_COUNCIL_PROFILE_REGISTRY = new CouncilProfileRegistry(\n BUILTIN_COUNCIL_PROFILES,\n);\n\nexport function createCouncilProfileRegistry(\n additional: readonly CouncilProfileConfig[] = [],\n personas: CouncilPersonaRegistry = DEFAULT_COUNCIL_PERSONA_REGISTRY,\n): CouncilProfileRegistry {\n return new CouncilProfileRegistry([...BUILTIN_COUNCIL_PROFILES, ...additional], personas);\n}\n\nexport function resolveCouncilProfile(\n profile: string | CouncilProfileConfig | undefined,\n opts: {\n registry?: CouncilProfileRegistry | undefined;\n personas?: CouncilPersonaRegistry | undefined;\n defaultProfile?: string | undefined;\n } = {},\n): ResolvedCouncilProfile {\n const personas = opts.personas ?? DEFAULT_COUNCIL_PERSONA_REGISTRY;\n if (profile && typeof profile !== 'string') return normalizeCouncilProfile(profile, personas);\n const id = profile ?? opts.defaultProfile ?? 'balanced';\n return (opts.registry ?? DEFAULT_COUNCIL_PROFILE_REGISTRY).require(id);\n}\n\nexport function normalizeCouncilProfile(\n profile: CouncilProfileConfig,\n personas: CouncilPersonaRegistry = DEFAULT_COUNCIL_PERSONA_REGISTRY,\n): ResolvedCouncilProfile {\n const id = profile.id.trim();\n if (!PROFILE_ID_RE.test(id)) {\n throw new Error(`CouncilProfileRegistry: invalid profile id \"${profile.id}\".`);\n }\n if (profile.seats.length === 0) {\n throw new Error(`CouncilProfileRegistry: profile \"${id}\" requires at least one seat.`);\n }\n\n const usedIds = new Set<string>();\n const seats = profile.seats.map((seat) => {\n const persona = personas.require(seat.persona.trim());\n const explicitSeatId = seat.id?.trim();\n if (explicitSeatId && usedIds.has(explicitSeatId)) {\n throw new Error(`CouncilProfileRegistry: duplicate seat id \"${explicitSeatId}\".`);\n }\n const seatId = uniqueSeatId(explicitSeatId || persona.id, usedIds);\n const label = seat.label?.trim() || persona.name;\n const weight = seat.weight ?? persona.defaultWeight ?? 1;\n if (!Number.isFinite(weight) || weight <= 0) {\n throw new Error(`CouncilProfileRegistry: seat \"${seatId}\" has an invalid weight.`);\n }\n return Object.freeze({\n id: seatId,\n label,\n persona: persona.id,\n ...(seat.target ? { target: freezeTarget(seat.target, `seat \"${seatId}\"`) } : {}),\n weight,\n veto: seat.veto ?? persona.defaultVeto ?? false,\n }) satisfies ResolvedCouncilSeat;\n });\n\n const quorumFraction = fraction(\n profile.quorumFraction ?? DEFAULT_COUNCIL_QUORUM_FRACTION,\n 'quorumFraction',\n id,\n );\n const approvalFraction = fraction(\n profile.approvalFraction ?? DEFAULT_COUNCIL_APPROVAL_FRACTION,\n 'approvalFraction',\n id,\n );\n const distinctness = profile.distinctness ?? 'model';\n if (!DISTINCTNESS_VALUES.has(distinctness)) {\n throw new Error(`CouncilProfileRegistry: profile \"${id}\" has invalid distinctness.`);\n }\n const voterMaxTokens = positiveInteger(\n profile.voterMaxTokens ?? DEFAULT_COUNCIL_VOTER_MAX_TOKENS,\n 'voterMaxTokens',\n id,\n );\n const judgeMaxTokens = positiveInteger(\n profile.judgeMaxTokens ?? DEFAULT_COUNCIL_JUDGE_MAX_TOKENS,\n 'judgeMaxTokens',\n id,\n );\n const perCallTimeoutMs = positiveInteger(\n profile.perCallTimeoutMs ?? DEFAULT_COUNCIL_PER_CALL_TIMEOUT_MS,\n 'perCallTimeoutMs',\n id,\n );\n const overallTimeoutMs = positiveInteger(\n profile.overallTimeoutMs ?? DEFAULT_COUNCIL_OVERALL_TIMEOUT_MS,\n 'overallTimeoutMs',\n id,\n );\n if (overallTimeoutMs < perCallTimeoutMs) {\n throw new Error(\n `CouncilProfileRegistry: profile \"${id}\" overallTimeoutMs must be at least perCallTimeoutMs.`,\n );\n }\n\n return Object.freeze({\n id,\n name: profile.name?.trim() || id,\n description: profile.description?.trim() || '',\n seats: Object.freeze(seats),\n judge: profile.judge ? freezeTarget(profile.judge, 'judge') : false,\n quorumFraction,\n approvalFraction,\n distinctness,\n voterMaxTokens,\n judgeMaxTokens,\n perCallTimeoutMs,\n overallTimeoutMs,\n });\n}\n\nfunction uniqueSeatId(base: string, used: Set<string>): string {\n if (!PROFILE_ID_RE.test(base)) {\n throw new Error(`CouncilProfileRegistry: invalid seat id \"${base}\".`);\n }\n let id = base;\n let suffix = 2;\n while (used.has(id)) id = `${base}-${suffix++}`;\n used.add(id);\n return id;\n}\n\nfunction freezeTarget(target: CouncilModelTarget, label: string): CouncilModelTarget {\n const providerId = optionalText(target.providerId);\n const model = optionalText(target.model);\n const role = optionalText(target.role);\n const fallbackProfile = optionalText(target.fallbackProfile);\n const fallbackModels = Object.freeze(\n [...new Set((target.fallbackModels ?? []).map((ref) => ref.trim()).filter(Boolean))],\n );\n if (\n !providerId &&\n !model &&\n !role &&\n !fallbackProfile &&\n fallbackModels.length === 0\n ) {\n throw new Error(`CouncilProfileRegistry: ${label} target is empty.`);\n }\n return Object.freeze({\n ...(providerId ? { providerId } : {}),\n ...(model ? { model } : {}),\n ...(role ? { role } : {}),\n ...(fallbackProfile ? { fallbackProfile } : {}),\n ...(fallbackModels.length > 0 ? { fallbackModels } : {}),\n });\n}\n\nfunction optionalText(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed || undefined;\n}\n\nfunction fraction(value: number, field: string, profileId: string): number {\n if (!Number.isFinite(value) || value <= 0 || value > 1) {\n throw new Error(`CouncilProfileRegistry: profile \"${profileId}\" ${field} must be in (0, 1].`);\n }\n return value;\n}\n\nfunction positiveInteger(value: number, field: string, profileId: string): number {\n if (!Number.isSafeInteger(value) || value <= 0) {\n throw new Error(\n `CouncilProfileRegistry: profile \"${profileId}\" ${field} must be a positive integer.`,\n );\n }\n return value;\n}\n", "import { readFileSync, statSync } from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Cache of resolved instruction text, keyed by the relative path. Bundled\n * instruction files are immutable for the process lifetime, so re-reading them\n * on every call (some callers do so per LLM request) is wasted disk I/O.\n */\nconst textCache = new Map<string, string>();\n\n/** Resolved once \u2014 the candidate roots only depend on this module's location. */\nlet rootCandidates: string[] | undefined;\n\nexport function readBundledInstructionText(relativePath: string): string {\n const cached = textCache.get(relativePath);\n if (cached !== undefined) return cached;\n\n let resolved = '';\n for (const root of instructionRootCandidates()) {\n try {\n resolved = readFileSync(path.join(root, relativePath), 'utf8').trimEnd();\n break;\n } catch {\n // try next candidate\n }\n }\n textCache.set(relativePath, resolved);\n return resolved;\n}\n\nexport function renderInstructionTemplate(\n template: string,\n values: Record<string, string>,\n): string {\n return template.replace(/\\{\\{\\s*([a-zA-Z0-9_.-]+)\\s*\\}\\}/g, (match, key: string) =>\n Object.hasOwn(values, key) ? (values[key] ?? '') : match,\n );\n}\n\nfunction instructionRootCandidates(): string[] {\n if (rootCandidates !== undefined) return rootCandidates;\n const here = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n path.resolve(here, '../../instructions'),\n path.resolve(here, '../instructions'),\n path.resolve(here, 'instructions'),\n ];\n rootCandidates = candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));\n return rootCandidates;\n}\n\nfunction isDirectory(candidate: string): boolean {\n try {\n return statSync(candidate).isDirectory();\n } catch {\n return false;\n }\n}\n", "import type {\n CouncilOption,\n CouncilPersona,\n CouncilQuestion,\n CouncilVoteResult,\n ResolvedCouncilSeat,\n} from '../types/council.js';\nimport {\n readBundledInstructionText,\n renderInstructionTemplate,\n} from '../utils/instruction-file.js';\n\nexport const COUNCIL_VOTER_PROMPT_PATH = 'llm/council-voter.md';\nexport const COUNCIL_JUDGE_PROMPT_PATH = 'llm/council-judge.md';\n\n/** Build the trusted system instruction for one independent seat. */\nexport function buildCouncilVoterSystemPrompt(persona: CouncilPersona): string {\n const template = requiredInstruction(COUNCIL_VOTER_PROMPT_PATH);\n return renderInstructionTemplate(template, {\n personaInstruction: persona.instruction,\n });\n}\n\n/** Build the trusted system instruction for the final judge. */\nexport function buildCouncilJudgeSystemPrompt(): string {\n return requiredInstruction(COUNCIL_JUDGE_PROMPT_PATH);\n}\n\n/** Render the original question as delimited, untrusted user data. */\nexport function buildCouncilQuestionPrompt(\n question: CouncilQuestion,\n opts: { refusalOptionId?: string | undefined } = {},\n): string {\n const text = question.question.trim();\n if (!text) throw new Error('buildCouncilQuestionPrompt: question must not be empty.');\n const options = normalizeOptions(question.options);\n return [\n '<council-question>',\n `Question: ${text}`,\n question.context?.trim() ? `Context:\\n${question.context.trim()}` : '',\n options.length > 0 ? `Options (JSON):\\n${JSON.stringify(options)}` : 'Options: none',\n opts.refusalOptionId\n ? `Refusal option id: ${opts.refusalOptionId}`\n : 'Refusal option id: not supplied',\n '</council-question>',\n ]\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/** Build the voter user prompt. Persona instructions stay in the system prompt. */\nexport function buildCouncilVoterUserPrompt(\n question: CouncilQuestion,\n seat: ResolvedCouncilSeat,\n opts: { refusalOptionId?: string | undefined } = {},\n): string {\n return [\n buildCouncilQuestionPrompt(question, opts),\n '<seat-metadata>',\n `Seat id: ${seat.id}`,\n `Seat label: ${seat.label}`,\n `Persona id: ${seat.persona}`,\n '</seat-metadata>',\n ].join('\\n');\n}\n\n/** Build the judge user prompt with seat outputs serialized as untrusted JSON. */\nexport function buildCouncilJudgeUserPrompt(\n question: CouncilQuestion,\n votes: readonly CouncilVoteResult[],\n opts: {\n reason?: string | undefined;\n refusalOptionId?: string | undefined;\n } = {},\n): string {\n const ballots = votes.map((vote) => ({\n seatId: vote.seatId,\n persona: vote.persona,\n status: vote.status,\n ...(vote.optionId ? { optionId: vote.optionId } : {}),\n ...(vote.stance ? { stance: vote.stance } : {}),\n ...(vote.rationale ? { rationale: vote.rationale } : {}),\n }));\n return [\n buildCouncilQuestionPrompt(question, { refusalOptionId: opts.refusalOptionId }),\n '<council-ballots>',\n opts.reason?.trim() ? `Reason judging is required: ${opts.reason.trim()}` : '',\n JSON.stringify(ballots),\n '</council-ballots>',\n ]\n .filter(Boolean)\n .join('\\n\\n');\n}\n\nfunction normalizeOptions(options: readonly CouncilOption[] | undefined): CouncilOption[] {\n if (!options) return [];\n const seen = new Set<string>();\n return options.map((option) => {\n const id = option.id.trim();\n const label = option.label.trim();\n if (!id) throw new Error('buildCouncilQuestionPrompt: option id must not be empty.');\n if (!label) throw new Error(`buildCouncilQuestionPrompt: option \"${id}\" needs a label.`);\n if (seen.has(id)) throw new Error(`buildCouncilQuestionPrompt: duplicate option id \"${id}\".`);\n seen.add(id);\n return {\n id,\n label,\n ...(option.consequence?.trim() ? { consequence: option.consequence.trim() } : {}),\n };\n });\n}\n\nfunction requiredInstruction(path: string): string {\n const text = readBundledInstructionText(path);\n if (!text) throw new Error(`Council instruction file is unavailable: ${path}`);\n return text;\n}\n", "/**\n * Provider- and Brain-independent council vote resolution.\n *\n * This module contains only deterministic quorum, veto, weighted-majority,\n * refusal, and judge-escalation rules. LLM calls, prompts, parsing, and host\n * decision types belong in adapters such as `council-brain.ts`.\n */\n\nexport interface CouncilResolutionSeat {\n id: string;\n /** Vote weight in the tally. Default 1. */\n weight?: number | undefined;\n /** A refusal from this seat immediately denies the proposal. */\n veto?: boolean | undefined;\n}\n\nexport interface CouncilResolutionVote {\n seatId: string;\n optionId: string;\n}\n\nexport interface CouncilResolutionInput {\n seats: readonly CouncilResolutionSeat[];\n votes: readonly CouncilResolutionVote[];\n refusalOptionId: string;\n /** Fraction of configured seats required to return a vote. */\n quorumFraction: number;\n /** Winning weight must exceed this fraction of cast weight. */\n approvalFraction: number;\n}\n\nexport type CouncilResolution =\n | {\n status: 'abstained';\n reason: 'quorum_not_met';\n validVoteCount: number;\n seatCount: number;\n }\n | {\n status: 'denied';\n method: 'veto';\n optionId: string;\n seatId: string;\n }\n | {\n status: 'denied';\n method: 'refusal';\n optionId: string;\n winningWeight: number;\n castWeight: number;\n }\n | {\n status: 'decided';\n method: 'majority';\n optionId: string;\n winningWeight: number;\n castWeight: number;\n }\n | {\n status: 'needs_judge';\n reason: 'tie' | 'approval_threshold_not_met';\n castWeight: number;\n };\n\n/** Resolve already-parsed council votes without performing any I/O. */\nexport function resolveCouncilVotes(input: CouncilResolutionInput): CouncilResolution {\n validateInput(input);\n\n const seatById = new Map(input.seats.map((seat) => [seat.id, seat] as const));\n const validVotes: CouncilResolutionVote[] = [];\n const votedSeatIds = new Set<string>();\n for (const vote of input.votes) {\n if (!seatById.has(vote.seatId) || votedSeatIds.has(vote.seatId)) continue;\n votedSeatIds.add(vote.seatId);\n validVotes.push(vote);\n }\n\n if (validVotes.length / input.seats.length < input.quorumFraction) {\n return {\n status: 'abstained',\n reason: 'quorum_not_met',\n validVoteCount: validVotes.length,\n seatCount: input.seats.length,\n };\n }\n\n const veto = validVotes.find(\n (vote) =>\n vote.optionId === input.refusalOptionId && seatById.get(vote.seatId)?.veto === true,\n );\n if (veto) {\n return {\n status: 'denied',\n method: 'veto',\n optionId: veto.optionId,\n seatId: veto.seatId,\n };\n }\n\n const weightByOption = new Map<string, number>();\n let castWeight = 0;\n for (const vote of validVotes) {\n const weight = seatById.get(vote.seatId)?.weight ?? 1;\n castWeight += weight;\n weightByOption.set(vote.optionId, (weightByOption.get(vote.optionId) ?? 0) + weight);\n }\n\n let winner: { optionId: string; weight: number } | undefined;\n let contested = false;\n for (const [optionId, weight] of weightByOption) {\n if (!winner || weight > winner.weight) {\n winner = { optionId, weight };\n contested = false;\n } else if (weight === winner.weight) {\n contested = true;\n }\n }\n\n const decisive =\n winner !== undefined &&\n !contested &&\n winner.weight > input.approvalFraction * castWeight;\n\n if (!decisive || !winner) {\n return {\n status: 'needs_judge',\n reason: contested ? 'tie' : 'approval_threshold_not_met',\n castWeight,\n };\n }\n\n if (winner.optionId === input.refusalOptionId) {\n return {\n status: 'denied',\n method: 'refusal',\n optionId: winner.optionId,\n winningWeight: winner.weight,\n castWeight,\n };\n }\n\n return {\n status: 'decided',\n method: 'majority',\n optionId: winner.optionId,\n winningWeight: winner.weight,\n castWeight,\n };\n}\n\nfunction validateInput(input: CouncilResolutionInput): void {\n if (input.seats.length === 0) {\n throw new Error('resolveCouncilVotes: at least one seat is required.');\n }\n requireFraction(input.quorumFraction, 'quorumFraction');\n requireFraction(input.approvalFraction, 'approvalFraction');\n\n const seatIds = new Set<string>();\n for (const seat of input.seats) {\n if (!seat.id.trim()) throw new Error('resolveCouncilVotes: seat id must not be empty.');\n if (seatIds.has(seat.id)) {\n throw new Error(`resolveCouncilVotes: duplicate seat id \"${seat.id}\".`);\n }\n seatIds.add(seat.id);\n if (seat.weight !== undefined && (!Number.isFinite(seat.weight) || seat.weight <= 0)) {\n throw new Error(`resolveCouncilVotes: invalid weight for seat \"${seat.id}\".`);\n }\n }\n}\n\nfunction requireFraction(value: number, label: string): void {\n if (!Number.isFinite(value) || value <= 0 || value > 1) {\n throw new Error(`resolveCouncilVotes: ${label} must be in (0, 1].`);\n }\n}\n", "import type {\n CouncilLLMCaller,\n CouncilModelTarget,\n CouncilQuestion,\n CouncilResult,\n CouncilUsage,\n CouncilVoteResult,\n ResolvedCouncilProfile,\n ResolvedCouncilSeat,\n} from '../types/council.js';\nimport type { OneShotLLMResult } from '../types/one-shot-llm.js';\nimport {\n DEFAULT_COUNCIL_PERSONA_REGISTRY,\n type CouncilPersonaRegistry,\n} from './council-personas.js';\nimport {\n DEFAULT_COUNCIL_PROFILE_REGISTRY,\n type CouncilProfileRegistry,\n resolveCouncilProfile,\n} from './council-profiles.js';\nimport {\n buildCouncilJudgeSystemPrompt,\n buildCouncilJudgeUserPrompt,\n buildCouncilVoterSystemPrompt,\n buildCouncilVoterUserPrompt,\n} from './council-prompts.js';\nimport { resolveCouncilVotes } from './council-resolution.js';\nimport type { FallbackProfileManager } from '../core/fallback-profile-manager.js';\nimport type { Config } from '../types/config.js';\n\n/** Synthetic ballot entry for \"refuse every real option\". */\nexport const COUNCIL_REFUSAL_OPTION_ID = 'council_refuse';\nexport const DEFAULT_COUNCIL_MAX_CONCURRENCY = 3;\nexport const MAX_COUNCIL_CONCURRENCY = 8;\n\nexport interface CouncilOrchestratorOptions {\n caller: CouncilLLMCaller;\n personas?: CouncilPersonaRegistry | undefined;\n profiles?: CouncilProfileRegistry | undefined;\n defaultProfile?: string | undefined;\n maxConcurrency?: number | undefined;\n refusalOptionId?: string | undefined;\n /** Live config accessor for fallback profile resolution. */\n getConfig?: (() => Config) | undefined;\n /**\n * Shared live FallbackProfileManager \u2014 required for reliable fallback\n * profile pre-resolution. Pass the runtime container's manager.\n */\n fallbackProfileManager?: FallbackProfileManager | undefined;\n /**\n * Per-seat LLM caller factory. When set, each seat gets its own caller\n * instead of the shared `caller`. The factory receives (seatIndex) and\n * returns a CouncilLLMCaller. Used by Brain council arbitration where\n * each voter has its own Provider instance.\n */\n seatCaller?: ((seatIndex: number) => CouncilLLMCaller) | undefined;\n /**\n * Separate caller for the judge seat. Required when `seatCaller` is set\n * because the judge uses the shared caller path. When absent and\n * `seatCaller` is set, the judge falls back to `seatCaller(0)`.\n */\n judgeCaller?: CouncilLLMCaller | undefined;\n}\n\ninterface ParsedVote {\n optionId?: string | undefined;\n stance?: string | undefined;\n rationale?: string | undefined;\n}\n\ninterface ParsedJudge {\n optionId?: string | undefined;\n answer?: string | undefined;\n rationale?: string | undefined;\n}\n\ninterface UsageAccumulator {\n calls: number;\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n}\n\n/** Provider-neutral Council runner backed by an injected one-shot LLM caller. */\nexport class CouncilOrchestrator {\n private readonly caller: CouncilLLMCaller;\n private readonly personas: CouncilPersonaRegistry;\n private readonly profiles: CouncilProfileRegistry;\n private readonly defaultProfile: string | undefined;\n private readonly maxConcurrency: number;\n private readonly refusalOptionId: string;\n private readonly fallbackProfileManager: FallbackProfileManager | undefined;\n private readonly seatCaller: ((seatIndex: number) => CouncilLLMCaller) | undefined;\n private readonly judgeCaller: CouncilLLMCaller | undefined;\n\n constructor(opts: CouncilOrchestratorOptions) {\n this.caller = opts.caller;\n this.personas = opts.personas ?? DEFAULT_COUNCIL_PERSONA_REGISTRY;\n this.profiles = opts.profiles ?? DEFAULT_COUNCIL_PROFILE_REGISTRY;\n this.defaultProfile = opts.defaultProfile;\n this.maxConcurrency = validateConcurrency(\n opts.maxConcurrency ?? DEFAULT_COUNCIL_MAX_CONCURRENCY,\n );\n this.refusalOptionId = opts.refusalOptionId?.trim() || COUNCIL_REFUSAL_OPTION_ID;\n this.fallbackProfileManager = opts.fallbackProfileManager;\n this.seatCaller = opts.seatCaller;\n this.judgeCaller = opts.judgeCaller;\n }\n\n async ask(question: CouncilQuestion): Promise<CouncilResult> {\n const startedAt = Date.now();\n const profile = resolveCouncilProfile(question.profile, {\n registry: this.profiles,\n personas: this.personas,\n defaultProfile: this.defaultProfile,\n });\n validateRefusalCollision(question, this.refusalOptionId);\n\n const timeoutSignal = AbortSignal.timeout(profile.overallTimeoutMs);\n const signal = question.signal\n ? AbortSignal.any([question.signal, timeoutSignal])\n : timeoutSignal;\n const usage: UsageAccumulator = {\n calls: 0,\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n };\n\n const votes = await mapConcurrent(\n profile.seats,\n Math.min(this.maxConcurrency, profile.seats.length),\n async (seat, i) => {\n try {\n return await this.callSeat(question, profile, seat, i, signal, usage);\n } catch (error) {\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: signal.aborted ? 'cancelled' : 'failed',\n error: errorMessage(error),\n } satisfies CouncilVoteResult;\n }\n },\n );\n const warnings = distinctnessWarnings(votes, profile);\n const errors = votes\n .filter((vote) => vote.status === 'failed' || vote.status === 'invalid')\n .map((vote) => `${vote.seatId}: ${vote.error ?? vote.status}`);\n\n if (question.signal?.aborted) {\n return resultEnvelope({\n status: 'cancelled',\n reason: 'Council call cancelled.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (timeoutSignal.aborted) {\n return resultEnvelope({\n status: 'failed',\n reason: 'Council overall timeout exceeded.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors: [...errors, 'Council overall timeout exceeded.'],\n });\n }\n\n if (!question.options || question.options.length === 0) {\n return this.resolveOpenQuestion(\n question,\n profile,\n votes,\n signal,\n usage,\n startedAt,\n warnings,\n errors,\n );\n }\n return this.resolveOptionQuestion(\n question,\n profile,\n votes,\n signal,\n usage,\n startedAt,\n warnings,\n errors,\n );\n }\n\n private async callSeat(\n question: CouncilQuestion,\n profile: ResolvedCouncilProfile,\n seat: ResolvedCouncilSeat,\n seatIndex: number,\n signal: AbortSignal,\n usage: UsageAccumulator,\n ): Promise<CouncilVoteResult> {\n if (signal.aborted) return cancelledVote(seat);\n let persona;\n try {\n persona = this.personas.require(seat.persona);\n } catch (error) {\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: 'failed',\n error: errorMessage(error),\n };\n }\n const result = await this.safeCall({\n system: buildCouncilVoterSystemPrompt(persona),\n userPrompt: buildCouncilVoterUserPrompt(question, seat, {\n refusalOptionId: question.options?.length ? this.refusalOptionId : undefined,\n }),\n target: seat.target,\n maxTokens: profile.voterMaxTokens,\n timeoutMs: profile.perCallTimeoutMs,\n signal,\n usage,\n seatIndex,\n });\n\n const metadata = callMetadata(result);\n if (result.error) {\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: signal.aborted ? 'cancelled' : 'failed',\n ...metadata,\n error: result.error,\n };\n }\n const parsed = parseVote(result.text, question, this.refusalOptionId);\n if (!parsed.ok) {\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: 'invalid',\n ...metadata,\n error: parsed.error,\n };\n }\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: 'valid',\n ...parsed.vote,\n ...metadata,\n };\n }\n\n private async resolveOptionQuestion(\n question: CouncilQuestion,\n profile: ResolvedCouncilProfile,\n votes: CouncilVoteResult[],\n signal: AbortSignal,\n usage: UsageAccumulator,\n startedAt: number,\n warnings: string[],\n errors: string[],\n ): Promise<CouncilResult> {\n const validVotes = votes.filter(\n (vote): vote is CouncilVoteResult & { optionId: string } =>\n vote.status === 'valid' && typeof vote.optionId === 'string',\n );\n const resolution = resolveCouncilVotes({\n seats: profile.seats.map((seat) => ({\n id: seat.id,\n weight: seat.weight,\n veto: seat.veto,\n })),\n votes: validVotes.map((vote) => ({ seatId: vote.seatId, optionId: vote.optionId })),\n refusalOptionId: this.refusalOptionId,\n quorumFraction: profile.quorumFraction,\n approvalFraction: profile.approvalFraction,\n });\n\n if (resolution.status === 'abstained') {\n return resultEnvelope({\n status: 'abstained',\n reason: 'Council quorum was not met.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (resolution.status === 'denied') {\n return resultEnvelope({\n status: 'denied',\n optionId: resolution.optionId,\n reason: `Council denied the proposal via ${resolution.method}.`,\n resolution: resolution.method,\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (resolution.status === 'decided') {\n return resultEnvelope({\n status: 'decided',\n optionId: resolution.optionId,\n answer: optionLabel(question, resolution.optionId),\n resolution: 'majority',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (!profile.judge) {\n return resultEnvelope({\n status: 'abstained',\n reason: `Council requires a judge (${resolution.reason}), but this profile has none.`,\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n\n const judged = await this.callJudge(\n question,\n profile,\n votes,\n profile.judge,\n resolution.reason,\n signal,\n usage,\n );\n if (!judged.ok) {\n return resultEnvelope({\n status: signal.aborted ? 'cancelled' : 'abstained',\n reason: judged.error,\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors: [...errors, judged.error],\n judgeUsed: true,\n });\n }\n if (judged.value.optionId === this.refusalOptionId) {\n return resultEnvelope({\n status: 'denied',\n optionId: this.refusalOptionId,\n reason: judged.value.rationale ?? 'Council judge refused all options.',\n resolution: 'judge',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n judgeUsed: true,\n });\n }\n return resultEnvelope({\n status: 'decided',\n optionId: judged.value.optionId,\n answer: optionLabel(question, judged.value.optionId),\n reason: judged.value.rationale,\n resolution: 'judge',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n judgeUsed: true,\n });\n }\n\n private async resolveOpenQuestion(\n question: CouncilQuestion,\n profile: ResolvedCouncilProfile,\n votes: CouncilVoteResult[],\n signal: AbortSignal,\n usage: UsageAccumulator,\n startedAt: number,\n warnings: string[],\n errors: string[],\n ): Promise<CouncilResult> {\n const valid = votes.filter(\n (vote): vote is CouncilVoteResult & { stance: string } =>\n vote.status === 'valid' && typeof vote.stance === 'string',\n );\n if (valid.length / profile.seats.length < profile.quorumFraction) {\n return resultEnvelope({\n status: 'abstained',\n reason: 'Council quorum was not met.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (!profile.judge) {\n const first = valid[0];\n if (!first) {\n return resultEnvelope({\n status: 'failed',\n reason: 'Council produced no valid stance.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n return resultEnvelope({\n status: 'decided',\n answer: first.stance,\n reason: first.rationale,\n resolution: 'first_stance',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n\n const judged = await this.callJudge(\n question,\n profile,\n votes,\n profile.judge,\n 'open_question_synthesis',\n signal,\n usage,\n );\n if (!judged.ok) {\n return resultEnvelope({\n status: signal.aborted ? 'cancelled' : 'failed',\n reason: judged.error,\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors: [...errors, judged.error],\n judgeUsed: true,\n });\n }\n return resultEnvelope({\n status: 'decided',\n answer: judged.value.answer,\n reason: judged.value.rationale,\n resolution: 'judge',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n judgeUsed: true,\n });\n }\n\n private async callJudge(\n question: CouncilQuestion,\n profile: ResolvedCouncilProfile,\n votes: CouncilVoteResult[],\n target: CouncilModelTarget,\n reason: string,\n signal: AbortSignal,\n usage: UsageAccumulator,\n ): Promise<{ ok: true; value: ParsedJudge } | { ok: false; error: string }> {\n const result = await this.safeCall({\n system: buildCouncilJudgeSystemPrompt(),\n userPrompt: buildCouncilJudgeUserPrompt(question, votes, {\n reason,\n refusalOptionId: question.options?.length ? this.refusalOptionId : undefined,\n }),\n target,\n maxTokens: profile.judgeMaxTokens,\n timeoutMs: profile.perCallTimeoutMs,\n signal,\n usage,\n });\n if (result.error) return { ok: false, error: result.error };\n return parseJudge(result.text, question, this.refusalOptionId);\n }\n\n private async safeCall(input: {\n system: string;\n userPrompt: string;\n target?: CouncilModelTarget | undefined;\n maxTokens: number;\n timeoutMs: number;\n signal: AbortSignal;\n usage: UsageAccumulator;\n seatIndex?: number | undefined;\n }): Promise<OneShotLLMResult> {\n const effectiveCaller =\n input.seatIndex !== undefined && this.seatCaller\n ? this.seatCaller(input.seatIndex)\n : this.judgeCaller ?? (this.seatCaller ? this.seatCaller(0) : this.caller);\n\n const resolvedTarget = this.resolveCouncilTarget(input.target);\n\n try {\n const result = await effectiveCaller.call({\n system: input.system,\n userPrompt: input.userPrompt,\n responseFormat: { type: 'json_object' },\n maxTokens: input.maxTokens,\n timeoutMs: input.timeoutMs,\n signal: input.signal,\n ...(resolvedTarget?.providerId ? { providerId: resolvedTarget.providerId } : {}),\n ...(resolvedTarget?.model ? { model: resolvedTarget.model } : {}),\n ...(resolvedTarget?.role ? { role: resolvedTarget.role } : {}),\n ...(resolvedTarget?.fallbackModels && resolvedTarget.fallbackModels.length > 0\n ? { fallbackModels: [...resolvedTarget.fallbackModels] }\n : {}),\n });\n addUsage(input.usage, result);\n return result;\n } catch (error) {\n input.usage.calls += 1;\n return emptyCallResult(errorMessage(error));\n }\n }\n\n /**\n * Resolve a CouncilModelTarget: pre-resolve fallbackProfile to fallbackModels\n * so the downstream caller only sees the resolved chain.\n */\n private resolveCouncilTarget(\n target?: CouncilModelTarget | undefined,\n ): CouncilModelTarget | undefined {\n if (!target) return undefined;\n if (!target.fallbackProfile) return target;\n\n const mgr = this.fallbackProfileManager;\n if (!mgr) return target;\n const chain = mgr.resolve(target.fallbackProfile);\n if (chain.length === 0) return target;\n\n // Combine profile-resolved chain with any explicit fallbackModels\n const combined = [\n ...chain.map((e) => `${e.providerId}/${e.model}`),\n ...(target.fallbackModels ?? []),\n ];\n // Deduplicate while preserving order\n const seen = new Set<string>();\n const deduped = combined.filter((ref) => {\n if (seen.has(ref)) return false;\n seen.add(ref);\n return true;\n });\n\n return {\n ...(target.providerId ? { providerId: target.providerId } : {}),\n ...(target.model ? { model: target.model } : {}),\n ...(target.role ? { role: target.role } : {}),\n fallbackModels: deduped,\n };\n }\n}\n\nfunction parseVote(\n text: string,\n question: CouncilQuestion,\n refusalOptionId: string,\n): { ok: true; vote: ParsedVote } | { ok: false; error: string } {\n const parsed = parseObject(text);\n if (!parsed.ok && (!question.options || question.options.length === 0)) {\n // Optionless: if JSON parsing fails, use the raw text as stance\n // (backward compat with old council-brain behavior).\n const fallback = text.trim();\n if (fallback) return { ok: true, vote: { stance: fallback } };\n return { ok: false, error: 'Voter returned an empty response.' };\n }\n if (!parsed.ok) return parsed;\n const rationale = optionalString(parsed.value['rationale']);\n if (question.options && question.options.length > 0) {\n const optionId = optionalString(parsed.value['optionId']);\n const allowed = new Set([...question.options.map((option) => option.id.trim()), refusalOptionId]);\n if (!optionId || !allowed.has(optionId)) {\n return { ok: false, error: 'Voter returned an unknown or missing optionId.' };\n }\n return { ok: true, vote: { optionId, ...(rationale ? { rationale } : {}) } };\n }\n const stance = optionalString(parsed.value['stance']);\n if (!stance) return { ok: false, error: 'Voter returned an empty or missing stance.' };\n return { ok: true, vote: { stance, ...(rationale ? { rationale } : {}) } };\n}\n\nfunction parseJudge(\n text: string,\n question: CouncilQuestion,\n refusalOptionId: string,\n): { ok: true; value: ParsedJudge } | { ok: false; error: string } {\n const parsed = parseObject(text);\n if (!parsed.ok && (!question.options || question.options.length === 0)) {\n // Optionless: if JSON parsing fails, use raw text as answer\n const fallback = text.trim();\n if (fallback) return { ok: true, value: { answer: fallback } };\n return { ok: false, error: 'Judge returned an empty response.' };\n }\n if (!parsed.ok) return parsed;\n const rationale = optionalString(parsed.value['rationale']);\n if (question.options && question.options.length > 0) {\n const optionId = optionalString(parsed.value['optionId']);\n const allowed = new Set([...question.options.map((option) => option.id.trim()), refusalOptionId]);\n if (!optionId || !allowed.has(optionId)) {\n return { ok: false, error: 'Judge returned an unknown or missing optionId.' };\n }\n return { ok: true, value: { optionId, ...(rationale ? { rationale } : {}) } };\n }\n const answer = optionalString(parsed.value['answer']);\n if (!answer) return { ok: false, error: 'Judge returned an empty or missing answer.' };\n return { ok: true, value: { answer, ...(rationale ? { rationale } : {}) } };\n}\n\nfunction parseObject(\n text: string,\n): { ok: true; value: Record<string, unknown> } | { ok: false; error: string } {\n const trimmed = text.trim();\n const first = trimmed.indexOf('{');\n const last = trimmed.lastIndexOf('}');\n if (first < 0 || last < first) return { ok: false, error: 'LLM response did not contain JSON.' };\n try {\n const value: unknown = JSON.parse(trimmed.slice(first, last + 1));\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return { ok: false, error: 'LLM response JSON must be an object.' };\n }\n return { ok: true, value: value as Record<string, unknown> };\n } catch (error) {\n return { ok: false, error: `Invalid LLM response JSON: ${errorMessage(error)}` };\n }\n}\n\nfunction resultEnvelope(input: {\n status: CouncilResult['status'];\n answer?: string | undefined;\n optionId?: string | undefined;\n reason?: string | undefined;\n resolution: CouncilResult['resolution'];\n votes: CouncilVoteResult[];\n profile: ResolvedCouncilProfile;\n usage: UsageAccumulator;\n startedAt: number;\n warnings: string[];\n errors: string[];\n judgeUsed?: boolean | undefined;\n}): CouncilResult {\n const validVoteCount = input.votes.filter((vote) => vote.status === 'valid').length;\n return {\n status: input.status,\n ...(input.answer ? { answer: input.answer } : {}),\n ...(input.optionId ? { optionId: input.optionId } : {}),\n ...(input.reason ? { reason: input.reason } : {}),\n resolution: input.resolution,\n votes: Object.freeze([...input.votes]),\n configuredSeatCount: input.profile.seats.length,\n validVoteCount,\n distinctTargetCount: distinctTargetCount(input.votes, input.profile),\n judgeUsed: input.judgeUsed ?? false,\n usage: usageResult(input.usage, input.startedAt),\n ...(input.warnings.length > 0 ? { warnings: Object.freeze([...input.warnings]) } : {}),\n ...(input.errors.length > 0 ? { errors: Object.freeze([...input.errors]) } : {}),\n };\n}\n\nfunction callMetadata(result: OneShotLLMResult): Omit<CouncilVoteResult, 'seatId' | 'persona' | 'status'> {\n return {\n ...(result.provider ? { provider: result.provider } : {}),\n ...(result.model ? { model: result.model } : {}),\n ...(result.fromFallback ? { fromFallback: true } : {}),\n durationMs: result.durationMs,\n };\n}\n\nfunction addUsage(usage: UsageAccumulator, result: OneShotLLMResult): void {\n usage.calls += 1;\n usage.inputTokens += result.tokens.input;\n usage.outputTokens += result.tokens.output;\n usage.totalTokens += result.tokens.total;\n}\n\nfunction usageResult(usage: UsageAccumulator, startedAt: number): CouncilUsage {\n return Object.freeze({ ...usage, durationMs: Math.max(0, Date.now() - startedAt) });\n}\n\nfunction cancelledVote(seat: ResolvedCouncilSeat): CouncilVoteResult {\n return { seatId: seat.id, persona: seat.persona, status: 'cancelled', error: 'Cancelled.' };\n}\n\nfunction distinctTargetCount(\n votes: readonly CouncilVoteResult[],\n profile: ResolvedCouncilProfile,\n): number {\n const keys = votes\n .filter((vote) => vote.status === 'valid')\n .map((vote) =>\n profile.distinctness === 'provider'\n ? vote.provider\n : `${vote.provider ?? ''}/${vote.model ?? ''}`,\n )\n .filter(Boolean);\n return new Set(keys).size;\n}\n\nfunction distinctnessWarnings(\n votes: readonly CouncilVoteResult[],\n profile: ResolvedCouncilProfile,\n): string[] {\n if (profile.distinctness === 'none') return [];\n const valid = votes.filter((vote) => vote.status === 'valid');\n const distinct = distinctTargetCount(valid, profile);\n if (valid.length > 1 && distinct < valid.length) {\n return [\n `Council distinctness policy \"${profile.distinctness}\" was not met: ${distinct} distinct target(s) served ${valid.length} valid vote(s).`,\n ];\n }\n return [];\n}\n\nfunction optionLabel(question: CouncilQuestion, optionId: string | undefined): string | undefined {\n if (!optionId) return undefined;\n return question.options?.find((option) => option.id.trim() === optionId)?.label.trim();\n}\n\nfunction validateRefusalCollision(question: CouncilQuestion, refusalOptionId: string): void {\n if (question.options?.some((option) => option.id.trim() === refusalOptionId)) {\n throw new Error(`CouncilOrchestrator: option id \"${refusalOptionId}\" is reserved.`);\n }\n}\n\nfunction validateConcurrency(value: number): number {\n if (!Number.isSafeInteger(value) || value <= 0 || value > MAX_COUNCIL_CONCURRENCY) {\n throw new Error(\n `CouncilOrchestrator: maxConcurrency must be an integer in [1, ${MAX_COUNCIL_CONCURRENCY}].`,\n );\n }\n return value;\n}\n\nasync function mapConcurrent<T, R>(\n items: readonly T[],\n concurrency: number,\n worker: (item: T, index: number) => Promise<R>,\n): Promise<R[]> {\n const results = new Array<R>(items.length);\n let next = 0;\n const run = async (): Promise<void> => {\n while (true) {\n const index = next++;\n if (index >= items.length) return;\n const item = items[index];\n if (item !== undefined) results[index] = await worker(item, index);\n }\n };\n await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => run()));\n return results;\n}\n\nfunction emptyCallResult(error: string): OneShotLLMResult {\n return {\n text: '',\n model: '',\n provider: '',\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: 0,\n fromFallback: false,\n error,\n };\n}\n\nfunction optionalString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n", "import { CouncilOrchestrator } from '../execution/council-orchestrator.js';\nimport type { FallbackProfileManager } from '../core/fallback-profile-manager.js';\nimport type {\n CouncilLLMCaller,\n CouncilOption,\n CouncilProfileConfig,\n CouncilQuestion,\n CouncilResult,\n} from '../types/council.js';\nimport type { JSONSchema, Tool } from '../types/tool.js';\nimport type { CouncilPersonaRegistry } from '../execution/council-personas.js';\nimport type { CouncilProfileRegistry } from '../execution/council-profiles.js';\n\nexport const COUNCIL_TOOL_NAME = 'council';\nexport const MAX_COUNCIL_TOOL_OPTIONS = 12;\nexport const MAX_COUNCIL_QUESTION_CHARS = 20_000;\nexport const MAX_COUNCIL_CONTEXT_CHARS = 80_000;\n\nexport interface CouncilToolInput {\n question: string;\n context?: string | undefined;\n options?: CouncilOption[] | undefined;\n profile?: string | CouncilProfileConfig | undefined;\n}\n\nexport interface CreateCouncilToolOptions {\n caller: CouncilLLMCaller;\n personas?: CouncilPersonaRegistry | undefined;\n profiles?: CouncilProfileRegistry | undefined;\n defaultProfile?: string | undefined;\n maxConcurrency?: number | undefined;\n refusalOptionId?: string | undefined;\n /** Shared live FallbackProfileManager. */\n fallbackProfileManager?: FallbackProfileManager | undefined;\n}\n\nconst INPUT_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n question: {\n type: 'string',\n description: 'The decision or open question for the Council.',\n maxLength: MAX_COUNCIL_QUESTION_CHARS,\n },\n context: {\n type: 'string',\n description: 'Optional evidence and constraints. Treated as untrusted quoted data.',\n maxLength: MAX_COUNCIL_CONTEXT_CHARS,\n },\n options: {\n type: 'array',\n maxItems: MAX_COUNCIL_TOOL_OPTIONS,\n items: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Stable option id.' },\n label: { type: 'string', description: 'Human-readable option label.' },\n consequence: { type: 'string', description: 'Optional consequence or trade-off.' },\n },\n required: ['id', 'label'],\n additionalProperties: false,\n },\n description: 'Optional bounded list of choices. Omit for an open-ended Council answer.',\n },\n profile: {\n type: 'string',\n description: 'Registered Council profile id. Defaults to the host-configured profile.',\n },\n },\n required: ['question'],\n additionalProperties: false,\n};\n\n/** Create a read-only, bounded agent-callable Council tool. */\nexport function createCouncilTool(\n opts: CreateCouncilToolOptions,\n): Tool<CouncilToolInput, CouncilResult> {\n const orchestrator = new CouncilOrchestrator({\n ...opts,\n fallbackProfileManager: opts.fallbackProfileManager,\n });\n return {\n name: COUNCIL_TOOL_NAME,\n description:\n 'Ask an independent, multi-persona Council to evaluate a decision or synthesize an answer. ' +\n 'Uses bounded parallel voters, quorum/veto/weighted resolution, optional judging, model routing, fallback chains, and cancellation.',\n usageHint:\n 'Use for consequential or disputed decisions that benefit from independent lenses. ' +\n 'Provide `options` for a vote or omit them for an open answer. ' +\n 'Keep context evidence-focused; the Council treats it as untrusted data.',\n category: 'meta',\n inputSchema: INPUT_SCHEMA,\n permission: 'auto',\n mutating: false,\n riskTier: 'safe',\n managesOwnTimeout: true,\n maxOutputBytes: 256_000,\n async execute(input, _ctx, { signal }) {\n const question: CouncilQuestion = {\n question: input.question,\n ...(input.context ? { context: input.context } : {}),\n ...(input.options ? { options: input.options } : {}),\n ...(input.profile ? { profile: input.profile } : {}),\n signal,\n };\n return orchestrator.ask(question);\n },\n validate: validateCouncilToolInput,\n };\n}\n\nfunction validateCouncilToolInput(input: CouncilToolInput): string[] {\n const errors: string[] = [];\n const question = input.question?.trim() ?? '';\n if (!question) errors.push('`question` must not be empty.');\n if (question.length > MAX_COUNCIL_QUESTION_CHARS) {\n errors.push(`\\`question\\` must not exceed ${MAX_COUNCIL_QUESTION_CHARS} characters.`);\n }\n if ((input.context?.length ?? 0) > MAX_COUNCIL_CONTEXT_CHARS) {\n errors.push(`\\`context\\` must not exceed ${MAX_COUNCIL_CONTEXT_CHARS} characters.`);\n }\n if ((input.options?.length ?? 0) > MAX_COUNCIL_TOOL_OPTIONS) {\n errors.push(`\\`options\\` must not contain more than ${MAX_COUNCIL_TOOL_OPTIONS} items.`);\n }\n const ids = new Set<string>();\n for (const option of input.options ?? []) {\n const id = option.id.trim();\n if (!id) errors.push('Every option must have a non-empty `id`.');\n if (!option.label.trim()) errors.push(`Option \"${id || '<empty>'}\" must have a label.`);\n if (ids.has(id)) errors.push(`Duplicate option id \"${id}\".`);\n ids.add(id);\n }\n return errors;\n}\n", "export interface ModelBlackoutRule {\n id: string;\n enabled?: boolean | undefined;\n provider?: string | undefined;\n model?: string | undefined;\n /** JavaScript weekday numbers: Sunday=0 \u2026 Saturday=6. Empty means every day. */\n days?: number[] | undefined;\n /** Inclusive local start, HH:mm. */\n start: string;\n /** Exclusive local end, HH:mm. Equal to start means all day. */\n end: string;\n /** IANA timezone. Defaults to the host timezone. */\n timezone?: string | undefined;\n label?: string | undefined;\n /** `blackout`: deny inside. `allow_only`: deny outside all matching allow windows. */\n mode?: 'blackout' | 'allow_only' | undefined;\n}\n\nexport interface ModelCalendarDecision {\n allowed: boolean;\n rule?: ModelBlackoutRule | undefined;\n}\n\nexport function logicalCalendarTarget(\n providerId: string,\n model: string,\n): {\n providerId: string;\n model: string;\n} {\n if (providerId !== 'omniroute') return { providerId, model };\n const slash = model.indexOf('/');\n return slash > 0 && slash < model.length - 1\n ? { providerId: model.slice(0, slash), model: model.slice(slash + 1) }\n : { providerId, model };\n}\n\nconst WEEKDAYS: Record<string, number> = {\n Sun: 0,\n Mon: 1,\n Tue: 2,\n Wed: 3,\n Thu: 4,\n Fri: 5,\n Sat: 6,\n};\n\nfunction minuteOfDay(value: string): number | undefined {\n const match = /^(\\d{2}):(\\d{2})$/.exec(value);\n if (!match) return undefined;\n const hour = Number(match[1]);\n const minute = Number(match[2]);\n if (hour > 23 || minute > 59) return undefined;\n return hour * 60 + minute;\n}\n\nfunction clockAt(date: Date, timezone?: string): { day: number; minute: number } | undefined {\n try {\n const parts = new Intl.DateTimeFormat('en-US', {\n timeZone: timezone,\n weekday: 'short',\n hour: '2-digit',\n minute: '2-digit',\n hourCycle: 'h23',\n }).formatToParts(date);\n const weekday = parts.find((part) => part.type === 'weekday')?.value;\n const hour = Number(parts.find((part) => part.type === 'hour')?.value);\n const minute = Number(parts.find((part) => part.type === 'minute')?.value);\n if (!weekday || WEEKDAYS[weekday] === undefined || !Number.isFinite(hour + minute))\n return undefined;\n return { day: WEEKDAYS[weekday], minute: hour * 60 + minute };\n } catch {\n return undefined;\n }\n}\n\nfunction targetMatches(rule: ModelBlackoutRule, providerId: string, model: string): boolean {\n if (rule.provider && rule.provider !== providerId) return false;\n if (rule.model && rule.model !== model) return false;\n return Boolean(rule.provider || rule.model);\n}\n\nfunction timeMatches(rule: ModelBlackoutRule, day: number, minute: number): boolean {\n const start = minuteOfDay(rule.start);\n const end = minuteOfDay(rule.end);\n if (start === undefined || end === undefined) return false;\n const days = rule.days?.length ? new Set(rule.days) : undefined;\n if (start === end) return !days || days.has(day);\n if (start < end) return (!days || days.has(day)) && minute >= start && minute < end;\n // Overnight: Monday 22:00\u201307:00 includes early Tuesday morning.\n if (minute >= start) return !days || days.has(day);\n const previousDay = (day + 6) % 7;\n return minute < end && (!days || days.has(previousDay));\n}\n\nexport function evaluateModelCalendar(\n rules: readonly ModelBlackoutRule[] | undefined,\n providerId: string,\n model: string,\n at = new Date(),\n): ModelCalendarDecision {\n ({ providerId, model } = logicalCalendarTarget(providerId, model));\n const allowRules: ModelBlackoutRule[] = [];\n let allowMatched = false;\n for (const rule of rules ?? []) {\n if (rule.enabled === false || !targetMatches(rule, providerId, model)) continue;\n const clock = clockAt(at, rule.timezone);\n if (!clock || minuteOfDay(rule.start) === undefined || minuteOfDay(rule.end) === undefined)\n continue;\n if (rule.mode === 'allow_only') {\n allowRules.push(rule);\n if (timeMatches(rule, clock.day, clock.minute)) allowMatched = true;\n } else if (timeMatches(rule, clock.day, clock.minute)) {\n return { allowed: false, rule };\n }\n }\n if (allowRules.length > 0 && !allowMatched) return { allowed: false, rule: allowRules[0] };\n return { allowed: true };\n}\n", "import { truncate } from '../utils/string.js';\nimport type { ContentBlock, TextBlock } from './blocks.js';\nimport type { ErrorCode } from './errors.js';\nimport { ERROR_CODES, WrongStackError } from './errors.js';\nimport type { Message } from './messages.js';\nimport type { Tool } from './tool.js';\n\n/**\n * Token usage for a single provider call, normalized across providers.\n *\n * Disjoint semantics: the four fields never overlap. `input` is the count\n * of FRESH input tokens (billed at the full input rate); `cacheRead` and\n * `cacheWrite` are separate cached subsets each priced at their own rate.\n * The total context the model loaded for this turn is\n * `input + (cacheRead ?? 0) + (cacheWrite ?? 0)`.\n *\n * Provider quirks normalized at the adapter layer:\n * - Anthropic: returns `input_tokens` already disjoint from cache fields.\n * - OpenAI / OpenAI-compatible: `prompt_tokens` is the TOTAL including\n * cached portion; the adapter subtracts `cached_tokens` to stay disjoint.\n * - Google: `promptTokenCount` likewise includes cache; adapter subtracts\n * `cachedContentTokenCount`.\n *\n * Cost math and the context-fullness chip both depend on the disjoint\n * invariant \u2014 a TOTAL `input` plus a separate `cacheRead` count would bill\n * cached tokens twice and skew cache-hit-ratio reporting.\n */\nexport type ReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';\nexport type CacheTtl = '5m' | '1h';\n\n/**\n * Provider-agnostic response-format directive.\n *\n * - `{ type: 'text' }` \u2014 free-form text (default).\n * - `{ type: 'json_object' }` \u2014 valid JSON without a schema constraint.\n * - `{ type: 'json_schema', jsonSchema: { name, schema, strict? } }` \u2014 JSON\n * constrained to the supplied JSON Schema. The `strict` flag is\n * OpenAI-specific; Gemini ignores it in favour of `responseMimeType`.\n *\n * Each provider adapter maps this into its own wire format:\n * OpenAI \u2192 `response_format`\n * Gemini \u2192 `responseMimeType` + `responseSchema`\n * Anthropic \u2192 (not yet supported; uses tools for structured output)\n */\nexport interface JsonSchemaSpec {\n name: string;\n /** OpenAI-specific: enable strict schema adherence. */\n strict?: boolean | undefined;\n /** The JSON Schema object describing the expected shape. */\n schema: Record<string, unknown>;\n /** Optional human-readable description (OpenAI). */\n description?: string | undefined;\n}\n\nexport type ResponseFormat =\n | { type: 'text' }\n | { type: 'json_object' }\n | { type: 'json_schema'; jsonSchema: JsonSchemaSpec };\n\n/**\n * Safety category threshold pair used by Google Gemini's `safetySettings`.\n *\n * Categories: `HARM_CATEGORY_HARASSMENT`, `HARM_CATEGORY_HATE_SPEECH`,\n * `HARM_CATEGORY_SEXUALLY_EXPLICIT`, `HARM_CATEGORY_DANGEROUS_CONTENT`.\n *\n * Thresholds: `BLOCK_NONE`, `BLOCK_ONLY_HIGH`, `BLOCK_MEDIUM_AND_ABOVE`,\n * `BLOCK_LOW_AND_ABOVE`.\n */\nexport interface SafetySetting {\n category: string;\n threshold: string;\n}\n\nexport interface Usage {\n input: number;\n output: number;\n cacheRead?: number | undefined;\n /** Back-compat aggregate of all cache-write tokens. Prefer TTL-specific fields when present. */\n cacheWrite?: number | undefined;\n cacheWrite5m?: number | undefined;\n cacheWrite1h?: number | undefined;\n}\n\n/**\n * Effective prompt tokens loaded by the model for one request.\n *\n * Provider adapters normalize `Usage` to disjoint fields: `input` is fresh\n * full-rate tokens, `cacheRead` is cached prefix tokens, and `cacheWrite` is\n * the cache-written prefix segment. Context-window pressure cares about the\n * full prompt the model saw, not only the bill-at-full-rate slice.\n */\nexport function effectiveInputTokens(usage: Usage): number {\n return usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);\n}\n\nexport interface ReasoningRequest {\n enabled?: boolean | undefined;\n effort?: ReasoningEffort | undefined;\n preserve?: boolean | undefined;\n display?: 'summarized' | 'omitted' | undefined;\n}\n\nexport interface RequestCacheControl {\n ttl?: CacheTtl | undefined;\n /**\n * Provider-agnostic cache-partition key. A stable hash of the cacheable\n * system-prompt prefix (see `deriveCachePrefixKey`); requests sharing a prefix\n * share a key so provider backends route them to the same automatic-cache\n * partition. Consumed by OpenAI-family wires as `prompt_cache_key`; ignored by\n * Anthropic (which uses `ttl` + explicit `cache_control` markers).\n */\n key?: string | undefined;\n /**\n * Opt-in flag (from `ModelRuntimeCacheConfig.geminiExplicit`) telling the\n * Google provider to use explicit `cachedContents` for this request. Ignored\n * by other providers.\n */\n geminiExplicit?: boolean | undefined;\n /**\n * Resolved Gemini `cachedContents/*` resource name, injected by\n * `GoogleProvider.stream()` after it creates/reuses the cache. When present,\n * the Google wire sends `cachedContent` and OMITS the (now-cached) system\n * instruction + tool defs from the live body. Internal \u2014 never set by callers.\n */\n geminiCachedContentName?: string | undefined;\n}\n\nexport interface ReasoningConfig {\n default: 'enabled' | 'disabled' | 'adaptive' | 'always_on';\n disableSupported: boolean;\n effortSupported: boolean;\n effortLevels: ReasoningEffort[];\n preserveThinking: 'unsupported' | 'optional' | 'always_on';\n}\n\nexport interface Capabilities {\n tools: boolean;\n parallelTools: boolean;\n vision: boolean;\n streaming: boolean;\n promptCache: boolean;\n systemPrompt: boolean;\n jsonMode: boolean;\n reasoning: boolean;\n maxContext: number;\n /**\n * Maximum output tokens the model can produce in a single response.\n * Used as the default for `Request.maxTokens` when the caller doesn't\n * supply an explicit value \u2014 letting subagents run up to the model's\n * native ceiling instead of a fixed 8192 cap. Omit (undefined) to fall\n * back to a conservative default; populate per family in\n * `family-capabilities.ts` once you know the spec.\n */\n maxOutput?: number | undefined;\n cacheControl: 'native' | 'auto' | 'none';\n\n // \u2500\u2500 Extended parameter support (optional; family defaults in CAPABILITIES_BY_FAMILY) \u2500\u2500\n\n /** Model accepts `top_k` / `topK` sampling parameter. */\n topK?: boolean | undefined;\n /** Model accepts `frequency_penalty` / `frequencyPenalty` parameter. */\n frequencyPenalty?: boolean | undefined;\n /** Model accepts `presence_penalty` / `presencePenalty` parameter. */\n presencePenalty?: boolean | undefined;\n /** Model accepts `seed` parameter for deterministic generation. */\n seed?: boolean | undefined;\n /**\n * Model accepts JSON Schema / structured-output constraints\n * (OpenAI `response_format.json_schema`, Gemini `responseMimeType`+`responseSchema`).\n * Distinct from `jsonMode` (which is just a system-prompt hint).\n */\n structuredOutput?: boolean | undefined;\n /** Model supports log-probability output (`logprobs`, `top_logprobs`). */\n logprobs?: boolean | undefined;\n /** Model supports audio input/output modality. */\n audio?: boolean | undefined;\n /** Model supports the `n` parameter for multiple completions. */\n multipleCompletions?: boolean | undefined;\n}\n\nexport interface Request {\n model: string;\n system?: TextBlock[] | undefined;\n messages: Message[];\n tools?: Tool[] | undefined;\n /**\n * Cap on output tokens for this single response. Optional \u2014 when\n * omitted, the provider adapter falls back to its own\n * `capabilities.maxOutput` (which the catalog populates from\n * `ModelsDevModel.limit.output`). If neither is available, the\n * adapter applies a conservative 8192 safety net. Letting this stay\n * undefined at the call site means callers like Chimera can hand the\n * model its native output ceiling without hard-coding a number.\n */\n maxTokens?: number | undefined;\n temperature?: number | undefined;\n topP?: number | undefined;\n topK?: number | undefined;\n frequencyPenalty?: number | undefined;\n presencePenalty?: number | undefined;\n seed?: number | undefined;\n /**\n * End-user identifier for abuse monitoring and per-user rate limiting.\n * - Anthropic \u2192 `metadata.user_id`\n * - OpenAI \u2192 `user`\n * - Gemini \u2192 (not supported)\n */\n user?: string | undefined;\n /**\n * Number of response candidates to generate. Google Gemini supports\n * this via `generationConfig.candidateCount`. OpenAI does not have\n * an equivalent (`n` is conceptually similar but distinct).\n */\n candidateCount?: number | undefined;\n /**\n * Whether to return log probabilities for output tokens.\n * - OpenAI \u2192 `logprobs: boolean` (+ `topLogprobs: number`)\n * - Gemini \u2192 `generationConfig.logprobs: number` (how many top candidates)\n * Default undefined = no logprobs requested.\n */\n logprobs?: boolean | undefined;\n /**\n * Number of most probable tokens to return log probabilities for\n * (OpenAI `top_logprobs`). Only meaningful when `logprobs` is true.\n * Range: 0-20. Gemini ignores this (uses `logprobs` as the count).\n */\n topLogprobs?: number | undefined;\n stopSequences?: string[] | undefined;\n toolChoice?: 'auto' | 'required' | 'none' | { type: 'tool' | undefined; name: string };\n reasoning?: ReasoningRequest | undefined;\n cache?: RequestCacheControl | undefined;\n /**\n * Structured-output / response-format directive.\n * When set, the provider adapter maps this to its native response-format\n * parameter (OpenAI `response_format`, Gemini `responseMimeType`, etc.).\n * The model must advertise `capabilities.structuredOutput` for this to be\n * honoured; unsupported models will likely 400 or ignore it.\n */\n responseFormat?: ResponseFormat | undefined;\n /**\n * Safety category thresholds for filtering harmful content.\n * - Gemini \u2192 top-level `safetySettings` array with `{ category, threshold }`\n * - OpenAI \u2192 not supported (uses server-side moderation)\n * - Anthropic \u2192 not supported\n */\n safetySettings?: SafetySetting[] | undefined;\n}\n\nexport type StopReason = 'end_turn' | 'tool_use' | 'max_tokens' | 'stop_sequence' | 'refusal';\n\nexport interface Response {\n content: ContentBlock[];\n stopReason: StopReason;\n usage: Usage;\n model: string;\n}\n\nexport type StreamEvent =\n | { type: 'message_start'; model: string }\n | {\n type: 'content_block_start';\n kind: 'text' | 'tool_use' | 'thinking';\n id?: string | undefined;\n name?: string | undefined;\n }\n | { type: 'content_block_stop'; index: number }\n | { type: 'text_delta'; text: string }\n | { type: 'tool_use_start'; id: string; name: string }\n | { type: 'tool_use_input_delta'; id: string; partial: string }\n | { type: 'tool_use_stop'; id: string; input: unknown; providerMeta?: Record<string, unknown> }\n | { type: 'thinking_start'; providerMeta?: Record<string, unknown> }\n | { type: 'thinking_delta'; text: string }\n | { type: 'thinking_signature'; signature: string }\n | { type: 'thinking_stop' }\n | { type: 'message_stop'; stopReason: StopReason; usage: Usage };\n\nexport interface Provider {\n readonly id: string;\n readonly capabilities: Capabilities;\n /** Canonical streaming entry point. `complete()` defaults to a wrapper that\n * aggregates this stream \u2014 providers may override for non-streaming wires. */\n stream(req: Request, opts: { signal: AbortSignal }): AsyncIterable<StreamEvent>;\n complete(req: Request, opts: { signal: AbortSignal }): Promise<Response>;\n}\n\n/**\n * Structured body parsed from a provider's HTTP error response. Populated\n * best-effort: providers return JSON shaped differently (Anthropic uses\n * `{error: {type, message}}`, OpenAI uses `{error: {message, code}}`,\n * Google uses `{error: {status, message}}`), so the fields here are the\n * intersection that's usable for rendering and routing.\n */\nexport interface ProviderErrorBody {\n /** Provider-specific kind, e.g. \"overloaded_error\", \"rate_limit_error\", \"invalid_request_error\". */\n type?: string | undefined;\n /** Human-readable explanation from the provider. */\n message?: string | undefined;\n /** Provider request id, when present in the body or headers. */\n requestId?: string | undefined;\n /** Parsed Retry-After header (or equivalent body hint) in milliseconds. */\n retryAfterMs?: number | undefined;\n /** The raw response body (truncated to ~2 KB), kept for debugging. */\n raw?: string | undefined;\n /** True when `raw` was truncated; check `rawLength` for the original size. */\n truncated?: boolean | undefined;\n /** Original length of the response body in bytes, when `truncated` is true. */\n rawLength?: number | undefined;\n}\n\n/**\n * Canonical provider-failure taxonomy. Computed ONCE at error-construction\n * time (`classifyProviderError`) and carried on `ProviderError.kind` so\n * every downstream consumer \u2014 retry policy, cross-provider fallback,\n * recovery strategies, the subagent error classifier \u2014 branches on the\n * same classification instead of re-deriving it from status codes and\n * message regexes. When a new provider's error format needs special\n * handling, this module is the only place to teach it.\n */\nexport type ProviderErrorKind =\n | 'rate_limit' // 429 / rate_limit_error \u2014 back off (honour Retry-After), then failover\n | 'quota_exhausted' // credits/plan depleted \u2014 do not retry same route; fail over immediately\n | 'overloaded' // 529 / overloaded_error \u2014 retry with backoff, then failover\n | 'server' // other 5xx \u2014 retry same provider\n | 'timeout' // 408 request timeout\n | 'network' // status 0 \u2014 connection/DNS failure before a response arrived\n | 'stream_hang' // 599 sentinel \u2014 stream stalled mid-response (StreamHangError)\n | 'auth' // 401/403 \u2014 key invalid/expired; retrying without action is pointless\n | 'context_overflow' // 413 or an overflow-shaped 4xx \u2014 compact, don't retry as-is\n | 'content_filter' // provider refused on policy grounds \u2014 a sibling model may pass, but the `content_filter_reroute` recovery strategy owns that hop, NOT the fallback engine (which surfaces this kind)\n | 'invalid_request' // other 4xx \u2014 request is malformed; retrying won't help\n | 'unknown';\n\n/**\n * Overflow-shaped provider messages. Union of the patterns previously\n * scattered across `error-handler.ts` and `coordinator/error-classifier.ts`\n * (which had drifted apart) \u2014 keep additions here, nowhere else.\n */\nconst CONTEXT_OVERFLOW_RE =\n /context.length|context.window|maximum context|max.*tokens?.*exceeded|prompt is too long|too long|exceeds the context|\\btokens\\b.*exceed|too many tokens|reduce the length|resulted in \\d+ tokens|input.{0,12}too (?:large|long)|context_length_exceeded/i;\n\n/** Content-policy refusals surfaced as HTTP errors (Azure/OpenAI `content_filter`, etc.). */\nconst CONTENT_FILTER_RE = /content.(filter|policy|moderation)|safety (system|filter)/i;\nconst QUOTA_EXHAUSTED_RE =\n /(?:insufficient|exhausted|depleted|exceeded|no|not enough)[-_\\s]*(?:quota|credit|balance)|(?:quota|credit|balance)[-_\\s]*(?:exhausted|depleted|exceeded|insufficient)|billing[_\\s-]*(?:hard[_\\s-]*)?limit|payment required|spending limit|plan limit|usage[-_\\s]*limit[-_\\s]*(?:reached|exceeded)/i;\n/** \"rate limit exceeded\" pattern \u2014 checked against body.message only, NOT the\n * raw JSON text, because OpenAI's `\"code\":\"rate_limit_exceeded\"` field would\n * produce a false positive in the combined-text regex. */\nconst RATE_LIMIT_EXCEEDED_RE = /rate[-_\\s]*limit[-_\\s]*exceeded/i;\n\n/**\n * Classify a provider HTTP failure into the canonical taxonomy from its\n * status code plus the parsed error body (and, for message-only errors\n * without a structured body, the error message itself). Pure and total \u2014\n * always returns a kind, never throws.\n */\nexport function classifyProviderError(\n status: number,\n body?: ProviderErrorBody,\n message?: string,\n): ProviderErrorKind {\n const type = body?.type;\n const text = [message, body?.message, type, body?.raw].filter(Boolean).join('\\n');\n if (status === 0) return 'network';\n if (status === 408) return 'timeout';\n if (status === 599) return 'stream_hang';\n if (status === 402 || QUOTA_EXHAUSTED_RE.test(text)) return 'quota_exhausted';\n // Check body.message separately for \"rate limit exceeded\" \u2014 this pattern\n // should NOT match against body.raw because OpenAI's error response\n // includes `\"code\":\"rate_limit_exceeded\"` in the JSON, which would be a\n // false positive (it's a transient burst, not a hard limit).\n if (status === 429 && body?.message && RATE_LIMIT_EXCEEDED_RE.test(body.message)) {\n return 'quota_exhausted';\n }\n if (type === 'rate_limit_error' || status === 429) return 'rate_limit';\n if (type === 'overloaded_error' || status === 529) return 'overloaded';\n if (status >= 500) return 'server';\n if (\n type === 'authentication_error' ||\n type === 'permission_error' ||\n status === 401 ||\n status === 403\n ) {\n return 'auth';\n }\n if (type === 'content_filter' || CONTENT_FILTER_RE.test(text)) return 'content_filter';\n if (status === 413 || (status >= 400 && CONTEXT_OVERFLOW_RE.test(text))) {\n return 'context_overflow';\n }\n if (status >= 400) return 'invalid_request';\n return 'unknown';\n}\n\n/**\n * Whether a kind is worth retrying against the SAME provider/model.\n * `context_overflow` is deliberately false \u2014 the request must shrink first;\n * `auth`/`invalid_request`/`content_filter` won't improve on replay.\n *\n * Exhaustive by construction (`Record<ProviderErrorKind, \u2026>`): adding a new\n * kind refuses to compile until it is classified here. Every kind\u2192X mapping\n * in the codebase follows this drift-guard pattern \u2014 see also KIND_TO_CODE\n * below, DefaultRetryPolicy.maxAttempts, fallback-model shouldFallback, and\n * the coordinator's providerErrorToSubagentError.\n */\nexport function isRetryableKind(kind: ProviderErrorKind): boolean {\n return RETRYABLE_BY_KIND[kind];\n}\n\nconst RETRYABLE_BY_KIND: Record<ProviderErrorKind, boolean> = {\n rate_limit: true,\n quota_exhausted: false,\n overloaded: true,\n server: true,\n timeout: true,\n network: true,\n stream_hang: true,\n auth: false,\n context_overflow: false,\n content_filter: false,\n invalid_request: false,\n unknown: false,\n};\n\n/**\n * Whether a kind is worth HOPPING to a different provider/model \u2014 the gate for\n * the cross-provider fallback engine (agent-loop extension AND the one-shot\n * orchestrator both branch on this ONE table, so their behavior can't drift).\n *\n * A distinct question from {@link isRetryableKind} (retry the SAME model):\n * a hop only helps for capacity/transport failures. Request-shaped failures\n * surface instead \u2014 `context_overflow` needs compaction, `content_filter` is\n * owned by the `content_filter_reroute` recovery strategy, and `auth` /\n * `invalid_request` are user-actionable and would fail identically on a hop.\n * The value set is currently identical to the retryable set, but it is kept as\n * its own table on purpose: the two answer different questions and may diverge.\n *\n * Exhaustive by construction (`Record<ProviderErrorKind, \u2026>`) \u2014 a new kind\n * refuses to compile until it is classified here.\n */\nexport function isFallbackWorthy(kind: ProviderErrorKind): boolean {\n return FALLBACK_WORTHY_BY_KIND[kind];\n}\n\nconst FALLBACK_WORTHY_BY_KIND: Record<ProviderErrorKind, boolean> = {\n rate_limit: true,\n quota_exhausted: true,\n overloaded: true,\n server: true,\n timeout: true,\n network: true,\n stream_hang: true,\n auth: false,\n context_overflow: false,\n content_filter: false,\n invalid_request: false,\n unknown: false,\n};\n\nexport class ProviderError extends WrongStackError {\n public readonly status: number;\n public readonly retryable: boolean;\n public readonly providerId: string;\n /** Canonical failure classification \u2014 see {@link ProviderErrorKind}. */\n public readonly kind: ProviderErrorKind;\n public readonly body?: ProviderErrorBody | undefined;\n\n constructor(\n message: string,\n status: number,\n retryable: boolean,\n providerId: string,\n opts: {\n body?: ProviderErrorBody | undefined;\n cause?: unknown | undefined;\n /** Override the computed classification (rarely needed \u2014 tests, custom wires). */\n kind?: ProviderErrorKind | undefined;\n } = {},\n ) {\n const kind = opts.kind ?? classifyProviderError(status, opts.body, message);\n super({\n message,\n code: kindToCode(kind),\n subsystem: 'provider',\n severity: status >= 500 ? 'error' : 'warning',\n recoverable: retryable,\n context: { providerId, status },\n cause: opts.cause,\n });\n this.name = 'ProviderError';\n this.status = status;\n this.retryable = retryable;\n this.providerId = providerId;\n this.kind = kind;\n this.body = opts.body;\n }\n\n /**\n * Render a one-line, user-facing description. Designed for the CLI/TUI\n * status line and the agent's retry warning. Avoids dumping raw JSON\n * (which is what users see today when a 529 lands and the log message\n * includes the full `{\"type\":\"error\",...}` body).\n *\n * Examples:\n * \"minimax-coding-plan overloaded (529): High traffic detected. Upgrade for highspeed model. [req 06534785201de9c0\u2026]\"\n * \"openai rate limited (429): Retry after 12s\"\n * \"anthropic invalid request (400): messages.0.role must be one of 'user'|'assistant'\"\n * \"groq HTTP 500 (server error)\"\n */\n override describe(): string {\n const kind = describeStatus(this.status, this.body?.type);\n const head = `${this.providerId} ${kind}`;\n const detail = this.body?.message?.trim();\n const reqId = this.body?.requestId\n ? ` [req ${this.body.requestId.slice(0, 16)}${this.body.requestId.length > 16 ? '\u2026' : ''}]`\n : '';\n if (detail && detail.length > 0) {\n return `${head}: ${truncate(detail, 240)}${reqId}`;\n }\n return `${head}${reqId}`;\n }\n}\n\n/**\n * Belt-and-suspenders overflow detection for the recovery layer. Returns true\n * when a `ProviderError` is *shaped* like a context overflow even if its `kind`\n * says otherwise \u2014 an HTTP 413, or an overflow phrase anywhere in its message /\n * body. Gateways and proxies sometimes relabel an overflow as a generic\n * `invalid_request`/400 (or a caller constructs the error with an explicit\n * wrong `kind`); the `context_overflow_reduce` strategy uses this so those\n * still trigger compact-and-retry instead of failing terminally.\n */\nexport function isContextOverflowShaped(err: unknown): boolean {\n if (!(err instanceof ProviderError)) return false;\n if (err.kind === 'context_overflow' || err.status === 413) return true;\n if (err.status < 400) return false;\n const text = [err.message, err.body?.message, err.body?.type, err.body?.raw]\n .filter(Boolean)\n .join('\\n');\n return CONTEXT_OVERFLOW_RE.test(text);\n}\n\nfunction describeStatus(status: number, type?: string): string {\n if (status === 0) return 'network error';\n if (status === 599) return `stream hang (${status})`;\n if (type === 'overloaded_error' || status === 529) return `overloaded (${status})`;\n if (type === 'rate_limit_error' || status === 429) return `rate limited (${status})`;\n if (type === 'authentication_error' || status === 401) return `auth failed (${status})`;\n if (type === 'permission_error' || status === 403) return `forbidden (${status})`;\n if (type === 'not_found_error' || status === 404) return `not found (${status})`;\n if (type === 'content_filter') return `content filtered (${status})`;\n if (type === 'invalid_request_error' || status === 400) return `invalid request (${status})`;\n if (status === 408) return `timeout (${status})`;\n if (status >= 500 && status < 600) return `HTTP ${status} (server error)`;\n if (type) return `${type} (${status})`;\n return `HTTP ${status}`;\n}\n\n/**\n * Thrown when the provider stream stops delivering data mid-response.\n * This is distinct from a network error (TCP reset, DNS failure) \u2014 the\n * connection is established and the response started, but chunks stopped\n * arriving before the stream completed.\n *\n * Status 599 is used as a sentinel to distinguish stream hangs from\n * regular HTTP errors while still flowing through ProviderError-based\n * retry and fallback infrastructure.\n */\nexport class StreamHangError extends ProviderError {\n /** Name of the provider that hung, e.g. \"zai\", \"anthropic\". */\n public readonly hungProviderId: string;\n /** Model that was being called when the hang occurred. */\n public readonly hungModel: string;\n /** How long (ms) we waited for the next chunk before declaring a hang. */\n public readonly hangTimeoutMs: number;\n /** How many bytes were received before the hang. */\n public readonly bytesReceived: number;\n /** Elapsed time (ms) from the start of the stream until the hang. */\n public readonly elapsedMs: number;\n\n constructor(opts: {\n providerId: string;\n model: string;\n hangTimeoutMs: number;\n bytesReceived: number;\n elapsedMs: number;\n cause?: unknown | undefined;\n }) {\n super(\n `Stream hang: ${opts.providerId}/${opts.model} \u2014 no data for ${opts.hangTimeoutMs}ms after ${opts.bytesReceived} bytes (${opts.elapsedMs}ms elapsed)`,\n 599,\n true, // always retryable\n opts.providerId,\n {\n body: {\n message: `Stream stalled after ${opts.elapsedMs}ms, ${opts.bytesReceived} bytes received`,\n },\n cause: opts.cause,\n },\n );\n this.name = 'StreamHangError';\n this.hungProviderId = opts.providerId;\n this.hungModel = opts.model;\n this.hangTimeoutMs = opts.hangTimeoutMs;\n this.bytesReceived = opts.bytesReceived;\n this.elapsedMs = opts.elapsedMs;\n }\n}\n\n/** Exhaustive kind \u2192 ErrorCode mapping \u2014 new kinds must be added here or the\n * file stops compiling (same drift-guard pattern as RETRYABLE_BY_KIND). */\nconst KIND_TO_CODE: Record<ProviderErrorKind, ErrorCode> = {\n network: ERROR_CODES.PROVIDER_NETWORK_ERROR,\n timeout: ERROR_CODES.PROVIDER_NETWORK_ERROR,\n rate_limit: ERROR_CODES.PROVIDER_RATE_LIMITED,\n quota_exhausted: ERROR_CODES.PROVIDER_RATE_LIMITED,\n auth: ERROR_CODES.PROVIDER_AUTH_FAILED,\n overloaded: ERROR_CODES.PROVIDER_OVERLOADED,\n context_overflow: ERROR_CODES.PROVIDER_CONTEXT_OVERFLOW,\n server: ERROR_CODES.PROVIDER_SERVER_ERROR,\n stream_hang: ERROR_CODES.PROVIDER_SERVER_ERROR,\n content_filter: ERROR_CODES.PROVIDER_INVALID_REQUEST,\n invalid_request: ERROR_CODES.PROVIDER_INVALID_REQUEST,\n unknown: ERROR_CODES.PROVIDER_INVALID_REQUEST,\n};\n\nfunction kindToCode(kind: ProviderErrorKind): ErrorCode {\n return KIND_TO_CODE[kind];\n}\n", "import type { FallbackChain } from '../core/fallback-profile-manager.js';\nimport { evaluateModelCalendar } from '../core/model-availability-calendar.js';\nimport { isTextBlock } from '../types/blocks.js';\nimport type { Config } from '../types/config.js';\nimport type { Message } from '../types/messages.js';\nimport type {\n OneShotLLMInput,\n OneShotLLMResult,\n OneShotOrchestratorOptions,\n} from '../types/one-shot-llm.js';\nimport {\n isFallbackWorthy,\n type Provider,\n ProviderError,\n type Request,\n type Response,\n} from '../types/provider.js';\n\n/**\n * Default timeout for one-shot LLM calls when the caller doesn't specify one.\n */\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/**\n * Default max output tokens when the caller doesn't specify.\n */\nconst DEFAULT_MAX_TOKENS = 1024;\n\ntype CallAttempt =\n | { response: Response; error?: never; fallbackEligible: false }\n | { response?: never; error: unknown; fallbackEligible: boolean };\n\n/**\n * OneShotOrchestrator \u2014 a stateless, reusable utility for making single\n * LLM calls with provider resolution, fallback chains, and structured results.\n *\n * Usage:\n * ```ts\n * const oneShot = new OneShotOrchestrator({ buildProvider, getConfig });\n * const result = await oneShot.call({\n * system: 'You are a helpful assistant.',\n * userPrompt: 'Summarize this conversation.',\n * model: 'deepseek-chat',\n * fallbackModels: ['anthropic/claude-haiku'],\n * });\n * console.log(result.text);\n * ```\n *\n * Every method is stateless \u2014 a single instance can be shared across\n * the entire process lifetime.\n */\nexport class OneShotOrchestrator {\n private readonly opts: OneShotOrchestratorOptions;\n\n constructor(opts: OneShotOrchestratorOptions) {\n this.opts = opts;\n }\n\n /**\n * Make a one-shot LLM call. Resolves provider+model, applies fallback\n * chain on transient errors, and returns a structured result.\n *\n * Never throws \u2014 all errors are captured in `OneShotLLMResult.error`.\n */\n async call(input: OneShotLLMInput): Promise<OneShotLLMResult> {\n const startedAt = performance.now();\n const config = this.opts.getConfig();\n\n // \u2500\u2500 1. Resolve target provider + model \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const target = this.resolveTarget(input, config);\n if (!target) {\n return {\n text: '',\n model: input.model ?? config.model ?? 'unknown',\n provider: input.providerId ?? config.provider ?? 'unknown',\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: Math.round(performance.now() - startedAt),\n fromFallback: false,\n error: 'No provider or model could be resolved. Check your config.',\n };\n }\n\n let provider: Provider;\n try {\n provider = await this.opts.buildProvider(target.providerId, target.model);\n } catch (err) {\n return {\n text: '',\n model: target.model,\n provider: target.providerId,\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: Math.round(performance.now() - startedAt),\n fromFallback: false,\n error: `Cannot build provider \"${target.providerId}\": ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n // \u2500\u2500 2. Build the request \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const request = this.buildRequest(input, target.model);\n const signal = this.resolveSignal(input);\n\n // \u2500\u2500 3. Build fallback chain \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const chain = this.resolveFallbackChain(input, config, target);\n\n // \u2500\u2500 4. Attempt the call with fallback rotation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const tracker = this.opts.statusTracker;\n let servingProviderId = provider.id;\n let servingModel = target.model;\n let fromFallback = false;\n let lastError: unknown;\n let fallbackEligible = false;\n\n // Check if the primary target is blocked\n if (\n (tracker && !tracker.isAvailable(target.providerId, target.model)) ||\n !evaluateModelCalendar(config.modelAvailabilitySchedule, target.providerId, target.model)\n .allowed\n ) {\n this.opts.logger?.debug(\n `one-shot: primary \"${target.providerId}/${target.model}\" is blocked \u2014 trying fallback`,\n );\n // Fall through to the fallback chain\n } else {\n const primaryAttempt = await this.tryCall(\n provider,\n request,\n signal,\n target.providerId,\n target.model,\n );\n const result = primaryAttempt.response;\n lastError = primaryAttempt.error;\n fallbackEligible = primaryAttempt.fallbackEligible;\n\n if (result) {\n tracker?.recordSuccess(target.providerId, target.model);\n servingProviderId = provider.id;\n servingModel = target.model;\n return this.buildResult(result, servingProviderId, servingModel, false, startedAt);\n }\n\n if (!fallbackEligible || chain.length === 0) {\n return this.buildErrorResult(lastError, target.providerId, target.model, false, startedAt);\n }\n }\n\n // \u2500\u2500 4b. Fallback chain \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Filter blocked entries from the chain\n const usableChain = tracker\n ? chain.filter((e) => tracker.isAvailable(e.providerId, e.model))\n : chain;\n\n for (const entry of usableChain) {\n if (\n !evaluateModelCalendar(config.modelAvailabilitySchedule, entry.providerId, entry.model)\n .allowed\n )\n continue;\n // Re-check availability right before attempting \u2014 a concurrent failure\n // may have pushed this entry into the waiting room since the chain was\n // filtered. Skipping here avoids a wasted provider call.\n if (tracker && !tracker.isAvailable(entry.providerId, entry.model)) {\n continue;\n }\n if (entry.providerId === provider.id && entry.model === target.model) continue;\n\n let fbProvider: Provider;\n try {\n fbProvider = await this.opts.buildProvider(entry.providerId, entry.model);\n } catch (err) {\n lastError = err;\n continue;\n }\n\n servingProviderId = fbProvider.id;\n servingModel = entry.model;\n const attempt = await this.tryCall(\n fbProvider,\n this.buildRequest(input, entry.model),\n signal,\n entry.providerId,\n entry.model,\n );\n if (attempt.response) {\n tracker?.recordSuccess(entry.providerId, entry.model);\n fromFallback = true;\n return this.buildResult(attempt.response, servingProviderId, servingModel, true, startedAt);\n }\n\n lastError = attempt.error;\n fallbackEligible = attempt.fallbackEligible;\n if (!fallbackEligible) break;\n }\n\n // Total failure \u2014 all providers exhausted or non-retryable error.\n return this.buildErrorResult(\n lastError,\n servingProviderId,\n servingModel,\n fromFallback,\n startedAt,\n );\n }\n\n // \u2500\u2500 Private helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Resolve the target provider + model from input + config.\n * Priority: role-based routing > explicit providerId+model > defaults.\n */\n private resolveTarget(\n input: OneShotLLMInput,\n config: import('../types/config.js').Config,\n ): { providerId: string; model: string } | undefined {\n // Role-based routing via ModelRouter (highest priority)\n if (input.role && this.opts.modelRouter) {\n const pick = this.opts.modelRouter.pickForTask(input.role, '');\n if (pick) {\n return { providerId: pick.provider, model: pick.model };\n }\n }\n\n // Explicit providerId + model\n if (input.providerId && input.model) {\n return { providerId: input.providerId, model: input.model };\n }\n\n // Model only \u2014 use default provider\n if (input.model) {\n return { providerId: config.provider, model: input.model };\n }\n\n // Provider only \u2014 use default model\n if (input.providerId) {\n return { providerId: input.providerId, model: config.model };\n }\n\n // Neither \u2014 use session defaults\n if (config.provider && config.model) {\n return { providerId: config.provider, model: config.model };\n }\n\n return undefined;\n }\n\n /**\n * Build a Provider Request from the input.\n */\n private buildRequest(input: OneShotLLMInput, model: string): Request {\n const messages: Message[] = [...(input.messages ?? [])];\n if (input.userPrompt) {\n messages.push({ role: 'user', content: input.userPrompt });\n }\n\n const system = asTextBlocks(input.system);\n\n return {\n model,\n ...(system.length > 0 ? { system } : {}),\n messages,\n maxTokens: input.maxTokens ?? DEFAULT_MAX_TOKENS,\n ...(input.temperature !== undefined ? { temperature: input.temperature } : {}),\n ...(input.responseFormat ? { responseFormat: input.responseFormat } : {}),\n };\n }\n\n /**\n * Resolve the abort signal. Provider calls always receive the per-call\n * timeout, composed with external cancellation when the caller supplies it.\n */\n private resolveSignal(input: OneShotLLMInput): AbortSignal {\n const timeoutSignal = AbortSignal.timeout(input.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n return input.signal ? AbortSignal.any([input.signal, timeoutSignal]) : timeoutSignal;\n }\n\n /**\n * Build the fallback model chain from input + config + current target.\n * The injected {@link OneShotOrchestratorOptions.fallbackProfileManager}\n * is the only allowed manager \u2014 OneShot never owns a private snapshot\n * so a live `ConfigStore` change reaches every call without rebuilding\n * the manager.\n */\n private resolveFallbackChain(\n input: OneShotLLMInput,\n config: Config,\n target: { providerId: string; model: string },\n ): FallbackChain {\n const mgr = this.opts.fallbackProfileManager;\n\n // Explicit chain wins\n if (input.fallbackModels && input.fallbackModels.length > 0) {\n return mgr.resolveRefs(input.fallbackModels, target);\n }\n\n // Config-level fallbackModels \u2014 independent of fallbackAuto\n if (config.fallbackModels && config.fallbackModels.length > 0) {\n return mgr.resolveRefs(config.fallbackModels, target);\n }\n\n // Smart default from config (only when auto-derivation is enabled)\n if (config.fallbackAuto !== false) {\n return mgr.resolveEffective({\n fallbackAuto: true,\n exclude: target,\n });\n }\n\n return Object.freeze([]) as FallbackChain;\n }\n\n /** Attempt a provider call while preserving the actual failure for callers. */\n private async tryCall(\n provider: Provider,\n request: Request,\n signal: AbortSignal,\n providerId?: string,\n model?: string,\n ): Promise<CallAttempt> {\n try {\n return {\n response: await provider.complete(request, { signal }),\n fallbackEligible: false,\n };\n } catch (err) {\n // Record the failure in the tracker\n if (err instanceof ProviderError && providerId && model) {\n this.opts.statusTracker?.recordFailure(\n providerId,\n model,\n err.kind,\n err.status,\n err.describe(),\n { retryAfterMs: err.body?.retryAfterMs },\n );\n }\n return {\n error: err,\n fallbackEligible:\n !signal.aborted && (!(err instanceof ProviderError) || isFallbackWorthy(err.kind)),\n };\n }\n }\n\n /** Build a success result from a provider Response. */\n private buildResult(\n response: Response,\n servingProviderId: string,\n servingModel: string,\n fromFallback: boolean,\n startedAt: number,\n ): OneShotLLMResult {\n const textBlocks = response.content.filter(isTextBlock);\n const text = textBlocks\n .map((b) => b.text)\n .join('\\n')\n .trim();\n return {\n text: text || '(empty response)',\n model: response.model ?? servingModel,\n provider: servingProviderId,\n tokens: {\n input: response.usage?.input ?? 0,\n output: response.usage?.output ?? 0,\n total: (response.usage?.input ?? 0) + (response.usage?.output ?? 0),\n },\n durationMs: Math.round(performance.now() - startedAt),\n fromFallback,\n stopReason: response.stopReason,\n };\n }\n\n /** Build a total-failure error result. */\n private buildErrorResult(\n error: unknown,\n servingProviderId: string,\n servingModel: string,\n fromFallback: boolean,\n startedAt: number,\n ): OneShotLLMResult {\n return {\n text: '',\n model: servingModel,\n provider: servingProviderId,\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: Math.round(performance.now() - startedAt),\n fromFallback,\n error: error instanceof Error ? error.message : String(error ?? 'Unknown error'),\n };\n }\n}\n\n/**\n * Normalize system prompt to TextBlock[].\n */\nfunction asTextBlocks(\n system: string | import('../types/blocks.js').TextBlock[] | undefined,\n): import('../types/blocks.js').TextBlock[] {\n if (!system) return [];\n if (Array.isArray(system)) return system;\n return [{ type: 'text', text: system }];\n}\n", "import type { JSONSchema, Tool } from '../types/tool.js';\nimport type { OneShotLLMInput, OneShotLLMResult, OneShotOrchestratorOptions } from '../types/one-shot-llm.js';\nimport { OneShotOrchestrator } from '../execution/one-shot-llm.js';\n\n/**\n * Tool name for the one-shot LLM tool.\n * Register in ToolRegistry as `llm` so any agent can call it.\n */\nexport const ONE_SHOT_LLM_TOOL_NAME = 'llm';\n\n/**\n * Options for creating the LLM tool.\n * Mirrors OneShotOrchestratorOptions \u2014 the tool wraps an internal orchestrator.\n * When `defaultProvider` and `defaultModel` are not set, callers MUST\n * provide `providerId` and `model` explicitly.\n */\nexport interface CreateOneShotLLMToolOptions {\n buildProvider: OneShotOrchestratorOptions['buildProvider'];\n getConfig: OneShotOrchestratorOptions['getConfig'];\n /** Shared live FallbackProfileManager \u2014 required. */\n fallbackProfileManager: OneShotOrchestratorOptions['fallbackProfileManager'];\n modelRouter?: OneShotOrchestratorOptions['modelRouter'];\n logger?: OneShotOrchestratorOptions['logger'];\n /**\n * Default provider to use when the caller doesn't specify one.\n * When absent, callers MUST provide `providerId` explicitly.\n */\n defaultProvider?: string | undefined;\n /**\n * Default model to use when the caller doesn't specify one.\n * When absent, callers MUST provide `model` explicitly.\n */\n defaultModel?: string | undefined;\n}\n\n/**\n * JSON Schema for the llm tool input.\n */\nconst INPUT_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n system: {\n type: 'string',\n description: 'System prompt guiding the LLM behaviour.',\n },\n userPrompt: {\n type: 'string',\n description: 'Single user turn \u2014 appended as a user-role message.',\n },\n messages: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n role: {\n type: 'string',\n enum: ['system', 'user', 'assistant', 'tool'],\n description: 'Message author role.',\n },\n content: {\n type: 'string',\n description: 'Message text content.',\n },\n },\n required: ['role', 'content'],\n additionalProperties: true,\n },\n description: 'Conversation messages for few-shot examples or multi-turn context. Appended before userPrompt when both are set.',\n },\n model: {\n type: 'string',\n description: 'Model id (e.g. \"deepseek-chat\", \"gpt-4o-mini\"). Defaults to session model.',\n },\n providerId: {\n type: 'string',\n description: 'Provider id (e.g. \"anthropic\", \"openai\"). Defaults to session provider.',\n },\n role: {\n type: 'string',\n description: 'Roster role for model-matrix routing. Overrides model/providerId.',\n },\n fallbackModels: {\n type: 'array',\n items: { type: 'string' },\n description: 'Explicit fallback model chain (e.g. [\"anthropic/claude-haiku\", \"openai/gpt-4o-mini\"]). Resolved named profiles from FallbackProfileManager are passed here.',\n },\n maxTokens: {\n type: 'number',\n description: 'Maximum output tokens (default 1024).',\n },\n responseFormat: {\n oneOf: [\n { type: 'string', enum: ['text', 'json_object'], description: 'Simple response format.' },\n {\n type: 'object',\n properties: {\n type: { type: 'string', enum: ['json_schema'], description: 'Structured JSON output.' },\n json_schema: {\n type: 'object',\n description: 'JSON Schema definition for the structured output.',\n },\n },\n required: ['type'],\n additionalProperties: false,\n },\n ],\n description: 'Response format: \"text\" (default), \"json_object\", or { type: \"json_schema\", json_schema: {...} }.',\n },\n temperature: {\n type: 'number',\n description: 'Sampling temperature.',\n },\n timeoutMs: {\n type: 'number',\n description: 'Hard timeout in ms (default 30s).',\n },\n },\n};\n\n/**\n * Create the `llm` tool \u2014 a general-purpose one-shot LLM invocation tool\n * that any agent can call. Wraps OneShotOrchestrator internally for\n * provider resolution, fallback chain support, and structured results.\n *\n * Usage from an agent:\n * ```\n * llm({\n * system: \"You are a helpful assistant.\",\n * userPrompt: \"Summarize this conversation.\",\n * model: \"deepseek-chat\",\n * maxTokens: 1024,\n * })\n * ```\n *\n * Register with the ToolRegistry and it becomes available everywhere:\n * ```ts\n * toolRegistry.register(createOneShotLLMTool({ buildProvider, getConfig }));\n * ```\n */\nexport function createOneShotLLMTool(opts: CreateOneShotLLMToolOptions): Tool<OneShotLLMInput, OneShotLLMResult> {\n const orchestrator = new OneShotOrchestrator({\n buildProvider: opts.buildProvider,\n getConfig: opts.getConfig,\n fallbackProfileManager: opts.fallbackProfileManager,\n modelRouter: opts.modelRouter,\n logger: opts.logger,\n });\n\n return {\n name: ONE_SHOT_LLM_TOOL_NAME,\n description:\n 'Make a one-shot LLM call with a system prompt and user input. ' +\n 'Supports provider selection, model routing by role, fallback chains, and timeout. ' +\n 'Returns the response text, model info, token usage, and whether a fallback was used. ' +\n 'Use this for summarization, classification, extraction, and any single-turn LLM task.',\n usageHint:\n 'Provide `system` for the instruction and `userPrompt` for the input. ' +\n 'Either set `model`+`providerId`, or have defaults configured on the tool. ' +\n 'Set `fallbackModels` for resilience. ' +\n 'Check `error` on the result for failure details.',\n inputSchema: INPUT_SCHEMA,\n permission: 'auto',\n mutating: false,\n\n async execute(\n input: OneShotLLMInput,\n _ctx,\n { signal }: { signal: AbortSignal },\n ): Promise<OneShotLLMResult> {\n // If the caller didn't provide model/providerId, check for tool-level defaults.\n // This prevents silent fallback to session config which may not be intended.\n if (!input.model && !input.providerId && !opts.defaultModel && !opts.defaultProvider) {\n return {\n text: '',\n model: '',\n provider: '',\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: 0,\n fromFallback: false,\n error:\n 'Either provide `model` and `providerId` in the call, or configure ' +\n 'defaultProvider/defaultModel when creating the tool. The `llm` tool ' +\n 'does not infer provider/model from the session by default.',\n };\n }\n\n // Apply defaults when caller omits model/providerId but defaults are configured.\n const effectiveInput: OneShotLLMInput = {\n ...input,\n signal: input.signal ? AbortSignal.any([input.signal, signal]) : signal,\n model: input.model ?? opts.defaultModel,\n providerId: input.providerId ?? opts.defaultProvider,\n };\n\n return orchestrator.call(effectiveInput);\n },\n };\n}\n", "/**\n * Catalog types for the WrongStack agent fleet.\n *\n * An `AgentDefinition` bundles the runtime `SubagentConfig` (id/name/role/\n * prompt/tools) with two things the bare config lacks:\n * - a per-role `budget` tier (consumed by FLEET_ROSTER_BUDGETS), and\n * - dispatcher `capability` metadata (keywords + summary + phase) used by\n * the smart dispatcher to route a free-form task to the best agent.\n *\n * Phase files (`phase1-discovery.ts` \u2026 `phase9-meta.ts`) each export an\n * `AgentDefinition[]`; `index.ts` aggregates them into `AGENT_CATALOG`.\n * `fleet.ts` derives `FLEET_ROSTER` + `FLEET_ROSTER_BUDGETS` from the catalog.\n */\nimport type { SubagentConfig } from '../../types/multi-agent.js';\n\n/** Lifecycle phase grouping. Drives statusline labels + dispatcher tie-breaks. */\nexport type AgentPhase =\n | 'discovery'\n | 'planning'\n | 'build'\n | 'verify'\n | 'review'\n | 'domain'\n | 'knowledge'\n | 'delivery'\n | 'meta';\n\n/** Per-role budget tier. Same shape as fleet.ts `FleetRosterBudget`. */\nexport interface AgentBudgetTier {\n timeoutMs?: number | undefined;\n maxIterations?: number | undefined;\n maxToolCalls?: number | undefined;\n maxTokens?: number | undefined;\n maxCostUsd?: number | undefined;\n}\n\n/** Dispatcher routing metadata. */\nexport interface AgentCapability {\n phase: AgentPhase;\n /**\n * One-line capability summary. Fed to the LLM dispatcher classifier as the\n * candidate's description, and shown to the user when explaining a routing\n * decision. Keep it concrete and distinct from sibling agents.\n */\n summary: string;\n /**\n * Lowercased signal words/phrases for the heuristic dispatcher. A task whose\n * description contains these scores toward this agent. Order doesn't matter;\n * prefer specific terms (\"graphql\", \"wcag\") over generic ones (\"code\").\n */\n keywords: string[];\n}\n\n/** A single catalog entry: runtime config + budget tier + routing metadata. */\nexport interface AgentDefinition {\n config: SubagentConfig;\n budget: AgentBudgetTier;\n capability: AgentCapability;\n}\n\nconst HOUR = 60 * 60 * 1000;\n\n/**\n * Budget tiers by workload weight. Deliberately generous \u2014 the project's\n * existing roster uses multi-hour ceilings to avoid spurious timeouts on\n * monorepo-scale work, and the auto-extend handshake raises them further when\n * a subagent is still making progress.\n */\nexport const LIGHT_BUDGET: AgentBudgetTier = {\n timeoutMs: 3 * HOUR,\n maxIterations: 3000,\n maxToolCalls: 8000,\n};\nexport const MEDIUM_BUDGET: AgentBudgetTier = {\n timeoutMs: 5 * HOUR,\n maxIterations: 5000,\n maxToolCalls: 14000,\n};\nexport const HEAVY_BUDGET: AgentBudgetTier = {\n timeoutMs: 10 * HOUR,\n maxIterations: 8000,\n maxToolCalls: 20000,\n};\n\n/**\n * Tool allowlist presets. Agents pass the smallest set that covers their job \u2014\n * a planning agent should not hold `write`/`bash`, a reviewer should be\n * read-only. Spread + extend per-agent where a role needs one extra tool.\n */\nexport const TOOLS = {\n /** Pure read/inspect \u2014 safe for analysis and review agents. */\n read: ['read', 'grep', 'glob', 'search', 'tree', 'mailbox'],\n /** Read + structured inspection (logs, diffs, json, dependency audit). */\n inspect: ['read', 'grep', 'glob', 'search', 'tree', 'json', 'diff', 'logs', 'audit', 'mailbox'],\n /** Read + edit (no shell). For agents that write code/docs but don't run it. */\n write: ['read', 'grep', 'glob', 'search', 'tree', 'write', 'edit', 'replace', 'patch', 'mailbox'],\n /** Full build loop: edit + run (lint/format/typecheck/test/bash). */\n build: [\n 'read',\n 'grep',\n 'glob',\n 'search',\n 'tree',\n 'write',\n 'edit',\n 'replace',\n 'patch',\n 'bash',\n 'exec',\n 'lint',\n 'format',\n 'typecheck',\n 'test',\n 'mailbox',\n ],\n /** Version control. */\n vcs: ['read', 'grep', 'glob', 'git', 'diff'],\n /** Dependency management + CVE audit. */\n deps: ['read', 'grep', 'glob', 'install', 'outdated', 'audit', 'json', 'mailbox'],\n /** Documentation authoring. */\n docs: ['read', 'grep', 'glob', 'search', 'tree', 'write', 'edit', 'document', 'mailbox'],\n /** Web research. */\n research: ['read', 'grep', 'glob', 'search', 'fetch', 'mailbox'],\n} as const satisfies Record<string, readonly string[]>;\n", "import { readFileSync, statSync } from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Cache of resolved prompt text, keyed by `<envDir>\\0<id>`. Prompt files do\n * not change during a process lifetime, so the first successful (or failed)\n * lookup is memoized. The key includes the override env var so tests that set\n * `WRONGSTACK_AGENT_INSTRUCTIONS_DIR` still observe fresh resolution.\n */\nconst promptCache = new Map<string, string>();\n\n/**\n * Cache of the ordered candidate directory list, keyed by `<envDir>\\0<cwd-home>`.\n * The list is otherwise identical for every `agentPrompt()` call, so resolving\n * (and sorting via `statSync`) it once per env avoids ~7 redundant `statSync`\n * probes per call. `fleet.ts` + the phase catalogs alone call `agentPrompt()`\n * ~60 times at import time.\n */\nconst candidateCache = new Map<string, string[]>();\n\nexport function agentPrompt(id: string): string {\n const envDir = process.env['WRONGSTACK_AGENT_INSTRUCTIONS_DIR'] ?? '';\n const cacheKey = `${envDir}\\u0000${id}`;\n const cached = promptCache.get(cacheKey);\n if (cached !== undefined) return cached;\n\n const fileName = `${id}.md`;\n let resolved = '';\n for (const dir of agentPromptDirCandidates(envDir)) {\n try {\n resolved = readFileSync(path.join(dir, fileName), 'utf8').trimEnd();\n break;\n } catch {\n // try next candidate\n }\n }\n promptCache.set(cacheKey, resolved);\n return resolved;\n}\n\nfunction agentPromptDirCandidates(envDir: string): string[] {\n const globalRoot = process.env['WRONGSTACK_HOME'] || path.join(os.homedir(), '.wrongstack');\n const candKey = `${envDir}\\u0000${globalRoot}`;\n const cached = candidateCache.get(candKey);\n if (cached !== undefined) return cached;\n\n const here = path.dirname(fileURLToPath(import.meta.url));\n const explicitDir = envDir || undefined;\n const candidates = [\n ...(explicitDir ? [path.resolve(explicitDir)] : []),\n path.join(globalRoot, 'instructions', 'agents'),\n path.resolve(here, '../../../../instructions/agents'),\n path.resolve(here, '../../../instructions/agents'),\n path.resolve(here, '../../instructions/agents'),\n path.resolve(here, '../instructions/agents'),\n path.resolve(here, 'instructions/agents'),\n ];\n const ordered = candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));\n candidateCache.set(candKey, ordered);\n return ordered;\n}\n\nfunction isDirectory(candidate: string): boolean {\n try {\n return statSync(candidate).isDirectory();\n } catch {\n return false;\n }\n}\n", "import { type AgentDefinition, LIGHT_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 1 \u00B7 Discovery \u2014 map the territory before any work begins. */\nexport const DISCOVERY_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'explore',\n name: 'Explore',\n role: 'explore',\n tools: [...TOOLS.read],\n prompt: agentPrompt('explore'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'discovery',\n summary: 'Maps unfamiliar codebases: entry points, structure, architecture, feature flow (read-only).',\n keywords: [\n 'explore',\n 'map',\n 'understand',\n 'where is',\n 'how does',\n 'codebase',\n 'architecture',\n 'structure',\n 'overview',\n 'find file',\n 'entry point',\n 'orient',\n ],\n },\n },\n {\n config: {\n id: 'search',\n name: 'Search',\n role: 'search',\n tools: [...TOOLS.read],\n prompt: agentPrompt('search'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'discovery',\n summary: 'Semantic + lexical code search across repos; finds definitions, references, duplicates, ranks by relevance.',\n keywords: [\n 'search',\n 'find all',\n 'references',\n 'usages',\n 'call sites',\n 'grep',\n 'locate symbol',\n 'duplicate',\n 'where used',\n 'occurrences',\n 'cross-repo',\n ],\n },\n },\n {\n config: {\n id: 'research',\n name: 'Research',\n role: 'research',\n tools: [...TOOLS.research],\n prompt: agentPrompt('research'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'discovery',\n summary: 'Technical research and feasibility: compares libraries/approaches, recommends a path with evidence and tradeoffs.',\n keywords: [\n 'research',\n 'feasibility',\n 'compare libraries',\n 'which library',\n 'best practice',\n 'tradeoff',\n 'investigate',\n 'evaluate approach',\n 'should we use',\n 'pros and cons',\n ],\n },\n },\n];\n", "import { type AgentDefinition, HEAVY_BUDGET, LIGHT_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\nconst PLAN_TOOLS = [...TOOLS.read, 'plan', 'todo'];\n\n/** Phase 2 \u00B7 Planning \u2014 turn intent into requirements, plans, and architecture. */\nexport const PLANNING_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'analyst',\n name: 'Analyst',\n role: 'analyst',\n tools: [...PLAN_TOOLS],\n prompt: agentPrompt('analyst'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'planning',\n summary: 'Requirement analysis: turns vague requests into testable specs with acceptance criteria and open questions.',\n keywords: [\n 'requirements',\n 'analyze requirement',\n 'acceptance criteria',\n 'spec',\n 'specification',\n 'clarify',\n 'scope',\n 'user story',\n 'what should it do',\n ],\n },\n },\n {\n config: {\n id: 'planner',\n name: 'Planner',\n role: 'planner',\n tools: [...PLAN_TOOLS],\n prompt: agentPrompt('planner'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'planning',\n summary: 'Execution planning: decomposes a goal into ordered, dependency-aware, parallelizable steps with checkpoints.',\n keywords: [\n 'plan',\n 'execution plan',\n 'break down',\n 'decompose',\n 'steps',\n 'sequence',\n 'roadmap',\n 'task breakdown',\n 'order of work',\n 'milestones',\n ],\n },\n },\n {\n config: {\n id: 'architect',\n name: 'Architect',\n role: 'architect',\n tools: [...PLAN_TOOLS],\n prompt: agentPrompt('architect'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'planning',\n summary: 'System architecture: designs module boundaries, interfaces, data flow, and records key decisions.',\n keywords: [\n 'architecture',\n 'design system',\n 'module boundaries',\n 'interfaces',\n 'data flow',\n 'component design',\n 'system design',\n 'decision record',\n 'adr',\n 'structure the',\n ],\n },\n },\n {\n config: {\n id: 'critic',\n name: 'Critic',\n role: 'critic',\n tools: [...TOOLS.read],\n prompt: agentPrompt('critic'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'planning',\n summary: 'Adversarial review of plans/designs: finds gaps, risks, and unstated assumptions with ranked fixes.',\n keywords: [\n 'critique',\n 'review plan',\n 'review design',\n 'red team',\n 'poke holes',\n 'risks',\n 'what could go wrong',\n 'second opinion',\n 'challenge',\n 'flaws',\n ],\n },\n },\n {\n config: {\n id: 'refactor-planner',\n name: 'Refactor Planner',\n role: 'refactor-planner',\n tools: [...PLAN_TOOLS, 'diff'],\n prompt: agentPrompt('refactor-planner'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'planning',\n summary: 'Refactoring planner: analyzes code structure, maps dependencies, produces risk-scored phased plans with rollback strategy.',\n keywords: [\n 'refactor',\n 'refactoring',\n 'restructure',\n 'debt',\n 'technical debt',\n 'clean up',\n 'modularize',\n 'decouple',\n 'dependency graph',\n 'code structure',\n ],\n },\n },\n];\n", "import { type AgentDefinition, HEAVY_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 3 \u00B7 Build \u2014 write, refactor, migrate, and fix code. */\nexport const BUILD_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'executor',\n name: 'Executor',\n role: 'executor',\n tools: [...TOOLS.build],\n prompt: agentPrompt('executor'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Implements well-specified tasks: writes code, runs checks, leaves the tree green.',\n keywords: [\n 'implement',\n 'build',\n 'write code',\n 'add feature',\n 'create',\n 'code up',\n 'develop',\n 'apply change',\n 'make it work',\n ],\n },\n },\n {\n config: {\n id: 'refactor',\n name: 'Refactor',\n role: 'refactor',\n tools: [...TOOLS.build],\n prompt: agentPrompt('refactor'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Structural refactoring: extract/split/move/rename/decouple without changing observable behavior.',\n keywords: [\n 'refactor',\n 'restructure',\n 'extract',\n 'split module',\n 'decouple',\n 'rename',\n 'move code',\n 'break dependency',\n 'reorganize',\n ],\n },\n },\n {\n config: {\n id: 'simplifier',\n name: 'Simplifier',\n role: 'simplifier',\n tools: [...TOOLS.build],\n prompt: agentPrompt('simplifier'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Reduces complexity: deletes dead code, collapses needless abstractions, shortens and clarifies code.',\n keywords: [\n 'simplify',\n 'dead code',\n 'remove unused',\n 'reduce complexity',\n 'clean up',\n 'denest',\n 'shorten',\n 'over-engineered',\n 'too complex',\n ],\n },\n },\n {\n config: {\n id: 'migration',\n name: 'Migration',\n role: 'migration',\n tools: [...TOOLS.build, 'install', 'outdated'],\n prompt: agentPrompt('migration'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Framework/language/version upgrades: applies codemods across call sites, staged and verified.',\n keywords: [\n 'migrate',\n 'upgrade',\n 'codemod',\n 'breaking change',\n 'major version',\n 'port to',\n 'convert to',\n 'esm',\n 'modernize',\n ],\n },\n },\n {\n config: {\n id: 'vision',\n name: 'Vision',\n role: 'vision',\n tools: [...TOOLS.write, 'fetch'],\n prompt: agentPrompt('vision'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Screenshot/mockup \u2192 UI code: infers component tree and generates matching, accessible markup.',\n keywords: [\n 'screenshot',\n 'mockup',\n 'design to code',\n 'image to ui',\n 'figma',\n 'replicate this ui',\n 'from this picture',\n 'vision',\n 'clone ui',\n ],\n },\n },\n {\n config: {\n id: 'debugger',\n name: 'Debugger',\n role: 'debugger',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('debugger'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Root-cause bug fixing: reproduces, bisects to the true cause, applies a minimal fix with a regression test.',\n keywords: [\n 'bug',\n 'fix',\n 'debug',\n 'broken',\n 'error',\n 'crash',\n 'root cause',\n 'not working',\n 'failing',\n 'reproduce',\n 'why does',\n ],\n },\n },\n {\n config: {\n id: 'tracer',\n name: 'Tracer',\n role: 'tracer',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('tracer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'build',\n summary: 'Runtime tracing: instruments and runs code to observe call order, values, and timing, then cleans up.',\n keywords: [\n 'trace',\n 'runtime',\n 'instrument',\n 'execution path',\n 'what happens at runtime',\n 'call order',\n 'profile execution',\n 'observe behavior',\n 'stack trace',\n ],\n },\n },\n];\n", "import { agentPrompt } from './agent-prompts.js';\nimport { type AgentDefinition, HEAVY_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\n\n/** Phase 4 \u00B7 Verify \u2014 prove the code works under normal, end-to-end, and adverse conditions. */\nexport const VERIFY_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'verifier',\n name: 'Verifier',\n role: 'verifier',\n tools: [...TOOLS.inspect, 'bash', 'exec', 'lint', 'typecheck', 'test', 'git'],\n prompt: agentPrompt('verifier'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Independent verification gate: runs the relevant checks until they pass or returns exact failures that need another implementation pass.',\n keywords: [\n 'verify',\n 'verification',\n 'quality gate',\n 'prove it works',\n 'run checks',\n 'run tests until pass',\n 'test pass',\n 'green build',\n 'typecheck',\n 'lint',\n 'regression check',\n 'acceptance gate',\n ],\n },\n },\n {\n config: {\n id: 'test',\n name: 'Test',\n role: 'test',\n tools: [...TOOLS.build],\n prompt: agentPrompt('test'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Unit + integration testing: writes meaningful tests covering golden path and edge cases, runs the suite.',\n keywords: [\n 'test',\n 'unit test',\n 'integration test',\n 'write tests',\n 'coverage',\n 'test suite',\n 'vitest',\n 'jest',\n 'add tests',\n 'spec',\n ],\n },\n },\n {\n config: {\n id: 'e2e',\n name: 'E2E',\n role: 'e2e',\n tools: [\n ...TOOLS.build,\n 'fetch',\n 'playwright_navigate',\n 'playwright_screenshot',\n 'playwright_click',\n 'playwright_type',\n 'playwright_evaluate',\n 'playwright_select_option',\n 'playwright_hover',\n 'playwright_fill_form',\n 'playwright_wait_for',\n 'playwright_press_key',\n 'playwright_drag',\n ],\n prompt: agentPrompt('e2e'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'End-to-end testing: drives full user journeys across UI/CLI/API boundaries with reproducible failures.',\n keywords: [\n 'e2e',\n 'end to end',\n 'end-to-end',\n 'user journey',\n 'smoke test',\n 'playwright',\n 'browser',\n 'screenshot',\n 'web ui',\n 'headless',\n 'cypress',\n 'full flow',\n 'browser test',\n 'acceptance test',\n 'navigate',\n 'click',\n 'form fill',\n 'dom',\n 'page load',\n ],\n },\n },\n {\n config: {\n id: 'browser',\n name: 'Browser',\n role: 'browser',\n tools: [\n ...TOOLS.read,\n 'fetch',\n 'playwright_navigate',\n 'playwright_screenshot',\n 'playwright_click',\n 'playwright_type',\n 'playwright_evaluate',\n 'playwright_select_option',\n 'playwright_hover',\n 'playwright_fill_form',\n 'playwright_wait_for',\n 'playwright_press_key',\n 'playwright_drag',\n ],\n prompt: agentPrompt('browser'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Browser automation: opens pages, clicks, types, screenshots, extracts data via Playwright headless Chromium.',\n keywords: [\n 'browser',\n 'screenshot',\n 'navigate',\n 'web page',\n 'scrape',\n 'crawl',\n 'headless',\n 'chrome',\n 'open url',\n 'capture',\n 'page title',\n 'extract data',\n 'fill form',\n 'click button',\n 'take screenshot',\n ],\n },\n },\n {\n config: {\n id: 'performance',\n name: 'Performance',\n role: 'performance',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('performance'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Performance analysis: benchmarks/profiles to find the real bottleneck, optimizes, proves speedup with numbers.',\n keywords: [\n 'performance',\n 'slow',\n 'optimize',\n 'bottleneck',\n 'profile',\n 'benchmark',\n 'latency',\n 'throughput',\n 'memory',\n 'speed up',\n 'too slow',\n ],\n },\n },\n {\n config: {\n id: 'chaos',\n name: 'Chaos',\n role: 'chaos',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('chaos'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Resilience testing via fault injection: breaks network/disk/timing to find ungraceful failures and recovery gaps.',\n keywords: [\n 'chaos',\n 'resilience',\n 'fault injection',\n 'failure mode',\n 'fail safe',\n 'retry',\n 'circuit breaker',\n 'graceful degradation',\n 'inject failure',\n 'robustness',\n ],\n },\n },\n {\n config: {\n id: 'security-scanner',\n name: 'Security Scanner',\n role: 'security-scanner',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('security-scanner'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Security scanner: detects hardcoded secrets, injection vectors, insecure patterns, and supply-chain risks with remediation.',\n keywords: [\n 'security',\n 'scan',\n 'vulnerability',\n 'secret',\n 'api key',\n 'hardcoded',\n 'injection',\n 'cve',\n 'audit dependencies',\n 'supply chain',\n 'xss',\n 'sqli',\n 'shell injection',\n 'sensitive data',\n 'credential',\n ],\n },\n },\n {\n config: {\n id: 'bug-hunter',\n name: 'Bug Hunter',\n role: 'bug-hunter',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('bug-hunter'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Bug hunter: scans source code for bugs, anti-patterns, and code smells, producing a file:line-ranked hit list with fixes.',\n keywords: [\n 'bug',\n 'hunt',\n 'scan',\n 'code smell',\n 'anti-pattern',\n 'race condition',\n 'memory leak',\n 'null deref',\n 'type safety',\n 'unhandled error',\n 'find bugs',\n 'audit code',\n 'code quality',\n ],\n },\n },\n {\n config: {\n id: 'audit-log',\n name: 'Audit Log',\n role: 'audit-log',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('audit-log'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'verify',\n summary:\n 'Audit log analyzer: parses session JSONL, detects failure patterns, tool anomalies, and cost trends with structured reports.',\n keywords: [\n 'audit',\n 'log',\n 'logs',\n 'session',\n 'trace',\n 'analyze logs',\n 'error patterns',\n 'cost analysis',\n 'tool usage',\n 'token usage',\n 'post-mortem',\n 'trend',\n 'anomaly',\n ],\n },\n },\n];\n", "import { agentPrompt } from './agent-prompts.js';\nimport { type AgentDefinition, MEDIUM_BUDGET, TOOLS } from './types.js';\n\n/** Phase 5 \u00B7 Review \u2014 read-only quality, security, a11y, and compliance gates. */\nexport const REVIEW_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'reviewer',\n name: 'Reviewer',\n role: 'reviewer',\n tools: [...TOOLS.inspect, 'git'],\n prompt: agentPrompt('reviewer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n \"Independent AI reviewer: audits another agent's output, flags uncertainty, correlated-failure risk, and must-fix defects.\",\n keywords: [\n 'reviewer',\n 'independent review',\n 'ai review',\n 'review agent',\n 'quality review',\n 'second opinion',\n 'check another agent',\n 'cross check',\n 'uncertainty',\n 'correlated error',\n 'verify output',\n 'quality control',\n ],\n },\n },\n {\n config: {\n id: 'code-reviewer',\n name: 'Code Reviewer',\n role: 'code-reviewer',\n tools: [...TOOLS.inspect, 'git'],\n prompt: agentPrompt('code-reviewer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n 'Correctness-first code review of diffs/PRs: finds bugs, edge cases, and convention violations with fixes.',\n keywords: [\n 'review',\n 'code review',\n 'review pr',\n 'review diff',\n 'look over',\n 'feedback on code',\n 'quality',\n 'is this correct',\n 'check my code',\n ],\n },\n },\n {\n config: {\n id: 'security-reviewer',\n name: 'Security Reviewer',\n role: 'security-reviewer',\n tools: [...TOOLS.inspect, 'git'],\n prompt: agentPrompt('security-reviewer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n 'Security review: finds injection/authz/secret/crypto issues mapped to OWASP severity with remediation.',\n keywords: [\n 'security review',\n 'security',\n 'vulnerability',\n 'vulnerabilities',\n 'owasp',\n 'injection',\n 'sql injection',\n 'xss',\n 'ssrf',\n 'authz',\n 'secrets',\n 'security audit',\n 'threat',\n 'unsafe',\n ],\n },\n },\n {\n config: {\n id: 'accessibility',\n name: 'Accessibility',\n role: 'accessibility',\n tools: [...TOOLS.read],\n prompt: agentPrompt('accessibility'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n 'WCAG/a11y review of UI: checks semantics, ARIA, keyboard, contrast; maps findings to success criteria.',\n keywords: [\n 'accessibility',\n 'a11y',\n 'wcag',\n 'aria',\n 'screen reader',\n 'keyboard navigation',\n 'contrast',\n 'disabled users',\n 'accessible',\n ],\n },\n },\n {\n config: {\n id: 'compliance',\n name: 'Compliance',\n role: 'compliance',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('compliance'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'review',\n summary:\n 'License/privacy/regulatory review: audits licenses, PII handling, and controls vs GDPR/SOC2.',\n keywords: [\n 'compliance',\n 'license',\n 'gdpr',\n 'soc2',\n 'privacy',\n 'pii',\n 'data retention',\n 'regulatory',\n 'audit log',\n 'legal review',\n ],\n },\n },\n];\n", "import { type AgentDefinition, HEAVY_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 6 \u00B7 Domain \u2014 specialists for the major slices of a system. */\nexport const DOMAIN_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'database',\n name: 'Database',\n role: 'database',\n tools: [...TOOLS.build],\n prompt: agentPrompt('database'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'Schema design, query optimization, and safe reversible migrations for SQL databases.',\n keywords: [\n 'database',\n 'schema',\n 'sql',\n 'migration',\n 'query',\n 'index',\n 'postgres',\n 'mysql',\n 'table',\n 'orm',\n 'slow query',\n ],\n },\n },\n {\n config: {\n id: 'api',\n name: 'API',\n role: 'api',\n tools: [...TOOLS.build, 'fetch'],\n prompt: agentPrompt('api'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'REST + GraphQL API design and implementation: contracts, HTTP/GraphQL semantics, versioning.',\n keywords: [\n 'api',\n 'rest',\n 'graphql',\n 'endpoint',\n 'resolver',\n 'http',\n 'openapi',\n 'swagger',\n 'route',\n 'contract',\n 'webhook',\n ],\n },\n },\n {\n config: {\n id: 'auth',\n name: 'Auth',\n role: 'auth',\n tools: [...TOOLS.build],\n prompt: agentPrompt('auth'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'Authentication and authorization: identity, sessions/tokens, RBAC/ABAC, OAuth/OIDC, done securely.',\n keywords: [\n 'auth',\n 'authentication',\n 'authorization',\n 'login',\n 'session',\n 'jwt',\n 'oauth',\n 'oidc',\n 'rbac',\n 'permissions',\n 'token',\n 'sso',\n ],\n },\n },\n {\n config: {\n id: 'data',\n name: 'Data',\n role: 'data',\n tools: [...TOOLS.build],\n prompt: agentPrompt('data'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'Data engineering: ETL/ELT pipelines, data-quality validation, idempotent transforms, reconciliation.',\n keywords: [\n 'etl',\n 'elt',\n 'pipeline',\n 'data quality',\n 'data engineering',\n 'transform',\n 'ingestion',\n 'batch',\n 'stream',\n 'reconcile',\n 'dataset',\n ],\n },\n },\n {\n config: {\n id: 'frontend',\n name: 'Frontend',\n role: 'frontend',\n tools: [...TOOLS.build, 'fetch'],\n prompt: agentPrompt('frontend'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'UI implementation: components, client state, data fetching, responsive and accessible by default.',\n keywords: [\n 'frontend',\n 'component',\n 'react',\n 'vue',\n 'svelte',\n 'client state',\n 'ui implementation',\n 'css',\n 'responsive',\n 'hook',\n 'render',\n ],\n },\n },\n {\n config: {\n id: 'backend',\n name: 'Backend',\n role: 'backend',\n tools: [...TOOLS.build],\n prompt: agentPrompt('backend'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'Server-side logic: services, business rules, persistence/queue wiring, concurrency and transactions.',\n keywords: [\n 'backend',\n 'server',\n 'service',\n 'business logic',\n 'controller',\n 'handler',\n 'queue',\n 'cache',\n 'transaction',\n 'microservice',\n 'server-side',\n ],\n },\n },\n {\n config: {\n id: 'designer',\n name: 'Designer',\n role: 'designer',\n tools: [...TOOLS.docs],\n prompt: agentPrompt('designer'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'domain',\n summary: 'UI/UX design: user flows, layout/wireframes, interaction states, and design-system decisions.',\n keywords: [\n 'design',\n 'ux',\n 'ui design',\n 'wireframe',\n 'user flow',\n 'layout',\n 'design system',\n 'interaction',\n 'mockup design',\n 'information architecture',\n ],\n },\n },\n {\n config: {\n id: 'ios',\n name: 'iOS',\n role: 'ios',\n tools: [...TOOLS.build, 'fetch'],\n prompt: agentPrompt('ios'),\n },\n budget: HEAVY_BUDGET,\n capability: {\n phase: 'domain',\n summary:\n 'Apple-platform app development in Swift against the latest Xcode/iOS-SDK line: SwiftUI, UIKit, SwiftData, concurrency, accessibility, and App Store submission.',\n keywords: [\n 'ios',\n 'iphone',\n 'ipad',\n 'ipados',\n 'watchos',\n 'tvos',\n 'visionos',\n 'macos',\n 'swift',\n 'swiftui',\n 'uikit',\n 'xcode',\n 'swiftdata',\n 'app store',\n 'app intents',\n 'swift package manager',\n 'cocoapods',\n 'foundation models',\n ],\n },\n },\n];\n", "import { type AgentDefinition, LIGHT_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 7 \u00B7 Knowledge \u2014 documentation, diagrams, localization, and prompts. */\nexport const KNOWLEDGE_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'document',\n name: 'Document',\n role: 'document',\n tools: [...TOOLS.docs],\n prompt: agentPrompt('document'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'knowledge',\n summary: 'Technical documentation: READMEs, API/reference docs, guides, and verified examples grounded in code.',\n keywords: [\n 'document',\n 'documentation',\n 'readme',\n 'docs',\n 'write up',\n 'guide',\n 'api docs',\n 'explain in writing',\n 'reference',\n 'changelog notes',\n ],\n },\n },\n {\n config: {\n id: 'uml',\n name: 'UML',\n role: 'uml',\n tools: [...TOOLS.read, 'write', 'edit'],\n prompt: agentPrompt('uml'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'knowledge',\n summary: 'Diagram generation from code: class/sequence/component/ER diagrams as Mermaid/PlantUML.',\n keywords: [\n 'uml',\n 'diagram',\n 'mermaid',\n 'plantuml',\n 'sequence diagram',\n 'class diagram',\n 'er diagram',\n 'visualize',\n 'flowchart',\n 'architecture diagram',\n ],\n },\n },\n {\n config: {\n id: 'i18n',\n name: 'I18n',\n role: 'i18n',\n tools: [...TOOLS.write],\n prompt: agentPrompt('i18n'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'knowledge',\n summary: 'Internationalization/localization: string extraction, catalog management, plurals/RTL/format handling.',\n keywords: [\n 'i18n',\n 'internationalization',\n 'localization',\n 'l10n',\n 'translation',\n 'translate ui',\n 'locale',\n 'rtl',\n 'message catalog',\n 'multilingual',\n ],\n },\n },\n {\n config: {\n id: 'prompt',\n name: 'Prompt',\n role: 'prompt',\n tools: [...TOOLS.write],\n prompt: agentPrompt('prompt'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'knowledge',\n summary: 'Prompt engineering: designs/refines/evaluates LLM system prompts and agent instructions.',\n keywords: [\n 'prompt',\n 'prompt engineering',\n 'system prompt',\n 'llm instructions',\n 'few-shot',\n 'refine prompt',\n 'agent instructions',\n 'prompt template',\n ],\n },\n },\n];\n", "import { type AgentDefinition, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 8 \u00B7 Delivery & Ops \u2014 ship it, run it, keep it healthy. */\nexport const DELIVERY_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'git',\n name: 'Git',\n role: 'git',\n tools: [...TOOLS.vcs, 'bash'],\n prompt: agentPrompt('git'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'delivery',\n summary: 'Git automation: focused commits, branch/rebase/conflict handling, PR prep, history investigation.',\n keywords: [\n 'git',\n 'commit',\n 'branch',\n 'rebase',\n 'merge',\n 'pull request',\n 'pr',\n 'conflict',\n 'blame',\n 'bisect',\n 'cherry-pick',\n 'stash',\n ],\n },\n },\n {\n config: {\n id: 'release',\n name: 'Release',\n role: 'release',\n tools: [...TOOLS.vcs, 'bash', 'json'],\n prompt: agentPrompt('release'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'delivery',\n summary: 'Release management: semver bumps, changelogs, and release notes derived from real history.',\n keywords: [\n 'release',\n 'version',\n 'semver',\n 'changelog',\n 'release notes',\n 'tag',\n 'bump version',\n 'publish',\n 'versioning',\n ],\n },\n },\n {\n config: {\n id: 'devops',\n name: 'DevOps',\n role: 'devops',\n tools: [\n ...TOOLS.build,\n 'mcp__ssh__ssh_list_servers',\n 'mcp__ssh__ssh_connection_status',\n 'mcp__ssh__ssh_execute',\n 'mcp__ssh__ssh_execute_sudo',\n 'mcp__ssh__ssh_upload',\n 'mcp__ssh__ssh_download',\n 'mcp__ssh__ssh_sync',\n 'mcp__ssh__ssh_deploy',\n 'mcp__ssh__ssh_health_check',\n 'mcp__ssh__ssh_service_status',\n 'mcp__ssh__ssh_process_manager',\n 'mcp__ssh__ssh_tunnel',\n 'mcp__ssh__ssh_backup_create',\n 'mcp__ssh__ssh_backup_list',\n 'mcp__ssh__ssh_backup_restore',\n 'mcp__ssh__ssh_db_list',\n 'mcp__ssh__ssh_db_query',\n 'mcp__ssh__ssh_profile',\n ],\n prompt: agentPrompt('devops'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'delivery',\n summary: 'CI/CD, containerization, and deployment config: reproducible builds and safe deploys with rollback.',\n keywords: [\n 'devops',\n 'ci',\n 'cd',\n 'ci/cd',\n 'pipeline',\n 'docker',\n 'dockerfile',\n 'kubernetes',\n 'k8s',\n 'deploy',\n 'ssh',\n 'remote ssh',\n 'remote server',\n 'sftp',\n 'tunnel',\n 'bastion',\n 'jump host',\n 'github actions',\n 'container',\n ],\n },\n },\n {\n config: {\n id: 'observability',\n name: 'Observability',\n role: 'observability',\n tools: [...TOOLS.build, 'logs'],\n prompt: agentPrompt('observability'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'delivery',\n summary: 'Observability: structured logging, metrics, distributed tracing, and alerts/dashboards.',\n keywords: [\n 'observability',\n 'logging',\n 'metrics',\n 'tracing',\n 'telemetry',\n 'opentelemetry',\n 'otel',\n 'prometheus',\n 'monitoring',\n 'alert',\n 'dashboard',\n 'instrument',\n ],\n },\n },\n {\n config: {\n id: 'dependency',\n name: 'Dependency',\n role: 'dependency',\n tools: [...TOOLS.deps, 'bash'],\n prompt: agentPrompt('dependency'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'delivery',\n summary: 'Package management + supply-chain safety: CVE audit, safe upgrades, pruning, install-script review.',\n keywords: [\n 'dependency',\n 'dependencies',\n 'package',\n 'npm',\n 'pnpm',\n 'cve',\n 'vulnerability scan',\n 'upgrade deps',\n 'audit',\n 'supply chain',\n 'outdated',\n 'lockfile',\n ],\n },\n },\n];\n", "import { type AgentDefinition, LIGHT_BUDGET, MEDIUM_BUDGET, TOOLS } from './types.js';\nimport { agentPrompt } from './agent-prompts.js';\n\n/** Phase 9 \u00B7 Meta \u2014 agents that improve the agent system itself. */\nexport const META_AGENTS: AgentDefinition[] = [\n {\n config: {\n id: 'skill-manage',\n name: 'Skill Manager',\n role: 'skill-manage',\n tools: [...TOOLS.write],\n prompt: agentPrompt('skill-manage'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'meta',\n summary: 'Skill curation: audits, refines descriptions/triggers, scaffolds, and retires skills.',\n keywords: [\n 'skill',\n 'skills',\n 'curate skill',\n 'skill description',\n 'create skill',\n 'skill library',\n 'skill trigger',\n 'manage skills',\n ],\n },\n },\n {\n config: {\n id: 'self-improving',\n name: 'Self-Improving',\n role: 'self-improving',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('self-improving'),\n },\n budget: MEDIUM_BUDGET,\n capability: {\n phase: 'meta',\n summary: 'Learns from execution logs: mines recurring failures/inefficiencies and proposes evidence-based improvements.',\n keywords: [\n 'self-improving',\n 'learn from',\n 'session logs',\n 'execution analysis',\n 'recurring failure',\n 'improve agents',\n 'post-mortem',\n 'retrospective',\n 'meta-analysis',\n ],\n },\n },\n {\n config: {\n id: 'context',\n name: 'Context',\n role: 'context',\n tools: [...TOOLS.inspect, 'remember', 'forget'],\n prompt: agentPrompt('context'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'meta',\n summary: 'Memory + context-window management: compaction, recall, and curation within a token budget.',\n keywords: [\n 'context',\n 'context window',\n 'memory',\n 'compact',\n 'summarize history',\n 'recall',\n 'token budget',\n 'prune context',\n 'remember',\n 'dfmt',\n ],\n },\n },\n {\n config: {\n id: 'cost',\n name: 'Cost',\n role: 'cost',\n tools: [...TOOLS.inspect],\n prompt: agentPrompt('cost'),\n },\n budget: LIGHT_BUDGET,\n capability: {\n phase: 'meta',\n summary: 'Token/cloud cost optimization: finds spend waste, recommends model routing and trimming with $ estimates.',\n keywords: [\n 'cost',\n 'token cost',\n 'optimize cost',\n 'spend',\n 'cheaper',\n 'model routing',\n 'budget',\n 'expensive',\n 'reduce tokens',\n 'pricing',\n 'cloud cost',\n ],\n },\n },\n {\n config: {\n id: 'tech-stack',\n name: 'Tech Stack Validator',\n role: 'tech-stack',\n tools: ['search', 'fetch', 'read', 'grep', 'glob', 'outdated', 'audit', 'json', 'mailbox'],\n prompt: agentPrompt('tech-stack'),\n },\n budget: {\n timeoutMs: 120_000,\n maxIterations: 10,\n maxToolCalls: 40,\n maxTokens: 60_000,\n maxCostUsd: 0.25,\n },\n capability: {\n phase: 'meta',\n summary: 'Single-shot tech stack validator: checks npm for latest versions, rejects dead/obsolete packages, enforces modern alternatives.',\n keywords: [\n 'tech stack',\n 'version',\n 'package',\n 'library',\n 'framework',\n 'dependency',\n 'install',\n 'upgrade',\n 'latest',\n 'npm',\n 'pnpm add',\n 'outdated',\n 'obsolete',\n 'deprecated',\n 'what version',\n 'which package',\n 'check version',\n 'verify version',\n 'is this current',\n ],\n },\n },\n];\n", "/**\n * Agent catalog aggregator.\n *\n * Collects every phase's `AgentDefinition[]` into:\n * - `ALL_AGENT_DEFINITIONS` \u2014 flat list, catalog order (phase 1 \u2192 9)\n * - `AGENT_CATALOG` \u2014 keyed by role for O(1) lookup\n * - `AGENTS_BY_PHASE` \u2014 grouped for statusline / dispatcher tie-breaks\n *\n * `fleet.ts` derives `FLEET_ROSTER` + `FLEET_ROSTER_BUDGETS` from this, and the\n * dispatcher routes free-form tasks against `capability` metadata here.\n */\nimport type { AgentDefinition, AgentPhase } from './types.js';\nimport { DISCOVERY_AGENTS } from './phase1-discovery.js';\nimport { PLANNING_AGENTS } from './phase2-planning.js';\nimport { BUILD_AGENTS } from './phase3-build.js';\nimport { VERIFY_AGENTS } from './phase4-verify.js';\nimport { REVIEW_AGENTS } from './phase5-review.js';\nimport { DOMAIN_AGENTS } from './phase6-domain.js';\nimport { KNOWLEDGE_AGENTS } from './phase7-knowledge.js';\nimport { DELIVERY_AGENTS } from './phase8-delivery.js';\nimport { META_AGENTS } from './phase9-meta.js';\n\nexport * from './types.js';\nexport {\n DISCOVERY_AGENTS,\n PLANNING_AGENTS,\n BUILD_AGENTS,\n VERIFY_AGENTS,\n REVIEW_AGENTS,\n DOMAIN_AGENTS,\n KNOWLEDGE_AGENTS,\n DELIVERY_AGENTS,\n META_AGENTS,\n};\n\n/** Every catalog agent, in phase order. */\nexport const ALL_AGENT_DEFINITIONS: AgentDefinition[] = [\n ...DISCOVERY_AGENTS,\n ...PLANNING_AGENTS,\n ...BUILD_AGENTS,\n ...VERIFY_AGENTS,\n ...REVIEW_AGENTS,\n ...DOMAIN_AGENTS,\n ...KNOWLEDGE_AGENTS,\n ...DELIVERY_AGENTS,\n ...META_AGENTS,\n];\n\n/** Phase \u2192 its agents, for grouped display and dispatcher fallbacks. */\nexport const AGENTS_BY_PHASE: Record<AgentPhase, AgentDefinition[]> = {\n discovery: DISCOVERY_AGENTS,\n planning: PLANNING_AGENTS,\n build: BUILD_AGENTS,\n verify: VERIFY_AGENTS,\n review: REVIEW_AGENTS,\n domain: DOMAIN_AGENTS,\n knowledge: KNOWLEDGE_AGENTS,\n delivery: DELIVERY_AGENTS,\n meta: META_AGENTS,\n};\n\n/**\n * Role \u2192 definition. Built once at module load. Throws on a duplicate role so\n * a copy-paste collision fails loudly at startup instead of silently shadowing.\n */\nexport const AGENT_CATALOG: Record<string, AgentDefinition> = (() => {\n const map: Record<string, AgentDefinition> = {};\n for (const def of ALL_AGENT_DEFINITIONS) {\n const role = def.config.role;\n if (!role) {\n throw new Error(`Agent \"${def.config.name}\" is missing a role`);\n }\n if (map[role]) {\n throw new Error(`Duplicate agent role in catalog: \"${role}\"`);\n }\n map[role] = def;\n }\n return map;\n})();\n\n/** Role lookup helper. Returns undefined for unknown roles. */\nexport function getAgentDefinition(role: string): AgentDefinition | undefined {\n return AGENT_CATALOG[role];\n}\n", "/**\n * FallbackProfileManager \u2014 centralized, decoupled fallback profile resolution.\n *\n * Every consumer (fallback-model, council orchestrator, one-shot LLM, plugins)\n * resolves its fallback chain through this single manager instead of parsing\n * config.fallbackProfiles independently. This guarantees consistent resolution,\n * provider-health filtering, and a single reload point on config changes.\n *\n * Design:\n * - Stable service identity: `reload()` atomically replaces the manager's\n * immutable config/profile snapshot so injected consumers stay live.\n * - Immutable outputs: every resolved chain is frozen.\n * - Provider-aware: each profile entry is checked against live provider config\n * (has API key?) before inclusion.\n * - Zero coupling: consumers only see `readonly FallbackChainEntry[]` \u2014\n * no awareness of profile names, config shape, or provider internals.\n */\n\nimport type { ProviderModelStatusTracker } from '../coordination/provider-status-tracker.js';\nimport type { Config, ProviderConfig } from '../types/config.js';\nimport { parseModelRef } from './fallback-model.js';\nimport { evaluateModelCalendar } from './model-availability-calendar.js';\n\n// \u2500\u2500 Public types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** One resolved entry in a fallback chain. */\nexport interface FallbackChainEntry {\n /** Resolved provider id. */\n readonly providerId: string;\n /** Resolved model id. */\n readonly model: string;\n /** Whether this entry uses a different provider than the primary. */\n readonly providerSwitched: boolean;\n}\n\n/** Immutable fallback chain returned by the manager. */\nexport type FallbackChain = readonly FallbackChainEntry[];\n\n/**\n * Configuration-level provider health used while resolving fallback chains.\n *\n * This deliberately answers whether the runtime has enough configuration to\n * construct the provider; it does not perform a network probe. Keyless\n * self-hosted endpoints are usable when they declare a `baseUrl`.\n */\nexport interface ProviderHealth {\n readonly providerId: string;\n readonly hasKey: boolean;\n readonly hasEndpoint: boolean;\n readonly hasModels: boolean;\n readonly usable: boolean;\n}\n\n/** @deprecated Use {@link ProviderHealth}. */\nexport type ProviderAvailability = ProviderHealth;\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction hasText(value: unknown): value is string {\n return typeof value === 'string' && value.trim().length > 0;\n}\n\nfunction providerHasKey(entry: ProviderConfig | undefined): boolean {\n if (!entry) return false;\n if (hasText(entry.apiKey)) return true;\n if (Array.isArray(entry.apiKeys) && entry.apiKeys.some((k) => hasText(k?.apiKey))) return true;\n if (Array.isArray(entry.envVars) && entry.envVars.some((v) => hasText(process.env[v])))\n return true;\n return false;\n}\n\nfunction visibleProviderModels(\n config: Config,\n providerId: string,\n providerModels: string[],\n): string[] {\n const entry = config.providers?.[providerId];\n return entry?.models !== undefined ? [...entry.models] : providerModels;\n}\n\nfunction buildProfiles(config: Config): ReadonlyMap<string, readonly string[]> {\n const entries = new Map<string, readonly string[]>();\n for (const [name, chain] of Object.entries(config.fallbackProfiles ?? {})) {\n if (Array.isArray(chain) && chain.length > 0) {\n entries.set(name, Object.freeze([...chain]));\n }\n }\n return entries;\n}\n\n// \u2500\u2500 Manager \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class FallbackProfileManager {\n /** Immutable snapshot of config.fallbackProfiles for the active config. */\n private profiles: ReadonlyMap<string, readonly string[]>;\n /** Active frozen config snapshot for provider lookups. */\n private config: Config;\n /** Optional shared runtime status tracker. */\n private statusTracker: ProviderModelStatusTracker | undefined;\n\n constructor(config: Config, opts?: { statusTracker?: ProviderModelStatusTracker | undefined }) {\n this.config = config;\n this.profiles = buildProfiles(config);\n this.statusTracker = opts?.statusTracker;\n }\n\n /**\n * Bind (or replace) the shared runtime status tracker.\n * Called by the boot path after the tracker is created.\n */\n setStatusTracker(tracker: ProviderModelStatusTracker | undefined): void {\n this.statusTracker = tracker;\n }\n\n // \u2500\u2500 Profile existence \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n hasProfile(name: string): boolean {\n return this.profiles.has(name);\n }\n\n listProfiles(): readonly string[] {\n return Object.freeze([...this.profiles.keys()]);\n }\n\n // \u2500\u2500 Resolution \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Resolve a named fallback profile to a validated, provider-filtered chain.\n *\n * Returns an empty chain when:\n * - The profile doesn't exist.\n * - Every entry's provider is missing, has no key, or has no matching model.\n *\n * @param name - Profile name from config.fallbackProfiles.\n * @param defaultProvider - Used when an entry has no explicit provider.\n * @param exclude - Optional { providerId, model } to skip (avoid self-fallback).\n */\n resolve(\n name: string,\n opts: {\n defaultProvider?: string | undefined;\n exclude?: { providerId: string; model: string } | undefined;\n } = {},\n ): FallbackChain {\n const defaultProvider = opts.defaultProvider ?? this.config.provider;\n const chain = this.profiles.get(name);\n if (!chain) return FREEZER_EMPTY;\n\n const excludeKey = opts.exclude\n ? `${opts.exclude.providerId}/${opts.exclude.model}`\n : undefined;\n\n const resolved: FallbackChainEntry[] = [];\n const seen = new Set<string>();\n\n for (const ref of chain) {\n const parsed = parseModelRef(ref);\n if (!parsed.model) continue;\n\n const providerId = parsed.provider ?? defaultProvider;\n const key = `${providerId}/${parsed.model}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n // Skip self-reference\n if (excludeKey && key === excludeKey) continue;\n\n const health = this.checkProvider(providerId);\n if (!health.usable) continue;\n\n // Skip entries that are blocked by the runtime status tracker\n if (this.statusTracker && !this.statusTracker.isAvailable(providerId, parsed.model)) continue;\n if (\n !evaluateModelCalendar(this.config.modelAvailabilitySchedule, providerId, parsed.model)\n .allowed\n )\n continue;\n\n // Skip entries whose provider has no matching model in its allow-list\n // (provider may restrict which models are available).\n const allowedModels = this.config.providers?.[providerId]?.models;\n if (allowedModels && !allowedModels.includes(parsed.model)) continue;\n\n resolved.push({\n providerId,\n model: parsed.model,\n providerSwitched: providerId !== (opts.exclude?.providerId ?? this.config.provider),\n });\n }\n\n return Object.freeze(resolved);\n }\n\n /**\n * Resolve the effective fallback chain for a session: explicit fallbackModels\n * first, then named profile, then smart default (unless disabled).\n *\n * Mirrors the previous `effectiveFallbackChain()` logic but centralized.\n */\n resolveEffective(\n opts: {\n fallbackModels?: readonly string[] | undefined;\n fallbackProfile?: string | undefined;\n fallbackAuto?: boolean | undefined;\n exclude?: { providerId: string; model: string } | undefined;\n } = {},\n ): FallbackChain {\n // 1. Explicit fallbackModels (already resolved refs)\n // Only return if non-empty; empty chain falls through to next source.\n if (opts.fallbackModels && opts.fallbackModels.length > 0) {\n const resolved = this.resolveRefs(opts.fallbackModels, opts.exclude);\n if (resolved.length > 0) return resolved;\n }\n\n // 2. Named profile \u2014 only return if non-empty\n if (opts.fallbackProfile) {\n const resolved = this.resolve(opts.fallbackProfile, { exclude: opts.exclude });\n if (resolved.length > 0) return resolved;\n }\n\n // 3. Smart default\n if (opts.fallbackAuto !== false) {\n return this.smartDefault(opts.exclude);\n }\n\n return FREEZER_EMPTY;\n }\n\n // \u2500\u2500 Provider availability (read-only) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n checkProvider(providerId: string): ProviderHealth {\n const entry = this.config.providers?.[providerId];\n const isPrimary = providerId === this.config.provider;\n const hasKey = providerHasKey(entry) || (isPrimary && hasText(this.config.apiKey));\n const hasEndpoint = hasText(entry?.baseUrl) || (isPrimary && hasText(this.config.baseUrl));\n const hasModels =\n (Array.isArray(entry?.models) && entry.models.length > 0) ||\n (isPrimary && hasText(this.config.model));\n return Object.freeze({\n providerId,\n hasKey,\n hasEndpoint,\n hasModels,\n usable: hasKey || hasEndpoint,\n });\n }\n\n // \u2500\u2500 Rebuild on config change \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Atomically replace the active immutable snapshot while preserving this\n * service identity for every injected consumer.\n */\n reload(newConfig: Config): void {\n this.config = newConfig;\n this.profiles = buildProfiles(newConfig);\n }\n\n // \u2500\u2500 Internal helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Resolve an array of model ref strings (from explicit fallbackModels config).\n * Public so consumers like one-shot-llm can use it directly.\n */\n resolveRefs(\n refs: readonly string[],\n exclude?: { providerId: string; model: string },\n ): FallbackChain {\n const excludeKey = exclude ? `${exclude.providerId}/${exclude.model}` : undefined;\n const resolved: FallbackChainEntry[] = [];\n const seen = new Set<string>();\n\n for (const ref of refs) {\n const parsed = parseModelRef(ref);\n if (!parsed.model) continue;\n\n const providerId = parsed.provider ?? this.config.provider;\n const key = `${providerId}/${parsed.model}`;\n if (seen.has(key)) continue;\n seen.add(key);\n if (excludeKey && key === excludeKey) continue;\n\n // Skip entries blocked by the runtime status tracker\n if (this.statusTracker && !this.statusTracker.isAvailable(providerId, parsed.model)) continue;\n if (\n !evaluateModelCalendar(this.config.modelAvailabilitySchedule, providerId, parsed.model)\n .allowed\n )\n continue;\n\n resolved.push({\n providerId,\n model: parsed.model,\n providerSwitched: providerId !== (exclude?.providerId ?? this.config.provider),\n });\n }\n\n return Object.freeze(resolved);\n }\n\n /**\n * Derive a smart default chain from configured providers when nothing\n * explicit is set. Same-provider alternatives first, then cross-provider.\n * Limited to 4 entries to avoid burning through models on a transient blip.\n */\n private smartDefault(exclude?: { providerId: string; model: string }): FallbackChain {\n const leaderProvider = this.config.provider;\n const leaderModel = this.config.model;\n const providers = this.config.providers ?? {};\n const favoriteSet = new Set(\n (this.config.favoriteModels ?? []).map((ref) => {\n const p = parseModelRef(ref);\n return `${p.provider ?? leaderProvider}/${p.model}`;\n }),\n );\n const hasFavorites = favoriteSet.size > 0;\n const favoritesOnly = this.config.favoriteModelsOnly === true;\n const seen = new Set<string>();\n const favorites: string[] = [];\n const sameProvider: string[] = [];\n const crossProvider: string[] = [];\n\n const excludeKey = exclude ? `${exclude.providerId}/${exclude.model}` : undefined;\n\n const ids = Object.keys(providers).sort((a, b) =>\n a === leaderProvider ? -1 : b === leaderProvider ? 1 : a.localeCompare(b),\n );\n\n for (const id of ids) {\n const entry = providers[id];\n if (!this.checkProvider(id).usable) continue;\n // Skip the entire provider if it's blocked at the provider level\n // (all its models would be blocked too, but we check per-model below)\n const models = visibleProviderModels(this.config, id, entry?.models ?? []);\n for (const model of models) {\n if (id === leaderProvider && model === leaderModel) continue;\n const ref = `${id}/${model}`;\n if (seen.has(ref)) continue;\n seen.add(ref);\n if (excludeKey && ref === excludeKey) continue;\n // Skip models blocked by the runtime status tracker\n if (this.statusTracker && !this.statusTracker.isAvailable(id, model)) continue;\n if (!evaluateModelCalendar(this.config.modelAvailabilitySchedule, id, model).allowed)\n continue;\n if (favoriteSet.has(ref)) {\n favorites.push(ref);\n continue;\n }\n if (favoritesOnly && hasFavorites) continue;\n (id === leaderProvider ? sameProvider : crossProvider).push(ref);\n }\n }\n\n const MAX = 4;\n const all = [...favorites, ...sameProvider, ...crossProvider].slice(0, MAX);\n return Object.freeze(\n all.map((ref) => {\n const p = parseModelRef(ref);\n return {\n providerId: p.provider ?? leaderProvider,\n model: p.model,\n providerSwitched:\n (p.provider ?? leaderProvider) !== (exclude?.providerId ?? leaderProvider),\n } satisfies FallbackChainEntry;\n }),\n );\n }\n}\n\nconst FREEZER_EMPTY: FallbackChain = Object.freeze([]);\n", "/**\n * Cross-provider fallback model extension.\n *\n * Lives in core so EVERY agent surface can reuse it: the CLI leader, the CLI\n * director/host subagent factory, and the runtime light subagent factory (used\n * by standalone SDD runs). It wraps the provider runner and, when the active\n * model 429s / overloads / stream-hangs, rotates through a fallback chain. The\n * chain is recomputed from live config every turn, so changes take effect\n * without a restart; an empty chain makes the wrapper a no-op.\n *\n * Moved here from `@wrongstack/cli` (it only ever depended on core types) so the\n * runtime light factory can wire fallbacks for SDD worker subagents.\n */\n\nimport type { ProviderModelStatusTracker } from '../coordination/provider-status-tracker.js';\nimport type { AgentExtension } from '../extension/extension-points.js';\nimport type { EventBus } from '../kernel/events.js';\nimport { isTextBlock, isToolUseBlock } from '../types/blocks.js';\nimport type { Config } from '../types/config.js';\nimport type { Logger } from '../types/logger.js';\nimport {\n isFallbackWorthy,\n type Provider,\n ProviderError,\n type Response,\n} from '../types/provider.js';\nimport type { FallbackChain, FallbackChainEntry } from './fallback-profile-manager.js';\nimport { FallbackProfileManager } from './fallback-profile-manager.js';\nimport { evaluateModelCalendar, logicalCalendarTarget } from './model-availability-calendar.js';\n\nexport interface FallbackModelDeps {\n /** Returns the live config (re-read each turn so `/model` switches are honored). */\n getConfig: () => Config;\n /** Shared live manager from the runtime container. */\n fallbackProfileManager?: FallbackProfileManager | undefined;\n /** Live named profile selected for this worker (for example by `/setmodel`). */\n getFallbackProfile?: (() => string | undefined) | undefined;\n /** Live task/role-specific chain. Explicit task fallbacks may return a stable list. */\n getFallbackModels?: (() => readonly string[] | undefined) | undefined;\n /**\n * Builds a credential-resolved Provider for a provider id (alias-resolved),\n * WITHOUT persisting anything to config/configStore. Supplied by the boot\n * path, which shares this with the `/model` switch logic. May be async \u2014 the\n * subagent host resolves a provider's real context window asynchronously.\n */\n buildProvider: (providerId: string, modelId?: string | undefined) => Provider | Promise<Provider>;\n /**\n * Called after the active model changes (a fallback hop or the primary\n * restore) so the host can refresh the auto-compaction / context-window\n * denominator \u2014 important when a fallback crosses to a smaller-window model.\n */\n onModelSwitch?: (providerId: string, modelId: string) => void | Promise<void>;\n events: EventBus;\n /** Optional \u2014 warnings about un-buildable fallback providers. */\n logger?: Logger | undefined;\n /**\n * Base cooldown after the configured primary fails with a fallback-worthy\n * error. While active, `beforeRun` leaves the context on the working fallback\n * instead of retrying the primary at the start of every turn. Default: 60s.\n * Set 0 to preserve the legacy \"probe primary every turn\" behavior.\n */\n primaryCooldownMs?: number | undefined;\n /**\n * Maximum exponential cooldown for repeated failed primary probes. Default:\n * 10 minutes. Ignored when `primaryCooldownMs` is 0.\n */\n primaryCooldownMaxMs?: number | undefined;\n /** Test hook for deterministic cooldown assertions. */\n now?: (() => number) | undefined;\n /**\n * Shared provider/model status tracker. When set, the extension records\n * failures and successes in the tracker, and skips blocked entries in\n * the fallback chain.\n */\n statusTracker?: ProviderModelStatusTracker | undefined;\n}\n\ninterface ModelRef {\n provider?: string | undefined;\n model: string;\n}\n\n/** Parse a fallback entry: `model`, `provider/model`, or `provider model`. */\nexport function parseModelRef(ref: string): ModelRef {\n const trimmed = ref.trim();\n const slash = trimmed.indexOf('/');\n if (slash !== -1) {\n // An empty provider (leading slash, e.g. \"/gpt\") means \"use the primary\n // provider\" \u2014 collapse to undefined so the `?? cfg.provider` fallback fires.\n return {\n provider: trimmed.slice(0, slash) || undefined,\n model: trimmed.slice(slash + 1).trim(),\n };\n }\n const parts = trimmed.split(/\\s+/);\n if (parts.length >= 2) {\n return { provider: parts[0], model: parts.slice(1).join(' ') };\n }\n return { model: trimmed };\n}\n\nexport function formatModelRef(ref: ModelRef, defaultProvider?: string | undefined): string {\n const provider = ref.provider ?? defaultProvider;\n return provider ? `${provider}/${ref.model}` : ref.model;\n}\n\nexport function normalizeModelRef(ref: string, defaultProvider?: string | undefined): string {\n const parsed = parseModelRef(ref);\n return formatModelRef(parsed, defaultProvider);\n}\n\nexport function fallbackProfileChain(config: Config, profileName: string | undefined): string[] {\n if (!profileName) return [];\n const mgr = new FallbackProfileManager(config);\n return mgr.resolve(profileName).map((e) => `${e.providerId}/${e.model}`);\n}\n\n/**\n * Check if an error should trigger a fallback. Returns the status for\n * logging, or null if the error doesn't warrant a fallback attempt.\n *\n * Branches on the canonical `ProviderError.kind`: capacity/availability\n * failures (rate limit, overload, server error, stream hang, timeout,\n * network) are worth trying on another provider; request-shaped failures\n * (auth, invalid request, context overflow, content filter) would fail\n * identically anywhere \u2014 or need a different remedy (compaction, key fix) \u2014\n * so they surface instead.\n */\nfunction shouldFallback(err: unknown): number | null {\n if (!(err instanceof ProviderError)) return null;\n return isFallbackWorthy(err.kind) ? err.status : null;\n}\n\nfunction isUsableModelResponse(response: Response): boolean | undefined {\n if (!response?.content) return undefined;\n return response.content.some(\n (block) => isToolUseBlock(block) || (isTextBlock(block) && block.text.trim().length > 0),\n );\n}\n\nfunction ensureUsableModelResponse(\n response: Response,\n providerId: string,\n model: string,\n): Response {\n const usable = isUsableModelResponse(response);\n // undefined content means the caller didn't provide a content field (e.g. test mocks) \u2014 let it through\n if (usable !== false) return response;\n throw new ProviderError(\n `Empty response from ${providerId}/${model}; trying the next configured model`,\n 503,\n true,\n providerId,\n { kind: 'overloaded' },\n );\n}\n\nexport function smartDefaultFallbackChain(config: Config): string[] {\n const mgr = new FallbackProfileManager(config);\n return mgr.resolveEffective({ fallbackAuto: true }).map((e) => `${e.providerId}/${e.model}`);\n}\n\n/**\n * The effective fallback chain for a turn: the explicit `fallbackModels` list\n * when non-empty, otherwise the smart default (unless `fallbackAuto` is off).\n */\nexport function effectiveFallbackChain(config: Config): string[] {\n const mgr = new FallbackProfileManager(config);\n return mgr\n .resolveEffective({\n fallbackModels: config.fallbackModels,\n fallbackAuto: config.fallbackAuto,\n })\n .map((e) => `${e.providerId}/${e.model}`);\n}\n\nconst DEFAULT_PRIMARY_COOLDOWN_MS = 60_000;\nconst DEFAULT_PRIMARY_COOLDOWN_MAX_MS = 10 * 60_000;\n\nfunction sameTarget(\n a: { providerId: string; model: string } | undefined,\n b: { providerId: string; model: string },\n): boolean {\n return !!a && a.providerId === b.providerId && a.model === b.model;\n}\n\nfunction fallbackCandidates(\n config: Config,\n current: { providerId: string; model: string },\n opts: {\n fallbackModels?: readonly string[] | undefined;\n fallbackProfile?: string | undefined;\n sharedManager?: FallbackProfileManager | undefined;\n } = {},\n): FallbackChain {\n const mgr = opts.sharedManager ?? new FallbackProfileManager(config);\n const configuredPrimary = primaryTarget(config);\n const selectedChain = mgr.resolveEffective({\n fallbackModels: opts.fallbackModels ?? config.fallbackModels,\n fallbackProfile: opts.fallbackProfile,\n // A role/profile override is an ordered preference, not a closed world.\n // If every selected entry fails, keep deriving a route back to the known\n // session/default model and other configured providers.\n fallbackAuto: true,\n exclude: current,\n });\n const candidates: FallbackChainEntry[] = [];\n\n if (opts.fallbackProfile !== 'default') {\n candidates.push(...mgr.resolve('default', { exclude: current }));\n }\n\n // Always try the session's configured primary first when we're not already on it.\n if (!sameTarget(configuredPrimary, current)) {\n candidates.push({\n providerId: configuredPrimary.providerId,\n model: configuredPrimary.model,\n providerSwitched: configuredPrimary.providerId !== current.providerId,\n });\n }\n\n // Then try the role-selected or explicit chain.\n candidates.push(...selectedChain);\n\n // Finally try every other configured provider as a last resort.\n const smartDefaults = mgr.resolveEffective({ fallbackAuto: true, exclude: current });\n candidates.push(...smartDefaults);\n\n const seen = new Set<string>();\n return Object.freeze(\n candidates.filter((entry) => {\n const key = `${entry.providerId}/${entry.model}`;\n if (key === `${current.providerId}/${current.model}` || seen.has(key)) return false;\n seen.add(key);\n return true;\n }),\n );\n}\n\nconst primaryTarget = (cfg: Config) => ({ providerId: cfg.provider, model: cfg.model });\n\nfunction maxContextOf(provider: Provider): number {\n const max = provider.capabilities.maxContext;\n return typeof max === 'number' && Number.isFinite(max) ? max : 0;\n}\n\nfunction contextWindowWarning(\n currentProvider: Provider,\n nextProvider: Provider,\n currentTokens: unknown,\n):\n | { fromMaxContext: number; toMaxContext: number; currentTokens?: number | undefined }\n | undefined {\n const fromMaxContext = maxContextOf(currentProvider);\n const toMaxContext = maxContextOf(nextProvider);\n if (fromMaxContext <= 0 || toMaxContext <= 0 || toMaxContext >= fromMaxContext) return undefined;\n return {\n fromMaxContext,\n toMaxContext,\n ...(typeof currentTokens === 'number' && currentTokens > 0 ? { currentTokens } : {}),\n };\n}\n\n/**\n * Build the cross-provider fallback extension. Always returns an extension \u2014\n * the effective chain (`effectiveFallbackChain`) is recomputed every turn from\n * the live config, so a chain that is empty at boot but populated later (via\n * `/fallback add` or the smart default kicking in once a key is added) takes\n * effect WITHOUT a restart. An empty chain makes the wrapper a no-op (it just\n * rethrows the original error).\n *\n * Mechanism (see plan): wraps the provider runner. The inner runner already\n * applies the per-model retry policy (backoff, up to 5 tries for 429), so the\n * fallback only engages AFTER the active model's own retries are exhausted.\n * Because the wrapper resolves within a single provider call, it does not\n * consume the agent loop's `recoveryRetries` budget \u2014 chains longer than two\n * entries work. `beforeRun` keeps the last working fallback while the primary\n * is cooling down, then restores the configured primary for a half-open probe.\n */\nexport function createFallbackModelExtension(deps: FallbackModelDeps): AgentExtension {\n // True when a prior turn left the live context on a fallback model.\n let dirty = false;\n let primaryFailureStreak = 0;\n let blockedPrimary: { providerId: string; model: string } | undefined;\n let primaryBlockedUntil = 0;\n\n const now = () => deps.now?.() ?? Date.now();\n const cooldownBase = () => Math.max(0, deps.primaryCooldownMs ?? DEFAULT_PRIMARY_COOLDOWN_MS);\n const cooldownMax = () =>\n Math.max(cooldownBase(), deps.primaryCooldownMaxMs ?? DEFAULT_PRIMARY_COOLDOWN_MAX_MS);\n const primaryInCooldown = (cfg: Config) =>\n sameTarget(blockedPrimary, primaryTarget(cfg)) && now() < primaryBlockedUntil;\n\n const markPrimaryFailure = (cfg: Config) => {\n const primary = primaryTarget(cfg);\n primaryFailureStreak = sameTarget(blockedPrimary, primary) ? primaryFailureStreak + 1 : 1;\n blockedPrimary = primary;\n const base = cooldownBase();\n if (base <= 0) {\n primaryBlockedUntil = 0;\n return;\n }\n const multiplier = 2 ** Math.max(0, primaryFailureStreak - 1);\n primaryBlockedUntil = now() + Math.min(cooldownMax(), base * multiplier);\n };\n\n const resetPrimaryLadder = (cfg: Config) => {\n if (!sameTarget(blockedPrimary, primaryTarget(cfg))) return;\n primaryFailureStreak = 0;\n blockedPrimary = undefined;\n primaryBlockedUntil = 0;\n };\n\n return {\n name: 'fallback-model',\n\n beforeRun: async (ctx) => {\n if (!dirty) return;\n const cfg = deps.getConfig();\n if (primaryInCooldown(cfg)) return;\n if (\n !evaluateModelCalendar(cfg.modelAvailabilitySchedule, cfg.provider, cfg.model).allowed ||\n (deps.statusTracker && !deps.statusTracker.isAvailable(cfg.provider, cfg.model))\n )\n return;\n try {\n ctx.provider = await deps.buildProvider(cfg.provider, cfg.model);\n ctx.model = cfg.model;\n await deps.onModelSwitch?.(cfg.provider, cfg.model);\n // The next provider call is the half-open primary probe. If it\n // succeeds, the wrapper resets the ladder; if it fails, the catch path\n // marks a longer cooldown and rotates back through the chain.\n primaryBlockedUntil = 0;\n } catch (err) {\n deps.logger?.warn(\n `fallback-model: could not restore primary \"${cfg.provider}/${cfg.model}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n markPrimaryFailure(cfg);\n return;\n }\n dirty = false;\n },\n\n wrapProviderRunner: async (ctx, request, inner) => {\n // \u2500\u2500 Before calling, check if the current provider/model is blocked \u2500\u2500\n const tracker = deps.statusTracker;\n const calendar = evaluateModelCalendar(\n deps.getConfig().modelAvailabilitySchedule,\n ctx.provider.id,\n ctx.model,\n );\n const trackerBlocked = tracker ? !tracker.isAvailable(ctx.provider.id, ctx.model) : false;\n if (trackerBlocked || !calendar.allowed) {\n deps.logger?.warn(\n `provider-status: \"${ctx.provider.id}/${ctx.model}\" is blocked \u2014 trying fallback chain`,\n );\n // Emit active_blocked so the UI can surface a prominent warning\n const status = tracker?.getStatus(ctx.provider.id, ctx.model);\n const logical =\n tracker?.logicalIdentity(ctx.provider.id, ctx.model) ??\n logicalCalendarTarget(ctx.provider.id, ctx.model);\n deps.events.emit('provider.active_blocked', {\n providerId: logical.providerId,\n model: logical.model,\n state: 'blocked',\n fallbackProviderId: '',\n fallbackModel: '',\n lastError:\n calendar.rule?.label ??\n (calendar.rule ? 'Blocked by model availability calendar' : undefined) ??\n status?.lastErrorMessage ??\n 'Rate limit or repeated failures',\n sessionId: ctx.session?.id,\n timestamp: Date.now(),\n });\n // Skipping the blocked primary \u2014 simulate a fallback-worthy error\n const skipErr = new ProviderError(\n `Skipping unavailable \"${ctx.provider.id}/${ctx.model}\" \u2014 try fallback`,\n 429,\n true,\n ctx.provider.id,\n { kind: 'rate_limit' },\n );\n return runFallbackChain(ctx, request, inner, skipErr, true);\n }\n\n try {\n const response = ensureUsableModelResponse(\n await inner(ctx, request),\n ctx.provider.id,\n ctx.model,\n );\n // Record success in the tracker\n tracker?.recordSuccess(ctx.provider.id, ctx.model, {\n sessionId: ctx.session?.id,\n agentId: ctx.agentId,\n });\n const cfg = deps.getConfig();\n if (ctx.provider.id === cfg.provider && ctx.model === cfg.model) {\n resetPrimaryLadder(cfg);\n }\n return response;\n } catch (firstErr) {\n return runFallbackChain(ctx, request, inner, firstErr);\n }\n\n // \u2500\u2500 Shared fallback-chain runner with tracker integration \u2500\u2500\n async function runFallbackChain(\n ctx_: typeof ctx,\n request_: typeof request,\n inner_: typeof inner,\n firstErr_: unknown,\n alreadyTracked = false,\n ): Promise<Response> {\n let lastErr: unknown = firstErr_;\n const cfg = deps.getConfig();\n const current = { providerId: ctx_.provider.id, model: ctx_.model };\n\n // Record the failure in the tracker (real ProviderError, not our synthetic skip)\n if (!alreadyTracked && firstErr_ instanceof ProviderError && tracker) {\n tracker.recordFailure(\n ctx_.provider.id,\n ctx_.model,\n firstErr_.kind,\n firstErr_.status,\n firstErr_.describe(),\n {\n sessionId: ctx_.session?.id,\n agentId: ctx_.agentId,\n retryAfterMs: firstErr_.body?.retryAfterMs,\n },\n );\n }\n\n const chain = fallbackCandidates(cfg, current, {\n fallbackModels: deps.getFallbackModels?.(),\n fallbackProfile: deps.getFallbackProfile?.(),\n sharedManager: deps.fallbackProfileManager,\n });\n\n // Filter blocked entries from the chain via the tracker\n const usableChain = tracker\n ? chain.filter((e) => tracker.isAvailable(e.providerId, e.model))\n : chain;\n\n if (\n !alreadyTracked &&\n shouldFallback(firstErr_) !== null &&\n ctx_.provider.id === cfg.provider &&\n ctx_.model === cfg.model\n ) {\n markPrimaryFailure(cfg);\n }\n\n for (const entry of usableChain) {\n if (\n !evaluateModelCalendar(cfg.modelAvailabilitySchedule, entry.providerId, entry.model)\n .allowed\n )\n continue;\n const status = shouldFallback(lastErr);\n if (status === null) break; // not a fallback-worthy error\n\n // Re-check tracker availability right before attempting this entry.\n // The chain was computed from a snapshot of `isAvailable`, but an\n // intervening failure \u2014 from a concurrent subagent, a prior entry\n // in this loop, or a race with the one-shot LLM helper \u2014 may have\n // pushed this (providerId, model) into the waiting room since then.\n // A stale-chain call would waste time and burn rate-limit budget.\n if (tracker && !tracker.isAvailable(entry.providerId, entry.model)) {\n deps.logger?.warn(\n `provider-status: \"${entry.providerId}/${entry.model}\" entered the waiting room` +\n ` since the chain was computed \u2014 skipping`,\n );\n continue;\n }\n\n const targetProviderId = entry.providerId;\n const targetModel = entry.model;\n if (targetProviderId === ctx_.provider.id && targetModel === ctx_.model) continue;\n if (\n primaryInCooldown(cfg) &&\n targetProviderId === cfg.provider &&\n targetModel === cfg.model\n ) {\n continue;\n }\n\n const from = { providerId: ctx_.provider.id, model: ctx_.model };\n const logicalFrom = tracker?.logicalIdentity(from.providerId, from.model) ?? from;\n\n let nextProvider: Provider;\n try {\n nextProvider = await deps.buildProvider(targetProviderId, targetModel);\n } catch (err) {\n deps.logger?.warn(\n `fallback-model: skipping \"${targetProviderId}/${targetModel}\" \u2014 cannot build provider \"${targetProviderId}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n continue;\n }\n\n const providerSwitched = nextProvider.id !== from.providerId;\n const warning = contextWindowWarning(ctx_.provider, nextProvider, ctx_.lastRequestTokens);\n ctx_.provider = nextProvider;\n ctx_.model = targetModel;\n request_.model = targetModel;\n dirty = true;\n await deps.onModelSwitch?.(targetProviderId, targetModel);\n\n deps.events.emit('provider.fallback', {\n sessionId: ctx_.session?.id,\n from: logicalFrom,\n to: tracker?.logicalIdentity(nextProvider.id, targetModel) ?? {\n providerId: nextProvider.id,\n model: targetModel,\n },\n status,\n providerSwitched,\n ...(warning ? { contextWindowWarning: warning } : {}),\n });\n\n try {\n const response = ensureUsableModelResponse(\n await inner_(ctx_, request_),\n ctx_.provider.id,\n ctx_.model,\n );\n tracker?.recordSuccess(nextProvider.id, targetModel, {\n sessionId: ctx_.session?.id,\n agentId: ctx_.agentId,\n });\n return response;\n } catch (err) {\n // Record fallback failure too\n if (err instanceof ProviderError && tracker) {\n tracker.recordFailure(\n nextProvider.id,\n targetModel,\n err.kind,\n err.status,\n err.describe(),\n {\n sessionId: ctx_.session?.id,\n agentId: ctx_.agentId,\n retryAfterMs: err.body?.retryAfterMs,\n },\n );\n }\n lastErr = err;\n }\n }\n\n throw lastErr;\n }\n },\n };\n}\n", "/**\n * Per-task model matrix resolution.\n *\n * The matrix (Config.modelMatrix) maps a catalog **role**, a **phase** name, or\n * the `*` default to a {@link ModelMatrixEntry} (model + optional provider).\n * At subagent spawn time we resolve the most specific match so different task\n * types can run on different models \u2014 e.g. `security-scanner` on one model,\n * `documentation` on another \u2014 while the leader keeps its own model.\n *\n * Resolution precedence (most \u2192 least specific):\n * 1. exact role (matrix[\"security-scanner\"])\n * 2. the role's phase (matrix[\"review\"])\n * 3. the `*` default (matrix[\"*\"])\n * 4. undefined (caller falls back to the leader model)\n *\n * Set via the `/setmodel` slash command; this module is the single source of\n * truth both that command and the spawn path use to validate + resolve keys.\n */\n\nimport { fallbackProfileChain, parseModelRef } from '../core/fallback-model.js';\nimport type { Config, ModelMatrixEntry, ProviderConfig } from '../types/config.js';\nimport { AGENT_CATALOG, AGENTS_BY_PHASE } from './agents/index.js';\n\n/** All valid phase keys, in catalog order. */\nexport const MATRIX_PHASE_KEYS: readonly string[] = Object.keys(AGENTS_BY_PHASE);\n\n/** Role \u2192 phase lookup, built once from the catalog. */\nconst ROLE_TO_PHASE: Record<string, string> = (() => {\n const map: Record<string, string> = {};\n for (const [phase, defs] of Object.entries(AGENTS_BY_PHASE)) {\n for (const def of defs) {\n const role = def.config.role;\n if (role) map[role] = phase;\n }\n }\n return map;\n})();\n\n/** The phase a catalog role belongs to, or undefined for unknown roles. */\nexport function phaseForRole(role: string | undefined): string | undefined {\n return role ? ROLE_TO_PHASE[role] : undefined;\n}\n\nexport type ModelMatrixResolutionSource = 'role' | 'phase' | 'default';\n\nexport interface ModelMatrixResolution {\n entry: ModelMatrixEntry;\n source: ModelMatrixResolutionSource;\n key: string;\n}\n\n/**\n * Resolve the matrix entry plus the key tier it came from. Use this when the\n * caller needs to distinguish an explicit role/phase pin from the global `*`\n * default.\n */\nexport function resolveModelMatrixResolution(\n matrix: Record<string, ModelMatrixEntry> | undefined,\n role: string | undefined,\n): ModelMatrixResolution | undefined {\n if (!matrix) return undefined;\n if (role && matrix[role]) return { entry: matrix[role], source: 'role', key: role };\n const phase = phaseForRole(role);\n if (phase && matrix[phase]) return { entry: matrix[phase], source: 'phase', key: phase };\n if (matrix['*']) return { entry: matrix['*'], source: 'default', key: '*' };\n return undefined;\n}\n\n/**\n * Resolve the matrix entry for a subagent role. Returns the most specific\n * match (role \u2192 phase \u2192 `*`), or undefined when nothing matches.\n */\nexport function resolveModelMatrix(\n matrix: Record<string, ModelMatrixEntry> | undefined,\n role: string | undefined,\n): ModelMatrixEntry | undefined {\n return resolveModelMatrixResolution(matrix, role)?.entry;\n}\n\nexport interface ResolvedModelTarget {\n provider?: string | undefined;\n model?: string | undefined;\n modelRuntime?: Config['modelRuntime'] | undefined;\n fallbackModels?: string[] | undefined;\n fallbackProfile?: string | undefined;\n}\n\nexport interface ResolvedSubagentModelTarget extends ResolvedModelTarget {\n /** Where the concrete provider/model came from. */\n source: 'matrix' | 'diversity' | 'none';\n /** Matrix tier used before any reviewer diversity adjustment. */\n matrixSource?: ModelMatrixResolutionSource | undefined;\n /** True when a reviewer model was shifted away from the implementation model. */\n diversified?: boolean | undefined;\n}\n\n/**\n * Expand a matrix entry into a concrete primary model plus optional fallback\n * chain. A profile-only matrix entry treats the first profile model as primary\n * and the remaining profile entries as that subagent's fallback chain.\n */\nexport function resolveModelTargetFromEntry(\n config: Config,\n entry: ModelMatrixEntry | undefined,\n): ResolvedModelTarget | undefined {\n if (!entry) return undefined;\n if (entry.model) {\n return {\n provider: entry.provider,\n model: entry.model,\n modelRuntime: entry.modelRuntime,\n fallbackProfile: entry.fallbackProfile,\n fallbackModels: fallbackProfileChain(config, entry.fallbackProfile),\n };\n }\n const chain = fallbackProfileChain(config, entry.fallbackProfile);\n const first = chain[0];\n if (!first) {\n return entry.modelRuntime ? { modelRuntime: entry.modelRuntime } : undefined;\n }\n const parsed = parseModelRef(first);\n return {\n provider: parsed.provider,\n model: parsed.model,\n modelRuntime: entry.modelRuntime,\n fallbackProfile: entry.fallbackProfile,\n fallbackModels: chain.slice(1),\n };\n}\n\nexport interface ModelReference {\n provider?: string | undefined;\n model?: string | undefined;\n}\n\ninterface ConcreteModelReference {\n provider: string;\n model: string;\n}\n\n/**\n * Roles whose output is meant to challenge an implementer. When these roles\n * would otherwise use the same provider/model as the implementation path,\n * WrongStack tries to pick a different available model to reduce correlated\n * model-family mistakes. Exact role/phase `/setmodel` entries still win.\n */\nexport function roleNeedsIndependentReviewModel(role: string | undefined): boolean {\n if (!role) return false;\n return role === 'reviewer' || phaseForRole(role) === 'review';\n}\n\n/**\n * Resolve a subagent's matrix target with the reviewer diversity rule applied.\n *\n * Precedence:\n * 1. Exact role or phase matrix entry.\n * 2. Global `*` matrix entry when it is already different from the\n * implementation model.\n * 3. A different configured provider/model for review roles.\n * 4. The matrix/leader fallback.\n */\nexport function resolveSubagentModelTarget(\n config: Config,\n role: string | undefined,\n opts: { implementationTarget?: ModelReference | undefined } = {},\n): ResolvedSubagentModelTarget | undefined {\n const resolution = resolveModelMatrixResolution(config.modelMatrix, role);\n const matrixTarget = resolveModelTargetFromEntry(config, resolution?.entry);\n const implementationTarget =\n opts.implementationTarget ?? resolveImplementationModelTarget(config);\n\n if (!roleNeedsIndependentReviewModel(role)) {\n if (!matrixTarget) return undefined;\n return {\n ...matrixTarget,\n source: 'matrix',\n matrixSource: resolution?.source,\n };\n }\n\n const matrixRef = materializeTarget(config, matrixTarget);\n\n if (resolution?.source === 'role' || resolution?.source === 'phase') {\n return matrixTarget\n ? { ...matrixTarget, source: 'matrix', matrixSource: resolution.source }\n : undefined;\n }\n\n if (matrixRef && !sameModelReference(matrixRef, implementationTarget)) {\n return {\n ...(matrixTarget ?? {}),\n source: 'matrix',\n matrixSource: resolution?.source,\n };\n }\n\n const diverse = chooseDiverseModelTarget(config, implementationTarget);\n if (diverse) {\n return {\n provider: diverse.provider,\n model: diverse.model,\n modelRuntime: matrixTarget?.modelRuntime,\n fallbackModels: matrixTarget?.fallbackModels,\n fallbackProfile: matrixTarget?.fallbackProfile,\n source: 'diversity',\n matrixSource: resolution?.source,\n diversified: true,\n };\n }\n\n if (!matrixTarget) return undefined;\n return {\n ...matrixTarget,\n source: 'matrix',\n matrixSource: resolution?.source,\n };\n}\n\n/**\n * Resolve the default implementation lane. The generic Executor is the closest\n * stable proxy for \"the implementer\" when a reviewer is spawned without a\n * concrete sibling id.\n */\nexport function resolveImplementationModelTarget(config: Config): ModelReference {\n const target = resolveModelTargetFromEntry(\n config,\n resolveModelMatrix(config.modelMatrix, 'executor'),\n );\n return (\n materializeTarget(config, target) ?? {\n provider: config.provider,\n model: config.model,\n }\n );\n}\n\nexport function sameModelReference(\n a: ModelReference | undefined,\n b: ModelReference | undefined,\n): boolean {\n if (!a?.model || !b?.model) return false;\n const providerA = a.provider ?? '';\n const providerB = b.provider ?? '';\n return providerA === providerB && a.model === b.model;\n}\n\nfunction materializeTarget(\n config: Config,\n target: ResolvedModelTarget | undefined,\n): ModelReference | undefined {\n if (!target?.model) return undefined;\n return {\n provider: target.provider ?? config.provider,\n model: target.model,\n };\n}\n\nfunction chooseDiverseModelTarget(\n config: Config,\n avoid: ModelReference,\n): ConcreteModelReference | undefined {\n const candidates = collectConfiguredModelTargets(config).filter(\n (candidate) => !sameModelReference(candidate, avoid),\n );\n candidates.sort((a, b) => modelDiversityScore(b, avoid) - modelDiversityScore(a, avoid));\n return candidates[0];\n}\n\nfunction collectConfiguredModelTargets(config: Config): ConcreteModelReference[] {\n const seen = new Set<string>();\n const out: ConcreteModelReference[] = [];\n const add = (provider: string | undefined, model: string | undefined) => {\n if (!provider || !model) return;\n const key = `${provider}\\u0000${model}`;\n if (seen.has(key)) return;\n seen.add(key);\n out.push({ provider, model });\n };\n\n add(config.provider, config.model);\n for (const [providerId, provider] of Object.entries(config.providers ?? {})) {\n if (!isProviderAvailable(providerId, provider, config.provider)) continue;\n for (const model of provider.models ?? []) add(providerId, model);\n for (const model of Object.keys(provider.customModels ?? {})) add(providerId, model);\n }\n for (const model of Object.keys(config.models ?? {})) add(config.provider, model);\n return out;\n}\n\nfunction isProviderAvailable(\n providerId: string,\n provider: ProviderConfig,\n leaderProvider: string,\n): boolean {\n if (providerId === leaderProvider) return true;\n if (typeof provider.apiKey === 'string' && provider.apiKey.length > 0) return true;\n if (Array.isArray(provider.apiKeys) && provider.apiKeys.some((key) => key?.apiKey)) return true;\n if (typeof provider.baseUrl === 'string' && provider.baseUrl.length > 0) return true;\n return false;\n}\n\nfunction modelDiversityScore(candidate: ConcreteModelReference, avoid: ModelReference): number {\n let score = 0;\n if (candidate.provider !== avoid.provider) score += 100;\n if (candidate.model !== avoid.model) score += 20;\n if (/opus|gpt-5|o3|o4|gemini.*pro|deepseek-r1/i.test(candidate.model)) score += 10;\n if (/mini|haiku|flash/i.test(candidate.model)) score -= 5;\n return score;\n}\n\nexport type MatrixKeyKind = 'role' | 'phase' | 'default' | 'unknown';\n\n/** Classify a matrix key so `/setmodel` can reject typos before persisting. */\nexport function matrixKeyKind(key: string): MatrixKeyKind {\n if (key === '*') return 'default';\n if (key in AGENT_CATALOG) return 'role';\n if (MATRIX_PHASE_KEYS.includes(key)) return 'phase';\n return 'unknown';\n}\n\n/** True when `key` is a usable matrix key (role, phase, or `*`). */\nexport function isValidMatrixKey(key: string): boolean {\n return matrixKeyKind(key) !== 'unknown';\n}\n", "/**\n * LLM-accessible tools covering every provider/model/fallback configurable area\n * in the system: favorites, fallback chains & profiles, provider management,\n * API key handling, leader model, per-role model assignment, and system view.\n *\n * DESIGN: Every operation that accepts a provider/model reference validates\n * the entry against the user's `favoriteModels` list FIRST. This means all\n * fallback additions, profiles, and role assignments are restricted to\n * user-curated favorites \u2014 the LLM cannot add arbitrary unknown models.\n *\n * Exceptions:\n * - Removing entries (chain, profile, favorites) works on any existing entry.\n * - Listing/viewing works unconditionally.\n * - The active leader model itself is not restricted (it's already set).\n *\n * Tools (8 total):\n * favorite_manage \u2014 List, add, remove favorite models.\n * fallback_chain_manage \u2014 View, add, insert, remove, clear the active chain.\n * fallback_profile_manage \u2014 List, create/update, delete named profiles.\n * agent_model_assign \u2014 Assign model/profile to role/phase/* in the matrix.\n * provider_manage \u2014 List, add, configure, remove provider entries.\n * provider_key_set \u2014 Set API key via env var, direct key, or interactive prompt.\n * leader_model_set \u2014 View/set leader model, derive from profile, toggle settings.\n * system_config_view \u2014 Comprehensive view + validation doctor for full config.\n *\n * Usage from an agent:\n * ```\n * favorite_manage({ action: \"list\" })\n * favorite_manage({ action: \"add\", model: \"anthropic/claude-sonnet-4\" })\n * fallback_chain_manage({ action: \"add\", model: \"anthropic/claude-haiku-3\" })\n * fallback_profile_manage({ action: \"set\", name: \"fast\", chain: [\"openai/gpt-4o-mini\"] })\n * agent_model_assign({ role: \"security-scanner\", provider: \"anthropic\", model: \"claude-haiku-3\" })\n * provider_key_set({ provider: \"openai\", envVar: \"OPENAI_API_KEY\" })\n * leader_model_set({ action: \"show\" })\n * system_config_view({ section: \"all\" })\n * ```\n */\nimport type { Config } from '../types/config.js';\nimport type { Logger } from '../types/logger.js';\nimport type { JSONSchema, Tool } from '../types/tool.js';\nimport { AGENT_CATALOG } from '../coordination/agents/index.js';\nimport { isValidMatrixKey, phaseForRole, resolveSubagentModelTarget } from '../coordination/model-matrix.js';\nimport { normalizeModelRef } from '../core/fallback-model.js';\n\n// \u2500\u2500 Public types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const FAVORITE_MANAGE_TOOL_NAME = 'favorite_manage';\nexport const FALLBACK_CHAIN_MANAGE_TOOL_NAME = 'fallback_chain_manage';\nexport const FALLBACK_PROFILE_MANAGE_TOOL_NAME = 'fallback_profile_manage';\nexport const AGENT_MODEL_ASSIGN_TOOL_NAME = 'agent_model_assign';\n\nexport interface FallbackManageToolOptions {\n /** Returns the live config (re-read each call so changes are honored). */\n getConfig: () => Config;\n /**\n * Persist config mutations. Receives a mutator that receives the config\n * as a mutable JSON object \u2014 the tool sets the relevant fields and the\n * host writes back atomically + mirrors into the in-memory store.\n */\n updateConfig: (mutate: (cfg: Record<string, unknown>) => void) => Promise<void>;\n /**\n * Optional callback for requesting secure interactive input from the user.\n * When provided, tools like `provider_key_set` can use it to prompt the\n * user for secret values (API keys, tokens) without the value passing\n * through the LLM's context. The prompt string is shown to the user and\n * the returned string is the value they entered.\n *\n * When absent, `provider_key_set` returns a `needs_key` status and the\n * host is expected to handle it through other means (env var, CLI command).\n */\n requestInput?: ((prompt: string) => Promise<string>) | undefined;\n /** Optional logger for internal warnings. */\n logger?: Logger | undefined;\n}\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Canonicalize a model reference so equivalent spellings dedupe. */\nfunction normalizeRef(ref: string): string {\n return ref\n .trim()\n .replace(/\\s*\\/\\s*/g, '/')\n .replace(/\\s+/g, ' ');\n}\n\n/**\n * Validate that a model reference is in the user's favorites list (or that\n * favorites are not enforced). Returns `true` when the ref is valid.\n */\nfunction isFavoriteRef(ref: string, config: Config): boolean {\n const favorites = config.favoriteModels ?? [];\n if (favorites.length === 0) {\n // No favorites at all means the constraint is not active \u2014 allow anything\n return true;\n }\n const canonical = normalizeModelRef(ref, config.provider);\n return favorites.some((f) => normalizeModelRef(f, config.provider) === canonical);\n}\n\n/** Build a human-friendly error listing provider/model favorites. */\nfunction notFavoriteError(ref: string, config: Config): string {\n const favorites = config.favoriteModels ?? [];\n return (\n `\"${ref}\" is not in your favorites list. ` +\n (favorites.length === 0\n ? 'Add some favorites first with favorite_manage({ action: \"add\", model: \"<provider/model>\" }).'\n : `Current favorites: ${favorites.join(', ') || '(none)'}. ` +\n 'Use favorite_manage to add this model first.')\n );\n}\n\nfunction modelList(config: Config): string[] {\n return config.favoriteModels ?? [];\n}\n\nfunction profileList(config: Config): Record<string, string[]> {\n return (config.fallbackProfiles ?? {}) as Record<string, string[]>;\n}\n\nfunction chainList(config: Config): string[] {\n return config.fallbackModels ?? [];\n}\n\n// \u2500\u2500 1. FAVORITE_MANAGE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst FAVORITE_MANAGE_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'add', 'remove'],\n description: 'Operation to perform: list (show all), add (add a favorite), remove (remove by index or ref).',\n },\n model: {\n type: 'string',\n description:\n 'Model reference to add/remove (e.g. \"anthropic/claude-haiku-3\", \"openai/gpt-4o-mini\"). ' +\n 'Required for \"add\" and \"remove\" (when removing by ref).',\n },\n index: {\n type: 'number',\n description: '1-based index for removal. Alternative to `model`. Used when action=\"remove\".',\n },\n },\n required: ['action'],\n additionalProperties: false,\n};\n\ninterface FavoriteManageInput {\n action: 'list' | 'add' | 'remove';\n model?: string | undefined;\n index?: number | undefined;\n}\n\ninterface FavoriteManageOutput {\n status: 'ok' | 'error';\n message: string;\n favorites?: string[];\n}\n\nfunction createFavoriteManageTool(opts: FallbackManageToolOptions): Tool<FavoriteManageInput, FavoriteManageOutput> {\n return {\n name: FAVORITE_MANAGE_TOOL_NAME,\n description:\n 'Manage your favorite provider/model list. Favorites are the only models ' +\n 'that can be added to fallback chains and profiles. The LLM uses this tool ' +\n 'to curate which models are available for fallback and role assignment.',\n usageHint: 'Start with \"list\" to see current favorites. Use \"add <provider/model>\" to add. Use \"remove <index|ref>\" to remove.',\n category: 'Config',\n inputSchema: FAVORITE_MANAGE_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const favorites = [...modelList(config)];\n\n if (input.action === 'list') {\n const msg =\n favorites.length === 0\n ? 'No favorites set. Add one with favorite_manage({ action: \"add\", model: \"<provider/model>\" }).'\n : `Favorites (${favorites.length}):\\n` + favorites.map((f, i) => ` ${i + 1}. ${f}`).join('\\n');\n return { status: 'ok', message: msg, favorites: [...favorites] };\n }\n\n if (input.action === 'add') {\n if (!input.model) {\n return { status: 'error', message: 'Provide \"model\" (e.g. \"anthropic/claude-haiku-3\") to add a favorite.' };\n }\n const ref = normalizeRef(input.model);\n const canonical = normalizeModelRef(ref, config.provider);\n if (favorites.some((f) => normalizeModelRef(f, config.provider) === canonical)) {\n return { status: 'error', message: `\"${ref}\" is already a favorite.` };\n }\n favorites.push(ref);\n await opts.updateConfig((cfg) => {\n cfg.favoriteModels = favorites;\n });\n return {\n status: 'ok',\n message: `\u2713 Added favorite: ${ref} (${favorites.length} total)`,\n favorites: [...favorites],\n };\n }\n\n if (input.action === 'remove') {\n if (input.index !== undefined) {\n const idx = input.index - 1;\n if (idx < 0 || idx >= favorites.length) {\n return { status: 'error', message: `Index ${input.index} is out of range (1\u2013${favorites.length}).` };\n }\n const [removed] = favorites.splice(idx, 1);\n await opts.updateConfig((cfg) => {\n cfg.favoriteModels = favorites;\n });\n return { status: 'ok', message: `\u2713 Removed favorite: ${removed}`, favorites: [...favorites] };\n }\n if (input.model) {\n const ref = normalizeRef(input.model);\n const canonical = normalizeModelRef(ref, config.provider);\n const idx = favorites.findIndex((f) => normalizeModelRef(f, config.provider) === canonical);\n if (idx === -1) {\n return { status: 'error', message: `Favorite \"${ref}\" not found. Use \"list\" to see all favorites.` };\n }\n const [removed] = favorites.splice(idx, 1);\n await opts.updateConfig((cfg) => {\n cfg.favoriteModels = favorites;\n });\n return { status: 'ok', message: `\u2713 Removed favorite: ${removed}`, favorites: [...favorites] };\n }\n return { status: 'error', message: 'Provide either \"model\" or \"index\" to remove a favorite.' };\n }\n\n return { status: 'error', message: `Unknown action: \"${input.action}\". Use \"list\", \"add\", or \"remove\".` };\n },\n };\n}\n\n// \u2500\u2500 2. FALLBACK_CHAIN_MANAGE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst FALLBACK_CHAIN_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'add', 'insert', 'remove', 'clear'],\n description:\n 'Operation: list (show chain), add (append), insert (insert at position), ' +\n 'remove (by index or ref), clear (empty the chain).',\n },\n model: {\n type: 'string',\n description:\n 'Model reference for add/insert/remove (e.g. \"anthropic/claude-haiku-3\"). ' +\n 'Must be in your favorites list for add/insert. Required for add, insert, and remove (when removing by ref).',\n },\n index: {\n type: 'number',\n description:\n '1-based insertion position (for action=\"insert\") or removal index (for action=\"remove\"). ' +\n 'For insert: the new entry is placed before this position. Omit to append. ' +\n 'For remove: alternative to model. Omit to remove by model ref.',\n },\n },\n required: ['action'],\n additionalProperties: false,\n};\n\ninterface FallbackChainInput {\n action: 'list' | 'add' | 'insert' | 'remove' | 'clear';\n model?: string | undefined;\n index?: number | undefined;\n}\n\ninterface FallbackChainOutput {\n status: 'ok' | 'error';\n message: string;\n chain?: string[];\n}\n\nfunction createFallbackChainManageTool(opts: FallbackManageToolOptions): Tool<FallbackChainInput, FallbackChainOutput> {\n return {\n name: FALLBACK_CHAIN_MANAGE_TOOL_NAME,\n description:\n 'View or change the active rate-limit fallback chain. When the primary model ' +\n 'is overloaded (429/5xx), the agent rotates through this chain in order. ' +\n 'Every new entry must be a FAVORITE model \u2014 add it via favorite_manage first. ' +\n 'Use insert to place a fallback at a specific position; use remove to delete an entry.',\n usageHint:\n '\"list\" to see the current chain. \"add\" with a favorite model to append. ' +\n '\"insert\" with an index (1-based) to place before that position. ' +\n '\"remove\" with index or model ref. \"clear\" to empty the chain (auto fallback takes over).',\n category: 'Config',\n inputSchema: FALLBACK_CHAIN_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const chain = [...chainList(config)];\n\n if (input.action === 'list') {\n if (chain.length === 0) {\n return {\n status: 'ok',\n message: 'Fallback chain is empty. Add entries with \"add\" or enable auto fallback.',\n chain: [],\n };\n }\n const msg = chain.map((ref, i) => ` ${i + 1}. ${ref}`).join('\\n');\n return { status: 'ok', message: `Fallback chain (${chain.length}):\\n${msg}`, chain: [...chain] };\n }\n\n if (input.action === 'add') {\n if (!input.model) {\n return { status: 'error', message: 'Provide \"model\" (e.g. \"anthropic/claude-haiku-3\") to add to the chain.' };\n }\n const ref = normalizeRef(input.model);\n if (!isFavoriteRef(ref, config)) {\n return { status: 'error', message: notFavoriteError(ref, config) };\n }\n if (chain.some((e) => normalizeRef(e) === ref)) {\n return { status: 'error', message: `\"${ref}\" is already in the chain.` };\n }\n chain.push(ref);\n await opts.updateConfig((cfg) => {\n cfg.fallbackModels = chain;\n });\n return {\n status: 'ok',\n message: `\u2713 Added to chain: ${ref} (position ${chain.length})`,\n chain: [...chain],\n };\n }\n\n if (input.action === 'insert') {\n if (!input.model) {\n return { status: 'error', message: 'Provide \"model\" to insert into the chain.' };\n }\n const ref = normalizeRef(input.model);\n if (!isFavoriteRef(ref, config)) {\n return { status: 'error', message: notFavoriteError(ref, config) };\n }\n if (chain.some((e) => normalizeRef(e) === ref)) {\n return { status: 'error', message: `\"${ref}\" is already in the chain.` };\n }\n let pos = chain.length; // default: append\n if (input.index !== undefined) {\n pos = Math.max(0, Math.min(chain.length, input.index - 1));\n }\n chain.splice(pos, 0, ref);\n await opts.updateConfig((cfg) => {\n cfg.fallbackModels = chain;\n });\n return {\n status: 'ok',\n message: `\u2713 Inserted at position ${pos + 1}: ${ref}`,\n chain: [...chain],\n };\n }\n\n if (input.action === 'remove') {\n if (chain.length === 0) {\n return { status: 'error', message: 'Chain is empty \u2014 nothing to remove.' };\n }\n if (input.index !== undefined) {\n const idx = input.index - 1;\n if (idx < 0 || idx >= chain.length) {\n return { status: 'error', message: `Index ${input.index} is out of range (1\u2013${chain.length}).` };\n }\n const [removed] = chain.splice(idx, 1);\n await opts.updateConfig((cfg) => {\n cfg.fallbackModels = chain;\n });\n return { status: 'ok', message: `\u2713 Removed: ${removed}`, chain: [...chain] };\n }\n if (input.model) {\n const ref = normalizeRef(input.model);\n const idx = chain.findIndex((e) => normalizeRef(e) === ref);\n if (idx === -1) {\n return { status: 'error', message: `\"${ref}\" not found in chain.` };\n }\n const [removed] = chain.splice(idx, 1);\n await opts.updateConfig((cfg) => {\n cfg.fallbackModels = chain;\n });\n return { status: 'ok', message: `\u2713 Removed: ${removed}`, chain: [...chain] };\n }\n return { status: 'error', message: 'Provide \"index\" or \"model\" to remove from the chain.' };\n }\n\n if (input.action === 'clear') {\n if (chain.length === 0) {\n return { status: 'ok', message: 'Chain is already empty.' };\n }\n await opts.updateConfig((cfg) => {\n cfg.fallbackModels = [];\n });\n return { status: 'ok', message: '\u2713 Cleared the fallback chain. Auto fallback will take over when enabled.' };\n }\n\n return { status: 'error', message: `Unknown action: \"${input.action}\".` };\n },\n };\n}\n\n// \u2500\u2500 3. FALLBACK_PROFILE_MANAGE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst FALLBACK_PROFILE_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'set', 'delete'],\n description: 'Operation: list (show all profiles), set (create/update), delete (remove a profile).',\n },\n name: {\n type: 'string',\n description:\n 'Profile name (e.g. \"fast\", \"economy\", \"reliable\"). Required for \"set\" and \"delete\".',\n },\n chain: {\n type: 'array',\n items: { type: 'string' },\n description:\n 'Ordered list of model references for the profile. ' +\n 'Each entry must be a favorite model. Required for \"set\". Example: [\"anthropic/claude-haiku-3\", \"openai/gpt-4o-mini\"].',\n },\n },\n required: ['action'],\n additionalProperties: false,\n};\n\ninterface FallbackProfileInput {\n action: 'list' | 'set' | 'delete';\n name?: string | undefined;\n chain?: string[] | undefined;\n}\n\ninterface FallbackProfileOutput {\n status: 'ok' | 'error';\n message: string;\n profiles?: Record<string, string[]>;\n}\n\nfunction createFallbackProfileManageTool(opts: FallbackManageToolOptions): Tool<FallbackProfileInput, FallbackProfileOutput> {\n return {\n name: FALLBACK_PROFILE_MANAGE_TOOL_NAME,\n description:\n 'Manage named fallback profiles. A profile is a reusable, ordered list of ' +\n 'model references that can be assigned to agent roles. Every entry in a profile ' +\n 'must be a FAVORITE model \u2014 add it via favorite_manage first. ' +\n 'Use /setmodel or agent_model_assign to assign a profile to a role.',\n usageHint:\n '\"list\" to see all profiles. ' +\n '\"set\" with name and chain (array of model refs) to create or replace a profile. ' +\n '\"delete\" with name to remove a profile.',\n category: 'Config',\n inputSchema: FALLBACK_PROFILE_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const profiles = { ...profileList(config) };\n\n if (input.action === 'list') {\n const names = Object.keys(profiles);\n if (names.length === 0) {\n return {\n status: 'ok',\n message: 'No fallback profiles. Create one with \"set\".',\n profiles: {},\n };\n }\n const msg = names\n .sort()\n .map((name) => ` ${name} \u2192 ${profiles[name]?.join(' \u2192 ') || '(empty)'}`)\n .join('\\n');\n return { status: 'ok', message: `Fallback profiles:\\n${msg}`, profiles: { ...profiles } };\n }\n\n if (input.action === 'set') {\n if (!input.name) {\n return { status: 'error', message: 'Provide \"name\" for the profile (e.g. \"fast\").' };\n }\n if (!input.chain || input.chain.length === 0) {\n return { status: 'error', message: 'Provide \"chain\" \u2014 a non-empty array of model references.' };\n }\n // Validate every entry against favorites\n const invalid: string[] = [];\n for (const ref of input.chain) {\n if (!isFavoriteRef(ref, config)) {\n invalid.push(ref);\n }\n }\n if (invalid.length > 0) {\n return {\n status: 'error',\n message:\n `The following entries are not in your favorites list:\\n ${invalid.join('\\n ')}\\n\\n` +\n 'Add them first with favorite_manage({ action: \"add\", model: \"<ref>\" }).',\n };\n }\n profiles[input.name] = [...input.chain];\n await opts.updateConfig((cfg) => {\n cfg.fallbackProfiles = profiles;\n });\n return {\n status: 'ok',\n message: `\u2713 Profile \"${input.name}\" \u2192 ${input.chain.join(' \u2192 ')}`,\n profiles: { ...profiles },\n };\n }\n\n if (input.action === 'delete') {\n if (!input.name) {\n return { status: 'error', message: 'Provide \"name\" of the profile to delete.' };\n }\n if (!(input.name in profiles)) {\n return { status: 'error', message: `Profile \"${input.name}\" not found.` };\n }\n delete profiles[input.name];\n await opts.updateConfig((cfg) => {\n cfg.fallbackProfiles = profiles;\n });\n return {\n status: 'ok',\n message: `\u2713 Deleted profile: ${input.name}`,\n profiles: { ...profiles },\n };\n }\n\n return { status: 'error', message: `Unknown action: \"${input.action}\".` };\n },\n };\n}\n\n// \u2500\u2500 4. AGENT_MODEL_ASSIGN \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst AGENT_MODEL_ASSIGN_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n role: {\n type: 'string',\n description:\n 'Matrix key: a catalog role (e.g. \"security-scanner\", \"bug-hunter\"), a phase ' +\n 'name (e.g. \"review\", \"implementation\"), or \"*\" for the fleet-wide default.',\n },\n provider: {\n type: 'string',\n description:\n 'Provider id (e.g. \"anthropic\", \"openai\"). When omitted, the leader provider is used. ' +\n 'The provider.model combination must be in your favorites list.',\n },\n model: {\n type: 'string',\n description:\n 'Model id (e.g. \"claude-haiku-3\", \"gpt-4o-mini\"). When omitted together with provider, ' +\n 'the role falls back to the leader model. Must be in your favorites list.',\n },\n profile: {\n type: 'string',\n description:\n 'Named fallback profile to assign (e.g. \"fast\", \"economy\"). Alternative to provider+model. ' +\n 'When set, the first profile entry becomes the primary model and the rest are the fallback chain.',\n },\n clear: {\n type: 'boolean',\n description:\n 'Set to true to remove the matrix entry for this role (it will fall through to phase/*/leader).',\n },\n },\n // Flattened from a top-level oneOf \u2014 Anthropic-family endpoints reject\n // top-level combinators (omniroute 400: \"input_schema does not support\n // oneOf, allOf, or anyOf at the top level\"). Combination rules are\n // enforced in the handler instead.\n required: ['role'],\n additionalProperties: false,\n};\n\ninterface AgentModelAssignInput {\n role: string;\n provider?: string | undefined;\n model?: string | undefined;\n profile?: string | undefined;\n clear?: boolean | undefined;\n}\n\ninterface AgentModelAssignOutput {\n status: 'ok' | 'error';\n message: string;\n role?: string;\n}\n\nfunction createAgentModelAssignTool(opts: FallbackManageToolOptions): Tool<AgentModelAssignInput, AgentModelAssignOutput> {\n return {\n name: AGENT_MODEL_ASSIGN_TOOL_NAME,\n description:\n 'Assign a provider/model or a fallback profile to a specific agent role, phase, ' +\n 'or the fleet-wide default. This is the LLM-accessible equivalent of /setmodel set. ' +\n 'The provider+model combination must be in your favorites list (unless only clearing). ' +\n 'Resolution precedence: exact role \u2192 phase \u2192 * \u2192 leader model.',\n usageHint:\n 'Use \"list\" as role to see current assignments. ' +\n 'Set with role + model, or role + provider + model, or role + profile. ' +\n 'Set role + clear=true to remove a matrix entry. ' +\n 'The provider/model must be a favorite.',\n category: 'Config',\n inputSchema: AGENT_MODEL_ASSIGN_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n\n // Reject conflicting combination rules \u2014 only one mode at a time\n const modes = [input.clear ? 'clear' : null, input.profile ? 'profile' : null, input.model ? 'model' : null].filter(Boolean);\n if (modes.length > 1) {\n return {\n status: 'error',\n message: `Conflicting assignment modes: ${modes.join(' + ')}. ` +\n 'Use exactly one: clear=true, profile=\"name\", or model=\"name\" (optionally with provider).',\n };\n }\n\n // Special case: \"list\" role shows current matrix\n if (input.role === 'list') {\n const matrix = (config.modelMatrix ?? {}) as Record<string, unknown>;\n const keys = Object.keys(matrix);\n if (keys.length === 0) {\n return { status: 'ok', message: 'No matrix assignments. All roles use the leader model.' };\n }\n const msg = keys.sort().map((k) => ` ${k} \u2192 ${JSON.stringify(matrix[k])}`).join('\\n');\n return { status: 'ok', message: `Model matrix (${keys.length} entries):\\n${msg}` };\n }\n\n // Validate key\n if (!isValidMatrixKey(input.role)) {\n return {\n status: 'error',\n message:\n `\"${input.role}\" is not a valid matrix key. Use a catalog role (e.g. \"security-scanner\"), ` +\n 'a phase (e.g. \"review\"), or \"*\" for the fleet-wide default.',\n };\n }\n\n // Clear entry\n if (input.clear) {\n const matrix = { ...((config.modelMatrix ?? {}) as Record<string, unknown>) };\n if (!(input.role in matrix)) {\n return { status: 'ok', message: `No matrix entry for \"${input.role}\" to clear.` };\n }\n delete matrix[input.role];\n await opts.updateConfig((cfg) => {\n cfg.modelMatrix = matrix;\n });\n return { status: 'ok', message: `\u2713 Cleared matrix entry for \"${input.role}\".` };\n }\n\n // Show current assignment for this role\n if (!input.model && !input.profile && !input.provider) {\n const matrix = (config.modelMatrix ?? {}) as Record<string, unknown>;\n const entry = matrix[input.role];\n if (!entry) {\n return { status: 'ok', message: `No specific assignment for \"${input.role}\". It uses the leader model or phase/* fallback.` };\n }\n return { status: 'ok', message: `\"${input.role}\" \u2192 ${JSON.stringify(entry)}` };\n }\n\n // Assign profile (no model required)\n if (input.profile && !input.model) {\n const profiles = profileList(config);\n if (!profiles[input.profile]) {\n return { status: 'error', message: `Profile \"${input.profile}\" not found. Create it with fallback_profile_manage first.` };\n }\n const matrix = { ...((config.modelMatrix ?? {}) as Record<string, unknown>) };\n matrix[input.role] = { fallbackProfile: input.profile };\n await opts.updateConfig((cfg) => {\n cfg.modelMatrix = matrix;\n });\n return { status: 'ok', message: `\u2713 \"${input.role}\" \u2192 profile: ${input.profile}` };\n }\n\n // Assign provider+model (must be a favorite)\n if (input.model) {\n const effectiveProvider = input.provider ?? config.provider;\n const ref = `${effectiveProvider}/${input.model}`;\n if (!isFavoriteRef(ref, config)) {\n return { status: 'error', message: notFavoriteError(ref, config) };\n }\n const matrix = { ...((config.modelMatrix ?? {}) as Record<string, unknown>) };\n const previousRuntime = (matrix[input.role] as Record<string, unknown>)?.modelRuntime;\n matrix[input.role] = input.provider\n ? { provider: input.provider, model: input.model, ...(previousRuntime ? { modelRuntime: previousRuntime } : {}) }\n : { model: input.model, ...(previousRuntime ? { modelRuntime: previousRuntime } : {}) };\n await opts.updateConfig((cfg) => {\n cfg.modelMatrix = matrix;\n });\n const display = input.provider ? `${input.provider}/${input.model}` : `${input.model} (leader provider)`;\n return { status: 'ok', message: `\u2713 \"${input.role}\" \u2192 ${display}` };\n }\n\n return { status: 'error', message: 'Provide model, profile, or clear=true for the role assignment.' };\n },\n };\n}\n\n// \u2500\u2500 5. Factory \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// \u2500\u2500 5. PROVIDER_MANAGE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const PROVIDER_MANAGE_TOOL_NAME = 'provider_manage';\n\nconst PROVIDER_MANAGE_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'add', 'configure', 'remove'],\n description:\n 'Operation: list (show all providers), add (add a new provider config), ' +\n 'configure (update fields of an existing provider), remove (delete a provider config).',\n },\n provider: {\n type: 'string',\n description: 'Provider id (e.g. \"openai\", \"anthropic\"). Required for all actions except list.',\n },\n type: {\n type: 'string',\n description: 'Provider type (e.g. \"openai\", \"anthropic\"). Required for \"add\".',\n },\n models: {\n type: 'array',\n items: { type: 'string' },\n description:\n 'Model list to restrict visibility for this provider. Optional for add/configure.',\n },\n baseUrl: {\n type: 'string',\n description: 'Custom base URL (e.g. for self-hosted endpoints). Optional.',\n },\n family: {\n type: 'string',\n description:\n 'Wire-family override (e.g. \"openai\", \"openai-compatible\", \"anthropic\"). ' +\n 'When set, the provider can be constructed without a catalog entry.',\n },\n envVars: {\n type: 'array',\n items: { type: 'string' },\n description: 'Custom env var names to probe when apiKey is missing. Optional.',\n },\n autoDiscoverModels: {\n type: 'boolean',\n description: 'Auto-fetch model list from {baseUrl}/models. Optional.',\n },\n apiKey: {\n type: 'string',\n description:\n '**NOT RECOMMENDED** \u2014 use provider_key_set instead. ' +\n 'The LLM output may contain this value; use env var references for safety.',\n },\n },\n required: ['action'],\n additionalProperties: false,\n};\n\ninterface ProviderManageInput {\n action: 'list' | 'add' | 'configure' | 'remove';\n provider?: string | undefined;\n type?: string | undefined;\n models?: string[] | undefined;\n baseUrl?: string | undefined;\n family?: string | undefined;\n envVars?: string[] | undefined;\n autoDiscoverModels?: boolean | undefined;\n apiKey?: string | undefined;\n}\n\ninterface ProviderManageOutput {\n status: 'ok' | 'error';\n message: string;\n providers?: string[];\n}\n\nfunction createProviderManageTool(opts: FallbackManageToolOptions): Tool<ProviderManageInput, ProviderManageOutput> {\n return {\n name: PROVIDER_MANAGE_TOOL_NAME,\n description:\n 'View or configure provider entries. List all configured providers with their ' +\n 'type, model lists, base URL, and key status. Add new providers, update their ' +\n 'settings, or remove unused ones. API keys should be set via provider_key_set ' +\n 'instead of passing them here \u2014 they are visible in the LLM output.',\n usageHint:\n '\"list\" to see all providers. \"add\" with provider id and type to create. ' +\n '\"configure\" to update models, baseUrl, family, or envVars. ' +\n '\"remove\" to delete a provider. Use provider_key_set for API key management.',\n category: 'Config',\n inputSchema: PROVIDER_MANAGE_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const providers = {\n ...((config.providers ?? {}) as unknown as Record<string, Record<string, unknown>>),\n };\n const leaderProvider: string = config.provider ?? '';\n\n if (input.action === 'list') {\n const ids = Object.keys(providers);\n if (ids.length === 0) {\n return { status: 'ok', message: 'No providers configured.', providers: [] };\n }\n const msg = ids.sort().map((id) => {\n const entry = providers[id] ?? {};\n const type = (entry.type as string) ?? '(unknown)';\n const models = Array.isArray(entry.models) ? (entry.models as string[]).join(', ') : '(all)';\n const hasKey = entry.apiKey ? '\u2713' : entry.apiKeys ? '\u2713' : '\u2717';\n const prefix = id === leaderProvider ? '\u2605 ' : ' ';\n const baseUrl = entry.baseUrl ? ` url:${entry.baseUrl}` : '';\n const family = entry.family ? ` family:${entry.family}` : '';\n return ` ${prefix}${id} (${type}) key:${hasKey} models:[${models}]${baseUrl}${family}`;\n }).join('\\n');\n return {\n status: 'ok',\n message: `Providers (leader: ${leaderProvider}):\\n${msg}`,\n providers: ids,\n };\n }\n\n if (input.action === 'add') {\n if (!input.provider || !input.type) {\n return { status: 'error', message: 'Provide \"provider\" (id) and \"type\" to add a provider.' };\n }\n if (providers[input.provider]) {\n return { status: 'error', message: `Provider \"${input.provider}\" already exists. Use \"configure\" to update.` };\n }\n const entry: Record<string, unknown> = { type: input.type };\n if (input.models) entry.models = input.models;\n if (input.baseUrl) entry.baseUrl = input.baseUrl;\n if (input.family) entry.family = input.family;\n if (input.envVars) entry.envVars = input.envVars;\n if (input.autoDiscoverModels !== undefined) entry.autoDiscoverModels = input.autoDiscoverModels;\n if (input.apiKey) entry.apiKey = input.apiKey;\n providers[input.provider] = entry;\n await opts.updateConfig((cfg) => {\n cfg.providers = providers;\n });\n return { status: 'ok', message: `\u2713 Added provider: ${input.provider} (type: ${input.type})` };\n }\n\n if (input.action === 'configure') {\n if (!input.provider) {\n return { status: 'error', message: 'Provide \"provider\" id to configure.' };\n }\n if (!providers[input.provider]) {\n return { status: 'error', message: `Provider \"${input.provider}\" not found. Use \"add\" first or check \"list\".` };\n }\n const entry: Record<string, unknown> = { ...providers[input.provider] };\n if (input.models !== undefined) entry.models = input.models;\n if (input.baseUrl !== undefined) entry.baseUrl = input.baseUrl || undefined;\n if (input.family !== undefined) entry.family = input.family || undefined;\n if (input.envVars !== undefined) entry.envVars = input.envVars;\n if (input.autoDiscoverModels !== undefined) entry.autoDiscoverModels = input.autoDiscoverModels;\n if (input.apiKey !== undefined) entry.apiKey = input.apiKey || undefined;\n providers[input.provider] = entry;\n await opts.updateConfig((cfg) => {\n cfg.providers = providers;\n });\n const updated = Object.keys({ ...entry }).filter((k) => k !== 'apiKey').join(', ');\n return { status: 'ok', message: `\u2713 Updated ${input.provider}: ${updated}` };\n }\n\n if (input.action === 'remove') {\n if (!input.provider) {\n return { status: 'error', message: 'Provide \"provider\" id to remove.' };\n }\n if (!providers[input.provider]) {\n return { status: 'error', message: `Provider \"${input.provider}\" not found.` };\n }\n if (input.provider === leaderProvider) {\n return { status: 'error', message: `Cannot remove the active leader provider \"${input.provider}\". Switch the leader first.` };\n }\n delete providers[input.provider];\n await opts.updateConfig((cfg) => {\n cfg.providers = providers;\n });\n return { status: 'ok', message: `\u2713 Removed provider: ${input.provider}` };\n }\n\n return { status: 'error', message: `Unknown action: \"${input.action}\".` };\n },\n };\n}\n\n// \u2500\u2500 6. PROVIDER_KEY_SET \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const PROVIDER_KEY_SET_TOOL_NAME = 'provider_key_set';\n\nconst PROVIDER_KEY_SET_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n provider: {\n type: 'string',\n description: 'Provider id (e.g. \"openai\", \"anthropic\"). Required.',\n },\n key: {\n type: 'string',\n description:\n 'The API key value. When provided directly, it is stored as the provider\\'s ' +\n 'primary key. \u26A0\uFE0F This value is visible to the LLM \u2014 for secrets, omit this field ' +\n 'and use envVar instead, or provide the key through the interactive prompt.',\n },\n envVar: {\n type: 'string',\n description:\n 'Environment variable name that contains the key (e.g. \"OPENAI_API_KEY\"). ' +\n 'The key is read from the environment at tool execution time \u2014 the value is never ' +\n 'visible to the LLM. Preferred over passing the key directly.',\n },\n label: {\n type: 'string',\n description:\n 'Optional label for the key entry (e.g. \"work\", \"personal\"). Useful when managing multiple keys.',\n },\n setActive: {\n type: 'boolean',\n description: 'Whether to make this the active key. Default: true.',\n },\n },\n // Flattened from a top-level oneOf \u2014 Anthropic-family endpoints reject\n // top-level combinators (omniroute 400). Combination rules are enforced\n // in the handler instead.\n required: ['provider'],\n additionalProperties: false,\n};\n\ninterface ProviderKeySetInput {\n provider: string;\n key?: string | undefined;\n envVar?: string | undefined;\n label?: string | undefined;\n setActive?: boolean | undefined;\n}\n\ninterface ProviderKeySetOutput {\n status: 'ok' | 'error' | 'needs_key';\n message: string;\n}\n\nfunction createProviderKeySetTool(opts: FallbackManageToolOptions): Tool<ProviderKeySetInput, ProviderKeySetOutput> {\n return {\n name: PROVIDER_KEY_SET_TOOL_NAME,\n description:\n 'Set the API key for a provider. For security, prefer using envVar (reads from ' +\n 'environment variable, value never visible to the LLM) over passing the key directly. ' +\n 'When neither key nor envVar is provided, the tool returns a prompt for interactive key entry \u2014 ' +\n 'the UI will present an input field and the key is stored without LLM visibility.\\n\\n' +\n 'After setting a key, the provider becomes usable for model assignments and fallback chains. ' +\n 'Add its models to favorites with favorite_manage to unlock them for fallback/profile use.',\n usageHint:\n 'Preferred: provider_key_set({ provider: \"openai\", envVar: \"OPENAI_API_KEY\" }). ' +\n 'For interactive input: provider_key_set({ provider: \"openai\" }) \u2014 the UI will prompt. ' +\n 'Direct key: provider_key_set({ provider: \"openai\", key: \"sk-...\" }) \u2014 visible to LLM.',\n category: 'Config',\n inputSchema: PROVIDER_KEY_SET_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const providers = {\n ...((config.providers ?? {}) as unknown as Record<string, Record<string, unknown>>),\n };\n\n // Reject when both key and envVar are supplied \u2014 ambiguous intent\n if (input.key && input.envVar) {\n return {\n status: 'error',\n message: 'Provide either key (direct, visible to LLM) OR envVar (reads from environment, ' +\n 'never visible to LLM), not both. Use envVar for security.',\n };\n }\n\n // If no key or envVar is given, request interactive input\n if (!input.key && !input.envVar) {\n // Interactive input via host callback \u2014 LLM never sees the value\n if (opts.requestInput) {\n try {\n const value = await opts.requestInput(\n `Enter API key for \"${input.provider}\" (will be stored securely, LLM will not see it):`,\n );\n if (!value || value.trim().length === 0) {\n return { status: 'error', message: 'No key was entered. Operation cancelled.' };\n }\n return storeKey(providers, input, value.trim(), opts);\n } catch (err) {\n return {\n status: 'error',\n message: `Interactive input failed or was cancelled: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n }\n // No interactive callback \u2014 return a status the host can intercept\n return {\n status: 'needs_key',\n message:\n `To set the API key for \"${input.provider}\", use provider_key_set ` +\n `with either:\\n` +\n ` 1. envVar: \"${input.provider.toUpperCase()}_API_KEY\" (reads from env, LLM never sees it)\\n` +\n ` 2. key: \"sk-...\" (pass directly, visible to LLM)\\n\\n` +\n `Interactive key entry is handled by the UI \u2014 enter your key through the prompt surface.`,\n };\n }\n\n // Read from environment variable\n if (input.envVar) {\n const envValue = process.env[input.envVar];\n if (!envValue) {\n return {\n status: 'error',\n message: `Environment variable \"${input.envVar}\" is not set or empty. ` +\n `Set it first or use a different envVar.`,\n };\n }\n return storeKey(providers, input, envValue, opts);\n }\n\n // Key provided directly\n if (input.key) {\n return storeKey(providers, input, input.key, opts);\n }\n\n return { status: 'error', message: 'Unexpected \u2014 no key source available.' };\n },\n };\n}\n\nasync function storeKey(\n providers: Record<string, Record<string, unknown>>,\n input: ProviderKeySetInput,\n keyValue: string,\n opts: FallbackManageToolOptions,\n): Promise<ProviderKeySetOutput> {\n const providerId = input.provider;\n\n // Ensure the provider config exists\n if (!providers[providerId]) {\n // Auto-create with a best-guess type (user can configure properly later)\n providers[providerId] = { type: providerId };\n }\n\n const entry = providers[providerId]!;\n const existingKeys = Array.isArray(entry.apiKeys) ? [...(entry.apiKeys as Array<Record<string, unknown>>)] : [];\n const label = input.label ?? 'default';\n\n existingKeys.push({\n label,\n apiKey: keyValue,\n createdAt: new Date().toISOString(),\n });\n\n entry.apiKeys = existingKeys;\n entry.apiKey = undefined; // Clear legacy field after migration to multikey format\n\n if (input.setActive !== false) {\n entry.activeKey = label;\n }\n\n providers[providerId] = entry;\n\n await opts.updateConfig((cfg) => {\n cfg.providers = providers;\n });\n\n const sourceName = input.envVar ? `env:${input.envVar}` : 'direct key';\n return {\n status: 'ok',\n message: `\u2713 API key stored for \"${providerId}\" from ${sourceName}. ` +\n `Now add models to favorites with favorite_manage to use them in fallback chains.`,\n };\n}\n\n// \u2500\u2500 7. LEADER_MODEL_SET \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const LEADER_MODEL_SET_TOOL_NAME = 'leader_model_set';\n\nconst LEADER_MODEL_SET_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['show', 'set', 'profile', 'toggle'],\n description:\n 'Operation: show (current leader + toggles), set (change provider/model), ' +\n 'profile (set from a fallback profile), toggle (change fallbackAuto/favoriteModelsOnly).',\n },\n provider: {\n type: 'string',\n description: 'Provider id for the leader (e.g. \"anthropic\", \"openai\"). Required for \"set\".',\n },\n model: {\n type: 'string',\n description: 'Model id for the leader (e.g. \"claude-sonnet-4-20250514\"). Required for \"set\".',\n },\n profile: {\n type: 'string',\n description: 'Fallback profile name to derive the leader + chain from. Required for \"profile\".',\n },\n toggle: {\n type: 'string',\n enum: ['fallbackAuto', 'favoriteModelsOnly'],\n description: 'Which toggle to change. Required for \"toggle\".',\n },\n value: {\n type: 'boolean',\n description: 'New value for the toggle. Required for \"toggle\".',\n },\n },\n additionalProperties: false,\n};\n\ninterface LeaderModelSetInput {\n action: 'show' | 'set' | 'profile' | 'toggle';\n provider?: string | undefined;\n model?: string | undefined;\n profile?: string | undefined;\n toggle?: 'fallbackAuto' | 'favoriteModelsOnly' | undefined;\n value?: boolean | undefined;\n}\n\ninterface LeaderModelSetOutput {\n status: 'ok' | 'error';\n message: string;\n}\n\nfunction createLeaderModelSetTool(opts: FallbackManageToolOptions): Tool<LeaderModelSetInput, LeaderModelSetOutput> {\n return {\n name: LEADER_MODEL_SET_TOOL_NAME,\n description:\n 'View or change the leader provider/model and system toggles. The leader is the ' +\n 'primary model used for the main agent interactions. ' +\n '\"set\" changes it directly. \"profile\" derives it from a named fallback profile ' +\n '(first entry becomes leader, rest become the fallback chain). ' +\n '\"toggle\" controls fallbackAuto (smart default fallback) and favoriteModelsOnly ' +\n '(restrict auto-fallback to favorites only).',\n usageHint:\n '\"show\" to see current state. \"set\" with provider+model to change. ' +\n '\"profile\" with name to derive from a profile. ' +\n '\"toggle\" with toggle name and value to change a boolean setting.',\n category: 'Config',\n inputSchema: LEADER_MODEL_SET_SCHEMA,\n permission: 'auto',\n mutating: true,\n riskTier: 'standard',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n\n if (input.action === 'show') {\n const lines: string[] = [\n ` ${'leader'}: ${config.provider}/${config.model}`,\n ` ${'fallbackAuto'}: ${config.fallbackAuto !== false ? 'on' : 'off'}`,\n ` ${'favoriteModelsOnly'}: ${config.favoriteModelsOnly ? 'on' : 'off'}`,\n '',\n ` ${'fallback models'}: ${(config.fallbackModels ?? []).length > 0 ? (config.fallbackModels ?? []).join(' \u2192 ') : 'empty (auto fallback)'}`,\n ` ${'favorites'}: ${(config.favoriteModels ?? []).length > 0 ? `${(config.favoriteModels ?? []).length} models` : '(none)'}`,\n ` ${'refiner'}: ${config.autonomy?.refinerProvider ? `${config.autonomy.refinerProvider}/${config.autonomy.refinerModel ?? '(default model)'}` : '(same as leader)'}`,\n ];\n return { status: 'ok', message: lines.join('\\n') };\n }\n\n if (input.action === 'set') {\n if (!input.provider || !input.model) {\n return { status: 'error', message: 'Provide \"provider\" and \"model\" for the leader.' };\n }\n await opts.updateConfig((cfg) => {\n cfg.provider = input.provider;\n cfg.model = input.model;\n });\n return { status: 'ok', message: `\u2713 Leader \u2192 ${input.provider}/${input.model}` };\n }\n\n if (input.action === 'profile') {\n if (!input.profile) {\n return { status: 'error', message: 'Provide \"profile\" name to derive the leader from.' };\n }\n const profiles = (config.fallbackProfiles ?? {}) as Record<string, string[]>;\n const chain = profiles[input.profile];\n if (!chain || chain.length === 0) {\n return { status: 'error', message: `Profile \"${input.profile}\" not found or empty.` };\n }\n // Parse first entry as leader provider/model\n const first = chain[0]!;\n const p = parseRefInternal(first);\n const provider = p.provider ?? config.provider;\n const model = p.model;\n if (!model) {\n return { status: 'error', message: `Cannot parse \"${first}\" as a valid model reference.` };\n }\n const rest = chain.slice(1);\n await opts.updateConfig((cfg) => {\n cfg.provider = provider;\n cfg.model = model;\n cfg.fallbackModels = rest;\n });\n return {\n status: 'ok',\n message: `\u2713 Leader \u2192 ${provider}/${model} (profile: ${input.profile})` +\n (rest.length > 0 ? `\\n Fallback chain: ${rest.join(' \u2192 ')}` : ''),\n };\n }\n\n if (input.action === 'toggle') {\n if (!input.toggle || input.value === undefined) {\n return { status: 'error', message: 'Provide \"toggle\" (fallbackAuto | favoriteModelsOnly) and \"value\" (boolean).' };\n }\n await opts.updateConfig((cfg) => {\n if (input.toggle === 'fallbackAuto') {\n cfg.fallbackAuto = input.value;\n } else if (input.toggle === 'favoriteModelsOnly') {\n cfg.favoriteModelsOnly = input.value;\n }\n });\n return {\n status: 'ok',\n message: `\u2713 ${input.toggle} \u2192 ${input.value ? 'on' : 'off'}`,\n };\n }\n\n return { status: 'error', message: `Unknown action: \"${input.action}\".` };\n },\n };\n}\n\ninterface ParsedRef {\n provider?: string;\n model: string;\n}\n\nfunction parseRefInternal(ref: string): ParsedRef {\n const trimmed = ref.trim();\n const slash = trimmed.indexOf('/');\n if (slash !== -1) {\n const p = trimmed.slice(0, slash);\n const m = trimmed.slice(slash + 1).trim();\n if (p) return { provider: p, model: m };\n return { model: m };\n }\n const parts = trimmed.split(/\\s+/);\n if (parts.length >= 2) {\n return { provider: parts[0]!, model: parts.slice(1).join(' ') };\n }\n return { model: trimmed };\n}\n\n// \u2500\u2500 8. SYSTEM_CONFIG_VIEW \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const SYSTEM_CONFIG_VIEW_TOOL_NAME = 'system_config_view';\n\nconst SYSTEM_CONFIG_VIEW_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n section: {\n type: 'string',\n enum: ['all', 'providers', 'models', 'fallbacks', 'matrix', 'agents', 'refiner', 'doctor'],\n description:\n 'Which section to show: all (everything), providers (configured providers + keys), ' +\n 'models (favorites + leader), fallbacks (chain + profiles + toggles), ' +\n 'matrix (per-role assignments), agents (every catalog agent with resolved model), ' +\n 'refiner (goal refinement config), doctor (validate config and show issues/warnings). ' +\n 'Default: all.',\n },\n },\n additionalProperties: false,\n};\n\ninterface SystemConfigViewInput {\n section?: 'all' | 'providers' | 'models' | 'fallbacks' | 'matrix' | 'agents' | 'refiner' | 'doctor' | undefined;\n}\n\ninterface SystemConfigViewOutput {\n status: 'ok';\n message: string;\n}\n\nfunction createSystemConfigViewTool(opts: FallbackManageToolOptions): Tool<SystemConfigViewInput, SystemConfigViewOutput> {\n return {\n name: SYSTEM_CONFIG_VIEW_TOOL_NAME,\n description:\n 'Get a comprehensive view of all provider, model, fallback, and matrix configuration. ' +\n 'Shows the complete state across all configurable areas so you can see what is available ' +\n 'and make informed decisions when assigning models, creating fallback profiles, or ' +\n 'managing providers. Use the section parameter to focus on specific areas.',\n usageHint:\n '\"section: all\" for everything. \"section: providers\" for configured providers and key status. ' +\n '\"section: models\" for leader model and favorites. ' +\n '\"section: fallbacks\" for chains, profiles, and toggles. ' +\n '\"section: matrix\" for per-role assignments. ' +\n '\"section: refiner\" for goal refinement config.',\n category: 'Config',\n inputSchema: SYSTEM_CONFIG_VIEW_SCHEMA,\n permission: 'auto',\n mutating: false,\n riskTier: 'safe',\n icon: 'settings',\n async execute(input) {\n const config = opts.getConfig();\n const section = input.section ?? 'all';\n const sections: string[] = [];\n const addSection = (title: string, content: string) => {\n sections.push(`\u2500\u2500 ${title} \u2500\u2500\\n${content}`);\n };\n\n // Always show provider/model header\n addSection(\n 'Leader',\n ` ${config.provider}/${config.model}`,\n );\n\n if (section === 'all' || section === 'providers') {\n const providers = (config.providers ?? {}) as unknown as Record<string, Record<string, unknown>>;\n const ids = Object.keys(providers);\n if (ids.length === 0) {\n addSection('Providers', ' (none configured)');\n } else {\n const lines = ids.sort().map((id) => {\n const e = providers[id] ?? {};\n const type = (e.type as string) ?? '?';\n const models = Array.isArray(e.models) ? `[${(e.models as string[]).join(', ')}]` : '(all)';\n const hasKey = e.apiKey || (Array.isArray(e.apiKeys) && e.apiKeys.length > 0) ? '\u2713' : '\u2717';\n const baseUrl = e.baseUrl ? ` url:${e.baseUrl}` : '';\n const family = e.family ? ` family:${e.family}` : '';\n const envVars = Array.isArray(e.envVars) ? ` env:[${(e.envVars as string[]).join(', ')}]` : '';\n return ` ${id === config.provider ? '\u2605' : ' '} ${id} (${type}) key:${hasKey} models:${models}${baseUrl}${family}${envVars}`;\n });\n addSection('Providers', lines.join('\\n'));\n }\n }\n\n if (section === 'all' || section === 'models') {\n const favorites = config.favoriteModels ?? [];\n addSection(\n 'Favorites',\n favorites.length > 0\n ? favorites.map((f, i) => ` ${i + 1}. ${f}`).join('\\n')\n : ' (none \u2014 use favorite_manage to add)',\n );\n addSection(\n 'Settings',\n ` fallbackAuto: ${config.fallbackAuto !== false ? 'on' : 'off'}\\n` +\n ` favoriteModelsOnly: ${config.favoriteModelsOnly ? 'on' : 'off'}`,\n );\n }\n\n if (section === 'all' || section === 'fallbacks') {\n const fallbackModels = config.fallbackModels ?? [];\n const profiles = (config.fallbackProfiles ?? {}) as Record<string, string[]>;\n addSection(\n 'Fallback Chain',\n fallbackModels.length > 0\n ? fallbackModels.map((f, i) => ` ${i + 1}. ${f}`).join('\\n')\n : ' (empty \u2014 auto fallback applies when fallbackAuto is on)',\n );\n const profileNames = Object.keys(profiles);\n addSection(\n 'Fallback Profiles',\n profileNames.length > 0\n ? profileNames.sort().map((n) => ` ${n} \u2192 ${profiles[n]?.join(' \u2192 ') ?? '(empty)'}`).join('\\n')\n : ' (none)',\n );\n }\n\n if (section === 'all' || section === 'matrix') {\n const matrix = (config.modelMatrix ?? {}) as Record<string, Record<string, unknown>>;\n const keys = Object.keys(matrix);\n addSection(\n 'Model Matrix (role assignments)',\n keys.length > 0\n ? keys.sort().map((k) => ` ${k} \u2192 ${JSON.stringify(matrix[k])}`).join('\\n')\n : ' (empty \u2014 all roles use the leader model)',\n );\n }\n\n if (section === 'all' || section === 'agents') {\n const roleNames = Object.keys(AGENT_CATALOG).sort();\n const lines = roleNames.map((role) => {\n const phase = phaseForRole(role) ?? '?';\n const target = resolveSubagentModelTarget(config, role);\n const model = target?.provider\n ? `${target.provider}/${target.model ?? '(default)'}`\n : `${config.provider}/${config.model ?? '(leader)'}`;\n const src = target?.diversified\n ? ' (diversified)'\n : target?.source === 'matrix'\n ? ` (matrix:${target.matrixSource ?? '?'})`\n : '';\n return ` ${role.padEnd(24)} ${phase.padEnd(14)} ${model}${src}`;\n });\n addSection(\n `Agent Models (${roleNames.length} roles)`,\n lines.length > 0\n ? ` ${'ROLE'.padEnd(24)} ${'PHASE'.padEnd(14)} RESOLVED MODEL\\n` + lines.join('\\n')\n : ' (no agents in catalog)',\n );\n }\n\n if (section === 'all' || section === 'doctor') {\n const issues: string[] = [];\n const warnings: string[] = [];\n const ok: string[] = [];\n const providers = (config.providers ?? {}) as unknown as Record<string, Record<string, unknown>>;\n const favorites = config.favoriteModels ?? [];\n const profiles = (config.fallbackProfiles ?? {}) as Record<string, string[]>;\n const chain = config.fallbackModels ?? [];\n const matrix = (config.modelMatrix ?? {}) as Record<string, Record<string, unknown>>;\n\n // 1. Check favorites against provider model lists\n for (const fav of favorites) {\n const p = parseRefInternal(fav);\n const provId = p.provider ?? config.provider;\n const model = p.model;\n const prov = providers[provId];\n if (!prov) {\n warnings.push(`Favorite \"${fav}\" references unknown provider \"${provId}\"`);\n continue;\n }\n const provModels = prov.models as string[] | undefined;\n if (provModels && provModels.length > 0 && !provModels.includes(model)) {\n warnings.push(`Favorite \"${fav}\" \u2014 model \"${model}\" not in ${provId} model list (${provModels.join(', ')})`);\n } else {\n ok.push(`Favorite \"${fav}\" \u2014 provider ${provId} is configured`);\n }\n }\n\n // 2. Check fallback chain entries\n for (const entry of chain) {\n const p = parseRefInternal(entry);\n const provId = p.provider ?? config.provider;\n if (!providers[provId] && provId !== config.provider) {\n issues.push(`Chain entry \"${entry}\" references unknown provider \"${provId}\"`);\n } else {\n ok.push(`Chain entry \"${entry}\" \u2014 provider OK`);\n }\n }\n\n // 3. Check fallback profile entries\n for (const [pname, pchain] of Object.entries(profiles)) {\n if (!pchain || pchain.length === 0) {\n warnings.push(`Profile \"${pname}\" is empty`);\n continue;\n }\n for (const entry of pchain) {\n const p = parseRefInternal(entry);\n const provId = p.provider ?? config.provider;\n if (!providers[provId] && provId !== config.provider) {\n issues.push(`Profile \"${pname}\" entry \"${entry}\" references unknown provider \"${provId}\"`);\n }\n }\n }\n\n // 4. Check matrix assignments\n for (const [key, entry] of Object.entries(matrix)) {\n const eProvider = (entry.provider as string) ?? config.provider;\n const eModel = entry.model as string | undefined;\n if (eModel) {\n const provData = providers[eProvider];\n if (!provData && eProvider !== config.provider) {\n issues.push(`Matrix \"${key}\" references unknown provider \"${eProvider}\"`);\n }\n const provModels = provData?.models as string[] | undefined;\n if (provModels && provModels.length > 0 && !provModels.includes(eModel)) {\n warnings.push(`Matrix \"${key}\" \u2014 model \"${eModel}\" not in ${eProvider} model list`);\n }\n }\n // Check fallbackProfile reference\n const eProfile = entry.fallbackProfile as string | undefined;\n if (eProfile && !profiles[eProfile]) {\n issues.push(`Matrix \"${key}\" references unknown fallback profile \"${eProfile}\"`);\n }\n }\n\n // 5. Check leader provider\n if (!providers[config.provider] && Object.keys(providers).length > 0) {\n warnings.push(`Leader provider \"${config.provider}\" has no explicit config entry`);\n }\n\n // 6. Summary\n const summary = ` \u2713 ${ok.length} checks passed\\n` +\n ` \u26A0 ${warnings.length} warnings\\n` +\n ` \u2717 ${issues.length} issues`;\n const lines: string[] = [summary, ''];\n if (warnings.length > 0) {\n lines.push('\u2500\u2500 Warnings \u2500\u2500');\n lines.push(...warnings.map((w) => ` \u26A0 ${w}`));\n lines.push('');\n }\n if (issues.length > 0) {\n lines.push('\u2500\u2500 Issues \u2500\u2500');\n lines.push(...issues.map((i) => ` \u2717 ${i}`));\n lines.push('');\n }\n if (warnings.length === 0 && issues.length === 0 && ok.length > 0) {\n lines.push(' All checks passed \u2014 configuration is healthy.');\n }\n addSection('Configuration Doctor', lines.join('\\n'));\n }\n\n if (section === 'all' || section === 'refiner') {\n const ref = config.autonomy;\n addSection(\n 'Goal Refinement',\n ` refinerProvider: ${ref?.refinerProvider ?? '(same as leader)'}\\n` +\n ` refinerModel: ${ref?.refinerModel ?? '(default for provider)'}\\n` +\n ` refinerFallbackProfile: ${ref?.refinerFallbackProfile ?? '(none)'}`,\n );\n }\n\n return { status: 'ok', message: sections.join('\\n\\n') };\n },\n };\n}\n\n// \u2500\u2500 Factory \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Create all 8 provider/model/fallback management tools that LLMs can call.\n *\n * Register them all in the tool registry:\n * ```ts\n * const tools = createFallbackManageTools({ getConfig, updateConfig });\n * for (const tool of tools) toolRegistry.register(tool);\n * ```\n */\nexport function createFallbackManageTools(opts: FallbackManageToolOptions): Tool[] {\n return [\n createFavoriteManageTool(opts),\n createFallbackChainManageTool(opts),\n createFallbackProfileManageTool(opts),\n createAgentModelAssignTool(opts),\n createProviderManageTool(opts),\n createProviderKeySetTool(opts),\n createLeaderModelSetTool(opts),\n createSystemConfigViewTool(opts),\n ];\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["fs", "stat", "resolve", "path", "path", "path", "path", "INPUT_SCHEMA", "readFileSync", "statSync", "path", "fileURLToPath", "isDirectory"]
7
7
  }