nexus-agents 2.63.4 → 2.63.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/{adaptive-memory-2UIPH67R.js → adaptive-memory-XD5O3TC4.js} +3 -3
  2. package/dist/{chunk-NF5KOUKM.js → chunk-3BLWO2ZM.js} +2 -2
  3. package/dist/{chunk-PB2EXTSV.js → chunk-3H44UAHW.js} +2 -2
  4. package/dist/{chunk-EBFXDM3P.js → chunk-5CYDU2VX.js} +2 -2
  5. package/dist/{chunk-QAOI6EIU.js → chunk-5HQJGYYM.js} +2 -2
  6. package/dist/{chunk-FHFNOMNK.js → chunk-6MRF2PE2.js} +2 -2
  7. package/dist/{chunk-RCQZMJBZ.js → chunk-CQXNX6BQ.js} +3 -3
  8. package/dist/{chunk-WZ7Z5VLZ.js → chunk-CUGQAPGY.js} +254 -137
  9. package/dist/chunk-CUGQAPGY.js.map +1 -0
  10. package/dist/{chunk-CDWQP3UC.js → chunk-F2YQX6Q6.js} +3 -3
  11. package/dist/{chunk-KLZHA5KA.js → chunk-GISQ3EJB.js} +4 -4
  12. package/dist/{chunk-KYRDQJLY.js → chunk-HRTGSG4L.js} +7 -7
  13. package/dist/{chunk-ZC4KHPRL.js → chunk-N36KDK3E.js} +12 -12
  14. package/dist/chunk-N36KDK3E.js.map +1 -0
  15. package/dist/{chunk-FAUHVWYZ.js → chunk-NV63LTMM.js} +5 -1
  16. package/dist/chunk-NV63LTMM.js.map +1 -0
  17. package/dist/{chunk-GJVHRJO2.js → chunk-O3CBMPGT.js} +2 -1
  18. package/dist/chunk-O3CBMPGT.js.map +1 -0
  19. package/dist/{chunk-KVZNQWWI.js → chunk-O4AJGETH.js} +2 -2
  20. package/dist/{chunk-ORYMBSGF.js → chunk-OKU3VXWC.js} +5 -5
  21. package/dist/{chunk-ETZULQ7Z.js → chunk-P5NBYCEC.js} +2 -2
  22. package/dist/{chunk-FTWGBV7S.js → chunk-R4FVXOZF.js} +2 -2
  23. package/dist/{chunk-46S665SD.js → chunk-SUR2TLIG.js} +7 -7
  24. package/dist/{chunk-I37IQ26H.js → chunk-TR74DSB4.js} +2 -2
  25. package/dist/{chunk-PEDEZRPR.js → chunk-TSS7VN3V.js} +8 -8
  26. package/dist/{chunk-MSFUOGN4.js → chunk-UFHFX2GX.js} +2 -2
  27. package/dist/{chunk-UDKYZ7CS.js → chunk-VOBYREAG.js} +2 -2
  28. package/dist/{chunk-UCQTXKTS.js → chunk-WDWKKJHZ.js} +2 -2
  29. package/dist/{cli-circuit-breaker-5E6OWOMI.js → cli-circuit-breaker-JE6XKLUG.js} +4 -4
  30. package/dist/cli.js +74 -65
  31. package/dist/cli.js.map +1 -1
  32. package/dist/{composite-router-FC3H7NKN.js → composite-router-KBOGB7GQ.js} +2 -2
  33. package/dist/{consensus-vote-6FKSINXV.js → consensus-vote-PIU3D3KP.js} +9 -9
  34. package/dist/{doctor-deep-X3YCUM4Q.js → doctor-deep-DGY2N4U2.js} +3 -3
  35. package/dist/{expert-bridge-R6FQWUHB.js → expert-bridge-5IPLSDJH.js} +3 -3
  36. package/dist/{expert-config-BTPAEZWV.js → expert-config-6X4225UC.js} +2 -2
  37. package/dist/{factory-BOXBN4ZS.js → factory-PSFI6WDI.js} +4 -4
  38. package/dist/{factory-7DJA2CIL.js → factory-ZTNGLNFH.js} +5 -5
  39. package/dist/index.d.ts +5 -0
  40. package/dist/index.js +21 -21
  41. package/dist/{issue-triage-DGDKQQTD.js → issue-triage-VOZNNCUG.js} +4 -4
  42. package/dist/{mcp-config-CHS2ZC42.js → mcp-config-PDH6LS6E.js} +3 -3
  43. package/dist/{mobimem-NO7I2Y4O.js → mobimem-7KQVPLAW.js} +2 -2
  44. package/dist/{registry-command-ZO75YQJG.js → registry-command-BS75IWSA.js} +2 -2
  45. package/dist/{repo-security-plan-BZ3WOIEZ.js → repo-security-plan-VZTTNXYJ.js} +3 -3
  46. package/dist/{research-helpers-synthesize-SH34FJIE.js → research-helpers-synthesize-B3C6BFCX.js} +3 -3
  47. package/dist/{routing-memory-SALB3DZI.js → routing-memory-BGK2HMC3.js} +2 -2
  48. package/dist/{session-memory-IOXXN6XA.js → session-memory-ESTZAPL2.js} +3 -3
  49. package/dist/{setup-command-UVJRDNRF.js → setup-command-J6QG2G5V.js} +9 -9
  50. package/dist/{setup-config-FYRXUWQH.js → setup-config-LG67TIFO.js} +3 -3
  51. package/dist/{setup-custom-api-VAFP4X43.js → setup-custom-api-4DZABP47.js} +4 -4
  52. package/dist/{weather-report-SBJRXFTW.js → weather-report-HUY35FUZ.js} +2 -2
  53. package/package.json +1 -1
  54. package/dist/chunk-FAUHVWYZ.js.map +0 -1
  55. package/dist/chunk-GJVHRJO2.js.map +0 -1
  56. package/dist/chunk-WZ7Z5VLZ.js.map +0 -1
  57. package/dist/chunk-ZC4KHPRL.js.map +0 -1
  58. /package/dist/{adaptive-memory-2UIPH67R.js.map → adaptive-memory-XD5O3TC4.js.map} +0 -0
  59. /package/dist/{chunk-NF5KOUKM.js.map → chunk-3BLWO2ZM.js.map} +0 -0
  60. /package/dist/{chunk-PB2EXTSV.js.map → chunk-3H44UAHW.js.map} +0 -0
  61. /package/dist/{chunk-EBFXDM3P.js.map → chunk-5CYDU2VX.js.map} +0 -0
  62. /package/dist/{chunk-QAOI6EIU.js.map → chunk-5HQJGYYM.js.map} +0 -0
  63. /package/dist/{chunk-FHFNOMNK.js.map → chunk-6MRF2PE2.js.map} +0 -0
  64. /package/dist/{chunk-RCQZMJBZ.js.map → chunk-CQXNX6BQ.js.map} +0 -0
  65. /package/dist/{chunk-CDWQP3UC.js.map → chunk-F2YQX6Q6.js.map} +0 -0
  66. /package/dist/{chunk-KLZHA5KA.js.map → chunk-GISQ3EJB.js.map} +0 -0
  67. /package/dist/{chunk-KYRDQJLY.js.map → chunk-HRTGSG4L.js.map} +0 -0
  68. /package/dist/{chunk-KVZNQWWI.js.map → chunk-O4AJGETH.js.map} +0 -0
  69. /package/dist/{chunk-ORYMBSGF.js.map → chunk-OKU3VXWC.js.map} +0 -0
  70. /package/dist/{chunk-ETZULQ7Z.js.map → chunk-P5NBYCEC.js.map} +0 -0
  71. /package/dist/{chunk-FTWGBV7S.js.map → chunk-R4FVXOZF.js.map} +0 -0
  72. /package/dist/{chunk-46S665SD.js.map → chunk-SUR2TLIG.js.map} +0 -0
  73. /package/dist/{chunk-I37IQ26H.js.map → chunk-TR74DSB4.js.map} +0 -0
  74. /package/dist/{chunk-PEDEZRPR.js.map → chunk-TSS7VN3V.js.map} +0 -0
  75. /package/dist/{chunk-MSFUOGN4.js.map → chunk-UFHFX2GX.js.map} +0 -0
  76. /package/dist/{chunk-UDKYZ7CS.js.map → chunk-VOBYREAG.js.map} +0 -0
  77. /package/dist/{chunk-UCQTXKTS.js.map → chunk-WDWKKJHZ.js.map} +0 -0
  78. /package/dist/{cli-circuit-breaker-5E6OWOMI.js.map → cli-circuit-breaker-JE6XKLUG.js.map} +0 -0
  79. /package/dist/{composite-router-FC3H7NKN.js.map → composite-router-KBOGB7GQ.js.map} +0 -0
  80. /package/dist/{consensus-vote-6FKSINXV.js.map → consensus-vote-PIU3D3KP.js.map} +0 -0
  81. /package/dist/{doctor-deep-X3YCUM4Q.js.map → doctor-deep-DGY2N4U2.js.map} +0 -0
  82. /package/dist/{expert-bridge-R6FQWUHB.js.map → expert-bridge-5IPLSDJH.js.map} +0 -0
  83. /package/dist/{expert-config-BTPAEZWV.js.map → expert-config-6X4225UC.js.map} +0 -0
  84. /package/dist/{factory-7DJA2CIL.js.map → factory-PSFI6WDI.js.map} +0 -0
  85. /package/dist/{factory-BOXBN4ZS.js.map → factory-ZTNGLNFH.js.map} +0 -0
  86. /package/dist/{issue-triage-DGDKQQTD.js.map → issue-triage-VOZNNCUG.js.map} +0 -0
  87. /package/dist/{mcp-config-CHS2ZC42.js.map → mcp-config-PDH6LS6E.js.map} +0 -0
  88. /package/dist/{mobimem-NO7I2Y4O.js.map → mobimem-7KQVPLAW.js.map} +0 -0
  89. /package/dist/{registry-command-ZO75YQJG.js.map → registry-command-BS75IWSA.js.map} +0 -0
  90. /package/dist/{repo-security-plan-BZ3WOIEZ.js.map → repo-security-plan-VZTTNXYJ.js.map} +0 -0
  91. /package/dist/{research-helpers-synthesize-SH34FJIE.js.map → research-helpers-synthesize-B3C6BFCX.js.map} +0 -0
  92. /package/dist/{routing-memory-SALB3DZI.js.map → routing-memory-BGK2HMC3.js.map} +0 -0
  93. /package/dist/{session-memory-IOXXN6XA.js.map → session-memory-ESTZAPL2.js.map} +0 -0
  94. /package/dist/{setup-command-UVJRDNRF.js.map → setup-command-J6QG2G5V.js.map} +0 -0
  95. /package/dist/{setup-config-FYRXUWQH.js.map → setup-config-LG67TIFO.js.map} +0 -0
  96. /package/dist/{setup-custom-api-VAFP4X43.js.map → setup-custom-api-4DZABP47.js.map} +0 -0
  97. /package/dist/{weather-report-SBJRXFTW.js.map → weather-report-HUY35FUZ.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/time-provider.ts","../src/core/logger.ts","../src/context/mobimem-types.ts","../src/context/mobimem-impl.ts","../src/core/result.ts","../src/core/json-extract.ts","../src/core/step-events.ts","../src/core/step-bus.ts","../src/core/with-step.ts","../src/core/console-renderer.ts","../src/core/step-logger-bridge.ts","../src/core/step-notifications.ts","../src/core/errors.ts","../src/config/model-capabilities-types.ts","../src/config/model-capabilities.ts","../src/core/trace-pricing.ts","../src/core/trace-helpers.ts","../src/core/trace.ts","../src/core/trace-exporter.ts","../src/cli/ansi-output.ts","../src/core/trace-exporter-helpers.ts","../src/core/artifact.ts","../src/core/metrics.ts","../src/core/safe-regex.ts","../src/core/zod-helpers.ts","../src/core/task-analysis/task-type-classifier.ts","../src/core/task-analysis/product-type-detector.ts","../src/core/task-analysis/task-analysis-keywords.ts","../src/core/task-analysis/task-analysis-advocate.ts","../src/core/task-analysis/shared-task-analyzer.ts","../src/core/task-analysis/capability-gap-detector.ts","../src/utils/math-utils.ts","../src/core/task-analysis/task-profile-adapter.ts","../src/core/random-provider.ts","../src/core/token-estimator.ts","../src/config/model-config-helpers.ts","../src/cli-adapters/types-capability.ts","../src/cli-adapters/routing-memory-types.ts","../src/cli-adapters/budget-utils.ts","../src/cli-adapters/budget-warnings.ts","../src/cli-adapters/budget-errors.ts","../src/cli-adapters/budget-router.ts","../src/cli-adapters/topsis-types.ts","../src/cli-adapters/topsis-helpers.ts","../src/cli-adapters/topsis-router.ts","../src/cli-adapters/budget-router-types.ts","../src/cli-adapters/linucb-math.ts","../src/cli-adapters/linucb-bandit.ts","../src/cli-adapters/preference-router.ts","../src/cli-adapters/preference-router-types.ts","../src/cli-adapters/preference-router-store.ts","../src/cli-adapters/preference-router-extractor.ts","../src/cli-adapters/zero-router-types.ts","../src/cli-adapters/difficulty-estimators.ts","../src/cli-adapters/difficulty-space.ts","../src/cli-adapters/zero-router-calibration.ts","../src/cli-adapters/zero-router.ts","../src/cli-adapters/latency-tracker-types.ts","../src/cli-adapters/latency-tracker.ts","../src/context/routing-memory.ts","../src/cli-adapters/routing/router-stage.ts","../src/cli-adapters/confidence-router-types.ts","../src/cli-adapters/routing/stages/confidence-cascade-stage.ts","../src/config/task-specialization-types.ts","../src/config/task-specialization.ts","../src/cli-adapters/routing/stages/capability-match-stage.ts","../src/cli-adapters/routing/stages/quality-constraint-stage.ts","../src/cli-adapters/routing/stages/resource-strategy-stage.ts","../src/cli-adapters/routing/stages/distilled-rule-stage.ts","../src/cli-adapters/routing/stages/knn-routing-stage.ts","../src/learning/strategy-distiller-types.ts","../src/learning/strategy-distiller.ts","../src/orchestration/outcomes/outcome-types.ts","../src/orchestration/outcomes/outcome-store.ts","../src/pipeline/event-bus.ts","../src/cli/warm-up.ts","../src/cli-adapters/composite-router-types.ts","../src/cli-adapters/composite-router-helpers.ts","../src/mcp/tools/weather-report-types.ts","../src/mcp/gateway/gateway-keywords.ts","../src/mcp/gateway/tier-classifier.ts","../src/mcp/gateway/tier-recommender.ts","../src/orchestration/outcomes/adaptive-thresholds.ts","../src/adapters/rate-limit-detector.ts","../src/mcp/middleware/tool-metrics.ts","../src/agents/heartbeat-monitor.ts","../src/config/defaults-types.ts","../src/config/timeouts.ts","../src/mcp/tools/weather-report.ts","../src/cli-adapters/weather-bonus-stage.ts","../src/cli-adapters/composite-router-stages.ts","../src/cli-adapters/composite-router-outcome.ts","../src/cli-adapters/composite-router-metrics.ts","../src/cli-adapters/composite-router.ts","../src/core/types/model.ts","../src/core/types/agent.ts","../src/core/types/workflow.ts","../src/core/types/orchestrator.ts","../src/context/mobimem-impl-helpers.ts","../src/context/mobimem.ts"],"sourcesContent":["/**\n * Injectable Time Provider\n *\n * Provides a deterministic interface for time operations.\n * Allows injection of mock time for testing and reproducible builds.\n *\n * @module core/time-provider\n * (Source: System Mandate - Determinism improvement)\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Interface for time operations.\n * Inject this instead of using Date.now() directly.\n */\nexport interface ITimeProvider {\n /**\n * Get current timestamp in milliseconds.\n * Equivalent to Date.now() but injectable.\n */\n now(): number;\n\n /**\n * Get current date as ISO string.\n * Equivalent to new Date().toISOString() but injectable.\n */\n nowIso(): string;\n\n /**\n * Get current Date object.\n */\n nowDate(): Date;\n\n /**\n * Get current date as YYYY-MM-DD string.\n * Consolidates the common pattern: nowIso().split('T')[0]\n */\n nowDateString(): string;\n}\n\n/**\n * Configuration for time provider.\n */\nexport interface TimeProviderConfig {\n /**\n * Fixed timestamp for deterministic mode.\n * If set, now() always returns this value.\n */\n readonly fixedTime?: number;\n\n /**\n * Offset to add to real time.\n * Useful for testing time-sensitive logic.\n */\n readonly offsetMs?: number;\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/**\n * Default time provider using system clock.\n */\nexport class SystemTimeProvider implements ITimeProvider {\n private readonly offsetMs: number;\n\n constructor(config?: TimeProviderConfig) {\n this.offsetMs = config?.offsetMs ?? 0;\n }\n\n now(): number {\n return Date.now() + this.offsetMs;\n }\n\n nowIso(): string {\n return new Date(this.now()).toISOString();\n }\n\n nowDate(): Date {\n return new Date(this.now());\n }\n\n nowDateString(): string {\n return this.nowIso().split('T')[0] ?? '';\n }\n}\n\n/**\n * Fixed time provider for deterministic testing.\n * Always returns the same timestamp.\n */\nexport class FixedTimeProvider implements ITimeProvider {\n private currentTime: number;\n\n constructor(fixedTime: number | Date = Date.now()) {\n this.currentTime = typeof fixedTime === 'number' ? fixedTime : fixedTime.getTime();\n }\n\n now(): number {\n return this.currentTime;\n }\n\n nowIso(): string {\n return new Date(this.currentTime).toISOString();\n }\n\n nowDate(): Date {\n return new Date(this.currentTime);\n }\n\n nowDateString(): string {\n return this.nowIso().split('T')[0] ?? '';\n }\n\n /**\n * Advance the fixed time by the given amount.\n */\n advance(ms: number): void {\n this.currentTime += ms;\n }\n\n /**\n * Set the fixed time to a new value.\n */\n setTime(time: number | Date): void {\n this.currentTime = typeof time === 'number' ? time : time.getTime();\n }\n}\n\n// ============================================================================\n// Global Instance\n// ============================================================================\n\nlet globalTimeProvider: ITimeProvider = new SystemTimeProvider();\n\n/**\n * Get the global time provider instance.\n */\nexport function getTimeProvider(): ITimeProvider {\n return globalTimeProvider;\n}\n\n/**\n * Set the global time provider instance.\n * Use for testing or deterministic mode.\n */\nexport function setTimeProvider(provider: ITimeProvider): void {\n globalTimeProvider = provider;\n}\n\n/**\n * Get current date as YYYY-MM-DD string using the global time provider.\n * Test-mockable via setTimeProvider(). Canonical source for date strings.\n * @see Issue #1596 — DRY consolidation\n */\nexport function getCurrentDateString(): string {\n return new Date(getTimeProvider().now()).toISOString().slice(0, 10);\n}\n\n/**\n * Reset the global time provider to system clock.\n */\nexport function resetTimeProvider(): void {\n globalTimeProvider = new SystemTimeProvider();\n}\n\n/**\n * Creates a time provider.\n */\nexport function createTimeProvider(config?: TimeProviderConfig): ITimeProvider {\n if (config?.fixedTime !== undefined) {\n return new FixedTimeProvider(config.fixedTime);\n }\n return new SystemTimeProvider(config);\n}\n","/**\n * nexus-agents/core - Structured Logger\n *\n * JSON-structured logging with secret sanitization.\n */\n\nimport { getTimeProvider } from './time-provider.js';\n\n/** Log levels in order of severity */\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\n/** Log output format */\nexport type LogFormat = 'json' | 'pretty';\n\n/** Log output destination */\nexport type LogDestination = 'stdout' | 'stderr' | 'file';\n\n/** Log context/metadata */\nexport interface LogContext {\n [key: string]: unknown;\n}\n\n/** Structured log entry */\nexport interface LogEntry {\n timestamp: string;\n level: LogLevel;\n message: string;\n context?: LogContext;\n error?: {\n name: string;\n message: string;\n stack?: string;\n };\n}\n\n/** Logger interface */\nexport interface ILogger {\n debug(message: string, context?: LogContext): void;\n info(message: string, context?: LogContext): void;\n warn(message: string, context?: LogContext): void;\n error(message: string, error?: Error, context?: LogContext): void;\n child(context: LogContext): ILogger;\n setLevel(level: LogLevel): void;\n /** Set output format (json or pretty) - optional for backward compatibility */\n setFormat?: ((format: LogFormat) => void) | undefined;\n /** Set output destination (stdout, stderr, or file) - optional for backward compatibility */\n setDestination?: ((destination: LogDestination, filePath?: string) => void) | undefined;\n}\n\n/** Patterns to sanitize from logs */\nconst SECRET_PATTERNS = [\n // API keys (OpenAI sk-*, Anthropic sk-ant-*)\n /sk-[a-zA-Z0-9-_]{20,}/g,\n // Google AI / Gemini API keys (AIza prefix)\n /AIza[0-9A-Za-z_-]{35}/g,\n // Bearer tokens\n /Bearer [a-zA-Z0-9-_.]+/g,\n // Generic credential patterns — bounded quantifiers to prevent ReDoS (#1496)\n /password[\"']?[ \\t]*[:=][ \\t]*[\"']?[^\"'\\s]{1,256}/gi,\n /api[_-]?key[\"']?[ \\t]*[:=][ \\t]*[\"']?[^\"'\\s]{1,256}/gi,\n /secret[\"']?[ \\t]*[:=][ \\t]*[\"']?[^\"'\\s]{1,256}/gi,\n /token[\"']?[ \\t]*[:=][ \\t]*[\"']?[^\"'\\s]{1,256}/gi,\n // AWS credentials — bounded quantifiers to prevent ReDoS (#1496)\n /AKIA[0-9A-Z]{16}/g,\n /aws_secret_access_key[\"']?[ \\t]*[:=][ \\t]*[\"']?[^\"'\\s]{1,256}/gi,\n /aws_session_token[\"']?[ \\t]*[:=][ \\t]*[\"']?[^\"'\\s]{1,256}/gi,\n // Azure credentials\n /AccountKey=[a-zA-Z0-9+/=]{1,256}/gi,\n /SharedAccessSignature=[a-zA-Z0-9%]{1,256}/gi,\n /DefaultEndpointsProtocol=https?;AccountName=[^;]{1,256};AccountKey=[^;]{1,256}/gi,\n // GCP credentials — bounded quantifiers to prevent ReDoS (#1496)\n /\"private_key\":\\s*\"-----BEGIN[^\"]{1,5000}-----END[^\"]{1,500}-----\"/g,\n /\"private_key_id\":\\s*\"[a-f0-9]{1,256}\"/gi,\n // GitHub tokens\n /ghp_[a-zA-Z0-9]{36}/g,\n /github_pat_[a-zA-Z0-9_]{22,}/g,\n /gho_[a-zA-Z0-9]{36}/g,\n /ghu_[a-zA-Z0-9]{36}/g,\n /ghs_[a-zA-Z0-9]{36}/g,\n /ghr_[a-zA-Z0-9]{36}/g,\n];\n\n/**\n * Field names that should have their values fully redacted.\n * Case-insensitive matching.\n * (Source: OWASP Logging Cheat Sheet)\n */\nconst SENSITIVE_FIELD_NAMES = new Set([\n 'password',\n 'passwd',\n 'pwd',\n 'secret',\n 'apikey',\n 'api_key',\n 'apiKey',\n 'token',\n 'accesstoken',\n 'access_token',\n 'accessToken',\n 'refreshtoken',\n 'refresh_token',\n 'refreshToken',\n 'bearer',\n 'authorization',\n 'auth',\n 'credential',\n 'credentials',\n 'private_key',\n 'privatekey',\n 'privateKey',\n 'session',\n 'sessionid',\n 'session_id',\n 'sessionId',\n 'cookie',\n 'ssn',\n 'creditcard',\n 'credit_card',\n 'cardnumber',\n 'card_number',\n 'cvv',\n 'cvc',\n 'pin',\n 'x-api-key',\n 'xapikey',\n 'x_api_key',\n]);\n\nconst LEVEL_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\n/**\n * Valid log level values for NEXUS_LOG_LEVEL environment variable.\n * Issue #545: Implement environment variable support as documented in CLAUDE.md.\n */\nconst VALID_LOG_LEVELS = new Set<string>(['debug', 'info', 'warn', 'error']);\n\n/**\n * Gets the default log level from environment or returns 'info'.\n * Reads from NEXUS_LOG_LEVEL environment variable.\n */\nfunction getDefaultLogLevel(): LogLevel {\n const envLevel = process.env.NEXUS_LOG_LEVEL?.toLowerCase();\n if (envLevel !== undefined && VALID_LOG_LEVELS.has(envLevel)) {\n return envLevel as LogLevel;\n }\n return 'info';\n}\n\n/**\n * Sanitizes a string by redacting known secret patterns.\n */\nexport function sanitize(text: string): string {\n let result = text;\n for (const pattern of SECRET_PATTERNS) {\n result = result.replace(pattern, '[REDACTED]');\n }\n return result;\n}\n\n/**\n * Checks if a field name is sensitive and should be fully redacted.\n */\nfunction isSensitiveField(fieldName: string): boolean {\n return SENSITIVE_FIELD_NAMES.has(fieldName.toLowerCase());\n}\n\n/**\n * Sanitizes an array, handling circular references.\n */\nfunction sanitizeArray(arr: unknown[], seen: WeakSet<object>): unknown[] {\n if (seen.has(arr)) return ['[Circular]'];\n seen.add(arr);\n return arr.map((item) => sanitizeDeep(item, seen));\n}\n\n/**\n * Sanitizes an object, handling circular references and sensitive fields.\n */\nfunction sanitizeObject(obj: object, seen: WeakSet<object>): Record<string, unknown> {\n if (seen.has(obj)) return { _circular: '[Circular]' };\n seen.add(obj);\n\n const sanitized: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(obj)) {\n sanitized[key] = isSensitiveField(key) ? '[REDACTED]' : sanitizeDeep(val, seen);\n }\n return sanitized;\n}\n\n/**\n * Recursively sanitizes an object, redacting sensitive values.\n * Handles circular references safely.\n * (Source: Issue #185 Phase 1 - Deep object sanitization)\n */\nexport function sanitizeDeep(value: unknown, seen = new WeakSet<object>()): unknown {\n if (value === null || value === undefined) return value;\n if (typeof value === 'string') return sanitize(value);\n if (typeof value === 'number' || typeof value === 'boolean') return value;\n if (Array.isArray(value)) return sanitizeArray(value, seen);\n if (typeof value === 'object') return sanitizeObject(value, seen);\n return `[${typeof value}]`;\n}\n\nfunction formatTimestamp(date: Date): string {\n const formatter = new Intl.DateTimeFormat('en-US', {\n timeZone: 'America/New_York',\n timeZoneName: 'shortOffset',\n });\n const parts = formatter.formatToParts(date);\n const offset = parts.find((p) => p.type === 'timeZoneName')?.value ?? '-05:00';\n const base = date.toLocaleString('sv-SE', {\n timeZone: 'America/New_York',\n hour12: false,\n });\n return base.replace(' ', 'T') + offset.replace('GMT', '');\n}\n\ninterface ErrorEntry {\n name: string;\n message: string;\n stack?: string;\n}\n\nfunction formatError(error: Error): ErrorEntry {\n const entry: ErrorEntry = {\n name: error.name,\n message: sanitize(error.message),\n };\n if (error.stack !== undefined) {\n // Sanitize stack traces as they may contain local variable values with secrets\n entry.stack = sanitize(error.stack);\n }\n return entry;\n}\n\nfunction formatEntry(\n level: LogLevel,\n message: string,\n context: LogContext,\n entryContext?: LogContext,\n error?: Error\n): LogEntry {\n const entry: LogEntry = {\n timestamp: formatTimestamp(new Date(getTimeProvider().now())),\n level,\n message: sanitize(message),\n };\n const merged = { ...context, ...entryContext };\n if (Object.keys(merged).length > 0) {\n // Deep sanitize context to prevent secret leakage via nested objects\n entry.context = sanitizeDeep(merged) as LogContext;\n }\n if (error !== undefined) {\n entry.error = formatError(error);\n }\n return entry;\n}\n\n/** Whether color output is enabled (respects NO_COLOR standard). */\nconst loggerColorsEnabled = !('NO_COLOR' in process.env) && process.stderr.isTTY;\n\n/** ANSI color codes for pretty format. Empty strings when NO_COLOR set. */\nconst COLORS = {\n reset: loggerColorsEnabled ? '\\x1b[0m' : '',\n dim: loggerColorsEnabled ? '\\x1b[2m' : '',\n debug: loggerColorsEnabled ? '\\x1b[36m' : '', // cyan\n info: loggerColorsEnabled ? '\\x1b[32m' : '', // green\n warn: loggerColorsEnabled ? '\\x1b[33m' : '', // yellow\n error: loggerColorsEnabled ? '\\x1b[31m' : '', // red\n} as const;\n\n/** Formats a log entry in pretty human-readable format. */\nfunction formatPretty(entry: LogEntry): string {\n const color = COLORS[entry.level];\n const levelPad = entry.level.toUpperCase().padEnd(5);\n const ctx =\n entry.context !== undefined\n ? ` ${COLORS.dim}${JSON.stringify(entry.context)}${COLORS.reset}`\n : '';\n const err =\n entry.error !== undefined\n ? `\\n ${COLORS.error}${entry.error.name}: ${entry.error.message}${COLORS.reset}`\n : '';\n const stack =\n entry.error?.stack !== undefined ? `\\n${COLORS.dim}${entry.error.stack}${COLORS.reset}` : '';\n return `${COLORS.dim}${entry.timestamp}${COLORS.reset} ${color}${levelPad}${COLORS.reset} ${entry.message}${ctx}${err}${stack}\\n`;\n}\n\n/** Global logger configuration state. */\nlet globalFormat: LogFormat = 'json';\n// Default to stderr: when this process runs as an MCP stdio server, stdout is\n// reserved for JSON-RPC frames. A stdout default would corrupt the transport\n// on the first log call. CLI commands that want user-facing output use\n// console.log / explicit writers, not the structured logger.\nlet globalDestination: LogDestination = 'stderr';\nlet globalFilePath: string | undefined;\nlet fileStream: import('fs').WriteStream | undefined;\n\n/** Gets the output stream based on destination. */\nfunction getOutputStream(): NodeJS.WritableStream {\n if (globalDestination === 'file' && globalFilePath !== undefined) {\n if (fileStream === undefined) {\n // Lazy import fs to avoid issues in browser environments\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const fs = require('fs') as typeof import('fs');\n fileStream = fs.createWriteStream(globalFilePath, { flags: 'a' });\n }\n return fileStream;\n }\n return globalDestination === 'stderr' ? process.stderr : process.stdout;\n}\n\n/** Writes a log entry to the configured destination. */\nfunction writeLog(entry: LogEntry): void {\n const output = globalFormat === 'pretty' ? formatPretty(entry) : JSON.stringify(entry) + '\\n';\n getOutputStream().write(output);\n}\n\n/**\n * Creates a structured logger with configurable format and destination.\n * (Source: Issue #485 - Wire logging.format and logging.destination)\n */\nexport function createLogger(baseContext?: LogContext): ILogger {\n let currentLevel: LogLevel = getDefaultLogLevel();\n const context = baseContext ?? {};\n\n function shouldLog(level: LogLevel): boolean {\n return LEVEL_PRIORITY[level] >= LEVEL_PRIORITY[currentLevel];\n }\n\n function log(level: LogLevel, msg: string, ctx?: LogContext, e?: Error): void {\n if (shouldLog(level)) {\n writeLog(formatEntry(level, msg, context, ctx, e));\n }\n }\n\n return {\n debug: (msg, ctx): void => {\n log('debug', msg, ctx);\n },\n info: (msg, ctx): void => {\n log('info', msg, ctx);\n },\n warn: (msg, ctx): void => {\n log('warn', msg, ctx);\n },\n error: (msg, e, ctx): void => {\n log('error', msg, ctx, e);\n },\n child: (childCtx): ILogger => createLogger({ ...context, ...childCtx }),\n setLevel: (level): void => {\n currentLevel = level;\n },\n setFormat: (format): void => {\n globalFormat = format;\n },\n setDestination: (destination, filePath): void => {\n // Close existing file stream if changing destination\n if (fileStream !== undefined && (destination !== 'file' || filePath !== globalFilePath)) {\n fileStream.end();\n fileStream = undefined;\n }\n globalDestination = destination;\n globalFilePath = filePath;\n },\n };\n}\n\n/** Default logger instance */\nexport const logger = createLogger();\n","/**\n * nexus-agents/context - MobiMEM Types\n *\n * Type definitions for MobiMEM post-deployment evolution memory system.\n * Implements Profile, Experience, and Action memory modules for\n * continuous agent improvement without weight updates.\n *\n * @module context/mobimem-types\n * (Source: Issue #149, arXiv:2512.15784)\n */\n\nimport { z } from 'zod';\n\n/**\n * Profile entry storing agent/user preferences and patterns.\n */\nexport interface ProfileEntry {\n /** Unique identifier */\n readonly id: string;\n /** Associated agent or user ID */\n readonly entityId: string;\n /** Type of entity (agent or user) */\n readonly entityType: 'agent' | 'user';\n /** Preference key (e.g., \"preferred_model\", \"output_format\") */\n readonly preferenceKey: string;\n /** Preference value */\n readonly preferenceValue: unknown;\n /** Confidence in this preference (0-1) */\n readonly confidence: number;\n /** Number of observations supporting this preference */\n readonly observationCount: number;\n /** When first observed */\n readonly createdAt: Date;\n /** When last updated */\n readonly updatedAt: Date;\n}\n\n/**\n * Experience entry storing workflow execution patterns.\n */\nexport interface ExperienceEntry {\n /** Unique identifier */\n readonly id: string;\n /** Task type or category */\n readonly taskType: string;\n /** Sequence of actions taken */\n readonly actionSequence: readonly ActionStep[];\n /** Outcome of the execution */\n readonly outcome: ExecutionOutcome;\n /** Context in which this pattern succeeded */\n readonly contextSignature: string;\n /** How often this pattern has succeeded */\n readonly successCount: number;\n /** Total times this pattern was attempted */\n readonly attemptCount: number;\n /** Success rate (successCount / attemptCount) */\n readonly successRate: number;\n /** When first recorded */\n readonly createdAt: Date;\n /** When last used */\n readonly lastUsedAt: Date;\n}\n\n/**\n * A single step in an action sequence.\n */\nexport interface ActionStep {\n /** Step index (0-based) */\n readonly index: number;\n /** Action type (e.g., \"tool_call\", \"model_query\", \"agent_delegate\") */\n readonly actionType: string;\n /** Action-specific parameters */\n readonly parameters: Record<string, unknown>;\n /** Duration in milliseconds */\n readonly durationMs: number;\n /** Whether this step succeeded */\n readonly success: boolean;\n}\n\n/**\n * Outcome of a workflow execution.\n */\nexport interface ExecutionOutcome {\n /** Whether the overall execution succeeded */\n readonly success: boolean;\n /** Quality score if available (0-1) */\n readonly qualityScore?: number;\n /** Error type if failed */\n readonly errorType?: string;\n /** Total execution time */\n readonly totalDurationMs: number;\n /** Total tokens used */\n readonly tokensUsed: number;\n}\n\n/**\n * Action cache entry for rapid retrieval of successful interactions.\n */\nexport interface ActionCacheEntry {\n /** Unique identifier */\n readonly id: string;\n /** Input hash for quick matching */\n readonly inputHash: string;\n /** Original input that produced this result */\n readonly input: unknown;\n /** Cached result */\n readonly result: unknown;\n /** Time to generate original result */\n readonly originalDurationMs: number;\n /** Number of cache hits */\n readonly hitCount: number;\n /** Time saved through caching (hitCount * originalDurationMs) */\n readonly timeSavedMs: number;\n /** When cached */\n readonly cachedAt: Date;\n /** When last accessed */\n readonly lastAccessedAt: Date;\n /** Cache entry TTL */\n readonly expiresAt: Date;\n}\n\n/**\n * MobiMEM configuration.\n */\nexport interface MobiMemConfig {\n /** Database path for persistence */\n readonly dbPath: string;\n /** Maximum profile entries per entity */\n readonly maxProfileEntries: number;\n /** Maximum experience patterns to track */\n readonly maxExperiencePatterns: number;\n /** Maximum action cache entries */\n readonly maxActionCacheEntries: number;\n /** Action cache TTL in milliseconds */\n readonly actionCacheTtlMs: number;\n /** Minimum confidence to consider a profile preference established */\n readonly minProfileConfidence: number;\n /** Minimum success rate to consider an experience pattern reliable */\n readonly minExperienceSuccessRate: number;\n /** Enable automatic cache eviction */\n readonly autoEviction: boolean;\n}\n\n/**\n * Default MobiMEM configuration.\n */\nexport const DEFAULT_MOBIMEM_CONFIG: MobiMemConfig = {\n dbPath: ':memory:',\n maxProfileEntries: 100,\n maxExperiencePatterns: 500,\n maxActionCacheEntries: 1000,\n actionCacheTtlMs: 3600000, // 1 hour\n minProfileConfidence: 0.6,\n minExperienceSuccessRate: 0.7,\n autoEviction: true,\n};\n\n/**\n * Zod schema for config validation.\n */\nexport const MobiMemConfigSchema = z.object({\n dbPath: z.string(),\n maxProfileEntries: z.number().int().positive().default(100),\n maxExperiencePatterns: z.number().int().positive().default(500),\n maxActionCacheEntries: z.number().int().positive().default(1000),\n actionCacheTtlMs: z.number().int().positive().default(3600000),\n minProfileConfidence: z.number().min(0).max(1).default(0.6),\n minExperienceSuccessRate: z.number().min(0).max(1).default(0.7),\n autoEviction: z.boolean().default(true),\n});\n\n/**\n * Statistics for MobiMEM system.\n */\nexport interface MobiMemStats {\n /** Profile memory stats */\n readonly profile: {\n readonly totalEntries: number;\n readonly uniqueEntities: number;\n readonly avgConfidence: number;\n };\n /** Experience memory stats */\n readonly experience: {\n readonly totalPatterns: number;\n readonly uniqueTaskTypes: number;\n readonly avgSuccessRate: number;\n };\n /** Action cache stats */\n readonly action: {\n readonly totalEntries: number;\n readonly totalHits: number;\n readonly hitRate: number;\n readonly timeSavedMs: number;\n };\n}\n\n/**\n * Profile memory interface.\n */\nexport interface IProfileMemory {\n /** Record a preference observation */\n observe(\n entityId: string,\n entityType: 'agent' | 'user',\n preferenceKey: string,\n preferenceValue: unknown\n ): ProfileEntry;\n\n /** Get preferences for an entity */\n getPreferences(entityId: string): readonly ProfileEntry[];\n\n /** Get a specific preference */\n getPreference(entityId: string, preferenceKey: string): ProfileEntry | null;\n\n /** Get established preferences (above confidence threshold) */\n getEstablishedPreferences(entityId: string): readonly ProfileEntry[];\n\n /** Clear preferences for an entity */\n clearPreferences(entityId: string): number;\n}\n\n/**\n * Experience memory interface.\n */\nexport interface IExperienceMemory {\n /** Record a workflow execution */\n recordExecution(\n taskType: string,\n actionSequence: readonly ActionStep[],\n outcome: ExecutionOutcome,\n contextSignature: string\n ): ExperienceEntry;\n\n /** Find matching patterns for a task type */\n findPatterns(taskType: string, limit?: number): readonly ExperienceEntry[];\n\n /** Find reliable patterns (above success rate threshold) */\n findReliablePatterns(taskType: string): readonly ExperienceEntry[];\n\n /** Get the best pattern for a context */\n getBestPattern(taskType: string, contextSignature: string): ExperienceEntry | null;\n\n /** Update pattern metrics after execution */\n updatePatternMetrics(patternId: string, success: boolean): void;\n}\n\n/**\n * Action cache interface.\n */\nexport interface IActionCache {\n /** Cache a successful action result */\n cache(input: unknown, result: unknown, durationMs: number): ActionCacheEntry;\n\n /** Try to get a cached result */\n get(input: unknown): ActionCacheEntry | null;\n\n /** Record a cache hit */\n recordHit(entryId: string): void;\n\n /** Evict expired entries */\n evictExpired(): number;\n\n /** Clear all cache entries */\n clear(): number;\n\n /** Get cache statistics */\n getStats(): { entries: number; hits: number; hitRate: number; timeSavedMs: number };\n}\n\n/**\n * MobiMEM interface combining all three modules.\n */\nexport interface IMobiMem {\n /** Profile memory module */\n readonly profile: IProfileMemory;\n /** Experience memory module */\n readonly experience: IExperienceMemory;\n /** Action cache module */\n readonly action: IActionCache;\n\n /** Get overall statistics */\n getStats(): MobiMemStats;\n\n /** Run maintenance (eviction, compaction) */\n runMaintenance(): void;\n\n /** Close and cleanup resources */\n close(): void;\n}\n","/**\n * nexus-agents/context - MobiMEM Implementation Details\n *\n * Internal implementation classes for MobiMEM modules.\n *\n * @module context/mobimem-impl\n * (Source: Issue #149, arXiv:2512.15784)\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { getTimeProvider } from '../core/index.js';\nimport type {\n IProfileMemory,\n IExperienceMemory,\n IActionCache,\n MobiMemConfig,\n ProfileEntry,\n ExperienceEntry,\n ActionCacheEntry,\n ActionStep,\n ExecutionOutcome,\n} from './mobimem-types.js';\nimport {\n calculateConfidence,\n generatePatternKey,\n hashInput,\n calculatePatternScore,\n computeUpdatedMetrics,\n countUnique,\n computeAverage,\n} from './mobimem-impl-helpers.js';\n\n/**\n * Profile Memory implementation.\n * Tracks agent/user preferences with confidence scoring.\n */\nexport class ProfileMemoryImpl implements IProfileMemory {\n private readonly entries: Map<string, ProfileEntry> = new Map();\n private readonly config: MobiMemConfig;\n\n constructor(config: MobiMemConfig) {\n this.config = config;\n }\n\n observe(\n entityId: string,\n entityType: 'agent' | 'user',\n preferenceKey: string,\n preferenceValue: unknown\n ): ProfileEntry {\n const key = `${entityId}:${preferenceKey}`;\n const existing = this.entries.get(key);\n const now = new Date(getTimeProvider().now());\n\n if (existing !== undefined) {\n const newObservationCount = existing.observationCount + 1;\n const updated: ProfileEntry = {\n ...existing,\n preferenceValue,\n confidence: calculateConfidence(newObservationCount),\n observationCount: newObservationCount,\n updatedAt: now,\n };\n this.entries.set(key, updated);\n return updated;\n }\n\n const entry: ProfileEntry = {\n id: randomUUID(),\n entityId,\n entityType,\n preferenceKey,\n preferenceValue,\n confidence: calculateConfidence(1),\n observationCount: 1,\n createdAt: now,\n updatedAt: now,\n };\n\n this.enforceLimit(entityId);\n this.entries.set(key, entry);\n return entry;\n }\n\n getPreferences(entityId: string): readonly ProfileEntry[] {\n const results: ProfileEntry[] = [];\n for (const entry of this.entries.values()) {\n if (entry.entityId === entityId) {\n results.push(entry);\n }\n }\n return results.sort((a, b) => b.confidence - a.confidence);\n }\n\n getPreference(entityId: string, preferenceKey: string): ProfileEntry | null {\n const key = `${entityId}:${preferenceKey}`;\n return this.entries.get(key) ?? null;\n }\n\n getEstablishedPreferences(entityId: string): readonly ProfileEntry[] {\n return this.getPreferences(entityId).filter(\n (p) => p.confidence >= this.config.minProfileConfidence\n );\n }\n\n clearPreferences(entityId: string): number {\n let count = 0;\n for (const [key, entry] of this.entries) {\n if (entry.entityId === entityId) {\n this.entries.delete(key);\n count++;\n }\n }\n return count;\n }\n\n getEntryCount(): number {\n return this.entries.size;\n }\n\n getUniqueEntities(): number {\n return countUnique(this.entries.values(), (e) => e.entityId);\n }\n\n getAverageConfidence(): number {\n return computeAverage(this.entries.values(), (e) => e.confidence);\n }\n\n private enforceLimit(entityId: string): void {\n const entityPrefs = this.getPreferences(entityId);\n if (entityPrefs.length >= this.config.maxProfileEntries) {\n const toRemove = entityPrefs[entityPrefs.length - 1];\n if (toRemove !== undefined) {\n const key = `${entityId}:${toRemove.preferenceKey}`;\n this.entries.delete(key);\n }\n }\n }\n}\n\n/**\n * Experience Memory implementation.\n * Tracks workflow execution patterns with success rates.\n */\nexport class ExperienceMemoryImpl implements IExperienceMemory {\n private readonly patterns: Map<string, ExperienceEntry> = new Map();\n private readonly config: MobiMemConfig;\n\n constructor(config: MobiMemConfig) {\n this.config = config;\n }\n\n recordExecution(\n taskType: string,\n actionSequence: readonly ActionStep[],\n outcome: ExecutionOutcome,\n contextSignature: string\n ): ExperienceEntry {\n const patternKey = generatePatternKey(taskType, actionSequence, contextSignature);\n const existing = this.patterns.get(patternKey);\n const now = new Date(getTimeProvider().now());\n\n if (existing !== undefined) {\n const metrics = computeUpdatedMetrics(\n existing.successCount,\n existing.attemptCount,\n outcome.success\n );\n const updated: ExperienceEntry = {\n ...existing,\n outcome,\n ...metrics,\n lastUsedAt: now,\n };\n this.patterns.set(patternKey, updated);\n return updated;\n }\n\n const entry: ExperienceEntry = {\n id: randomUUID(),\n taskType,\n actionSequence,\n outcome,\n contextSignature,\n successCount: outcome.success ? 1 : 0,\n attemptCount: 1,\n successRate: outcome.success ? 1 : 0,\n createdAt: now,\n lastUsedAt: now,\n };\n\n this.enforceLimit(taskType);\n this.patterns.set(patternKey, entry);\n return entry;\n }\n\n findPatterns(taskType: string, limit = 10): readonly ExperienceEntry[] {\n const results: ExperienceEntry[] = [];\n for (const entry of this.patterns.values()) {\n if (entry.taskType === taskType) {\n results.push(entry);\n }\n }\n return results.sort((a, b) => b.successRate - a.successRate).slice(0, limit);\n }\n\n findReliablePatterns(taskType: string): readonly ExperienceEntry[] {\n return this.findPatterns(taskType, 100).filter(\n (p) => p.successRate >= this.config.minExperienceSuccessRate && p.attemptCount >= 3\n );\n }\n\n getBestPattern(taskType: string, contextSignature: string): ExperienceEntry | null {\n let best: ExperienceEntry | null = null;\n let bestScore = -1;\n\n for (const entry of this.patterns.values()) {\n if (entry.taskType !== taskType) continue;\n\n const contextMatches = entry.contextSignature === contextSignature;\n const score = calculatePatternScore(entry.successRate, contextMatches, entry.attemptCount);\n\n if (score > bestScore && entry.successRate >= this.config.minExperienceSuccessRate) {\n best = entry;\n bestScore = score;\n }\n }\n\n return best;\n }\n\n updatePatternMetrics(patternId: string, success: boolean): void {\n for (const [key, entry] of this.patterns) {\n if (entry.id === patternId) {\n const metrics = computeUpdatedMetrics(entry.successCount, entry.attemptCount, success);\n this.patterns.set(key, {\n ...entry,\n ...metrics,\n lastUsedAt: new Date(getTimeProvider().now()),\n });\n return;\n }\n }\n }\n\n getPatternCount(): number {\n return this.patterns.size;\n }\n\n getUniqueTaskTypes(): number {\n return countUnique(this.patterns.values(), (e) => e.taskType);\n }\n\n getAverageSuccessRate(): number {\n return computeAverage(this.patterns.values(), (e) => e.successRate);\n }\n\n private enforceLimit(taskType: string): void {\n const typePatterns = this.findPatterns(taskType, 1000);\n if (typePatterns.length >= this.config.maxExperiencePatterns) {\n const toRemove = typePatterns[typePatterns.length - 1];\n if (toRemove !== undefined) {\n for (const [key, entry] of this.patterns) {\n if (entry.id === toRemove.id) {\n this.patterns.delete(key);\n break;\n }\n }\n }\n }\n }\n}\n\n/**\n * Action Cache implementation.\n * Caches successful interaction results for fast retrieval.\n */\nexport class ActionCacheImpl implements IActionCache {\n private readonly entries: Map<string, ActionCacheEntry> = new Map();\n private readonly config: MobiMemConfig;\n private totalHits = 0;\n private totalRequests = 0;\n\n constructor(config: MobiMemConfig) {\n this.config = config;\n }\n\n cache(input: unknown, result: unknown, durationMs: number): ActionCacheEntry {\n const inputHash = hashInput(input);\n const now = new Date(getTimeProvider().now());\n\n const entry: ActionCacheEntry = {\n id: randomUUID(),\n inputHash,\n input,\n result,\n originalDurationMs: durationMs,\n hitCount: 0,\n timeSavedMs: 0,\n cachedAt: now,\n lastAccessedAt: now,\n expiresAt: new Date(now.getTime() + this.config.actionCacheTtlMs),\n };\n\n this.enforceLimit();\n this.entries.set(inputHash, entry);\n return entry;\n }\n\n get(input: unknown): ActionCacheEntry | null {\n this.totalRequests++;\n const inputHash = hashInput(input);\n const entry = this.entries.get(inputHash);\n\n if (entry === undefined) return null;\n\n if (entry.expiresAt < new Date(getTimeProvider().now())) {\n this.entries.delete(inputHash);\n return null;\n }\n\n this.totalHits++;\n return entry;\n }\n\n recordHit(entryId: string): void {\n for (const [hash, entry] of this.entries) {\n if (entry.id === entryId) {\n const updated: ActionCacheEntry = {\n ...entry,\n hitCount: entry.hitCount + 1,\n timeSavedMs: entry.timeSavedMs + entry.originalDurationMs,\n lastAccessedAt: new Date(getTimeProvider().now()),\n };\n this.entries.set(hash, updated);\n return;\n }\n }\n }\n\n evictExpired(): number {\n const now = new Date(getTimeProvider().now());\n let evicted = 0;\n\n for (const [hash, entry] of this.entries) {\n if (entry.expiresAt < now) {\n this.entries.delete(hash);\n evicted++;\n }\n }\n\n return evicted;\n }\n\n clear(): number {\n const count = this.entries.size;\n this.entries.clear();\n this.totalHits = 0;\n this.totalRequests = 0;\n return count;\n }\n\n getStats(): { entries: number; hits: number; hitRate: number; timeSavedMs: number } {\n let totalTimeSaved = 0;\n for (const entry of this.entries.values()) {\n totalTimeSaved += entry.timeSavedMs;\n }\n\n return {\n entries: this.entries.size,\n hits: this.totalHits,\n hitRate: this.totalRequests > 0 ? this.totalHits / this.totalRequests : 0,\n timeSavedMs: totalTimeSaved,\n };\n }\n\n private enforceLimit(): void {\n if (this.entries.size >= this.config.maxActionCacheEntries) {\n this.evictExpired();\n\n if (this.entries.size >= this.config.maxActionCacheEntries) {\n const sorted = [...this.entries.entries()].sort(\n (a, b) => a[1].lastAccessedAt.getTime() - b[1].lastAccessedAt.getTime()\n );\n const toRemove = sorted[0];\n if (toRemove !== undefined) {\n this.entries.delete(toRemove[0]);\n }\n }\n }\n }\n}\n","/**\n * nexus-agents/core - Result Pattern\n *\n * Type-safe Result pattern for handling fallible operations without exceptions.\n * Inspired by Rust's Result<T, E> type.\n */\n\n/**\n * A discriminated union representing either success (Ok) or failure (Err).\n * @template T - The success value type\n * @template E - The error value type\n */\nexport type Result<T, E> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly error: E };\n\n/**\n * Creates a successful Result containing the given value.\n * @template T - The success value type\n * @param value - The success value\n * @returns A Result in the Ok state\n *\n * @example\n * ```typescript\n * const result = ok(42);\n * if (result.ok) {\n * console.log(result.value); // 42\n * }\n * ```\n */\nexport function ok<T>(value: T): Result<T, never> {\n return { ok: true, value };\n}\n\n/**\n * Creates a failed Result containing the given error.\n * @template E - The error value type\n * @param error - The error value\n * @returns A Result in the Err state\n *\n * @example\n * ```typescript\n * const result = err(new Error('not found'));\n * if (!result.ok) {\n * console.error(result.error.message); // \"not found\"\n * }\n * ```\n */\nexport function err<E>(error: E): Result<never, E> {\n return { ok: false, error };\n}\n\n/**\n * Type guard to check if a Result is in the Ok state.\n * @template T - The success value type\n * @template E - The error value type\n * @param result - The Result to check\n * @returns True if the Result is Ok\n */\nexport function isOk<T, E>(\n result: Result<T, E>\n): result is { readonly ok: true; readonly value: T } {\n return result.ok;\n}\n\n/**\n * Type guard to check if a Result is in the Err state.\n * @template T - The success value type\n * @template E - The error value type\n * @param result - The Result to check\n * @returns True if the Result is Err\n */\nexport function isErr<T, E>(\n result: Result<T, E>\n): result is { readonly ok: false; readonly error: E } {\n return !result.ok;\n}\n\n/**\n * Transforms the success value of a Result using the provided function.\n * @template T - The original success value type\n * @template U - The transformed success value type\n * @template E - The error value type\n * @param result - The Result to transform\n * @param fn - The transformation function\n * @returns A new Result with the transformed value\n */\nexport function map<T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E> {\n if (result.ok) {\n return ok(fn(result.value));\n }\n return result;\n}\n\n/**\n * Transforms the error value of a Result using the provided function.\n * @template T - The success value type\n * @template E - The original error value type\n * @template F - The transformed error value type\n * @param result - The Result to transform\n * @param fn - The transformation function\n * @returns A new Result with the transformed error\n */\nexport function mapErr<T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F> {\n if (!result.ok) {\n return err(fn(result.error));\n }\n return result;\n}\n\n/**\n * Extracts the success value from a Result.\n * @template T - The success value type\n * @template E - The error value type\n * @param result - The Result to unwrap\n * @returns The success value\n * @throws Throws an Error wrapping the error value if the Result is Err\n */\nexport function unwrap<T, E>(result: Result<T, E>): T {\n if (result.ok) {\n return result.value;\n }\n if (result.error instanceof Error) {\n throw result.error;\n }\n throw new Error(String(result.error));\n}\n\n/**\n * Extracts the success value from a Result, or returns a default value.\n * @template T - The success value type\n * @template E - The error value type\n * @param result - The Result to unwrap\n * @param defaultValue - The default value to return if Err\n * @returns The success value or the default value\n *\n * @example\n * ```typescript\n * const result = err(new Error('failed'));\n * const value = unwrapOr(result, 'fallback');\n * console.log(value); // \"fallback\"\n * ```\n */\nexport function unwrapOr<T, E>(result: Result<T, E>, defaultValue: T): T {\n if (result.ok) {\n return result.value;\n }\n return defaultValue;\n}\n","/**\n * nexus-agents/core - Safe JSON substring extraction\n *\n * Shared helpers for extracting the first JSON object/array substring from\n * LLM / CLI output. Uses index-based slicing (O(n), no regex backtracking)\n * to avoid polynomial ReDoS on pathological inputs.\n *\n * (Source: Issue #1912 — bug-hunt wave 1; generalized from the fix in\n * pipeline/agent-executor.ts for CodeQL js/polynomial-redos, #1899.)\n *\n * @module core/json-extract\n */\n\n/**\n * Extracts the first JSON array substring from text, defined as the span from\n * the first `[` to the last `]` at or after it. Returns `undefined` when no\n * array is found. O(n), no regex backtracking.\n */\nexport function extractJsonArray(text: string): string | undefined {\n const start = text.indexOf('[');\n if (start === -1) return undefined;\n const end = text.lastIndexOf(']');\n if (end <= start) return undefined;\n return text.slice(start, end + 1);\n}\n\n/**\n * Extracts the first JSON object substring from text, defined as the span from\n * the first `{` to the last `}` at or after it. Returns `undefined` when no\n * object is found. O(n), no regex backtracking.\n */\nexport function extractJsonObject(text: string): string | undefined {\n const start = text.indexOf('{');\n if (start === -1) return undefined;\n const end = text.lastIndexOf('}');\n if (end <= start) return undefined;\n return text.slice(start, end + 1);\n}\n","/**\n * nexus-agents/core - Step Event Vocabulary\n *\n * A typed, discriminated-union vocabulary for \"operator-meaningful\"\n * step boundaries. Emitted via a process-local EventEmitter so both\n * the JSON logger and the stderr ConsoleRenderer (peer subscribers)\n * observe the same events.\n *\n * @module core/step-events\n * (Source: #1930 — human console notifications; ux-expert design.)\n */\n\n/** Semantic kind of a step — used to color/route output. */\nexport type StepKind =\n | 'pipeline.stage'\n | 'workflow.node'\n | 'expert.exec'\n | 'consensus.vote'\n | 'mcp.tool'\n | 'cli.call'\n | 'graph.hook';\n\n/** Error categories mirror the subprocess-adapter classifier so renderer can tag failures. */\nexport type StepErrorCategory =\n | 'timeout'\n | 'parse'\n | 'connection'\n | 'execution'\n | 'policy'\n | 'rate_limit'\n | 'unknown';\n\ninterface StepEventBase {\n /** Monotonic-enough unique id generated at step start. */\n stepId: string;\n /** Ambient parent from AsyncLocalStorage, undefined at root. */\n parentStepId?: string;\n /** Operator-facing step name, e.g. 'research', 'vote:security'. */\n name: string;\n /** Semantic kind. */\n kind: StepKind;\n /** Optional key/value attributes surfaced into logs. */\n attrs?: Record<string, unknown>;\n}\n\nexport interface StepStartedEvent extends StepEventBase {\n event: 'step.started';\n /** ISO timestamp at start. */\n startedAt: string;\n}\n\nexport interface StepCompletedEvent extends StepEventBase {\n event: 'step.completed';\n /** Wall-clock duration, milliseconds. */\n durationMs: number;\n status: 'ok';\n /** Optional one-line human summary (<=120 chars after truncation). */\n summary?: string;\n}\n\nexport interface StepFailedEvent extends StepEventBase {\n event: 'step.failed';\n durationMs: number;\n status: 'failed';\n errorCategory: StepErrorCategory;\n /** One-line error summary (truncated at 120 chars). */\n summary?: string;\n}\n\nexport type StepEvent = StepStartedEvent | StepCompletedEvent | StepFailedEvent;\n\n/** Max characters of summary shown to operator. */\nexport const STEP_SUMMARY_MAX_LEN = 120;\n\n/** Truncate a summary string for display without mutating the source. */\nexport function truncateSummary(s: string | undefined): string | undefined {\n if (s === undefined) return undefined;\n if (s.length <= STEP_SUMMARY_MAX_LEN) return s;\n return s.slice(0, STEP_SUMMARY_MAX_LEN - 1) + '…';\n}\n","/**\n * nexus-agents/core - Step Event Bus\n *\n * Process-local EventEmitter that carries `StepEvent`s. Multiple peer\n * subscribers (the JSON logger bridge, the stderr ConsoleRenderer, the\n * MCP notifier) observe the same events.\n *\n * Keep this module tiny and free of side effects so importing it doesn't\n * force a subscription.\n *\n * @module core/step-bus\n */\n\nimport { EventEmitter } from 'node:events';\nimport type { StepEvent } from './step-events.js';\n\n/**\n * Singleton emitter. Subscribers call `stepBus.on('step', handler)`.\n * Publishers call `stepBus.emit('step', event)`.\n */\nclass StepBus extends EventEmitter {\n override emit(eventName: 'step', event: StepEvent): boolean {\n return super.emit(eventName, event);\n }\n\n override on(eventName: 'step', listener: (event: StepEvent) => void): this {\n return super.on(eventName, listener);\n }\n\n override off(eventName: 'step', listener: (event: StepEvent) => void): this {\n return super.off(eventName, listener);\n }\n}\n\n/** Process-local step event bus. */\nexport const stepBus = new StepBus();\n\n// Node default is 10 listeners; we expect ≤5 (JSON logger, renderer, MCP notifier, tests).\n// Still, raise the cap slightly so test fixtures that attach/detach don't warn.\nstepBus.setMaxListeners(20);\n","/**\n * nexus-agents/core - `withStep` helper\n *\n * Wraps an async operation in a `step.started` / `step.completed` /\n * `step.failed` trio, propagating parent context via AsyncLocalStorage so\n * nested `withStep` calls get correct parentStepId without threading.\n *\n * @module core/with-step\n * (Source: #1930 — human console notifications; ux-expert design.)\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { randomBytes } from 'node:crypto';\nimport { getTimeProvider } from './time-provider.js';\nimport { stepBus } from './step-bus.js';\nimport type { StepEvent, StepErrorCategory, StepKind } from './step-events.js';\nimport { truncateSummary } from './step-events.js';\n\nexport interface StepOptions {\n /** Operator-facing name, e.g. 'research'. */\n readonly name: string;\n /** Semantic kind for routing/coloring. */\n readonly kind: StepKind;\n /** Optional attrs surfaced into events. */\n readonly attrs?: Record<string, unknown>;\n /**\n * Override parent. Default: ambient value from AsyncLocalStorage.\n * Pass `null` to explicitly start a new root.\n */\n readonly parent?: string | null;\n}\n\nexport interface StepContext {\n readonly stepId: string;\n /** Attach a one-line human summary shown on completion. */\n setSummary(text: string): void;\n /** Convenience factory for nested steps that inherit this parent. */\n child(opts: Omit<StepOptions, 'parent'>): StepOptions;\n}\n\n/** AsyncLocalStorage carrying just the parent step id. */\nconst als = new AsyncLocalStorage<string>();\n\n/** Expose the current ambient parent id (undefined at root). */\nexport function currentStepId(): string | undefined {\n return als.getStore();\n}\n\n/** Compact base62-ish id suitable for stepId. */\nfunction newStepId(): string {\n // 8 random bytes → 16 hex chars; enough for a process lifetime.\n return randomBytes(8).toString('hex');\n}\n\n/** Keyword → category table for categorizeError. Evaluated in order. */\nconst ERROR_CATEGORY_KEYWORDS: ReadonlyArray<{ match: readonly string[]; cat: StepErrorCategory }> =\n [\n { match: ['timeout', 'timed out'], cat: 'timeout' },\n { match: ['rate limit', 'rate-limited'], cat: 'rate_limit' },\n { match: ['parse', 'json'], cat: 'parse' },\n { match: ['connection', 'econnref', 'network'], cat: 'connection' },\n { match: ['policy', 'not allowed', 'forbidden'], cat: 'policy' },\n ];\n\n/** Classify an error into one of the known StepErrorCategory values. */\nfunction categorizeError(err: unknown): StepErrorCategory {\n if (!(err instanceof Error)) return 'unknown';\n const m = err.message.toLowerCase();\n for (const { match, cat } of ERROR_CATEGORY_KEYWORDS) {\n if (match.some((kw) => m.includes(kw))) return cat;\n }\n return 'execution';\n}\n\n/**\n * Emit a `step.started` / `step.completed` / `step.failed` trio around `fn`.\n *\n * The step is reified in AsyncLocalStorage so any nested `withStep` inside\n * `fn` (even through await points) inherits this step as parent.\n *\n * Semantics:\n * - Emits `step.started` synchronously before `fn` runs.\n * - On resolve: emits `step.completed` with durationMs + optional summary.\n * - On reject: emits `step.failed` with durationMs + errorCategory and\n * rethrows the original error unchanged.\n *\n * Never swallows errors.\n */\ninterface StepRuntime {\n readonly stepId: string;\n readonly parentStepId: string | undefined;\n readonly opts: StepOptions;\n readonly startNs: number;\n}\n\nfunction resolveParent(opts: StepOptions): string | undefined {\n if (opts.parent === null) return undefined;\n return opts.parent ?? als.getStore();\n}\n\nfunction emitStarted(rt: StepRuntime): void {\n const event: StepEvent = {\n event: 'step.started',\n stepId: rt.stepId,\n name: rt.opts.name,\n kind: rt.opts.kind,\n startedAt: new Date(rt.startNs).toISOString(),\n ...(rt.parentStepId !== undefined ? { parentStepId: rt.parentStepId } : {}),\n ...(rt.opts.attrs !== undefined ? { attrs: rt.opts.attrs } : {}),\n };\n stepBus.emit('step', event);\n}\n\nfunction emitCompleted(rt: StepRuntime, summary: string | undefined): void {\n const event: StepEvent = {\n event: 'step.completed',\n stepId: rt.stepId,\n name: rt.opts.name,\n kind: rt.opts.kind,\n durationMs: getTimeProvider().now() - rt.startNs,\n status: 'ok',\n ...(rt.parentStepId !== undefined ? { parentStepId: rt.parentStepId } : {}),\n ...(rt.opts.attrs !== undefined ? { attrs: rt.opts.attrs } : {}),\n ...(summary !== undefined ? { summary } : {}),\n };\n stepBus.emit('step', event);\n}\n\nfunction emitFailed(rt: StepRuntime, err: unknown, summary: string | undefined): void {\n const errSummary = summary ?? (err instanceof Error ? truncateSummary(err.message) : undefined);\n const event: StepEvent = {\n event: 'step.failed',\n stepId: rt.stepId,\n name: rt.opts.name,\n kind: rt.opts.kind,\n durationMs: getTimeProvider().now() - rt.startNs,\n status: 'failed',\n errorCategory: categorizeError(err),\n ...(rt.parentStepId !== undefined ? { parentStepId: rt.parentStepId } : {}),\n ...(rt.opts.attrs !== undefined ? { attrs: rt.opts.attrs } : {}),\n ...(errSummary !== undefined ? { summary: errSummary } : {}),\n };\n stepBus.emit('step', event);\n}\n\nexport async function withStep<T>(\n opts: StepOptions,\n fn: (ctx: StepContext) => Promise<T>\n): Promise<T> {\n const rt: StepRuntime = {\n stepId: newStepId(),\n parentStepId: resolveParent(opts),\n opts,\n startNs: getTimeProvider().now(),\n };\n let summary: string | undefined;\n const ctx: StepContext = {\n stepId: rt.stepId,\n setSummary(text: string): void {\n summary = truncateSummary(text);\n },\n child(childOpts: Omit<StepOptions, 'parent'>): StepOptions {\n return { ...childOpts, parent: rt.stepId };\n },\n };\n\n emitStarted(rt);\n try {\n const result = await als.run(rt.stepId, () => fn(ctx));\n emitCompleted(rt, summary);\n return result;\n } catch (err: unknown) {\n emitFailed(rt, err, summary);\n throw err;\n }\n}\n","/**\n * nexus-agents/core - Console Renderer for Step Events\n *\n * Subscribes to the step-bus and writes one line per event to **stderr**.\n * Stdout stays clean for JSON / MCP frames / tool output pipes.\n *\n * Output shape (TTY, with color/glyphs):\n * ⋮ research … 0.0s\n * ✓ research 2.3s 42 papers, 3 clusters\n * ⋮ vote:security (i=1) … 0.0s\n * ✗ vote:security (i=1) 4.7s FAILED timeout on codex\n *\n * Non-TTY / NO_COLOR / CI: ASCII-only glyphs `[start] / [ok] / [FAIL]`.\n *\n * @module core/console-renderer\n * (Source: #1930 — human console notifications; ux-expert design.)\n */\n\nimport { stepBus } from './step-bus.js';\nimport type { StepEvent } from './step-events.js';\n\ninterface RendererOptions {\n /** Writer used for output. Default: process.stderr.write bound. */\n readonly write?: (line: string) => void;\n /** TTY mode forces glyphs+color; CI mode forces ASCII. Auto-detected if omitted. */\n readonly tty?: boolean;\n /** Honor NO_COLOR. Default reads `process.env.NO_COLOR`. */\n readonly noColor?: boolean;\n}\n\ninterface ActiveRenderer {\n dispose(): void;\n}\n\nconst DEPTH_INDENT = ' '; // two spaces per parent level\n\n/** Map stepId → parentStepId so we can compute depth for indent. */\nconst parents = new Map<string, string | undefined>();\n\nfunction depthFor(stepId: string, parentId: string | undefined): number {\n if (parentId === undefined) return 0;\n let depth = 0;\n let cur: string | undefined = parentId;\n const seen = new Set<string>();\n while (cur !== undefined && !seen.has(cur)) {\n seen.add(cur);\n depth += 1;\n cur = parents.get(cur);\n }\n return depth;\n}\n\nfunction fmtDuration(ms: number): string {\n if (ms < 1_000) return `${String(ms)}ms`;\n const s = ms / 1000;\n if (s < 60) return `${s.toFixed(1)}s`;\n const min = Math.floor(s / 60);\n const secs = Math.round(s - min * 60);\n return `${String(min)}m${String(secs).padStart(2, '0')}s`;\n}\n\nfunction padRight(s: string, width: number): string {\n if (s.length >= width) return s;\n return s + ' '.repeat(width - s.length);\n}\n\ninterface Formatter {\n start(depth: number, name: string): string;\n ok(depth: number, name: string, durationMs: number, summary: string | undefined): string;\n fail(\n depth: number,\n name: string,\n durationMs: number,\n category: string,\n summary: string | undefined\n ): string;\n}\n\nconst glyphFmt: Formatter = {\n start(depth, name) {\n return `${DEPTH_INDENT.repeat(depth)}⋮ ${padRight(name, 28)}…\\n`;\n },\n ok(depth, name, durationMs, summary) {\n const base = `${DEPTH_INDENT.repeat(depth)}✓ ${padRight(name, 28)}${fmtDuration(durationMs).padStart(6)}`;\n return summary !== undefined && summary !== '' ? `${base} ${summary}\\n` : `${base}\\n`;\n },\n fail(depth, name, durationMs, category, summary) {\n const base = `${DEPTH_INDENT.repeat(depth)}✗ ${padRight(name, 28)}${fmtDuration(durationMs).padStart(6)} FAILED ${category}`;\n return summary !== undefined && summary !== '' ? `${base}: ${summary}\\n` : `${base}\\n`;\n },\n};\n\nconst asciiFmt: Formatter = {\n start(depth, name) {\n return `${DEPTH_INDENT.repeat(depth)}[start] ${name}\\n`;\n },\n ok(depth, name, durationMs, summary) {\n const base = `${DEPTH_INDENT.repeat(depth)}[ ok ] ${padRight(name, 28)} ${fmtDuration(durationMs)}`;\n return summary !== undefined && summary !== '' ? `${base} ${summary}\\n` : `${base}\\n`;\n },\n fail(depth, name, durationMs, category, summary) {\n const base = `${DEPTH_INDENT.repeat(depth)}[FAIL ] ${padRight(name, 28)} ${fmtDuration(durationMs)} [${category}]`;\n return summary !== undefined && summary !== '' ? `${base}: ${summary}\\n` : `${base}\\n`;\n },\n};\n\n/**\n * Start the stderr console renderer. Returns a disposer.\n * Safe to call multiple times — later calls replace earlier subscription.\n */\nexport function startConsoleRenderer(opts: RendererOptions = {}): ActiveRenderer {\n const write =\n opts.write ??\n ((line: string): void => {\n process.stderr.write(line);\n });\n const isTty = opts.tty ?? process.stderr.isTTY;\n const noColor = opts.noColor ?? process.env['NO_COLOR'] !== undefined;\n const fmt: Formatter = isTty && !noColor ? glyphFmt : asciiFmt;\n\n const handler = (event: StepEvent): void => {\n const depth = depthFor(event.stepId, event.parentStepId);\n switch (event.event) {\n case 'step.started':\n parents.set(event.stepId, event.parentStepId);\n write(fmt.start(depth, event.name));\n return;\n case 'step.completed':\n write(fmt.ok(depth, event.name, event.durationMs, event.summary));\n parents.delete(event.stepId);\n return;\n case 'step.failed':\n write(fmt.fail(depth, event.name, event.durationMs, event.errorCategory, event.summary));\n parents.delete(event.stepId);\n return;\n }\n };\n\n stepBus.on('step', handler);\n return {\n dispose(): void {\n stepBus.off('step', handler);\n },\n };\n}\n","/**\n * nexus-agents/core - Step Logger Bridge\n *\n * Subscribes to the step-bus and emits a structured JSON log entry for\n * every StepEvent. This preserves the existing \"JSON stream is the source\n * of truth\" invariant while enabling the stderr ConsoleRenderer to be a\n * purely additive, optional overlay.\n *\n * @module core/step-logger-bridge\n */\n\nimport { createLogger } from './logger.js';\nimport { stepBus } from './step-bus.js';\nimport type { StepEvent } from './step-events.js';\n\nconst logger = createLogger({ component: 'step-events' });\n\ninterface ActiveBridge {\n dispose(): void;\n}\n\n/**\n * Start publishing step events as info-level JSON log entries.\n * Returns a disposer. Safe to call multiple times.\n */\nexport function startStepLoggerBridge(): ActiveBridge {\n const handler = (event: StepEvent): void => {\n // Use logger.info for started/completed, logger.warn for failed.\n // Flat payload — consumers read discriminator off `event`.\n const payload = { ...event };\n if (event.event === 'step.failed') {\n logger.warn('step.failed', payload);\n } else {\n logger.info(event.event, payload);\n }\n };\n stepBus.on('step', handler);\n return {\n dispose(): void {\n stepBus.off('step', handler);\n },\n };\n}\n","/**\n * nexus-agents/core - Step Notification Bootstrap\n *\n * One-shot bootstrap that wires the step event bus to:\n * 1. The JSON logger (always on — preserves source-of-truth invariant).\n * 2. The stderr ConsoleRenderer (on by default for CLI, off for MCP stdio\n * server mode to avoid corrupting JSON-RPC frames; env override\n * `NEXUS_CONSOLE=0|1`).\n *\n * Call from CLI / server entrypoints exactly once at startup.\n *\n * @module core/step-notifications\n */\n\nimport { startStepLoggerBridge } from './step-logger-bridge.js';\nimport { startConsoleRenderer } from './console-renderer.js';\n\nexport interface BootstrapOptions {\n /**\n * What kind of runtime we're in. CLI gets the renderer by default; MCP\n * stdio server does NOT (stdout is reserved for JSON-RPC, and the MCP\n * notifier already surfaces progress through the MCP channel).\n */\n readonly mode: 'cli' | 'mcp-stdio' | 'mcp-http';\n}\n\nexport interface NotificationHandles {\n dispose(): void;\n}\n\n/**\n * Decide whether the stderr renderer should be enabled.\n *\n * Precedence:\n * NEXUS_CONSOLE=0 → always off\n * NEXUS_CONSOLE=1 → always on\n * else: on for cli, off for mcp-stdio, on for mcp-http\n */\nexport function shouldEnableConsoleRenderer(mode: BootstrapOptions['mode']): boolean {\n const env = process.env['NEXUS_CONSOLE'];\n if (env === '0' || env === 'false' || env === 'off') return false;\n if (env === '1' || env === 'true' || env === 'on') return true;\n return mode !== 'mcp-stdio';\n}\n\n/**\n * Process-global handle. Bootstrap is idempotent — repeat calls return the\n * existing handle so CLI dispatchers (and tests exercising them) don't stack\n * up duplicate listeners on the step bus.\n */\nlet active: NotificationHandles | undefined;\n\n/**\n * Wire up both subscribers. Returns a single disposer that tears down\n * both (useful for tests). Safe to call multiple times.\n */\nexport function bootstrapStepNotifications(opts: BootstrapOptions): NotificationHandles {\n if (active !== undefined) return active;\n const bridge = startStepLoggerBridge();\n const renderer = shouldEnableConsoleRenderer(opts.mode) ? startConsoleRenderer() : undefined;\n active = {\n dispose(): void {\n bridge.dispose();\n renderer?.dispose();\n active = undefined;\n },\n };\n return active;\n}\n","/**\n * nexus-agents/core - Error Hierarchy\n *\n * Structured error classes for consistent error handling across the codebase.\n */\n\n/**\n * Error codes for all Nexus Agents errors.\n */\nexport const ErrorCode = {\n // Validation errors\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n INVALID_INPUT: 'INVALID_INPUT',\n MISSING_REQUIRED: 'MISSING_REQUIRED',\n SCHEMA_ERROR: 'SCHEMA_ERROR',\n\n // Configuration errors\n CONFIG_ERROR: 'CONFIG_ERROR',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_INVALID: 'CONFIG_INVALID',\n\n // Model errors\n MODEL_ERROR: 'MODEL_ERROR',\n MODEL_UNAVAILABLE: 'MODEL_UNAVAILABLE',\n MODEL_RATE_LIMITED: 'MODEL_RATE_LIMITED',\n MODEL_TIMEOUT: 'MODEL_TIMEOUT',\n\n // Agent errors\n AGENT_ERROR: 'AGENT_ERROR',\n AGENT_NOT_FOUND: 'AGENT_NOT_FOUND',\n AGENT_EXECUTION_FAILED: 'AGENT_EXECUTION_FAILED',\n\n // Agent failure categories (Source: arxiv:2509.25370 - Where LLM Agents Fail)\n AGENT_MEMORY_FAILURE: 'AGENT_MEMORY_FAILURE',\n AGENT_REFLECTION_FAILURE: 'AGENT_REFLECTION_FAILURE',\n AGENT_PLANNING_FAILURE: 'AGENT_PLANNING_FAILURE',\n AGENT_ACTION_FAILURE: 'AGENT_ACTION_FAILURE',\n\n // Workflow errors\n WORKFLOW_ERROR: 'WORKFLOW_ERROR',\n WORKFLOW_NOT_FOUND: 'WORKFLOW_NOT_FOUND',\n WORKFLOW_PARSE_ERROR: 'WORKFLOW_PARSE_ERROR',\n WORKFLOW_EXECUTION_FAILED: 'WORKFLOW_EXECUTION_FAILED',\n\n // Security errors\n SECURITY_ERROR: 'SECURITY_ERROR',\n PATH_TRAVERSAL: 'PATH_TRAVERSAL',\n UNAUTHORIZED: 'UNAUTHORIZED',\n\n // System errors\n TIMEOUT_ERROR: 'TIMEOUT_ERROR',\n RATE_LIMIT_ERROR: 'RATE_LIMIT_ERROR',\n INTERNAL_ERROR: 'INTERNAL_ERROR',\n} as const;\n\nexport type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];\n\n/**\n * Serialized error format for JSON output.\n */\nexport interface SerializedError {\n name: string;\n code: ErrorCode;\n message: string;\n context?: Record<string, unknown>;\n cause?: SerializedError;\n stack?: string;\n}\n\n/**\n * Options for creating a NexusError.\n */\nexport interface NexusErrorOptions {\n code: ErrorCode;\n cause?: Error;\n context?: Record<string, unknown>;\n}\n\n/**\n * Base error class for all Nexus Agents errors.\n */\nexport class NexusError extends Error {\n readonly code: ErrorCode;\n readonly context: Record<string, unknown> | undefined;\n override readonly cause: Error | undefined;\n\n constructor(message: string, options: NexusErrorOptions) {\n super(message);\n this.name = 'NexusError';\n this.code = options.code;\n this.cause = options.cause;\n this.context = options.context;\n if (typeof Error.captureStackTrace === 'function') {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /**\n * Serializes the error to a JSON-safe object.\n */\n toJSON(): SerializedError {\n const result: SerializedError = {\n name: this.name,\n code: this.code,\n message: this.message,\n };\n if (this.context !== undefined) {\n result.context = this.context;\n }\n if (this.cause instanceof NexusError) {\n result.cause = this.cause.toJSON();\n }\n if (this.stack !== undefined) {\n result.stack = this.stack;\n }\n return result;\n }\n}\n\n/**\n * Validation error for invalid inputs or schema violations.\n */\nexport class ValidationError extends NexusError {\n constructor(message: string, options?: Partial<Omit<NexusErrorOptions, 'code'>>) {\n super(message, { code: ErrorCode.VALIDATION_ERROR, ...options });\n this.name = 'ValidationError';\n }\n}\n\n/**\n * Configuration error for missing or invalid configuration.\n */\nexport class ConfigError extends NexusError {\n constructor(message: string, options?: Partial<Omit<NexusErrorOptions, 'code'>>) {\n super(message, { code: ErrorCode.CONFIG_ERROR, ...options });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Model error for model adapter failures.\n *\n * Subclasses (e.g., AdapterModelError) can pass a specific ErrorCode\n * to categorize failures more granularly (rate-limited, timeout, etc.).\n */\nexport class ModelError extends NexusError {\n constructor(message: string, options?: Partial<NexusErrorOptions>) {\n const code = options?.code ?? ErrorCode.MODEL_ERROR;\n const nexusOpts: NexusErrorOptions = { code };\n if (options?.cause !== undefined) {\n nexusOpts.cause = options.cause;\n }\n if (options?.context !== undefined) {\n nexusOpts.context = options.context;\n }\n super(message, nexusOpts);\n this.name = 'ModelError';\n }\n}\n\n/**\n * Agent error for agent execution failures.\n */\nexport class AgentError extends NexusError {\n constructor(message: string, options?: Partial<Omit<NexusErrorOptions, 'code'>>) {\n super(message, { code: ErrorCode.AGENT_ERROR, ...options });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Agent failure categories for structured error taxonomy.\n * (Source: arxiv:2509.25370 - Where LLM Agents Fail)\n *\n * These categories enable better failure analysis and targeted improvements:\n * - MEMORY: Failed to retrieve or store relevant context\n * - REFLECTION: Failed to properly self-evaluate or verify outputs\n * - PLANNING: Failed to create valid execution plan\n * - ACTION: Failed to execute planned action correctly\n * - SYSTEM: Infrastructure or external system failure\n */\nexport const AgentErrorCategory = {\n MEMORY: 'memory',\n REFLECTION: 'reflection',\n PLANNING: 'planning',\n ACTION: 'action',\n SYSTEM: 'system',\n} as const;\n\nexport type AgentErrorCategory = (typeof AgentErrorCategory)[keyof typeof AgentErrorCategory];\n\n/**\n * Options for creating a categorized agent failure error.\n */\nexport interface AgentFailureOptions extends Partial<Omit<NexusErrorOptions, 'code'>> {\n readonly category: AgentErrorCategory;\n readonly recoverable?: boolean;\n readonly retryable?: boolean;\n readonly suggestedAction?: string;\n}\n\n/**\n * Maps agent error category to error code.\n */\nfunction categoryToErrorCode(category: AgentErrorCategory): ErrorCode {\n const codeMap: Record<AgentErrorCategory, ErrorCode> = {\n memory: ErrorCode.AGENT_MEMORY_FAILURE,\n reflection: ErrorCode.AGENT_REFLECTION_FAILURE,\n planning: ErrorCode.AGENT_PLANNING_FAILURE,\n action: ErrorCode.AGENT_ACTION_FAILURE,\n system: ErrorCode.INTERNAL_ERROR,\n };\n return codeMap[category];\n}\n\n/**\n * Structured agent failure error with category for analysis.\n * Enables failure pattern detection and targeted improvements.\n */\nexport class AgentFailureError extends NexusError {\n readonly category: AgentErrorCategory;\n readonly recoverable: boolean;\n readonly retryable: boolean;\n readonly suggestedAction: string | undefined;\n\n constructor(message: string, options: AgentFailureOptions) {\n super(message, {\n code: categoryToErrorCode(options.category),\n ...(options.cause !== undefined ? { cause: options.cause } : {}),\n ...(options.context !== undefined ? { context: options.context } : {}),\n });\n this.name = 'AgentFailureError';\n this.category = options.category;\n this.recoverable = options.recoverable ?? false;\n this.retryable = options.retryable ?? false;\n this.suggestedAction = options.suggestedAction;\n }\n\n override toJSON(): SerializedError & { category: AgentErrorCategory; recoverable: boolean } {\n return {\n ...super.toJSON(),\n category: this.category,\n recoverable: this.recoverable,\n };\n }\n}\n\n/**\n * Memory failure: agent failed to retrieve or store context.\n */\nexport class MemoryFailureError extends AgentFailureError {\n constructor(message: string, options?: Partial<Omit<AgentFailureOptions, 'category'>>) {\n super(message, {\n ...options,\n category: AgentErrorCategory.MEMORY,\n retryable: options?.retryable ?? true,\n suggestedAction: options?.suggestedAction ?? 'Verify context availability and retry',\n });\n this.name = 'MemoryFailureError';\n }\n}\n\n/**\n * Reflection failure: agent failed to self-evaluate or verify outputs.\n */\nexport class ReflectionFailureError extends AgentFailureError {\n constructor(message: string, options?: Partial<Omit<AgentFailureOptions, 'category'>>) {\n super(message, {\n ...options,\n category: AgentErrorCategory.REFLECTION,\n retryable: options?.retryable ?? true,\n suggestedAction: options?.suggestedAction ?? 'Request explicit verification step',\n });\n this.name = 'ReflectionFailureError';\n }\n}\n\n/**\n * Planning failure: agent failed to create valid execution plan.\n */\nexport class PlanningFailureError extends AgentFailureError {\n constructor(message: string, options?: Partial<Omit<AgentFailureOptions, 'category'>>) {\n super(message, {\n ...options,\n category: AgentErrorCategory.PLANNING,\n retryable: options?.retryable ?? true,\n suggestedAction: options?.suggestedAction ?? 'Simplify task or provide more constraints',\n });\n this.name = 'PlanningFailureError';\n }\n}\n\n/**\n * Action failure: agent failed to execute planned action correctly.\n */\nexport class ActionFailureError extends AgentFailureError {\n constructor(message: string, options?: Partial<Omit<AgentFailureOptions, 'category'>>) {\n super(message, {\n ...options,\n category: AgentErrorCategory.ACTION,\n retryable: options?.retryable ?? true,\n suggestedAction: options?.suggestedAction ?? 'Retry action or use alternative approach',\n });\n this.name = 'ActionFailureError';\n }\n}\n\n/**\n * Workflow error for workflow parsing or execution failures.\n */\nexport class WorkflowError extends NexusError {\n constructor(message: string, options?: Partial<Omit<NexusErrorOptions, 'code'>>) {\n super(message, { code: ErrorCode.WORKFLOW_ERROR, ...options });\n this.name = 'WorkflowError';\n }\n}\n\n/**\n * Security error for security violations.\n */\nexport class SecurityError extends NexusError {\n constructor(message: string, options?: Partial<Omit<NexusErrorOptions, 'code'>>) {\n super(message, { code: ErrorCode.SECURITY_ERROR, ...options });\n this.name = 'SecurityError';\n }\n}\n\n/**\n * Timeout error for operation timeouts.\n */\nexport class TimeoutError extends NexusError {\n constructor(message: string, options?: Partial<Omit<NexusErrorOptions, 'code'>>) {\n super(message, { code: ErrorCode.TIMEOUT_ERROR, ...options });\n this.name = 'TimeoutError';\n }\n}\n\n/**\n * Options for creating a rate limit error with actionable context.\n * (Source: Issue #996 — Rate limit error surfacing)\n */\nexport interface RateLimitErrorOptions extends Partial<Omit<NexusErrorOptions, 'code'>> {\n /** Milliseconds until the rate limit window resets. */\n readonly retryAfterMs?: number;\n /** ISO timestamp when the rate limit window resets. */\n readonly windowResetAt?: string;\n /** Provider or adapter that was rate-limited. */\n readonly provider?: string;\n}\n\n/**\n * Rate limit error with actionable backoff context.\n * (Source: Issue #996 — Rate limit error surfacing)\n */\nexport class RateLimitError extends NexusError {\n readonly retryAfterMs: number | undefined;\n readonly windowResetAt: string | undefined;\n readonly provider: string | undefined;\n\n constructor(message: string, options?: RateLimitErrorOptions) {\n super(message, { code: ErrorCode.RATE_LIMIT_ERROR, ...options });\n this.name = 'RateLimitError';\n this.retryAfterMs = options?.retryAfterMs;\n this.windowResetAt = options?.windowResetAt;\n this.provider = options?.provider;\n }\n}\n\n// ============================================================================\n// Error Categories (ADR-0009)\n// ============================================================================\n\n/**\n * Error category for classifying errors by type.\n * Used for monitoring, error handling, and observability.\n * (Source: ADR-0009 - Error Class Hierarchy)\n */\nexport const ErrorCategory = {\n /** Input validation failures */\n VALIDATION: 'validation',\n /** Failed operations (retryable) */\n OPERATION: 'operation',\n /** Configuration issues */\n CONFIGURATION: 'configuration',\n /** External resource failures */\n RESOURCE: 'resource',\n /** Security violations */\n SECURITY: 'security',\n /** Internal/system errors */\n INTERNAL: 'internal',\n} as const;\n\nexport type ErrorCategory = (typeof ErrorCategory)[keyof typeof ErrorCategory];\n\n/**\n * Operation error for failed operations that may be retryable.\n * Use for transient failures in internal operations.\n * (Source: ADR-0009 - Error Class Hierarchy)\n */\nexport class OperationError extends NexusError {\n readonly retryable: boolean;\n\n constructor(\n message: string,\n options?: Partial<Omit<NexusErrorOptions, 'code'>> & { retryable?: boolean }\n ) {\n super(message, { code: ErrorCode.INTERNAL_ERROR, ...options });\n this.name = 'OperationError';\n this.retryable = options?.retryable ?? true;\n }\n}\n\n/**\n * Resource error for external resource failures.\n * Use for failures interacting with external systems (APIs, databases, files).\n * (Source: ADR-0009 - Error Class Hierarchy)\n */\nexport class ResourceError extends NexusError {\n readonly resourceType: string;\n readonly retryable: boolean;\n\n constructor(\n message: string,\n options: Partial<Omit<NexusErrorOptions, 'code'>> & {\n resourceType: string;\n retryable?: boolean;\n }\n ) {\n super(message, { code: ErrorCode.INTERNAL_ERROR, ...options });\n this.name = 'ResourceError';\n this.resourceType = options.resourceType;\n this.retryable = options.retryable ?? true;\n }\n}\n\n/**\n * Get the error category for an error.\n * Useful for monitoring and error handling.\n */\nexport function getErrorCategory(error: Error): ErrorCategory {\n if (error instanceof ValidationError) return ErrorCategory.VALIDATION;\n if (error instanceof ConfigError) return ErrorCategory.CONFIGURATION;\n if (error instanceof SecurityError) return ErrorCategory.SECURITY;\n if (error instanceof ResourceError) return ErrorCategory.RESOURCE;\n if (error instanceof OperationError) return ErrorCategory.OPERATION;\n if (error instanceof NexusError) return ErrorCategory.INTERNAL;\n return ErrorCategory.INTERNAL;\n}\n\n/**\n * Check if an error is retryable.\n */\nexport function isRetryableError(error: Error): boolean {\n if (error instanceof OperationError) return error.retryable;\n if (error instanceof ResourceError) return error.retryable;\n if (error instanceof AgentFailureError) return error.retryable;\n if (error instanceof RateLimitError) return true;\n if (error instanceof TimeoutError) return true;\n return false;\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Convert an unknown error to an Error instance.\n * Useful for wrapping errors in Result types from try-catch blocks.\n */\nexport function toError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\n/**\n * Extract error message from unknown error type.\n * Safely converts any error value to a human-readable message string.\n *\n * @param error - Unknown error value\n * @param fallback - Fallback message if error has no message (default: 'Unknown error')\n * @returns Error message string\n *\n * @example\n * ```typescript\n * try {\n * await doSomething();\n * } catch (error) {\n * console.error('Failed:', getErrorMessage(error));\n * }\n * ```\n */\nexport function getErrorMessage(error: unknown, fallback = 'Unknown error'): string {\n if (error instanceof Error) return error.message;\n if (typeof error === 'string') return error;\n if (error === null || error === undefined) return fallback;\n if (typeof error === 'object') return extractObjectMessage(error, fallback);\n if (typeof error === 'number' || typeof error === 'boolean' || typeof error === 'bigint') {\n return String(error);\n }\n return fallback;\n}\n\n/** Extract message from an error-like object, falling back to JSON serialization. */\nfunction extractObjectMessage(error: object, fallback: string): string {\n const errObj = error as Record<string, unknown>;\n if (typeof errObj['message'] === 'string') return errObj['message'];\n try {\n return JSON.stringify(error);\n } catch {\n return fallback;\n }\n}\n","/**\n * nexus-agents/config - Model Capabilities Type Definitions\n *\n * Zod schemas and TypeScript interfaces for the model capabilities matrix.\n * Defines output/input modalities, tool support, and special features\n * for each supported AI model.\n *\n * @module config/model-capabilities-types\n * (Source: Issue #683, Epic #682)\n */\n\nimport { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Modality Enums\n// ---------------------------------------------------------------------------\n\n/** Output modalities a model can produce. */\nexport const OUTPUT_MODALITIES = [\n 'text',\n 'image_png',\n 'image_jpeg',\n 'audio_pcm',\n 'audio_wav',\n 'audio_mp3',\n 'video_mp4',\n 'svg',\n 'structured_json',\n 'code',\n] as const;\n\nexport type OutputModality = (typeof OUTPUT_MODALITIES)[number];\n\n/** Input modalities a model can accept. */\nexport const INPUT_MODALITIES = ['text', 'image', 'audio', 'video', 'pdf', 'code'] as const;\n\nexport type InputModality = (typeof INPUT_MODALITIES)[number];\n\n/** Tool capabilities a model supports. */\nexport const TOOL_CAPABILITIES = [\n 'mcp',\n 'function_calling',\n 'computer_use',\n 'code_execution_sandbox',\n 'web_search',\n 'file_operations',\n 'structured_output',\n 'apply_patch',\n] as const;\n\nexport type ToolCapability = (typeof TOOL_CAPABILITIES)[number];\n\n/** Special features beyond standard text generation. */\nexport const SPECIAL_FEATURES = [\n 'extended_thinking',\n 'deep_research',\n 'streaming',\n 'grounding',\n 'citations',\n 'image_editing',\n 'voice_cloning',\n 'live_api',\n 'context_caching',\n] as const;\n\nexport type SpecialFeature = (typeof SPECIAL_FEATURES)[number];\n\n// ---------------------------------------------------------------------------\n// Provider, CLI Name & Model ID enums\n// ---------------------------------------------------------------------------\n\nexport const PROVIDERS = ['anthropic', 'google', 'openai', 'custom-openai', 'openrouter'] as const;\nexport type Provider = (typeof PROVIDERS)[number];\n\n/** CLI tool names supported by the routing system. */\nexport const CLI_NAMES = ['claude', 'gemini', 'codex', 'opencode'] as const;\nexport type CliNameLiteral = (typeof CLI_NAMES)[number];\n\n/** Zod schema for CLI name validation. Canonical schema — import this instead of inlining z.enum. */\nexport const CliNameSchema = z.enum(CLI_NAMES);\n\n/** Default CLI used as fallback when task category detection yields no match. */\nexport const DEFAULT_CLI: CliNameLiteral = 'claude';\n\n/** Default confidence score for routing when no task analysis is performed. */\nexport const DEFAULT_ROUTING_CONFIDENCE = 0.85;\n\nexport const MODEL_IDS = [\n 'claude-opus',\n 'claude-sonnet',\n 'claude-haiku',\n 'gemini-3-pro',\n 'gemini-pro',\n 'gemini-3-flash',\n 'gemini-flash',\n 'codex-5.3',\n 'codex-5.2',\n 'codex-5.1-mini',\n 'opencode-default',\n 'opencode-custom-opus',\n 'opencode-custom-sonnet',\n 'openrouter-nemotron-super',\n 'openrouter-qwen-coder',\n] as const;\n\nexport type ModelId = (typeof MODEL_IDS)[number];\n\n// ---------------------------------------------------------------------------\n// Zod Schemas\n// ---------------------------------------------------------------------------\n\n/** Quality scores for model capability routing (0-10 scale). */\nexport const QualityScoresSchema = z.object({\n reasoning: z.number().min(0).max(10),\n codeGeneration: z.number().min(0).max(10),\n speed: z.number().min(0).max(10),\n cost: z.number().min(0).max(10),\n});\n\nexport type QualityScores = z.infer<typeof QualityScoresSchema>;\n\n/** Pricing information (USD per 1M tokens). */\nexport const PricingSchema = z.object({\n inputPer1M: z.number().nonnegative(),\n outputPer1M: z.number().nonnegative(),\n});\n\nexport type Pricing = z.infer<typeof PricingSchema>;\n\nexport const ModelCapabilitySchema = z.object({\n /** Unique model identifier matching delegate_to_model model IDs */\n id: z.enum(MODEL_IDS),\n /** Human-readable display name */\n displayName: z.string().min(1),\n /** Provider/vendor */\n provider: z.enum(PROVIDERS),\n /** Maximum context window in tokens */\n contextWindow: z.number().int().positive(),\n /** Output modalities this model can produce */\n outputModalities: z.array(z.enum(OUTPUT_MODALITIES)).min(1),\n /** Input modalities this model can accept */\n inputModalities: z.array(z.enum(INPUT_MODALITIES)).min(1),\n /** Tool/integration capabilities */\n toolCapabilities: z.array(z.enum(TOOL_CAPABILITIES)),\n /** Special features beyond standard generation */\n specialFeatures: z.array(z.enum(SPECIAL_FEATURES)),\n /** Known constraints or limitations */\n constraints: z.array(z.string()).optional(),\n /** Notes about the model (e.g., beta features, pricing tier) */\n notes: z.string().optional(),\n /** Pricing per 1M tokens (USD) */\n pricing: PricingSchema.optional(),\n /** Quality scores for routing (0-10 scale) */\n qualityScores: QualityScoresSchema.optional(),\n /** Maximum output tokens */\n maxOutputTokens: z.number().int().positive().optional(),\n /** Which CLI tool this model belongs to */\n cliName: z.enum(CLI_NAMES).optional(),\n /** Short alias used by the CLI (e.g., 'opus' for Claude CLI) */\n cliAlias: z.string().optional(),\n /** Model name the CLI binary expects (e.g., 'gemini-2.5-pro') */\n cliModelName: z.string().optional(),\n /**\n * Legacy / version-suffixed names that resolve to this model. Used by\n * adapters and routing to map historical user-facing names (e.g.,\n * `claude-opus-4-5-20251101`, `gemini-2.5-pro`) to the current registry\n * entry. Empty strings are rejected; uniqueness within the array is not\n * enforced at schema level (caller responsibility).\n *\n * Added for issue #2199 Child 1; populated by the companion migration\n * epic #2200.\n */\n aliases: z.array(z.string().min(1)).optional(),\n /** Whether this model is deprecated and should receive a scoring penalty */\n deprecated: z.boolean().optional(),\n /** ISO date when the model was deprecated (informational) */\n deprecatedAt: z.string().optional(),\n /** Model ID to migrate to (informational guidance) */\n replacedBy: z.enum(MODEL_IDS).optional(),\n});\n\nexport type ModelCapability = z.infer<typeof ModelCapabilitySchema>;\n\nexport const ModelCapabilitiesMatrixSchema = z.object({\n /** Schema version for forward compatibility */\n version: z.number().int().positive(),\n /** Last updated date (ISO 8601) */\n updatedAt: z.string(),\n /** Model capability definitions */\n models: z.array(ModelCapabilitySchema).min(1),\n});\n\nexport type ModelCapabilitiesMatrix = z.infer<typeof ModelCapabilitiesMatrixSchema>;\n","/* eslint-disable max-lines -- 436 lines, cohesive model registry data per governance */\n/**\n * nexus-agents/config - Model Capabilities Matrix\n *\n * Structured capability definitions for all supported AI models.\n * Tracks output/input modalities, tool support, context windows,\n * and special features based on official provider documentation.\n *\n * @module config/model-capabilities\n * (Source: Issue #683, Epic #682)\n */\n\nimport type {\n ModelCapabilitiesMatrix,\n ModelCapability,\n ModelId,\n OutputModality,\n InputModality,\n ToolCapability,\n SpecialFeature,\n Provider,\n CliNameLiteral,\n} from './model-capabilities-types.js';\n\n// Re-export types for consumer convenience\nexport type {\n ModelCapabilitiesMatrix,\n ModelCapability,\n ModelId,\n OutputModality,\n InputModality,\n ToolCapability,\n SpecialFeature,\n Provider,\n QualityScores,\n Pricing,\n CliNameLiteral,\n} from './model-capabilities-types.js';\n\nexport {\n ModelCapabilitySchema,\n ModelCapabilitiesMatrixSchema,\n QualityScoresSchema,\n PricingSchema,\n OUTPUT_MODALITIES,\n INPUT_MODALITIES,\n TOOL_CAPABILITIES,\n SPECIAL_FEATURES,\n PROVIDERS,\n MODEL_IDS,\n CLI_NAMES,\n CliNameSchema,\n DEFAULT_CLI,\n DEFAULT_ROUTING_CONFIDENCE,\n} from './model-capabilities-types.js';\n\n// ---------------------------------------------------------------------------\n// Capabilities Data\n// ---------------------------------------------------------------------------\n\n/**\n * Built-in model capabilities matrix.\n *\n * Sources:\n * - Anthropic: docs.anthropic.com (Claude model cards)\n * - Google: ai.google.dev (Gemini API docs, Veo/Imagen release notes)\n * - OpenAI: platform.openai.com (Codex/GPT model cards)\n */\nexport const DEFAULT_MODEL_CAPABILITIES: ModelCapabilitiesMatrix = {\n version: 3,\n updatedAt: '2026-03-14',\n models: [\n // ----- Anthropic Claude -----\n {\n id: 'claude-opus',\n displayName: 'Claude Opus 4.6',\n provider: 'anthropic',\n contextWindow: 1_000_000,\n outputModalities: ['text', 'structured_json', 'code'],\n inputModalities: ['text', 'image', 'pdf', 'code'],\n toolCapabilities: ['mcp', 'function_calling', 'computer_use', 'structured_output'],\n specialFeatures: ['extended_thinking', 'streaming', 'citations', 'context_caching'],\n notes:\n 'Strongest reasoning; 1M context GA (March 2026); ideal for architecture and complex analysis',\n pricing: { inputPer1M: 5.0, outputPer1M: 25.0 },\n qualityScores: { reasoning: 10, codeGeneration: 9, speed: 5, cost: 6 },\n maxOutputTokens: 128_000,\n cliName: 'claude',\n cliAlias: 'opus',\n cliModelName: 'claude-opus-4-6',\n aliases: ['claude-opus-4', 'claude-opus-4-5-20251101'],\n },\n {\n id: 'claude-sonnet',\n displayName: 'Claude Sonnet 4.6',\n provider: 'anthropic',\n contextWindow: 1_000_000,\n outputModalities: ['text', 'structured_json', 'code'],\n inputModalities: ['text', 'image', 'pdf', 'code'],\n toolCapabilities: ['mcp', 'function_calling', 'computer_use', 'structured_output'],\n specialFeatures: ['extended_thinking', 'streaming', 'citations', 'context_caching'],\n notes: 'Balanced performance and cost; 1M context GA (March 2026); default routing target',\n pricing: { inputPer1M: 3.0, outputPer1M: 15.0 },\n qualityScores: { reasoning: 9, codeGeneration: 9, speed: 7, cost: 6 },\n maxOutputTokens: 64_000,\n cliName: 'claude',\n cliAlias: 'sonnet',\n cliModelName: 'claude-sonnet-4-6',\n aliases: ['claude-sonnet-4', 'claude-sonnet-4-5-20250929'],\n },\n {\n id: 'claude-haiku',\n displayName: 'Claude Haiku 4.5',\n provider: 'anthropic',\n contextWindow: 200_000,\n outputModalities: ['text', 'structured_json', 'code'],\n inputModalities: ['text', 'image', 'pdf', 'code'],\n toolCapabilities: ['mcp', 'function_calling', 'structured_output'],\n specialFeatures: ['streaming'],\n notes: 'Fastest Claude model; optimized for speed and cost',\n pricing: { inputPer1M: 1.0, outputPer1M: 5.0 },\n qualityScores: { reasoning: 7, codeGeneration: 7, speed: 9, cost: 9 },\n maxOutputTokens: 64_000,\n cliName: 'claude',\n cliAlias: 'haiku',\n cliModelName: 'claude-haiku-4-5-20251001',\n aliases: ['claude-haiku-4', 'claude-haiku-3'],\n },\n // ----- Google Gemini -----\n {\n id: 'gemini-3-pro',\n displayName: 'Gemini 3.1 Pro (Preview)',\n provider: 'google',\n contextWindow: 1_048_576,\n outputModalities: [\n 'text',\n 'image_png',\n 'image_jpeg',\n 'audio_pcm',\n 'audio_wav',\n 'structured_json',\n 'code',\n ],\n inputModalities: ['text', 'image', 'audio', 'video', 'pdf', 'code'],\n toolCapabilities: [\n 'function_calling',\n 'code_execution_sandbox',\n 'web_search',\n 'structured_output',\n ],\n specialFeatures: ['deep_research', 'streaming', 'grounding', 'live_api'],\n notes: 'Gemini 3.1 Pro; replaces deprecated 3 Pro Preview (March 9 2026); 1M context',\n pricing: { inputPer1M: 2.0, outputPer1M: 12.0 },\n qualityScores: { reasoning: 10, codeGeneration: 9, speed: 8, cost: 6 },\n maxOutputTokens: 65_536,\n cliName: 'gemini',\n cliModelName: 'gemini-3.1-pro-preview',\n },\n {\n id: 'gemini-pro',\n displayName: 'Gemini 2.5 Pro',\n provider: 'google',\n contextWindow: 1_048_576,\n outputModalities: [\n 'text',\n 'image_png',\n 'image_jpeg',\n 'audio_pcm',\n 'audio_wav',\n 'structured_json',\n 'code',\n ],\n inputModalities: ['text', 'image', 'audio', 'video', 'pdf', 'code'],\n toolCapabilities: [\n 'function_calling',\n 'code_execution_sandbox',\n 'web_search',\n 'structured_output',\n ],\n specialFeatures: ['deep_research', 'streaming', 'grounding', 'live_api'],\n notes: 'Largest context (1M tokens); complex reasoning; native multimodal output',\n pricing: { inputPer1M: 1.25, outputPer1M: 10.0 },\n qualityScores: { reasoning: 9, codeGeneration: 8, speed: 8, cost: 7 },\n maxOutputTokens: 65_536,\n cliName: 'gemini',\n cliModelName: 'gemini-2.5-pro',\n },\n {\n id: 'gemini-3-flash',\n displayName: 'Gemini 3 Flash (Preview)',\n provider: 'google',\n contextWindow: 1_048_576,\n outputModalities: ['text', 'image_png', 'image_jpeg', 'structured_json', 'code'],\n inputModalities: ['text', 'image', 'audio', 'video', 'pdf', 'code'],\n toolCapabilities: [\n 'function_calling',\n 'code_execution_sandbox',\n 'web_search',\n 'structured_output',\n ],\n specialFeatures: ['streaming', 'grounding'],\n notes: 'Next-gen fast Gemini; improved over 2.5 Flash; 1M context',\n pricing: { inputPer1M: 0.5, outputPer1M: 3.0 },\n qualityScores: { reasoning: 8, codeGeneration: 8, speed: 10, cost: 9 },\n maxOutputTokens: 65_536,\n cliName: 'gemini',\n cliModelName: 'gemini-3-flash-preview',\n },\n {\n id: 'gemini-flash',\n displayName: 'Gemini 2.5 Flash',\n provider: 'google',\n contextWindow: 1_048_576,\n outputModalities: ['text', 'image_png', 'image_jpeg', 'structured_json', 'code'],\n inputModalities: ['text', 'image', 'audio', 'video', 'pdf', 'code'],\n toolCapabilities: [\n 'function_calling',\n 'code_execution_sandbox',\n 'web_search',\n 'structured_output',\n ],\n specialFeatures: ['streaming', 'grounding'],\n notes: 'Ultra-fast Gemini 2.5; 1M context; agents and streaming optimized',\n pricing: { inputPer1M: 0.3, outputPer1M: 2.5 },\n qualityScores: { reasoning: 7, codeGeneration: 7, speed: 10, cost: 9 },\n maxOutputTokens: 65_536,\n cliName: 'gemini',\n cliModelName: 'gemini-2.5-flash',\n },\n // ----- OpenAI Codex -----\n {\n id: 'codex-5.3',\n displayName: 'GPT-5.4',\n provider: 'openai',\n contextWindow: 1_050_000,\n outputModalities: ['text', 'structured_json', 'code'],\n inputModalities: ['text', 'image', 'pdf', 'code'],\n toolCapabilities: [\n 'function_calling',\n 'code_execution_sandbox',\n 'web_search',\n 'file_operations',\n 'structured_output',\n 'apply_patch',\n 'computer_use',\n ],\n specialFeatures: ['streaming'],\n notes: 'GPT-5.4; replaces GPT-5.3-Codex in Codex CLI; 1M context; native computer use',\n pricing: { inputPer1M: 2.5, outputPer1M: 15.0 },\n qualityScores: { reasoning: 10, codeGeneration: 10, speed: 7, cost: 5 },\n maxOutputTokens: 128_000,\n cliName: 'codex',\n cliModelName: 'gpt-5.4',\n },\n {\n id: 'codex-5.2',\n displayName: 'GPT-5.2-Codex',\n provider: 'openai',\n contextWindow: 272_000,\n outputModalities: ['text', 'structured_json', 'code'],\n inputModalities: ['text', 'image', 'pdf', 'code'],\n toolCapabilities: [\n 'function_calling',\n 'code_execution_sandbox',\n 'web_search',\n 'file_operations',\n 'structured_output',\n 'apply_patch',\n ],\n specialFeatures: ['streaming'],\n constraints: [\n 'Sandboxed execution only (Landlock/seccomp on Linux)',\n 'No native image/audio/video generation',\n 'Network access restricted in sandbox',\n ],\n notes: 'Best code generation; 272K context; sandboxed execution environment',\n pricing: { inputPer1M: 1.75, outputPer1M: 14.0 },\n qualityScores: { reasoning: 9, codeGeneration: 10, speed: 8, cost: 7 },\n maxOutputTokens: 100_000,\n cliName: 'codex',\n cliModelName: 'gpt-5.2-codex',\n },\n {\n id: 'codex-5.1-mini',\n displayName: 'GPT-5.1-Mini-Codex',\n provider: 'openai',\n contextWindow: 200_000,\n outputModalities: ['text', 'structured_json', 'code'],\n inputModalities: ['text', 'image', 'code'],\n toolCapabilities: [\n 'function_calling',\n 'code_execution_sandbox',\n 'file_operations',\n 'structured_output',\n 'apply_patch',\n ],\n specialFeatures: ['streaming'],\n constraints: ['Sandboxed execution only', 'No native image/audio/video generation'],\n notes: 'Compact Codex variant; fast and cost-effective for code tasks; o3-mini backbone',\n pricing: { inputPer1M: 1.1, outputPer1M: 4.4 },\n qualityScores: { reasoning: 7, codeGeneration: 8, speed: 9, cost: 7 },\n maxOutputTokens: 100_000,\n cliName: 'codex',\n cliModelName: 'o3-mini',\n },\n // ----- OpenCode (multi-provider proxy) -----\n {\n id: 'opencode-default',\n displayName: 'OpenCode Default',\n provider: 'anthropic',\n contextWindow: 1_000_000,\n outputModalities: ['text', 'structured_json', 'code'],\n inputModalities: ['text', 'image', 'code'],\n toolCapabilities: ['mcp', 'function_calling', 'file_operations', 'structured_output'],\n specialFeatures: ['streaming'],\n notes: 'OpenCode multi-provider proxy; model selected via --model flag',\n pricing: { inputPer1M: 3.0, outputPer1M: 15.0 },\n qualityScores: { reasoning: 9, codeGeneration: 9, speed: 7, cost: 6 },\n maxOutputTokens: 64_000,\n cliName: 'opencode',\n cliModelName: 'anthropic/claude-sonnet-4-6',\n },\n // ----- OpenCode + Custom OpenAI-compatible endpoint -----\n {\n id: 'opencode-custom-opus',\n displayName: 'Custom Endpoint — Claude Opus',\n provider: 'custom-openai',\n contextWindow: 1_000_000,\n outputModalities: ['text', 'structured_json', 'code'],\n inputModalities: ['text', 'image', 'pdf', 'code'],\n toolCapabilities: ['mcp', 'function_calling', 'structured_output'],\n specialFeatures: ['extended_thinking', 'streaming', 'citations', 'context_caching'],\n notes: 'Claude Opus via custom OpenAI-compatible gateway (opencode transport); 1M context',\n pricing: { inputPer1M: 5.0, outputPer1M: 25.0 },\n qualityScores: { reasoning: 10, codeGeneration: 9, speed: 5, cost: 6 },\n maxOutputTokens: 128_000,\n cliName: 'opencode',\n cliAlias: 'custom-opus',\n cliModelName: 'custom/claude-opus-4-6',\n },\n {\n id: 'opencode-custom-sonnet',\n displayName: 'Custom Endpoint — Claude Sonnet',\n provider: 'custom-openai',\n contextWindow: 1_000_000,\n outputModalities: ['text', 'structured_json', 'code'],\n inputModalities: ['text', 'image', 'pdf', 'code'],\n toolCapabilities: ['mcp', 'function_calling', 'structured_output'],\n specialFeatures: ['streaming', 'citations', 'context_caching'],\n notes: 'Claude Sonnet via custom OpenAI-compatible gateway (opencode transport); 1M context',\n pricing: { inputPer1M: 3.0, outputPer1M: 15.0 },\n qualityScores: { reasoning: 9, codeGeneration: 9, speed: 7, cost: 6 },\n maxOutputTokens: 64_000,\n cliName: 'opencode',\n cliAlias: 'custom-sonnet',\n cliModelName: 'custom/claude-sonnet-4-6',\n },\n\n // ── OpenRouter Free Models (via OpenAI-compatible API) ────────\n {\n id: 'openrouter-nemotron-super',\n displayName: 'NVIDIA Nemotron 3 Super 120B (free)',\n provider: 'openrouter',\n contextWindow: 1_000_000,\n outputModalities: ['text', 'structured_json', 'code'],\n inputModalities: ['text', 'code'],\n toolCapabilities: ['function_calling', 'structured_output'],\n specialFeatures: ['streaming'],\n notes:\n 'Hybrid Mamba-Transformer MoE (120B total, 12B active). ' +\n 'Designed for agentic reasoning. Free via OpenRouter.',\n pricing: { inputPer1M: 0, outputPer1M: 0 },\n qualityScores: { reasoning: 7, codeGeneration: 7, speed: 8, cost: 10 },\n maxOutputTokens: 32_768,\n cliName: 'opencode',\n cliModelName: 'nvidia/nemotron-3-super-120b-a12b:free',\n },\n {\n id: 'openrouter-qwen-coder',\n displayName: 'Qwen3 Coder 480B (free)',\n provider: 'openrouter',\n contextWindow: 262_144,\n outputModalities: ['text', 'structured_json', 'code'],\n inputModalities: ['text', 'code'],\n toolCapabilities: ['function_calling', 'structured_output'],\n specialFeatures: ['streaming'],\n notes:\n 'Strongest free coding model on OpenRouter. ' + '480B parameters, 262K context. Free tier.',\n pricing: { inputPer1M: 0, outputPer1M: 0 },\n qualityScores: { reasoning: 7, codeGeneration: 8, speed: 6, cost: 10 },\n maxOutputTokens: 32_768,\n cliName: 'opencode',\n cliModelName: 'qwen/qwen3-coder-480b-a35b:free',\n },\n ],\n};\n\n/**\n * Default (strongest) model per CLI tool.\n * Quality-first: each CLI routes to its strongest model by default.\n */\nexport const DEFAULT_MODEL_PER_CLI: Record<CliNameLiteral, ModelId> = {\n claude: 'claude-opus',\n gemini: 'gemini-3-pro',\n codex: 'codex-5.3',\n opencode: 'opencode-default',\n};\n\n// ---------------------------------------------------------------------------\n// Query Functions\n// ---------------------------------------------------------------------------\n\n/** Get capabilities for a specific model by ID. */\nexport function getModelCapabilities(\n modelId: string,\n matrix: ModelCapabilitiesMatrix = DEFAULT_MODEL_CAPABILITIES\n): ModelCapability | undefined {\n return matrix.models.find((m) => m.id === modelId);\n}\n\n/** Find all models that support a given output modality. */\nexport function findModelsByOutputModality(\n modality: OutputModality,\n matrix: ModelCapabilitiesMatrix = DEFAULT_MODEL_CAPABILITIES\n): ModelCapability[] {\n return matrix.models.filter((m) => m.outputModalities.includes(modality));\n}\n\n/** Find all models that support a given input modality. */\nexport function findModelsByInputModality(\n modality: InputModality,\n matrix: ModelCapabilitiesMatrix = DEFAULT_MODEL_CAPABILITIES\n): ModelCapability[] {\n return matrix.models.filter((m) => m.inputModalities.includes(modality));\n}\n\n/** Find all models that support a given tool capability. */\nexport function findModelsByToolCapability(\n capability: ToolCapability,\n matrix: ModelCapabilitiesMatrix = DEFAULT_MODEL_CAPABILITIES\n): ModelCapability[] {\n return matrix.models.filter((m) => m.toolCapabilities.includes(capability));\n}\n\n/** Find all models that have a given special feature. */\nexport function findModelsByFeature(\n feature: SpecialFeature,\n matrix: ModelCapabilitiesMatrix = DEFAULT_MODEL_CAPABILITIES\n): ModelCapability[] {\n return matrix.models.filter((m) => m.specialFeatures.includes(feature));\n}\n\n/** Find all models from a specific provider. */\nexport function findModelsByProvider(\n provider: Provider,\n matrix: ModelCapabilitiesMatrix = DEFAULT_MODEL_CAPABILITIES\n): ModelCapability[] {\n return matrix.models.filter((m) => m.provider === provider);\n}\n\n/** Find the best model for a required output modality, preferring larger context. */\nexport function findBestModelForOutput(\n modality: OutputModality,\n matrix: ModelCapabilitiesMatrix = DEFAULT_MODEL_CAPABILITIES\n): ModelCapability | undefined {\n const candidates = findModelsByOutputModality(modality, matrix);\n if (candidates.length === 0) return undefined;\n return candidates.sort((a, b) => b.contextWindow - a.contextWindow)[0];\n}\n\n/** Check that `haystack` includes every item in `required`. */\nfunction includesAll<T>(haystack: readonly T[], required: readonly T[] | undefined): boolean {\n if (required === undefined) return true;\n return required.every((item) => haystack.includes(item));\n}\n\n/**\n * Check if a model supports all required capabilities.\n * Useful for filtering models before routing.\n */\nexport function modelSupportsAll(\n modelId: ModelId,\n requirements: {\n outputModalities?: OutputModality[];\n inputModalities?: InputModality[];\n toolCapabilities?: ToolCapability[];\n specialFeatures?: SpecialFeature[];\n minContextWindow?: number;\n },\n matrix: ModelCapabilitiesMatrix = DEFAULT_MODEL_CAPABILITIES\n): boolean {\n const model = getModelCapabilities(modelId, matrix);\n if (model === undefined) return false;\n\n const meetsContext =\n requirements.minContextWindow === undefined ||\n model.contextWindow >= requirements.minContextWindow;\n\n return (\n meetsContext &&\n includesAll(model.outputModalities, requirements.outputModalities) &&\n includesAll(model.inputModalities, requirements.inputModalities) &&\n includesAll(model.toolCapabilities, requirements.toolCapabilities) &&\n includesAll(model.specialFeatures, requirements.specialFeatures)\n );\n}\n","/**\n * nexus-agents/core - Model Pricing\n *\n * Cost calculation functions using the canonical model registry.\n * All pricing data lives in config/model-capabilities.ts — this module\n * provides a convenience function to calculate costs from token usage.\n *\n * @see config/model-capabilities.ts — single source of truth for model pricing\n * @module core/trace-pricing\n * (Source: Issue #807, Issue #1149)\n */\n\nimport { DEFAULT_MODEL_CAPABILITIES } from '../config/model-capabilities.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Pricing information for a model.\n */\nexport interface ModelPricing {\n inputPer1M: number;\n outputPer1M: number;\n}\n\n// =============================================================================\n// Canonical Pricing Lookup\n// =============================================================================\n\n/** Extracts ModelPricing from a registry entry's pricing field. */\nfunction toPricing(\n pricing: { inputPer1M: number; outputPer1M: number } | undefined\n): ModelPricing | undefined {\n if (pricing === undefined) return undefined;\n return { inputPer1M: pricing.inputPer1M, outputPer1M: pricing.outputPer1M };\n}\n\n/** Checks if the query matches a registry entry by exact id, cliModelName, or cliAlias. */\nfunction isExactMatch(\n entry: { id: string; cliModelName?: string | undefined; cliAlias?: string | undefined },\n query: string\n): boolean {\n return entry.id === query || entry.cliModelName === query || entry.cliAlias === query;\n}\n\n/** Checks if the query starts with a registry entry's id or cliModelName. */\nfunction isPrefixMatch(\n entry: { id: string; cliModelName?: string | undefined },\n query: string\n): boolean {\n const id = entry.id;\n const cliName = entry.cliModelName ?? '';\n return (\n (id.length > 0 && query.startsWith(id)) || (cliName.length > 0 && query.startsWith(cliName))\n );\n}\n\n/**\n * Looks up pricing from the canonical model registry.\n * Matches by: exact (id, cliModelName, cliAlias), then prefix match.\n */\nfunction lookupCanonicalPricing(model: string): ModelPricing | undefined {\n for (const m of DEFAULT_MODEL_CAPABILITIES.models) {\n if (isExactMatch(m, model)) return toPricing(m.pricing);\n }\n for (const m of DEFAULT_MODEL_CAPABILITIES.models) {\n if (m.pricing !== undefined && isPrefixMatch(m, model)) return toPricing(m.pricing);\n }\n return undefined;\n}\n\n// =============================================================================\n// Cost Calculation\n// =============================================================================\n\n/**\n * Calculates the cost of an LLM call based on token usage.\n * Looks up pricing from the canonical model registry only.\n *\n * @param model - Model identifier (canonical id, cliModelName, or versioned name)\n * @param inputTokens - Number of input tokens\n * @param outputTokens - Number of output tokens\n * @returns Cost in USD, or undefined if model not in canonical registry\n */\nexport function calculateCost(\n model: string,\n inputTokens: number,\n outputTokens: number\n): number | undefined {\n const pricing = lookupCanonicalPricing(model);\n\n if (pricing === undefined) {\n return undefined;\n }\n\n const inputCost = (inputTokens / 1_000_000) * pricing.inputPer1M;\n const outputCost = (outputTokens / 1_000_000) * pricing.outputPer1M;\n\n return inputCost + outputCost;\n}\n","/**\n * nexus-agents/core - Trace Helpers\n *\n * Utility functions for trace management and global tracer access.\n */\n\nimport { randomUUID } from 'node:crypto';\nimport type {\n TraceContext,\n TracerConfig,\n LLMMetrics,\n TraceSpan as TraceSpanType,\n AggregatedMetrics as AggregatedMetricsType,\n} from './trace-types.js';\nimport { getErrorMessage } from './errors.js';\n\n// =============================================================================\n// ID Generation\n// =============================================================================\n\n/**\n * Generates a UUID-based trace ID.\n */\nexport function generateTraceId(): string {\n return randomUUID();\n}\n\n/**\n * Generates a UUID-based span ID.\n */\nexport function generateSpanId(): string {\n return randomUUID();\n}\n\n// =============================================================================\n// Global Tracer Management\n// =============================================================================\n\n/**\n * Aggregated metrics across multiple spans.\n * Duplicated here to avoid circular dependency with trace-types.\n */\ninterface AggregatedMetrics {\n totalSpans: number;\n successfulSpans: number;\n errorSpans: number;\n totalInputTokens: number;\n totalOutputTokens: number;\n totalCostUsd: number;\n durationMs: number;\n byModel: Record<string, { inputTokens: number; outputTokens: number; costUsd: number }>;\n byProvider: Record<string, { inputTokens: number; outputTokens: number; costUsd: number }>;\n}\n\n/**\n * A single trace span representing a unit of work.\n * Duplicated here to avoid circular dependency with trace-types.\n */\ninterface TraceSpan {\n context: TraceContext;\n name: string;\n startTime: number;\n endTime?: number;\n status: 'running' | 'success' | 'error';\n attributes: Record<string, unknown>;\n llmMetrics?: LLMMetrics;\n errorMessage?: string;\n}\n\n/**\n * Interface for the Tracer class to avoid circular dependency.\n * This matches the public API of the Tracer class.\n */\nexport interface ITracer {\n isEnabled(): boolean;\n startTrace(name: string, attributes?: Record<string, unknown>): TraceSpan | undefined;\n startSpan(\n name: string,\n attributes?: Record<string, unknown>,\n parentSpanId?: string\n ): TraceSpan | undefined;\n startChildSpan(\n parentSpanId: string,\n name: string,\n attributes?: Record<string, unknown>\n ): TraceSpan | undefined;\n endSpan(spanId: string, status: 'success' | 'error', errorMessage?: string): void;\n recordLLMMetrics(spanId: string, metrics: Omit<LLMMetrics, 'costUsd'>): void;\n addAttributes(spanId: string, attributes: Record<string, unknown>): void;\n getSpan(spanId: string): TraceSpan | undefined;\n getAllSpans(): TraceSpan[];\n getTraceId(): string | undefined;\n getCurrentContext(): TraceContext | undefined;\n getAggregatedMetrics(): AggregatedMetrics;\n clear(): void;\n}\n\n/** Global tracer instance */\nlet globalTracer: ITracer | undefined;\n\n/** Factory function to create a tracer (set by trace.ts to break circular dependency) */\nlet tracerFactory: ((config?: TracerConfig) => ITracer) | undefined;\n\n/**\n * Sets the tracer factory function.\n * This is called by trace.ts during module initialization.\n *\n * @internal\n */\nexport function setTracerFactory(factory: (config?: TracerConfig) => ITracer): void {\n tracerFactory = factory;\n}\n\n/**\n * Gets or creates the global tracer instance.\n *\n * @param config - Optional configuration for creating the tracer\n * @returns The global tracer instance\n */\nexport function getTracer(config?: TracerConfig): ITracer {\n if (globalTracer === undefined) {\n if (tracerFactory === undefined) {\n throw new Error(\n 'Tracer factory not initialized. Import from trace.ts before calling getTracer.'\n );\n }\n globalTracer = tracerFactory(config);\n }\n return globalTracer;\n}\n\n/**\n * Sets the global tracer instance.\n *\n * @param tracer - The tracer to use globally\n */\nexport function setTracer(tracer: ITracer): void {\n globalTracer = tracer;\n}\n\n// =============================================================================\n// Convenience Functions\n// =============================================================================\n\n/**\n * Wraps a function in a span, automatically tracking duration and errors.\n *\n * @param name - Name for the span\n * @param fn - Async function to wrap\n * @param attributes - Optional attributes to attach to the span\n * @returns Result of the wrapped function\n *\n * @example\n * ```typescript\n * const result = await withSpan('process-request', async () => {\n * return await processRequest(data);\n * });\n * ```\n */\nexport async function withSpan<T>(\n name: string,\n fn: () => Promise<T>,\n attributes: Record<string, unknown> = {}\n): Promise<T> {\n const tracer = getTracer();\n const span = tracer.startSpan(name, attributes);\n\n if (span === undefined) {\n // Tracing disabled, just run the function\n return fn();\n }\n\n try {\n const result = await fn();\n tracer.endSpan(span.context.spanId, 'success');\n return result;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n tracer.endSpan(span.context.spanId, 'error', errorMessage);\n throw error;\n }\n}\n\n/**\n * Records LLM metrics on the global tracer.\n *\n * @param spanId - ID of the span to record metrics for\n * @param metrics - LLM metrics to record\n */\nexport function recordLLMMetrics(spanId: string, metrics: Omit<LLMMetrics, 'costUsd'>): void {\n const tracer = getTracer();\n tracer.recordLLMMetrics(spanId, metrics);\n}\n\n/**\n * Gets the current trace context from the global tracer.\n *\n * @returns Current trace context, or undefined if no trace is active\n */\nexport function getTraceContext(): TraceContext | undefined {\n const tracer = getTracer();\n return tracer.getCurrentContext();\n}\n\n// =============================================================================\n// Aggregation Helpers\n// =============================================================================\n\n/**\n * Token bucket entry for model or provider aggregation.\n */\nexport interface TokenBucketEntry {\n inputTokens: number;\n outputTokens: number;\n costUsd: number;\n}\n\n/**\n * Result of span time bounds calculation.\n */\nexport interface SpanTimeBounds {\n minStartTime: number;\n maxEndTime: number;\n}\n\n/**\n * Counts span by its status, incrementing the appropriate counter.\n *\n * @param span - The span to count\n * @param metrics - The metrics object to update\n */\nexport function countSpanStatus(span: TraceSpanType, metrics: AggregatedMetricsType): void {\n if (span.status === 'success') {\n metrics.successfulSpans++;\n } else if (span.status === 'error') {\n metrics.errorSpans++;\n }\n}\n\n/**\n * Aggregates metrics into a keyed bucket (model or provider).\n *\n * @param bucket - The bucket to aggregate into\n * @param key - The key (model name or provider)\n * @param llm - The LLM metrics to aggregate\n */\nexport function aggregateByKey(\n bucket: Record<string, TokenBucketEntry>,\n key: string,\n llm: LLMMetrics\n): void {\n let entry = bucket[key];\n if (entry === undefined) {\n entry = { inputTokens: 0, outputTokens: 0, costUsd: 0 };\n bucket[key] = entry;\n }\n entry.inputTokens += llm.inputTokens;\n entry.outputTokens += llm.outputTokens;\n entry.costUsd += llm.costUsd ?? 0;\n}\n\n/**\n * Aggregates LLM metrics from a span into the aggregated metrics.\n *\n * @param span - The span containing LLM metrics\n * @param metrics - The metrics object to update\n */\nexport function aggregateLLMMetrics(span: TraceSpanType, metrics: AggregatedMetricsType): void {\n if (span.llmMetrics === undefined) {\n return;\n }\n\n const llm = span.llmMetrics;\n metrics.totalInputTokens += llm.inputTokens;\n metrics.totalOutputTokens += llm.outputTokens;\n metrics.totalCostUsd += llm.costUsd ?? 0;\n\n aggregateByKey(metrics.byModel, llm.model, llm);\n aggregateByKey(metrics.byProvider, llm.provider, llm);\n}\n\n/**\n * Calculates the total duration from time bounds.\n *\n * @param metrics - The metrics object to update\n * @param minStartTime - The earliest start time\n * @param maxEndTime - The latest end time\n */\nexport function calculateDuration(\n metrics: AggregatedMetricsType,\n minStartTime: number,\n maxEndTime: number\n): void {\n if (minStartTime !== Infinity && maxEndTime > 0) {\n metrics.durationMs = maxEndTime - minStartTime;\n }\n}\n\n/**\n * Aggregates individual span metrics into the aggregated metrics object.\n *\n * @param spans - Array of spans to aggregate\n * @param metrics - The metrics object to update\n * @returns The time bounds (min start, max end)\n */\nexport function aggregateSpanMetrics(\n spans: TraceSpanType[],\n metrics: AggregatedMetricsType\n): SpanTimeBounds {\n let minStartTime = Infinity;\n let maxEndTime = 0;\n\n for (const span of spans) {\n countSpanStatus(span, metrics);\n minStartTime = Math.min(minStartTime, span.startTime);\n if (span.endTime !== undefined) {\n maxEndTime = Math.max(maxEndTime, span.endTime);\n }\n aggregateLLMMetrics(span, metrics);\n }\n\n return { minStartTime, maxEndTime };\n}\n\n/**\n * Finds the most recent running span from a collection.\n *\n * @param spans - Iterator of spans to search\n * @returns The latest running span, or undefined if none found\n */\nexport function findLatestRunningSpan(spans: Iterable<TraceSpanType>): TraceSpanType | undefined {\n let latestSpan: TraceSpanType | undefined;\n for (const span of spans) {\n if (span.status === 'running') {\n if (latestSpan === undefined || span.startTime > latestSpan.startTime) {\n latestSpan = span;\n }\n }\n }\n return latestSpan;\n}\n\n/**\n * Identifies span IDs to prune based on age, keeping running spans.\n *\n * @param entries - Span entries as [spanId, span] pairs\n * @param prunePercent - Percentage of completed spans to remove (0-1)\n * @returns Array of span IDs to delete\n */\nexport function getSpansToPrune(\n entries: Iterable<[string, TraceSpanType]>,\n prunePercent: number = 0.1\n): string[] {\n const completedSpans = Array.from(entries)\n .filter(([, span]) => span.status !== 'running')\n .sort((a, b) => a[1].startTime - b[1].startTime);\n\n const toRemove = Math.ceil(completedSpans.length * prunePercent);\n const idsToDelete: string[] = [];\n\n for (let i = 0; i < toRemove && i < completedSpans.length; i++) {\n const entry = completedSpans[i];\n if (entry !== undefined) {\n idsToDelete.push(entry[0]);\n }\n }\n\n return idsToDelete;\n}\n","/**\n * nexus-agents/core - Lightweight Trace Module\n *\n * Token counting, cost tracking, and span management without OpenTelemetry.\n * Provides minimal overhead tracing for LLM operations.\n *\n * File length justification: Core Tracer class with types in trace-types.ts,\n * pricing in trace-pricing.ts, helpers in trace-helpers.ts. Remaining code is\n * tightly coupled span lifecycle management and metric aggregation.\n */\n\nimport type { ILogger, LogContext } from './logger.js';\nimport { createLogger } from './logger.js';\nimport { getTimeProvider } from './time-provider.js';\nimport type {\n TraceContext,\n LLMMetrics,\n TraceSpan,\n AggregatedMetrics,\n TracerConfig,\n} from './trace-types.js';\nimport { calculateCost } from './trace-pricing.js';\nimport {\n generateTraceId,\n generateSpanId,\n setTracerFactory,\n aggregateSpanMetrics,\n calculateDuration,\n findLatestRunningSpan,\n getSpansToPrune,\n} from './trace-helpers.js';\n\n// =============================================================================\n// Tracer Class\n// =============================================================================\n\n/**\n * Lightweight tracer for managing spans and collecting LLM metrics.\n *\n * The tracer creates and manages spans, supports parent-child relationships,\n * collects LLM metrics, and can aggregate data across a trace.\n *\n * @example\n * ```typescript\n * const tracer = new Tracer({ enabled: true });\n *\n * // Create a root span\n * const span = tracer.startSpan('orchestrate-task');\n *\n * // Record LLM metrics\n * tracer.recordLLMMetrics(span.context.spanId, {\n * inputTokens: 1000,\n * outputTokens: 500,\n * model: 'claude-sonnet-4',\n * provider: 'anthropic',\n * });\n *\n * // End the span\n * tracer.endSpan(span.context.spanId, 'success');\n *\n * // Get aggregated metrics\n * const metrics = tracer.getAggregatedMetrics();\n * ```\n */\nexport class Tracer {\n private readonly enabled: boolean;\n private readonly logger: ILogger;\n private readonly maxSpans: number;\n private readonly logSpans: boolean;\n private readonly spans: Map<string, TraceSpan> = new Map();\n private currentTraceId: string | undefined;\n\n /**\n * Creates a new Tracer instance.\n *\n * @param config - Tracer configuration\n */\n constructor(config: TracerConfig = {}) {\n this.enabled = config.enabled ?? true;\n this.logger = config.logger ?? createLogger({ component: 'tracer' });\n this.maxSpans = config.maxSpans ?? 1000;\n this.logSpans = config.logSpans ?? false;\n }\n\n /**\n * Checks if tracing is enabled.\n */\n isEnabled(): boolean {\n return this.enabled;\n }\n\n /**\n * Starts a new trace with a root span.\n *\n * @param name - Name for the root span\n * @param attributes - Optional attributes to attach\n * @returns The created span, or undefined if tracing is disabled\n */\n startTrace(name: string, attributes: Record<string, unknown> = {}): TraceSpan | undefined {\n if (!this.enabled) {\n return undefined;\n }\n\n this.currentTraceId = generateTraceId();\n return this.startSpan(name, attributes);\n }\n\n /**\n * Starts a new span within the current trace.\n *\n * @param name - Name for the span\n * @param attributes - Optional attributes to attach\n * @param parentSpanId - Optional parent span ID for nesting\n * @returns The created span, or undefined if tracing is disabled\n */\n startSpan(\n name: string,\n attributes: Record<string, unknown> = {},\n parentSpanId?: string\n ): TraceSpan | undefined {\n if (!this.enabled) {\n return undefined;\n }\n\n // Ensure we have a trace ID\n this.currentTraceId ??= generateTraceId();\n const traceId = this.currentTraceId;\n\n const spanId = generateSpanId();\n const context: TraceContext = {\n traceId,\n spanId,\n };\n // Only set parentSpanId if defined (exactOptionalPropertyTypes compliance)\n if (parentSpanId !== undefined) {\n context.parentSpanId = parentSpanId;\n }\n const span: TraceSpan = {\n context,\n name,\n startTime: getTimeProvider().now(),\n status: 'running',\n attributes,\n };\n\n // Enforce max spans limit\n if (this.spans.size >= this.maxSpans) {\n this.pruneOldestSpans();\n }\n\n this.spans.set(spanId, span);\n\n if (this.logSpans) {\n this.logger.debug('Span started', {\n spanId,\n traceId,\n name,\n parentSpanId,\n });\n }\n\n return span;\n }\n\n /**\n * Creates a child span under an existing parent span.\n *\n * @param parentSpanId - ID of the parent span\n * @param name - Name for the child span\n * @param attributes - Optional attributes to attach\n * @returns The created child span, or undefined if parent not found or tracing disabled\n */\n startChildSpan(\n parentSpanId: string,\n name: string,\n attributes: Record<string, unknown> = {}\n ): TraceSpan | undefined {\n if (!this.enabled) {\n return undefined;\n }\n\n const parentSpan = this.spans.get(parentSpanId);\n if (parentSpan === undefined) {\n this.logger.warn('Parent span not found', { parentSpanId });\n return undefined;\n }\n\n return this.startSpan(name, attributes, parentSpanId);\n }\n\n /**\n * Ends a span with a final status.\n *\n * @param spanId - ID of the span to end\n * @param status - Final status ('success' or 'error')\n * @param errorMessage - Optional error message if status is 'error'\n */\n endSpan(spanId: string, status: 'success' | 'error', errorMessage?: string): void {\n if (!this.enabled) {\n return;\n }\n\n const span = this.spans.get(spanId);\n if (span === undefined) {\n this.logger.warn('Span not found', { spanId });\n return;\n }\n\n span.endTime = getTimeProvider().now();\n span.status = status;\n if (errorMessage !== undefined) {\n span.errorMessage = errorMessage;\n }\n\n if (this.logSpans) {\n const durationMs = span.endTime - span.startTime;\n const context: LogContext = {\n spanId,\n name: span.name,\n status,\n durationMs,\n };\n if (span.llmMetrics !== undefined) {\n context['inputTokens'] = span.llmMetrics.inputTokens;\n context['outputTokens'] = span.llmMetrics.outputTokens;\n if (span.llmMetrics.costUsd !== undefined) {\n context['costUsd'] = span.llmMetrics.costUsd;\n }\n }\n if (errorMessage !== undefined) {\n context['error'] = errorMessage;\n }\n this.logger.debug('Span ended', context);\n }\n }\n\n /**\n * Records LLM metrics for a span.\n *\n * @param spanId - ID of the span to record metrics for\n * @param metrics - LLM metrics to record\n */\n recordLLMMetrics(spanId: string, metrics: Omit<LLMMetrics, 'costUsd'>): void {\n if (!this.enabled) {\n return;\n }\n\n const span = this.spans.get(spanId);\n if (span === undefined) {\n this.logger.warn('Span not found for LLM metrics', { spanId });\n return;\n }\n\n // Calculate cost\n const costUsd = calculateCost(metrics.model, metrics.inputTokens, metrics.outputTokens);\n\n // Build LLMMetrics with exactOptionalPropertyTypes compliance\n const llmMetrics: LLMMetrics = {\n inputTokens: metrics.inputTokens,\n outputTokens: metrics.outputTokens,\n model: metrics.model,\n provider: metrics.provider,\n };\n if (costUsd !== undefined) {\n llmMetrics.costUsd = costUsd;\n }\n span.llmMetrics = llmMetrics;\n\n if (this.logSpans) {\n this.logger.debug('LLM metrics recorded', {\n spanId,\n inputTokens: metrics.inputTokens,\n outputTokens: metrics.outputTokens,\n model: metrics.model,\n provider: metrics.provider,\n costUsd,\n });\n }\n }\n\n /**\n * Adds attributes to an existing span.\n *\n * @param spanId - ID of the span to update\n * @param attributes - Attributes to add/update\n */\n addAttributes(spanId: string, attributes: Record<string, unknown>): void {\n if (!this.enabled) {\n return;\n }\n\n const span = this.spans.get(spanId);\n if (span === undefined) {\n this.logger.warn('Span not found for attributes', { spanId });\n return;\n }\n\n span.attributes = { ...span.attributes, ...attributes };\n }\n\n /**\n * Gets a span by ID.\n *\n * @param spanId - ID of the span to retrieve\n * @returns The span, or undefined if not found\n */\n getSpan(spanId: string): TraceSpan | undefined {\n return this.spans.get(spanId);\n }\n\n /**\n * Gets all spans in the current trace.\n *\n * @returns Array of all spans\n */\n getAllSpans(): TraceSpan[] {\n return Array.from(this.spans.values());\n }\n\n /**\n * Gets the current trace ID.\n *\n * @returns Current trace ID, or undefined if no trace is active\n */\n getTraceId(): string | undefined {\n return this.currentTraceId;\n }\n\n /**\n * Gets the current trace context.\n *\n * @returns Current trace context with the most recent span, or undefined\n */\n getCurrentContext(): TraceContext | undefined {\n if (!this.enabled || this.currentTraceId === undefined) {\n return undefined;\n }\n return findLatestRunningSpan(this.spans.values())?.context;\n }\n\n /**\n * Aggregates metrics across all spans in the trace.\n *\n * @returns Aggregated metrics\n */\n getAggregatedMetrics(): AggregatedMetrics {\n const spans = this.getAllSpans();\n const metrics: AggregatedMetrics = {\n totalSpans: spans.length,\n successfulSpans: 0,\n errorSpans: 0,\n totalInputTokens: 0,\n totalOutputTokens: 0,\n totalCostUsd: 0,\n durationMs: 0,\n byModel: {},\n byProvider: {},\n };\n\n const { minStartTime, maxEndTime } = aggregateSpanMetrics(spans, metrics);\n calculateDuration(metrics, minStartTime, maxEndTime);\n\n return metrics;\n }\n\n /**\n * Clears all spans and resets the trace.\n */\n clear(): void {\n this.spans.clear();\n this.currentTraceId = undefined;\n }\n\n /**\n * Prunes oldest completed spans to stay under maxSpans limit.\n */\n private pruneOldestSpans(): void {\n const idsToDelete = getSpansToPrune(this.spans.entries(), 0.1);\n for (const id of idsToDelete) {\n this.spans.delete(id);\n }\n }\n}\n\n// =============================================================================\n// Initialize tracer factory (breaks circular dependency)\n// =============================================================================\n\n// Register the Tracer factory so trace-helpers can create instances\nsetTracerFactory((config?: TracerConfig) => new Tracer(config));\n\n// =============================================================================\n// Re-exports for backward compatibility\n// =============================================================================\n\nexport * from './trace-types.js';\nexport * from './trace-pricing.js';\nexport * from './trace-helpers.js';\n","/**\n * nexus-agents/core - Trace Exporter\n *\n * Export and visualize trace data for debugging and analysis.\n * Provides JSON file export and console pretty-printing.\n *\n * (Source: Issue #132)\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { getTimeProvider } from './index.js';\nimport type { TraceSpan, AggregatedMetrics, Tracer } from './trace.js';\nimport {\n type ResolvedVisualizationOptions,\n buildSpanTree,\n renderSpanNode,\n renderHeader,\n buildSummaryParts,\n} from './trace-exporter-helpers.js';\nimport { colors } from '../cli/ansi-output.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Export format options.\n */\nexport type ExportFormat = 'json' | 'json-pretty';\n\n/**\n * Exported trace data structure.\n */\nexport interface ExportedTrace {\n /** Trace ID */\n readonly traceId: string;\n /** Export timestamp (ISO format) */\n readonly exportedAt: string;\n /** All spans in the trace */\n readonly spans: readonly TraceSpan[];\n /** Aggregated metrics */\n readonly metrics: AggregatedMetrics;\n}\n\n/**\n * Options for trace visualization.\n */\nexport interface VisualizationOptions {\n /** Show cost information */\n readonly showCost?: boolean;\n /** Show token counts */\n readonly showTokens?: boolean;\n /** Indent size for tree structure */\n readonly indentSize?: number;\n /** Use colors in output */\n readonly colors?: boolean;\n}\n\nconst DEFAULT_VIS_OPTIONS: ResolvedVisualizationOptions = {\n showCost: true,\n showTokens: true,\n indentSize: 2,\n colors: true,\n};\n\n// =============================================================================\n// Trace Exporter\n// =============================================================================\n\n/**\n * Exports trace data to JSON file.\n *\n * @param tracer - Tracer instance to export from\n * @param filepath - Destination file path\n * @param format - Export format (default: 'json-pretty')\n */\nexport function exportTraceToFile(\n tracer: Tracer,\n filepath: string,\n format: ExportFormat = 'json-pretty'\n): void {\n const traceId = tracer.getTraceId() ?? 'unknown';\n const spans = tracer.getAllSpans();\n const metrics = tracer.getAggregatedMetrics();\n\n const exportData: ExportedTrace = {\n traceId,\n exportedAt: getTimeProvider().nowIso(),\n spans,\n metrics,\n };\n\n const content =\n format === 'json-pretty' ? JSON.stringify(exportData, null, 2) : JSON.stringify(exportData);\n\n // Ensure directory exists\n const dir = path.dirname(filepath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n fs.writeFileSync(filepath, content, 'utf-8');\n}\n\n/**\n * Exports trace data to JSON string.\n *\n * @param tracer - Tracer instance to export from\n * @param format - Export format (default: 'json-pretty')\n * @returns JSON string of trace data\n */\nexport function exportTraceToString(tracer: Tracer, format: ExportFormat = 'json-pretty'): string {\n const traceId = tracer.getTraceId() ?? 'unknown';\n const spans = tracer.getAllSpans();\n const metrics = tracer.getAggregatedMetrics();\n\n const exportData: ExportedTrace = {\n traceId,\n exportedAt: getTimeProvider().nowIso(),\n spans,\n metrics,\n };\n\n return format === 'json-pretty'\n ? JSON.stringify(exportData, null, 2)\n : JSON.stringify(exportData);\n}\n\n// =============================================================================\n// Visualization\n// =============================================================================\n\n/**\n * Generates a pretty-printed trace visualization.\n *\n * @param tracer - Tracer instance to visualize\n * @param options - Visualization options\n * @returns Array of lines for the visualization\n *\n * @example\n * ```typescript\n * const lines = visualizeTrace(tracer);\n * console.log(lines.join('\\n'));\n * ```\n *\n * Output example:\n * ```\n * Trace: abc123-def456\n * +-- [OK] orchestrate-task (2.34s)\n * | +-- [OK] analyze (890ms) [1,234 in / 456 out] $0.0052\n * | +-- [OK] review (1.45s) [2,345 in / 789 out] $0.0123\n * +-- Total: 2.34s | Tokens: 3,579 in / 1,245 out | Cost: $0.0175\n * ```\n */\nexport function visualizeTrace(tracer: Tracer, options?: VisualizationOptions): string[] {\n const opts: ResolvedVisualizationOptions = { ...DEFAULT_VIS_OPTIONS, ...options };\n const spans = tracer.getAllSpans();\n const metrics = tracer.getAggregatedMetrics();\n const traceId = tracer.getTraceId() ?? 'unknown';\n\n const lines: string[] = [];\n lines.push(renderHeader(traceId, opts.colors));\n\n // Build and render tree\n const tree = buildSpanTree(spans);\n for (let i = 0; i < tree.length; i++) {\n const root = tree[i];\n if (root !== undefined) {\n const isLast = i === tree.length - 1;\n lines.push(...renderSpanNode(root, '', isLast, opts));\n }\n }\n\n // Summary line\n const summaryParts = buildSummaryParts(metrics, opts);\n lines.push('');\n const summary = summaryParts.join(' | ');\n if (opts.colors) {\n lines.push(`${colors.dim}${summary}${colors.reset}`);\n } else {\n lines.push(summary);\n }\n\n return lines;\n}\n\n/**\n * Prints trace visualization to console.\n *\n * @param tracer - Tracer instance to visualize\n * @param options - Visualization options\n */\nexport function printTrace(tracer: Tracer, options?: VisualizationOptions): void {\n const lines = visualizeTrace(tracer, options);\n for (const line of lines) {\n // eslint-disable-next-line no-console -- intentional console output for trace visualization\n console.log(line);\n }\n}\n\n// =============================================================================\n// Convenience Functions\n// =============================================================================\n\n/**\n * Generates a default filename for trace export.\n *\n * @param traceId - Trace ID to include in filename\n * @returns Filename with timestamp\n */\nexport function generateTraceFilename(traceId: string): string {\n const timestamp = getTimeProvider().nowIso().replace(/[:.]/g, '-');\n const shortId = traceId.slice(0, 8);\n return `trace-${timestamp}-${shortId}.json`;\n}\n","/**\n * ANSI Output Utilities\n *\n * Consolidated terminal output utilities for CLI commands.\n * Provides colors, symbols, and output helpers with cross-platform support.\n *\n * @module cli/ansi-output\n */\n\n// ============================================================================\n// NO_COLOR Detection (https://no-color.org/)\n// ============================================================================\n\n/**\n * Whether color output is enabled.\n * Respects the NO_COLOR env var (any value disables color) and TTY detection.\n */\nexport const colorsEnabled = !('NO_COLOR' in process.env) && process.stdout.isTTY;\n\n// ============================================================================\n// ANSI Color Codes\n// ============================================================================\n\n/**\n * ANSI color codes for terminal output.\n * Returns empty strings when NO_COLOR is set or stdout is not a TTY.\n */\nexport const colors = {\n /** Reset all formatting */\n reset: colorsEnabled ? '\\x1b[0m' : '',\n /** Green text (success, enabled) */\n green: colorsEnabled ? '\\x1b[32m' : '',\n /** Yellow text (warning, caution) */\n yellow: colorsEnabled ? '\\x1b[33m' : '',\n /** Red text (error, disabled) */\n red: colorsEnabled ? '\\x1b[31m' : '',\n /** Cyan text (info, highlight) */\n cyan: colorsEnabled ? '\\x1b[36m' : '',\n /** Dim text (secondary info) */\n dim: colorsEnabled ? '\\x1b[2m' : '',\n /** Bold text (emphasis) */\n bold: colorsEnabled ? '\\x1b[1m' : '',\n /** Magenta text (special) */\n magenta: colorsEnabled ? '\\x1b[35m' : '',\n /** Blue text */\n blue: colorsEnabled ? '\\x1b[34m' : '',\n /** White text */\n white: colorsEnabled ? '\\x1b[37m' : '',\n /** Gray text (muted) */\n gray: colorsEnabled ? '\\x1b[90m' : '',\n} as const;\n\n/** Type for color names. */\nexport type ColorName = keyof typeof colors;\n\n// ============================================================================\n// Cross-Platform Symbols\n// ============================================================================\n\nconst isWindows = process.platform === 'win32';\n\n/**\n * Cross-platform console symbols.\n * Provides Unicode symbols on Unix, ASCII fallbacks on Windows.\n */\nexport const symbols = {\n /** Success indicator */\n check: isWindows ? '[OK]' : '✓',\n /** Failure indicator */\n cross: isWindows ? '[X]' : '✗',\n /** Warning indicator */\n warn: isWindows ? '[!]' : '⚠',\n /** Bullet point */\n bullet: isWindows ? '*' : '•',\n /** Arrow right */\n arrow: isWindows ? '->' : '→',\n /** Information */\n info: isWindows ? '[i]' : 'ℹ',\n /** Circle/empty indicator */\n circle: isWindows ? 'o' : '○',\n} as const;\n\n/** Type for symbol names. */\nexport type SymbolName = keyof typeof symbols;\n\n// ============================================================================\n// Output Functions\n// ============================================================================\n\n/**\n * Writes a line to stdout with newline.\n * If no text is provided, writes an empty line.\n */\nexport function writeLine(text: string = ''): void {\n process.stdout.write(text + '\\n');\n}\n\n/**\n * Writes an empty line to stdout.\n * Prefer writeLine() without arguments for consistency.\n */\nexport function writeEmptyLine(): void {\n process.stdout.write('\\n');\n}\n\n/**\n * Writes text to stdout without newline.\n */\nexport function write(text: string): void {\n process.stdout.write(text);\n}\n\n// ============================================================================\n// Formatting Helpers\n// ============================================================================\n\n/**\n * Wraps text in a color code with reset.\n */\nexport function colorize(text: string, color: ColorName): string {\n return `${colors[color]}${text}${colors.reset}`;\n}\n\n/**\n * Wraps text in a raw ANSI code with reset.\n * Use this when combining codes or using dynamic values.\n */\nexport function color(text: string, code: string): string {\n return `${code}${text}${colors.reset}`;\n}\n\n/**\n * Formats text as bold.\n */\nexport function bold(text: string): string {\n return `${colors.bold}${text}${colors.reset}`;\n}\n\n/**\n * Formats text as dim.\n */\nexport function dim(text: string): string {\n return `${colors.dim}${text}${colors.reset}`;\n}\n\n/**\n * Status types for formatStatus.\n * Basic: 'pass', 'warn', 'fail' (3-state)\n * Extended: adds 'success', 'failed', 'skipped', 'pending', 'warning' (setup command compatibility)\n */\nexport type StatusType =\n | 'pass'\n | 'warn'\n | 'fail'\n | 'success'\n | 'failed'\n | 'skipped'\n | 'pending'\n | 'warning';\n\n/**\n * Formats a status indicator with appropriate color and symbol.\n *\n * Supports both basic 3-state (pass/warn/fail) and extended 5-state\n * (success/failed/skipped/pending/warning) status indicators.\n */\nexport function formatStatus(status: StatusType): string {\n const statusMap: Record<StatusType, string> = {\n // Basic 3-state (system review, fitness audit)\n pass: colors.green + symbols.check,\n warn: colors.yellow + symbols.warn,\n fail: colors.red + symbols.cross,\n // Extended state aliases (setup command)\n success: colors.green + symbols.check,\n failed: colors.red + symbols.cross,\n skipped: colors.yellow + symbols.warn,\n pending: colors.dim + symbols.circle,\n warning: colors.yellow + symbols.warn,\n };\n return statusMap[status] + colors.reset;\n}\n\n/**\n * Formats a section header with bold styling.\n */\nexport function formatHeader(text: string): string {\n return `${colors.bold}${text}${colors.reset}`;\n}\n\n/**\n * Formats a code block with indentation and dim styling.\n */\nexport function formatCodeBlock(code: string): string {\n const lines = code.split('\\n');\n return lines.map((line) => ` ${colors.dim}${line}${colors.reset}`).join('\\n');\n}\n\n/**\n * Formats a boolean value with color.\n */\nexport function formatBoolean(value: boolean): string {\n return value ? `${colors.green}true${colors.reset}` : `${colors.red}false${colors.reset}`;\n}\n","/**\n * nexus-agents/core - Trace Exporter Helpers\n *\n * Pure helper functions for trace visualization.\n * Extracted from trace-exporter.ts to maintain file size limits.\n */\n\nimport type { TraceSpan, AggregatedMetrics } from './trace.js';\nimport { colors } from '../cli/ansi-output.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Options for trace visualization (resolved with defaults).\n */\nexport interface ResolvedVisualizationOptions {\n /** Show cost information */\n readonly showCost: boolean;\n /** Show token counts */\n readonly showTokens: boolean;\n /** Indent size for tree structure */\n readonly indentSize: number;\n /** Use colors in output */\n readonly colors: boolean;\n}\n\n/**\n * Tree node for span hierarchy.\n */\nexport interface SpanNode {\n span: TraceSpan;\n children: SpanNode[];\n}\n\n// =============================================================================\n// ANSI Colors\n// =============================================================================\n\n/**\n * Raw ANSI codes for trace visualization.\n * Used when opts.colors is true, bypassing TTY detection.\n */\nconst RAW_ANSI = {\n reset: '\\x1b[0m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n red: '\\x1b[31m',\n cyan: '\\x1b[36m',\n bold: '\\x1b[1m',\n} as const;\n\n/** Get color code — uses raw ANSI when forceColors is true, else module-level detection. */\nfunction c(code: keyof typeof RAW_ANSI, useColors: boolean): string {\n if (useColors) return RAW_ANSI[code];\n return colors[code];\n}\n\n// =============================================================================\n// Formatting Functions\n// =============================================================================\n\n/**\n * Formats duration in human-readable form.\n * Supports milliseconds, seconds, minutes, and hours.\n *\n * @param ms - Duration in milliseconds\n * @returns Formatted string like \"150ms\", \"2.5s\", \"3m 45s\", or \"2h 15m\"\n */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${String(ms)}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n }\n if (ms < 3600000) {\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.floor((ms % 60000) / 1000);\n return `${String(minutes)}m ${String(seconds)}s`;\n }\n // Hours format\n const hours = Math.floor(ms / 3600000);\n const remainMins = Math.floor((ms % 3600000) / 60000);\n return `${String(hours)}h ${String(remainMins)}m`;\n}\n\n/**\n * Formats duration in a simplified format (minutes only after 1min).\n * Useful for compact displays.\n *\n * @param ms - Duration in milliseconds\n * @returns Formatted string like \"150ms\", \"2.5s\", or \"3.5min\"\n */\nexport function formatDurationCompact(ms: number): string {\n if (ms < 1000) return `${String(ms)}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n return `${(ms / 60000).toFixed(1)}min`;\n}\n\n/**\n * Formats cost in USD.\n */\nexport function formatCost(cost: number): string {\n if (cost < 0.01) {\n return `$${cost.toFixed(6)}`;\n }\n if (cost < 1) {\n return `$${cost.toFixed(4)}`;\n }\n return `$${cost.toFixed(2)}`;\n}\n\n/**\n * Formats token count.\n */\nexport function formatTokens(input: number, output: number): string {\n return `${input.toLocaleString()} in / ${output.toLocaleString()} out`;\n}\n\n/**\n * Formats a decimal value as a percentage string.\n *\n * @param value - Decimal value (0-1 range, e.g., 0.85 for 85%)\n * @param decimals - Number of decimal places (default: 0)\n * @returns Formatted string like \"85%\" or \"85.5%\"\n */\nexport function formatPercentage(value: number, decimals: number = 0): string {\n return `${(value * 100).toFixed(decimals)}%`;\n}\n\n// =============================================================================\n// Status Indicators\n// =============================================================================\n\n/**\n * Gets status indicator with optional color.\n */\nexport function getStatusIndicator(status: string, useColors: boolean): string {\n if (useColors) {\n switch (status) {\n case 'success':\n return `${c('green', true)}✓${c('reset', true)}`;\n case 'error':\n return `${c('red', true)}✗${c('reset', true)}`;\n case 'running':\n return `${c('yellow', true)}●${c('reset', true)}`;\n default:\n return '?';\n }\n }\n switch (status) {\n case 'success':\n return '[OK]';\n case 'error':\n return '[ERR]';\n case 'running':\n return '[RUN]';\n default:\n return '[?]';\n }\n}\n\n// =============================================================================\n// Line Builders\n// =============================================================================\n\n/**\n * Appends token info to the main line if enabled.\n */\nexport function appendTokenInfo(\n mainLine: string,\n span: TraceSpan,\n opts: ResolvedVisualizationOptions\n): string {\n if (!opts.showTokens || span.llmMetrics === undefined) {\n return mainLine;\n }\n const tokenStr = formatTokens(span.llmMetrics.inputTokens, span.llmMetrics.outputTokens);\n if (opts.colors) {\n return `${mainLine} ${c('cyan', true)}[${tokenStr}]${c('reset', true)}`;\n }\n return `${mainLine} [${tokenStr}]`;\n}\n\n/**\n * Appends cost info to the main line if enabled.\n */\nexport function appendCostInfo(\n mainLine: string,\n span: TraceSpan,\n opts: ResolvedVisualizationOptions\n): string {\n if (!opts.showCost || span.llmMetrics?.costUsd === undefined) {\n return mainLine;\n }\n const costStr = formatCost(span.llmMetrics.costUsd);\n if (opts.colors) {\n return `${mainLine} ${c('yellow', true)}${costStr}${c('reset', true)}`;\n }\n return `${mainLine} ${costStr}`;\n}\n\n/**\n * Renders error message if present.\n */\nexport function renderErrorLine(\n span: TraceSpan,\n errorPrefix: string,\n opts: ResolvedVisualizationOptions\n): string | null {\n if (span.errorMessage === undefined) {\n return null;\n }\n if (opts.colors) {\n return `${errorPrefix}${c('red', true)}Error: ${span.errorMessage}${c('reset', true)}`;\n }\n return `${errorPrefix}Error: ${span.errorMessage}`;\n}\n\n// =============================================================================\n// Tree Building\n// =============================================================================\n\n/**\n * Sorts children of a span node by start time (recursive).\n */\nfunction sortChildren(node: SpanNode): void {\n node.children.sort((a, b) => a.span.startTime - b.span.startTime);\n for (const child of node.children) {\n sortChildren(child);\n }\n}\n\n/**\n * Builds a tree structure from flat span list.\n */\nexport function buildSpanTree(spans: readonly TraceSpan[]): SpanNode[] {\n const spanMap = new Map<string, SpanNode>();\n const roots: SpanNode[] = [];\n\n // Create nodes\n for (const span of spans) {\n spanMap.set(span.context.spanId, { span, children: [] });\n }\n\n // Build tree\n for (const span of spans) {\n const node = spanMap.get(span.context.spanId);\n if (node === undefined) continue;\n\n if (span.context.parentSpanId !== undefined) {\n const parent = spanMap.get(span.context.parentSpanId);\n if (parent !== undefined) {\n parent.children.push(node);\n } else {\n roots.push(node);\n }\n } else {\n roots.push(node);\n }\n }\n\n // Sort children by start time\n for (const root of roots) {\n sortChildren(root);\n }\n\n return roots.sort((a, b) => a.span.startTime - b.span.startTime);\n}\n\n// =============================================================================\n// Span Rendering\n// =============================================================================\n\n/**\n * Renders a single span node.\n */\nexport function renderSpanNode(\n node: SpanNode,\n prefix: string,\n isLast: boolean,\n opts: ResolvedVisualizationOptions\n): string[] {\n const lines: string[] = [];\n const { span } = node;\n\n // Compute duration\n const durationMs = span.endTime !== undefined ? span.endTime - span.startTime : 0;\n const durationStr = span.endTime !== undefined ? formatDuration(durationMs) : 'running';\n\n // Build main line\n const connector = isLast ? '└── ' : '├── ';\n const status = getStatusIndicator(span.status, opts.colors);\n let mainLine = `${prefix}${connector}${status} ${span.name} (${durationStr})`;\n mainLine = appendTokenInfo(mainLine, span, opts);\n mainLine = appendCostInfo(mainLine, span, opts);\n lines.push(mainLine);\n\n // Add error message if present\n const errorPrefix = prefix + (isLast ? ' ' : '│ ');\n const errorLine = renderErrorLine(span, errorPrefix, opts);\n if (errorLine !== null) {\n lines.push(errorLine);\n }\n\n // Render children\n const childPrefix = prefix + (isLast ? ' ' : '│ ');\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n if (child !== undefined) {\n const childIsLast = i === node.children.length - 1;\n lines.push(...renderSpanNode(child, childPrefix, childIsLast, opts));\n }\n }\n\n return lines;\n}\n\n// =============================================================================\n// Header and Summary\n// =============================================================================\n\n/**\n * Renders the trace header line.\n */\nexport function renderHeader(traceId: string, useColors: boolean): string {\n if (useColors) {\n return `${c('bold', true)}🔍 Trace: ${traceId}${c('reset', true)}`;\n }\n return `Trace: ${traceId}`;\n}\n\n/**\n * Builds summary parts for the trace.\n */\nexport function buildSummaryParts(\n metrics: AggregatedMetrics,\n opts: ResolvedVisualizationOptions\n): string[] {\n const parts: string[] = [];\n parts.push(`Total: ${formatDuration(metrics.durationMs)}`);\n\n if (opts.showTokens && (metrics.totalInputTokens > 0 || metrics.totalOutputTokens > 0)) {\n const tokensIn = metrics.totalInputTokens.toLocaleString();\n const tokensOut = metrics.totalOutputTokens.toLocaleString();\n parts.push(`Tokens: ${tokensIn} in / ${tokensOut} out`);\n }\n\n if (opts.showCost && metrics.totalCostUsd > 0) {\n parts.push(`Cost: ${formatCost(metrics.totalCostUsd)}`);\n }\n\n if (metrics.errorSpans > 0) {\n const errCount = String(metrics.errorSpans);\n if (opts.colors) {\n parts.push(`${c('red', true)}Errors: ${errCount}${c('reset', true)}`);\n } else {\n parts.push(`Errors: ${errCount}`);\n }\n }\n\n return parts;\n}\n","/**\n * nexus-agents/core - Artifact Provenance Envelope\n *\n * Thin wrapper for traceability that provides provenance tracking\n * for artifacts produced by agents during orchestration.\n *\n * Schema version: 1.0.0\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { z } from 'zod';\nimport { getTimeProvider } from './index.js';\n\n/**\n * Current schema version for artifacts.\n * Follows semantic versioning.\n */\nexport const ARTIFACT_SCHEMA_VERSION = '1.0.0';\n\n/**\n * Artifact type constants for discriminated union.\n */\nexport const ArtifactType = {\n /** Planning documents and task breakdowns */\n PLAN: 'plan',\n /** Analysis results and findings */\n ANALYSIS: 'analysis',\n /** Decisions made during orchestration */\n DECISION: 'decision',\n /** Final results and outputs */\n RESULT: 'result',\n /** Intent declarations for policy authorization */\n INTENT: 'intent',\n} as const;\n\nexport type ArtifactTypeValue = (typeof ArtifactType)[keyof typeof ArtifactType];\n\n/**\n * Zod schema for artifact type validation.\n */\nexport const ArtifactTypeSchema = z.enum([\n ArtifactType.PLAN,\n ArtifactType.ANALYSIS,\n ArtifactType.DECISION,\n ArtifactType.RESULT,\n ArtifactType.INTENT,\n]);\n\n/**\n * Metadata providing provenance information for an artifact.\n */\nexport interface ArtifactMetadata {\n /** ISO 8601 timestamp when the artifact was created */\n readonly createdAt: string;\n /** ID of the agent that created this artifact */\n readonly createdBy: string;\n /** ID of the parent artifact (if derived from another) */\n readonly parentId?: string;\n /** ID of the task this artifact belongs to */\n readonly taskId: string;\n /** Distributed tracing ID for correlation */\n readonly traceId?: string;\n}\n\n/**\n * Zod schema for artifact metadata validation.\n */\nexport const ArtifactMetadataSchema = z.object({\n createdAt: z.iso.datetime({ message: 'createdAt must be ISO 8601 format' }),\n createdBy: z.string().min(1, 'createdBy is required'),\n parentId: z.uuid().optional(),\n taskId: z.string().min(1, 'taskId is required'),\n traceId: z.string().optional(),\n});\n\n/**\n * Generic artifact envelope providing traceability for any data type.\n *\n * @template T - The type of data contained in the artifact\n *\n * @example\n * ```typescript\n * interface PlanData {\n * steps: string[];\n * estimatedDuration: number;\n * }\n *\n * const artifact: Artifact<PlanData> = createArtifact(\n * ArtifactType.PLAN,\n * { steps: ['analyze', 'implement', 'test'], estimatedDuration: 3600 },\n * { createdBy: 'tech-lead-001', taskId: 'task-123' }\n * );\n * ```\n */\nexport interface Artifact<T> {\n /** Unique identifier for this artifact (UUID v4) */\n readonly id: string;\n /** Type of artifact for categorization */\n readonly type: ArtifactTypeValue;\n /** Schema version for forward compatibility */\n readonly schemaVersion: string;\n /** The actual artifact data */\n readonly data: T;\n /** Provenance metadata */\n readonly metadata: ArtifactMetadata;\n}\n\n/**\n * Zod schema factory for artifact validation.\n *\n * @template T - The Zod schema type for the data field\n * @param dataSchema - Zod schema for validating the artifact data\n * @returns A Zod schema for the complete Artifact\n *\n * @example\n * ```typescript\n * const PlanDataSchema = z.object({\n * steps: z.array(z.string()),\n * estimatedDuration: z.number(),\n * });\n *\n * const PlanArtifactSchema = createArtifactSchema(PlanDataSchema);\n * const result = PlanArtifactSchema.safeParse(artifact);\n * ```\n */\nexport function createArtifactSchema<T extends z.ZodType>(\n dataSchema: T\n): z.ZodObject<{\n id: z.ZodUUID;\n type: typeof ArtifactTypeSchema;\n schemaVersion: z.ZodString;\n data: T;\n metadata: typeof ArtifactMetadataSchema;\n}> {\n return z.object({\n id: z.uuid(),\n type: ArtifactTypeSchema,\n schemaVersion: z.string().regex(/^\\d+\\.\\d+\\.\\d+$/, 'schemaVersion must be semver'),\n data: dataSchema,\n metadata: ArtifactMetadataSchema,\n });\n}\n\n/**\n * Base artifact schema with unknown data (for type guards).\n */\nexport const BaseArtifactSchema = createArtifactSchema(z.unknown());\n\n/**\n * Input for creating an artifact (without auto-generated fields).\n * Uses mutable version to allow conditional property assignment.\n */\nexport interface CreateArtifactInput {\n /** ID of the agent that created this artifact */\n createdBy: string;\n /** ID of the task this artifact belongs to */\n taskId: string;\n /** ID of the parent artifact (if derived from another) */\n parentId?: string;\n /** Distributed tracing ID for correlation */\n traceId?: string;\n}\n\n/**\n * Creates a new artifact with auto-generated ID, timestamp, and schema version.\n *\n * @template T - The type of data contained in the artifact\n * @param type - The artifact type\n * @param data - The artifact data\n * @param metadata - Metadata without createdAt (auto-generated)\n * @returns A complete Artifact with all fields populated\n *\n * @example\n * ```typescript\n * const artifact = createArtifact(\n * ArtifactType.ANALYSIS,\n * { findings: ['Issue A', 'Issue B'], severity: 'medium' },\n * { createdBy: 'security-expert-001', taskId: 'audit-456' }\n * );\n * ```\n */\nexport function createArtifact<T>(\n type: ArtifactTypeValue,\n data: T,\n metadata: CreateArtifactInput\n): Artifact<T> {\n return {\n id: randomUUID(),\n type,\n schemaVersion: ARTIFACT_SCHEMA_VERSION,\n data,\n metadata: {\n ...metadata,\n createdAt: getTimeProvider().nowIso(),\n },\n };\n}\n\n/**\n * Type guard to check if a value is a valid Artifact structure.\n *\n * Note: This validates the envelope structure but not the data content.\n * Use createArtifactSchema() with a specific data schema for full validation.\n *\n * @param value - The value to check\n * @returns True if the value matches the Artifact structure\n *\n * @example\n * ```typescript\n * if (isArtifact(maybeArtifact)) {\n * console.log(`Artifact ${maybeArtifact.id} created by ${maybeArtifact.metadata.createdBy}`);\n * }\n * ```\n */\nexport function isArtifact(value: unknown): value is Artifact<unknown> {\n const result = BaseArtifactSchema.safeParse(value);\n return result.success;\n}\n\n/**\n * Type guard to check if a value is an Artifact of a specific type.\n *\n * @param value - The value to check\n * @param type - The expected artifact type\n * @returns True if the value is an Artifact with the specified type\n *\n * @example\n * ```typescript\n * if (isArtifactOfType(artifact, ArtifactType.PLAN)) {\n * // TypeScript knows artifact.type === 'plan'\n * console.log('Processing plan artifact');\n * }\n * ```\n */\nexport function isArtifactOfType<T>(value: unknown, type: ArtifactTypeValue): value is Artifact<T> {\n return isArtifact(value) && value.type === type;\n}\n\n/**\n * Creates a derived artifact from a parent artifact.\n *\n * @template T - The type of data contained in the new artifact\n * @param type - The artifact type for the derived artifact\n * @param data - The artifact data\n * @param parent - The parent artifact to derive from\n * @param createdBy - The ID of the agent creating this artifact\n * @returns A new Artifact with parentId set to the parent's ID\n *\n * @example\n * ```typescript\n * const analysis = createArtifact(\n * ArtifactType.ANALYSIS,\n * { findings: ['Issue found'] },\n * { createdBy: 'analyzer', taskId: 'task-1' }\n * );\n *\n * const decision = deriveArtifact(\n * ArtifactType.DECISION,\n * { action: 'fix', reasoning: 'Critical issue' },\n * analysis,\n * 'decision-maker'\n * );\n * // decision.metadata.parentId === analysis.id\n * ```\n */\nexport function deriveArtifact<T, P>(\n type: ArtifactTypeValue,\n data: T,\n parent: Artifact<P>,\n createdBy: string\n): Artifact<T> {\n const input: CreateArtifactInput = {\n createdBy,\n taskId: parent.metadata.taskId,\n parentId: parent.id,\n };\n\n // Only include traceId if parent has one (exactOptionalPropertyTypes compliance)\n if (parent.metadata.traceId !== undefined) {\n input.traceId = parent.metadata.traceId;\n }\n\n return createArtifact(type, data, input);\n}\n","/**\n * nexus-agents/core - Error Metrics Collection\n *\n * Provides error telemetry and metrics aggregation for monitoring and debugging.\n * Tracks error counts by code, component, and time.\n *\n * (Source: Issue #112)\n */\n\nimport { type ErrorCode, NexusError } from './errors.js';\nimport { getTimeProvider } from './time-provider.js';\n\n/**\n * Snapshot of error metrics at a point in time.\n */\nexport interface ErrorMetrics {\n /** Total number of errors recorded */\n readonly totalErrors: number;\n /** Error counts by error code */\n readonly errorsByCode: ReadonlyMap<ErrorCode, number>;\n /** Error counts by component/source */\n readonly errorsByComponent: ReadonlyMap<string, number>;\n /** Most recent error info */\n readonly lastError?: {\n readonly code: ErrorCode;\n readonly component: string;\n readonly message: string;\n readonly timestamp: Date;\n };\n /** Timestamp when metrics collection started */\n readonly startedAt: Date;\n /** Number of milliseconds since metrics collection started */\n readonly uptimeMs: number;\n}\n\n/**\n * Options for recording an error.\n */\nexport interface RecordErrorOptions {\n /** The component or source of the error */\n readonly component: string;\n /** The error to record */\n readonly error: Error | NexusError;\n /** Optional additional context */\n readonly context?: Record<string, unknown>;\n}\n\n/**\n * Metrics export format for monitoring systems.\n */\nexport interface MetricsExport {\n /** Unix timestamp in milliseconds */\n readonly timestamp: number;\n /** Total error count */\n readonly totalErrors: number;\n /** Error rate per minute (last 5 minutes) */\n readonly errorRatePerMinute: number;\n /** Top 5 error codes by count */\n readonly topErrorCodes: ReadonlyArray<{ code: string; count: number }>;\n /** Top 5 components by error count */\n readonly topComponents: ReadonlyArray<{ component: string; count: number }>;\n /** Uptime in seconds */\n readonly uptimeSeconds: number;\n}\n\n/**\n * Internal error record for time-series tracking.\n */\ninterface ErrorRecord {\n readonly code: ErrorCode;\n readonly component: string;\n readonly message: string;\n readonly timestamp: Date;\n}\n\n/**\n * Maximum number of recent errors to keep for rate calculation.\n */\nconst MAX_RECENT_ERRORS = 1000;\n\n/**\n * Time window for error rate calculation (5 minutes).\n */\nconst RATE_WINDOW_MS = 5 * 60 * 1000;\n\n/**\n * Error metrics collector for monitoring and debugging.\n *\n * Thread-safe singleton that aggregates error data across the application.\n */\nexport class ErrorMetricsCollector {\n private totalErrors = 0;\n private readonly errorsByCode = new Map<ErrorCode, number>();\n private readonly errorsByComponent = new Map<string, number>();\n private readonly recentErrors: ErrorRecord[] = [];\n private lastError: ErrorRecord | undefined;\n private readonly startedAt: Date;\n\n constructor() {\n this.startedAt = new Date(getTimeProvider().now());\n }\n\n /**\n * Records an error occurrence.\n *\n * @param options - Error recording options\n */\n record(options: RecordErrorOptions): void {\n const { component, error } = options;\n const code = this.extractErrorCode(error);\n const timestamp = new Date(getTimeProvider().now());\n\n // Update counters\n this.totalErrors++;\n this.errorsByCode.set(code, (this.errorsByCode.get(code) ?? 0) + 1);\n this.errorsByComponent.set(component, (this.errorsByComponent.get(component) ?? 0) + 1);\n\n // Track recent error\n const record: ErrorRecord = {\n code,\n component,\n message: error.message,\n timestamp,\n };\n this.lastError = record;\n\n // Maintain bounded recent errors list for rate calculation\n this.recentErrors.push(record);\n if (this.recentErrors.length > MAX_RECENT_ERRORS) {\n this.recentErrors.shift();\n }\n }\n\n /**\n * Gets the current error metrics snapshot.\n */\n getMetrics(): ErrorMetrics {\n const now = getTimeProvider().now();\n const base = {\n totalErrors: this.totalErrors,\n errorsByCode: new Map(this.errorsByCode),\n errorsByComponent: new Map(this.errorsByComponent),\n startedAt: this.startedAt,\n uptimeMs: now - this.startedAt.getTime(),\n };\n\n // Use spread to conditionally include lastError (satisfies exactOptionalPropertyTypes)\n if (this.lastError) {\n return {\n ...base,\n lastError: {\n code: this.lastError.code,\n component: this.lastError.component,\n message: this.lastError.message,\n timestamp: this.lastError.timestamp,\n },\n };\n }\n return base;\n }\n\n /**\n * Exports metrics in a format suitable for monitoring systems.\n */\n export(): MetricsExport {\n const now = getTimeProvider().now();\n const windowStart = now - RATE_WINDOW_MS;\n\n // Calculate error rate from recent errors\n const recentCount = this.recentErrors.filter((e) => e.timestamp.getTime() > windowStart).length;\n const errorRatePerMinute = (recentCount / 5) * 1; // errors per minute over 5 minute window\n\n // Get top error codes\n const sortedCodes = [...this.errorsByCode.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([code, count]) => ({ code, count }));\n\n // Get top components\n const sortedComponents = [...this.errorsByComponent.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([component, count]) => ({ component, count }));\n\n return {\n timestamp: now,\n totalErrors: this.totalErrors,\n errorRatePerMinute,\n topErrorCodes: sortedCodes,\n topComponents: sortedComponents,\n uptimeSeconds: Math.floor((now - this.startedAt.getTime()) / 1000),\n };\n }\n\n /**\n * Gets the count of errors for a specific error code.\n *\n * @param code - The error code to query\n */\n getCountByCode(code: ErrorCode): number {\n return this.errorsByCode.get(code) ?? 0;\n }\n\n /**\n * Gets the count of errors for a specific component.\n *\n * @param component - The component name to query\n */\n getCountByComponent(component: string): number {\n return this.errorsByComponent.get(component) ?? 0;\n }\n\n /**\n * Resets all metrics. Useful for testing or metric rotation.\n */\n reset(): void {\n this.totalErrors = 0;\n this.errorsByCode.clear();\n this.errorsByComponent.clear();\n this.recentErrors.length = 0;\n this.lastError = undefined;\n }\n\n /**\n * Extracts the error code from an error object.\n */\n private extractErrorCode(error: Error | NexusError): ErrorCode {\n if (error instanceof NexusError) {\n return error.code;\n }\n // Default to INTERNAL_ERROR for non-NexusError errors\n return 'INTERNAL_ERROR';\n }\n}\n\n/**\n * Global error metrics collector instance.\n *\n * Use this singleton for application-wide error tracking.\n */\nexport const errorMetrics = new ErrorMetricsCollector();\n\n/**\n * Helper function to record an error with minimal boilerplate.\n *\n * @param component - The component or source of the error\n * @param error - The error to record\n */\nexport function recordError(component: string, error: Error | NexusError): void {\n errorMetrics.record({ component, error });\n}\n","/**\n * Safe RegExp Utilities\n *\n * Provides safe regex operations to prevent ReDoS (Regular Expression\n * Denial of Service) attacks. All dynamic regex construction should\n * use these utilities.\n *\n * (Source: Issue #341, CODING_STANDARDS.md Section 7)\n *\n * @module core/safe-regex\n */\n\nimport type { Result } from './result.js';\nimport { ok, err, isErr } from './result.js';\n\n/**\n * Maximum allowed pattern length to prevent memory issues.\n */\nexport const MAX_PATTERN_LENGTH = 500;\n\n/**\n * Characters that are dangerous in regex patterns and need escaping.\n */\nconst REGEX_SPECIAL_CHARS = /[.*+?^${}()|[\\]\\\\]/g;\n\n/**\n * Patterns that indicate potentially dangerous regex (ReDoS prone).\n * These patterns can cause catastrophic backtracking.\n *\n * ReDoS occurs when regex has:\n * - Nested quantifiers: (a+)+, (a*)*\n * - Overlapping alternations with quantifiers\n * - Repetitive groupings followed by similar patterns\n */\nconst DANGEROUS_PATTERNS = [\n /\\([^)]*[+*]\\)[+*]/, // Nested quantifiers: (a+)+, (a*)+, (ab+)*, etc.\n /\\(\\?(?!:|\\))/, // Lookahead/behind (allow non-capturing groups (?:) and (?))\n /([+*]){2,}/, // Multiple adjacent quantifiers: a++, a**\n /\\.\\*\\.\\*/, // Multiple .* patterns in sequence\n /\\.\\+\\.\\+/, // Multiple .+ patterns in sequence\n];\n\n/**\n * Error thrown when regex validation fails.\n */\nexport class SafeRegexError extends Error {\n constructor(\n message: string,\n public readonly pattern: string,\n public readonly reason: 'invalid' | 'too_long' | 'dangerous'\n ) {\n super(message);\n this.name = 'SafeRegexError';\n }\n}\n\n/**\n * Escape special regex characters in a string.\n * Use this when you need to match a literal string.\n *\n * @param str - The string to escape\n * @returns The escaped string safe for use in RegExp\n *\n * @example\n * ```typescript\n * const literal = escapeRegex('file.txt'); // 'file\\\\.txt'\n * const regex = new RegExp(literal);\n * ```\n */\nexport function escapeRegex(str: string): string {\n return str.replace(REGEX_SPECIAL_CHARS, '\\\\$&');\n}\n\n/**\n * Validate that a regex pattern is safe to compile.\n *\n * @param pattern - The regex pattern string to validate\n * @returns Result with void on success, SafeRegexError on failure\n */\nexport function validatePattern(pattern: string): Result<void, SafeRegexError> {\n // Check length\n if (pattern.length > MAX_PATTERN_LENGTH) {\n return err(\n new SafeRegexError(\n `Pattern exceeds maximum length of ${String(MAX_PATTERN_LENGTH)}`,\n pattern,\n 'too_long'\n )\n );\n }\n\n // Check for dangerous patterns\n for (const dangerous of DANGEROUS_PATTERNS) {\n if (dangerous.test(pattern)) {\n return err(\n new SafeRegexError(\n 'Pattern contains potentially dangerous constructs that may cause ReDoS',\n pattern,\n 'dangerous'\n )\n );\n }\n }\n\n // Try to compile to catch syntax errors\n try {\n new RegExp(pattern);\n } catch {\n return err(new SafeRegexError('Invalid regex pattern', pattern, 'invalid'));\n }\n\n return ok(undefined);\n}\n\n/**\n * Safely create a RegExp from a pattern string.\n * Validates the pattern before compilation to prevent ReDoS.\n *\n * @param pattern - The regex pattern string\n * @param flags - Optional regex flags\n * @returns Result with RegExp on success, SafeRegexError on failure\n *\n * @example\n * ```typescript\n * const result = safeRegex('error:\\\\s+(\\\\w+)', 'gi');\n * if (result.ok) {\n * const matches = text.match(result.value);\n * }\n * ```\n */\nexport function safeRegex(pattern: string, flags?: string): Result<RegExp, SafeRegexError> {\n const validation = validatePattern(pattern);\n if (isErr(validation)) {\n return err(validation.error);\n }\n\n try {\n return ok(new RegExp(pattern, flags));\n } catch {\n return err(new SafeRegexError('Failed to compile regex pattern', pattern, 'invalid'));\n }\n}\n\n/**\n * Create a RegExp that matches a literal string (escaped).\n * Safe for any input since all special characters are escaped.\n *\n * @param literal - The literal string to match\n * @param flags - Optional regex flags\n * @returns RegExp that matches the literal string\n *\n * @example\n * ```typescript\n * const regex = literalRegex('file.txt', 'i');\n * regex.test('file.txt'); // true\n * regex.test('filextxt'); // false\n * ```\n */\nexport function literalRegex(literal: string, flags?: string): RegExp {\n return new RegExp(escapeRegex(literal), flags);\n}\n\n/**\n * Test if a pattern matches text, with safety validation.\n *\n * @param text - The text to test\n * @param pattern - The regex pattern\n * @param flags - Optional regex flags\n * @returns True if pattern matches, false otherwise (including on invalid pattern)\n */\nexport function safeTest(text: string, pattern: string, flags?: string): boolean {\n const result = safeRegex(pattern, flags);\n if (!result.ok) {\n return false;\n }\n return result.value.test(text);\n}\n\n/**\n * Match text against a pattern with safety validation.\n *\n * @param text - The text to match\n * @param pattern - The regex pattern\n * @param flags - Optional regex flags\n * @returns Match array or null (null on invalid pattern)\n */\nexport function safeMatch(text: string, pattern: string, flags?: string): RegExpMatchArray | null {\n const result = safeRegex(pattern, flags);\n if (!result.ok) {\n return null;\n }\n return text.match(result.value);\n}\n\n/**\n * Replace text using a pattern with safety validation.\n *\n * @param text - The text to transform\n * @param pattern - The regex pattern\n * @param replacement - The replacement string\n * @param flags - Optional regex flags\n * @returns Result with transformed string or SafeRegexError\n */\nexport function safeReplace(\n text: string,\n pattern: string,\n replacement: string,\n flags?: string\n): Result<string, SafeRegexError> {\n const result = safeRegex(pattern, flags);\n if (isErr(result)) {\n return err(result.error);\n }\n return ok(text.replace(result.value, replacement));\n}\n","/**\n * nexus-agents/core - Zod Validation Helpers\n *\n * Centralized utilities for Zod error formatting.\n * Consolidates 20+ duplicate implementations across the codebase.\n *\n * @module core/zod-helpers\n * (Source: LOOP H-K consolidation)\n */\n\nimport type { ZodError, z } from 'zod';\n\n/**\n * Formats a single Zod issue into a readable string.\n *\n * @param issue - The Zod issue to format\n * @returns A formatted string like \"field.path: error message\" or \"error message\" if no path\n *\n * @example\n * ```typescript\n * const issue = { path: ['user', 'email'], message: 'Invalid email' };\n * formatZodIssue(issue); // \"user.email: Invalid email\"\n * ```\n */\nexport function formatZodIssue(issue: z.core.$ZodIssue): string {\n const path = issue.path.length > 0 ? `${issue.path.join('.')}: ` : '';\n return `${path}${issue.message}`;\n}\n\n/**\n * Formats all Zod issues into a single semicolon-separated string.\n *\n * @param error - The Zod error to format\n * @returns A formatted string with all issues joined by \"; \"\n *\n * @example\n * ```typescript\n * try {\n * schema.parse(data);\n * } catch (e) {\n * if (e instanceof ZodError) {\n * console.error(formatZodError(e)); // \"name: Required; age: Expected number, received string\"\n * }\n * }\n * ```\n */\nexport function formatZodError(error: ZodError): string {\n return error.issues.map(formatZodIssue).join('; ');\n}\n\n/**\n * Formats all Zod issues into an array of strings.\n *\n * @param error - The Zod error to format\n * @returns An array of formatted issue strings\n *\n * @example\n * ```typescript\n * const issues = formatZodIssuesAsArray(zodError);\n * // [\"name: Required\", \"age: Expected number, received string\"]\n * ```\n */\nexport function formatZodIssuesAsArray(error: ZodError): string[] {\n return error.issues.map(formatZodIssue);\n}\n\n/**\n * Formats Zod issues with \"root\" as fallback for empty paths.\n *\n * @param error - The Zod error to format\n * @returns A formatted string with each issue on its own\n *\n * @example\n * ```typescript\n * const issues = formatZodIssuesWithRoot(zodError);\n * // \"root: Invalid type\" or \"field.path: Required\"\n * ```\n */\nexport function formatZodIssueWithRoot(issue: z.core.$ZodIssue): string {\n const pathStr = issue.path.length > 0 ? issue.path.join('.') : 'root';\n return `${pathStr}: ${issue.message}`;\n}\n\n/**\n * Type guard to check if a value is a Zod error.\n *\n * @param error - The value to check\n * @returns True if the value is a ZodError\n *\n * @example\n * ```typescript\n * if (isZodError(error)) {\n * console.error(formatZodError(error));\n * }\n * ```\n */\nexport function isZodError(error: unknown): error is ZodError {\n return (\n error !== null &&\n typeof error === 'object' &&\n 'issues' in error &&\n Array.isArray((error as ZodError).issues)\n );\n}\n","/**\n * Task Type Classifier\n *\n * Classifies tasks as \"reasoning\" or \"knowledge\" type to enable\n * optimal protocol selection and routing decisions.\n *\n * Based on research from arXiv:2502.19130:\n * - Voting works better for reasoning tasks (+13.2%)\n * - Consensus works better for knowledge tasks (+2.8%)\n *\n * Moved to core/ to allow use by adapters layer without layer violation.\n *\n * @module core/task-analysis/task-type-classifier\n * (Source: Issue #125, arXiv:2502.19130)\n */\n\nimport type { Task } from '../types/agent.js';\nimport { createLogger } from '../logger.js';\nimport type { ILogger } from '../logger.js';\n\n/**\n * Task type classification.\n */\nexport type TaskType = 'reasoning' | 'knowledge' | 'unknown';\n\n/**\n * Classification result with confidence.\n */\nexport interface ClassificationResult {\n /** Classified task type */\n readonly type: TaskType;\n /** Confidence score (0-1) */\n readonly confidence: number;\n /** Signals that contributed to classification */\n readonly signals: readonly ClassificationSignal[];\n}\n\n/**\n * A signal that contributed to classification.\n */\nexport interface ClassificationSignal {\n /** Signal name */\n readonly name: string;\n /** Weight contribution to classification */\n readonly weight: number;\n /** Whether signal indicates reasoning or knowledge */\n readonly indicates: 'reasoning' | 'knowledge';\n}\n\n/**\n * Configuration for task type classifier.\n */\nexport interface TaskTypeClassifierConfig {\n /** Logger instance */\n readonly logger?: ILogger;\n /** Minimum confidence to return non-unknown type (default: 0.3) */\n readonly minConfidence?: number;\n}\n\n// Reasoning task indicators (logical inference, problem-solving)\nconst REASONING_PATTERNS: ReadonlyArray<{ pattern: RegExp; weight: number; name: string }> = [\n { pattern: /\\b(why|how come|explain why)\\b/i, weight: 0.3, name: 'causal-question' },\n { pattern: /\\b(analyze|evaluate|assess|compare)\\b/i, weight: 0.25, name: 'analysis-verb' },\n { pattern: /\\b(solve|calculate|compute|derive)\\b/i, weight: 0.35, name: 'problem-solving' },\n {\n pattern: /\\b(if|then|therefore|because|since|assuming)\\b/i,\n weight: 0.2,\n name: 'logical-connector',\n },\n { pattern: /\\b(prove|deduce|infer|conclude)\\b/i, weight: 0.35, name: 'deductive-verb' },\n {\n pattern: /\\b(trade-?off|pros? and cons?|advantages?|disadvantages?)\\b/i,\n weight: 0.25,\n name: 'tradeoff-analysis',\n },\n { pattern: /\\b(debug|fix|troubleshoot|diagnose)\\b/i, weight: 0.3, name: 'debugging' },\n { pattern: /\\b(design|architect|plan|strategy)\\b/i, weight: 0.25, name: 'design-task' },\n { pattern: /\\b(optimize|improve|enhance|refactor)\\b/i, weight: 0.2, name: 'optimization' },\n { pattern: /\\b(should|would|could|best approach)\\b/i, weight: 0.15, name: 'advisory-question' },\n];\n\n// Knowledge task indicators (factual retrieval, lookup)\nconst KNOWLEDGE_PATTERNS: ReadonlyArray<{ pattern: RegExp; weight: number; name: string }> = [\n { pattern: /\\b(what is|what are|who is|who are)\\b/i, weight: 0.3, name: 'factual-question' },\n { pattern: /\\b(define|definition of|meaning of)\\b/i, weight: 0.35, name: 'definition-request' },\n { pattern: /\\b(list|enumerate|name|identify)\\b/i, weight: 0.25, name: 'enumeration' },\n { pattern: /\\b(when|where|which)\\b/i, weight: 0.2, name: 'specific-query' },\n { pattern: /\\b(version|release|date|year|number)\\b/i, weight: 0.25, name: 'factual-detail' },\n { pattern: /\\b(syntax|format|structure|schema)\\b/i, weight: 0.2, name: 'format-query' },\n { pattern: /\\b(documentation|docs|reference|api)\\b/i, weight: 0.25, name: 'doc-lookup' },\n { pattern: /\\b(example|sample|template|boilerplate)\\b/i, weight: 0.2, name: 'example-request' },\n { pattern: /\\b(tell me|show me|give me)\\b/i, weight: 0.15, name: 'information-request' },\n];\n\nconst logger = createLogger({ component: 'task-type-classifier' });\n\n/**\n * Classifies tasks as reasoning or knowledge type.\n */\nexport class TaskTypeClassifier {\n private readonly config: Required<Omit<TaskTypeClassifierConfig, 'logger'>>;\n private readonly log: ILogger;\n\n constructor(config?: TaskTypeClassifierConfig) {\n this.config = {\n minConfidence: config?.minConfidence ?? 0.3,\n };\n this.log = config?.logger ?? logger;\n }\n\n /**\n * Classify a task based on its content.\n */\n classify(task: Task): ClassificationResult {\n const content = this.extractContent(task);\n const signals: ClassificationSignal[] = [];\n\n const reasoningScore = this.matchPatterns(content, REASONING_PATTERNS, 'reasoning', signals);\n const knowledgeScore = this.matchPatterns(content, KNOWLEDGE_PATTERNS, 'knowledge', signals);\n\n return this.computeResult(reasoningScore, knowledgeScore, signals);\n }\n\n private matchPatterns(\n content: string,\n patterns: ReadonlyArray<{ pattern: RegExp; weight: number; name: string }>,\n indicates: 'reasoning' | 'knowledge',\n signals: ClassificationSignal[]\n ): number {\n let score = 0;\n for (const { pattern, weight, name } of patterns) {\n if (pattern.test(content)) {\n score += weight;\n signals.push({ name, weight, indicates });\n }\n }\n return score;\n }\n\n private computeResult(\n reasoningScore: number,\n knowledgeScore: number,\n signals: readonly ClassificationSignal[]\n ): ClassificationResult {\n const totalScore = reasoningScore + knowledgeScore;\n if (totalScore === 0) {\n return { type: 'unknown', confidence: 0, signals };\n }\n\n const reasoningRatio = reasoningScore / totalScore;\n const knowledgeRatio = knowledgeScore / totalScore;\n const confidence = Math.abs(reasoningRatio - knowledgeRatio);\n\n if (confidence < this.config.minConfidence) {\n this.log.debug('Classification confidence below threshold', {\n reasoningScore,\n knowledgeScore,\n confidence,\n threshold: this.config.minConfidence,\n });\n return { type: 'unknown', confidence, signals };\n }\n\n const type: TaskType = reasoningRatio > knowledgeRatio ? 'reasoning' : 'knowledge';\n this.log.debug('Task classified', {\n type,\n confidence,\n reasoningScore,\n knowledgeScore,\n signalCount: signals.length,\n });\n\n return { type, confidence, signals };\n }\n\n private extractContent(task: Task): string {\n const parts: string[] = [];\n\n if (task.description) {\n parts.push(task.description);\n }\n\n if (task.context.history !== undefined) {\n for (const item of task.context.history) {\n if (item.content) {\n parts.push(item.content);\n }\n }\n }\n\n if (task.context.metadata !== undefined) {\n const metadata = task.context.metadata;\n if (typeof metadata['instructions'] === 'string') {\n parts.push(metadata['instructions']);\n }\n }\n\n return parts.join(' ');\n }\n}\n\n/**\n * Creates a task type classifier.\n */\nexport function createTaskTypeClassifier(config?: TaskTypeClassifierConfig): TaskTypeClassifier {\n return new TaskTypeClassifier(config);\n}\n","/**\n * Product Type Detector\n *\n * Detects product type from task content using keyword matching against\n * the product matrix taxonomy. Used by SharedTaskAnalyzer to\n * enrich analysis results with product routing information.\n *\n * @module core/task-analysis/product-type-detector\n * (Source: Epic #643 Phase 3 - Product Matrix Routing)\n */\n\nimport type { ProductType } from '../../config/product-matrix/types.js';\n\n/**\n * Result of product type detection.\n */\nexport interface ProductTypeDetection {\n readonly type: ProductType;\n readonly confidence: number;\n}\n\n/** Product type keyword patterns for detection */\nconst PRODUCT_TYPE_KEYWORDS: Record<ProductType, readonly string[]> = {\n api: ['rest', 'graphql', 'endpoint', 'api gateway', 'http handler', 'serialization'],\n 'web-service': ['full-stack', 'web service', 'backend', 'server-side'],\n cli: ['command line', 'cli', 'terminal', 'shell script', 'argument parsing'],\n 'frontend-web': ['react', 'vue', 'angular', 'spa', 'browser', 'component', 'ui/ux'],\n mobile: ['ios', 'android', 'react native', 'flutter', 'mobile app'],\n 'data-pipeline': ['etl', 'pipeline', 'kafka', 'streaming', 'batch processing', 'airflow'],\n 'ml-service': ['model', 'machine learning', 'pytorch', 'tensorflow', 'inference'],\n 'infra-module': ['terraform', 'kubernetes', 'infrastructure', 'iac', 'cloud', 'docker'],\n};\n\n/**\n * Detects the product type from task content by scoring keyword matches.\n *\n * @param content - Task content to analyze\n * @param signals - Mutable array to push matched signal names into\n * @returns Detection result with type and confidence, or undefined if no match\n */\nexport function detectProductType(\n content: string,\n signals: string[]\n): ProductTypeDetection | undefined {\n const lower = content.toLowerCase();\n const scores: Partial<Record<ProductType, number>> = {};\n let totalMatches = 0;\n\n for (const [type, keywords] of Object.entries(PRODUCT_TYPE_KEYWORDS) as Array<\n [ProductType, readonly string[]]\n >) {\n for (const keyword of keywords) {\n if (lower.includes(keyword)) {\n scores[type] = (scores[type] ?? 0) + 1;\n totalMatches++;\n signals.push(`productType:${type}:${keyword}`);\n }\n }\n }\n\n if (totalMatches === 0) return undefined;\n\n // Find the product type with the highest score\n let bestType: ProductType | undefined;\n let bestScore = 0;\n for (const [type, score] of Object.entries(scores) as Array<[ProductType, number]>) {\n if (score > bestScore) {\n bestType = type;\n bestScore = score;\n }\n }\n\n if (bestType === undefined) return undefined;\n\n const confidence = bestScore / totalMatches;\n return { type: bestType, confidence };\n}\n","/**\n * Task Analysis Keyword Registries\n *\n * Centralized keyword/pattern data for task classification.\n * Separated from SharedTaskAnalyzer to keep the analyzer under\n * the 400-line file limit while maintaining cohesive data definitions.\n *\n * @module core/task-analysis/task-analysis-keywords\n * (Source: Issue #574, ADR-0004)\n */\n\nimport type { TaskTypeCategory } from './shared-task-analyzer.js';\n\n/** Weighted pattern entry for reasoning/knowledge classification */\nexport interface WeightedPattern {\n readonly pattern: RegExp;\n readonly weight: number;\n readonly name: string;\n}\n\n/** Reasoning task patterns (arXiv:2502.19130) */\nexport const REASONING_PATTERNS: readonly WeightedPattern[] = [\n { pattern: /\\b(why|how come|explain why)\\b/i, weight: 0.3, name: 'causal-question' },\n { pattern: /\\b(analyze|evaluate|assess|compare)\\b/i, weight: 0.25, name: 'analysis-verb' },\n { pattern: /\\b(solve|calculate|compute|derive)\\b/i, weight: 0.35, name: 'problem-solving' },\n {\n pattern: /\\b(if|then|therefore|because|since|assuming)\\b/i,\n weight: 0.2,\n name: 'logical-connector',\n },\n { pattern: /\\b(prove|deduce|infer|conclude)\\b/i, weight: 0.35, name: 'deductive-verb' },\n {\n pattern: /\\b(trade-?off|pros? and cons?|advantages?|disadvantages?)\\b/i,\n weight: 0.25,\n name: 'tradeoff-analysis',\n },\n { pattern: /\\b(debug|fix|troubleshoot|diagnose)\\b/i, weight: 0.3, name: 'debugging' },\n { pattern: /\\b(design|architect|plan|strategy)\\b/i, weight: 0.25, name: 'design-task' },\n { pattern: /\\b(optimize|improve|enhance|refactor)\\b/i, weight: 0.2, name: 'optimization' },\n];\n\n/** Knowledge task patterns (arXiv:2502.19130) */\nexport const KNOWLEDGE_PATTERNS: readonly WeightedPattern[] = [\n { pattern: /\\b(what is|what are|who is|who are)\\b/i, weight: 0.3, name: 'factual-question' },\n { pattern: /\\b(define|definition of|meaning of)\\b/i, weight: 0.35, name: 'definition-request' },\n { pattern: /\\b(list|enumerate|name|identify)\\b/i, weight: 0.25, name: 'enumeration' },\n { pattern: /\\b(when|where|which)\\b/i, weight: 0.2, name: 'specific-query' },\n { pattern: /\\b(version|release|date|year|number)\\b/i, weight: 0.25, name: 'factual-detail' },\n { pattern: /\\b(syntax|format|structure|schema)\\b/i, weight: 0.2, name: 'format-query' },\n { pattern: /\\b(documentation|docs|reference|api)\\b/i, weight: 0.25, name: 'doc-lookup' },\n { pattern: /\\b(example|sample|template|boilerplate)\\b/i, weight: 0.2, name: 'example-request' },\n { pattern: /\\b(tell me|show me|give me)\\b/i, weight: 0.15, name: 'information-request' },\n];\n\n/** Task type keywords for 9-type taxonomy */\nexport const TASK_TYPE_KEYWORDS: Record<TaskTypeCategory, readonly string[]> = {\n architecture: [\n 'architecture',\n 'design',\n 'system',\n 'pattern',\n 'scalability',\n 'microservice',\n 'distributed',\n 'api design',\n ],\n code_implementation: [\n 'implement',\n 'create',\n 'build',\n 'write code',\n 'add feature',\n 'function',\n 'class',\n 'module',\n 'component',\n ],\n code_review: ['review', 'audit', 'check', 'analyze code', 'evaluate', 'inspect', 'bugs'],\n security_review: [\n 'security review',\n 'security audit',\n 'vulnerabilities',\n 'cve',\n 'owasp',\n 'injection',\n 'xss',\n 'csrf',\n 'penetration',\n 'threat model',\n ],\n test_generation: [\n 'test',\n 'unit test',\n 'integration test',\n 'e2e',\n 'coverage',\n 'spec',\n 'mock',\n 'vitest',\n 'jest',\n ],\n documentation: [\n 'document',\n 'readme',\n 'jsdoc',\n 'comment',\n 'explain',\n 'tutorial',\n 'guide',\n 'api doc',\n 'changelog',\n ],\n large_codebase: [\n 'entire codebase',\n 'all files',\n 'whole project',\n 'repository',\n 'monorepo',\n 'workspace',\n 'many files',\n ],\n bulk_operations: [\n 'bulk',\n 'batch',\n 'mass',\n 'multiple files',\n 'refactor all',\n 'update all',\n 'rename all',\n 'migrate',\n ],\n general: [],\n};\n\n/** High complexity indicators */\nexport const HIGH_COMPLEXITY_KEYWORDS: readonly string[] = [\n 'complex',\n 'optimize',\n 'architecture',\n 'security',\n 'performance',\n 'distributed',\n 'concurrent',\n 'async',\n 'race condition',\n 'deadlock',\n 'memory leak',\n 'algorithm',\n 'trade-off',\n 'decision',\n 'design pattern',\n 'refactor',\n 'legacy',\n 'centralize',\n 'consolidate',\n 'migrate',\n 'integrate',\n 'system-wide',\n 'cross-cutting',\n];\n\n/** Code generation indicators */\nexport const CODE_GEN_KEYWORDS: readonly string[] = [\n 'implement',\n 'create',\n 'write',\n 'generate',\n 'build',\n 'add',\n 'new',\n 'function',\n 'class',\n 'component',\n 'test',\n];\n\n/** Multimodal indicators */\nexport const MULTIMODAL_KEYWORDS: readonly string[] = [\n 'image',\n 'screenshot',\n 'diagram',\n 'photo',\n 'picture',\n 'audio',\n 'video',\n 'ui',\n 'visual',\n 'mockup',\n];\n\n/** Parallelizable indicators */\nexport const PARALLEL_KEYWORDS: readonly string[] = [\n 'multiple',\n 'batch',\n 'bulk',\n 'all files',\n 'each',\n 'every',\n 'parallel',\n 'concurrent',\n 'independent',\n];\n\n// ============================================================================\n// Advocate Analysis Keywords (Issue #903)\n// ============================================================================\n\n/** Vague verbs that increase ambiguity score */\nexport const VAGUE_VERBS: readonly string[] = [\n 'improve',\n 'fix',\n 'help',\n 'update',\n 'change',\n 'make better',\n 'handle',\n 'deal with',\n 'look at',\n 'work on',\n 'do something',\n 'clean up',\n 'take care of',\n];\n\n/** Time constraint patterns */\nexport const TIME_CONSTRAINT_PATTERNS: readonly WeightedPattern[] = [\n { pattern: /\\b(asap|urgent|immediately|right now)\\b/i, weight: 1.0, name: 'urgent' },\n {\n pattern: /\\bby (friday|monday|tuesday|wednesday|thursday|saturday|sunday)\\b/i,\n weight: 0.8,\n name: 'deadline-day',\n },\n {\n pattern: /\\bby (today|tomorrow|end of day|eod|end of week|eow)\\b/i,\n weight: 0.9,\n name: 'deadline-relative',\n },\n { pattern: /\\b(quick|fast|hurry|rush)\\b/i, weight: 0.6, name: 'speed' },\n { pattern: /\\bwithin \\d+ (hours?|days?|weeks?)\\b/i, weight: 0.8, name: 'deadline-duration' },\n];\n\n/** Quality constraint patterns */\nexport const QUALITY_CONSTRAINT_PATTERNS: readonly WeightedPattern[] = [\n {\n pattern: /\\b(production[- ]ready|prod[- ]ready|ship[- ]ready)\\b/i,\n weight: 1.0,\n name: 'production',\n },\n { pattern: /\\b(proof of concept|poc|prototype|spike)\\b/i, weight: 0.8, name: 'prototype' },\n {\n pattern: /\\b(quick hack|quick fix|workaround|temporary|temp fix)\\b/i,\n weight: 0.6,\n name: 'hack',\n },\n { pattern: /\\b(robust|thorough|comprehensive|complete)\\b/i, weight: 0.9, name: 'thorough' },\n { pattern: /\\b(mvp|minimum viable|bare minimum)\\b/i, weight: 0.7, name: 'mvp' },\n];\n\n/** Scope indicator patterns — match file paths, directories, modules */\nexport const SCOPE_PATTERNS: readonly RegExp[] = [\n /\\b[\\w-]+\\.(ts|js|tsx|jsx|py|rs|go|java|rb|md|json|yaml|yml)\\b/i,\n /\\bsrc\\/[\\w/-]+/,\n /\\b(packages|modules|components|services)\\/[\\w-]+/,\n /\\b(file|directory|folder|module|package|component)\\s+[`\"']?[\\w./-]+/i,\n /\\b(PR|pull request|issue)\\s*#?\\d+/i,\n];\n","/**\n * Task Analysis — Advocate Extensions (Issue #903)\n *\n * Deterministic heuristic functions for:\n * - Ambiguity scoring (0-1)\n * - Constraint extraction (time, quality, scope)\n * - Required capabilities inference (tools, experts)\n *\n * Separated from SharedTaskAnalyzer to respect the 400-line file limit.\n *\n * @module core/task-analysis/task-analysis-advocate\n */\n\nimport type { TaskTypeCategory, TaskCapabilities } from './shared-task-analyzer.js';\nimport {\n VAGUE_VERBS,\n TIME_CONSTRAINT_PATTERNS,\n QUALITY_CONSTRAINT_PATTERNS,\n SCOPE_PATTERNS,\n} from './task-analysis-keywords.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Extracted constraints from task description.\n */\nexport interface TaskConstraints {\n /** Detected time constraint (e.g., \"urgent\", \"by Friday\") */\n readonly time?: string;\n /** Detected quality level (e.g., \"production-ready\", \"proof of concept\") */\n readonly quality?: string;\n /** Detected scope references (file paths, modules, PR numbers) */\n readonly scope: readonly string[];\n}\n\n/**\n * Inferred capabilities needed to fulfill the task.\n */\nexport interface RequiredCapabilities {\n /** MCP tools likely needed */\n readonly tools: readonly string[];\n /** Expert roles likely valuable */\n readonly experts: readonly string[];\n}\n\n// ============================================================================\n// Ambiguity Score\n// ============================================================================\n\n/** Minimum word count threshold — below this, ambiguity increases */\nconst MIN_WORDS_FOR_CLARITY = 8;\n\n/** Word count below which ambiguity is at maximum */\nconst VERY_SHORT_THRESHOLD = 3;\n\n/**\n * Compute an ambiguity score (0-1) for task content.\n *\n * Heuristics:\n * - Short input → higher ambiguity\n * - No specific references (files, PRs, issues) → higher ambiguity\n * - Vague verbs without specific targets → higher ambiguity\n */\nexport function computeAmbiguityScore(content: string, signals: string[]): number {\n if (content.trim() === '') return 1.0;\n\n const lower = content.toLowerCase();\n const words = content.split(/\\s+/).filter((w) => w.length > 0);\n const wordCount = words.length;\n let score = 0;\n\n // Factor 1: Word count (0-0.3)\n if (wordCount <= VERY_SHORT_THRESHOLD) {\n score += 0.3;\n signals.push('ambiguity:very-short');\n } else if (wordCount < MIN_WORDS_FOR_CLARITY) {\n score += 0.15;\n signals.push('ambiguity:short');\n }\n\n // Factor 2: Vague verbs without specific targets (0-0.3)\n const vagueCount = VAGUE_VERBS.filter((v) => lower.includes(v)).length;\n if (vagueCount > 0) {\n score += Math.min(vagueCount / 3, 1) * 0.3;\n signals.push('ambiguity:vague-verbs(' + String(vagueCount) + ')');\n }\n\n // Factor 3: No scope references (0-0.2)\n const hasScope = SCOPE_PATTERNS.some((p) => p.test(content));\n if (!hasScope) {\n score += 0.2;\n signals.push('ambiguity:no-scope');\n }\n\n // Factor 4: No specific identifiers — numbers, quoted strings (0-0.2)\n const hasSpecifics = /\\b\\d{2,}\\b/.test(content) || /[\"'`][\\w./-]+[\"'`]/.test(content);\n if (!hasSpecifics) {\n score += 0.2;\n signals.push('ambiguity:no-specifics');\n }\n\n return Math.min(score, 1);\n}\n\n// ============================================================================\n// Constraint Extraction — helpers\n// ============================================================================\n\n/**\n * Find best-matching time constraint by weight.\n */\nfunction findTimeConstraint(content: string): string | undefined {\n let best: string | undefined;\n let bestWeight = 0;\n for (const p of TIME_CONSTRAINT_PATTERNS) {\n const match = p.pattern.exec(content);\n if (match !== null && p.weight > bestWeight) {\n best = match[0];\n bestWeight = p.weight;\n }\n }\n return best;\n}\n\n/**\n * Find best-matching quality constraint by weight.\n */\nfunction findQualityConstraint(content: string): string | undefined {\n let best: string | undefined;\n let bestWeight = 0;\n for (const p of QUALITY_CONSTRAINT_PATTERNS) {\n const match = p.pattern.exec(content);\n if (match !== null && p.weight > bestWeight) {\n best = match[0];\n bestWeight = p.weight;\n }\n }\n return best;\n}\n\n/**\n * Collect all unique scope references from content.\n */\nfunction collectScopeReferences(content: string): string[] {\n const scope: string[] = [];\n for (const pattern of SCOPE_PATTERNS) {\n const globalPattern = new RegExp(pattern.source, pattern.flags + 'g');\n let match = globalPattern.exec(content);\n while (match !== null) {\n if (!scope.includes(match[0])) {\n scope.push(match[0]);\n }\n match = globalPattern.exec(content);\n }\n }\n return scope;\n}\n\n// ============================================================================\n// Constraint Extraction\n// ============================================================================\n\n/**\n * Extract structured constraints from task content.\n */\nexport function extractConstraints(content: string, signals: string[]): TaskConstraints {\n const time = findTimeConstraint(content);\n const quality = findQualityConstraint(content);\n const scope = collectScopeReferences(content);\n\n if (time !== undefined) signals.push('constraint:time:' + time);\n if (quality !== undefined) signals.push('constraint:quality:' + quality);\n if (scope.length > 0) signals.push('constraint:scope(' + String(scope.length) + ')');\n\n const result: TaskConstraints = { scope };\n if (time !== undefined && quality !== undefined) {\n return { ...result, time, quality };\n }\n if (time !== undefined) {\n return { ...result, time };\n }\n if (quality !== undefined) {\n return { ...result, quality };\n }\n return result;\n}\n\n// ============================================================================\n// Required Capabilities Inference\n// ============================================================================\n\n/** Task type → relevant MCP tools mapping */\nconst TASK_TYPE_TO_TOOLS: Record<TaskTypeCategory, readonly string[]> = {\n architecture: ['orchestrate', 'consensus_vote'],\n code_implementation: ['create_expert', 'execute_expert'],\n code_review: ['run_workflow', 'create_expert'],\n security_review: ['create_expert', 'execute_expert'],\n test_generation: ['create_expert', 'execute_expert'],\n documentation: ['create_expert', 'execute_expert'],\n large_codebase: ['orchestrate', 'run_graph_workflow'],\n bulk_operations: ['run_graph_workflow', 'orchestrate'],\n general: ['delegate_to_model'],\n};\n\n/** Task type → relevant expert roles mapping */\nconst TASK_TYPE_TO_EXPERTS: Record<TaskTypeCategory, readonly string[]> = {\n architecture: ['architecture_expert', 'security_expert'],\n code_implementation: ['code_expert', 'testing_expert'],\n code_review: ['code_expert', 'security_expert'],\n security_review: ['security_expert', 'code_expert'],\n test_generation: ['testing_expert', 'code_expert'],\n documentation: ['documentation_expert'],\n large_codebase: ['architecture_expert', 'code_expert'],\n bulk_operations: ['devops_expert', 'code_expert'],\n general: ['pm_expert'],\n};\n\n/**\n * Infer required capabilities from task analysis signals.\n */\nexport function inferRequiredCapabilities(\n taskType: TaskTypeCategory,\n capabilities: TaskCapabilities,\n signals: string[]\n): RequiredCapabilities {\n const tools = [...TASK_TYPE_TO_TOOLS[taskType]];\n const experts = [...TASK_TYPE_TO_EXPERTS[taskType]];\n\n if (capabilities.highContext) {\n if (!tools.includes('orchestrate')) tools.push('orchestrate');\n if (!experts.includes('research_expert')) experts.push('research_expert');\n signals.push('capability:needs-research');\n }\n\n if (capabilities.codeGeneration && !experts.includes('testing_expert')) {\n experts.push('testing_expert');\n }\n\n signals.push('required:tools(' + String(tools.length) + ')');\n signals.push('required:experts(' + String(experts.length) + ')');\n\n return { tools, experts };\n}\n","/**\n * Unified task analysis — classification views for routing.\n * Consolidates 5 independent analyzers per ADR-0004.\n * @module core/task-analysis/shared-task-analyzer\n * (Source: Issue #574, ADR-0004)\n */\n\nimport { createLogger, type ILogger } from '../logger.js';\nimport type { Task } from '../types/agent.js';\nimport type { ProductType } from '../../config/product-matrix/types.js';\nimport { detectProductType } from './product-type-detector.js';\nimport {\n REASONING_PATTERNS,\n KNOWLEDGE_PATTERNS,\n TASK_TYPE_KEYWORDS,\n HIGH_COMPLEXITY_KEYWORDS,\n CODE_GEN_KEYWORDS,\n MULTIMODAL_KEYWORDS,\n PARALLEL_KEYWORDS,\n} from './task-analysis-keywords.js';\nimport {\n type TaskConstraints,\n type RequiredCapabilities,\n computeAmbiguityScore,\n extractConstraints,\n inferRequiredCapabilities,\n} from './task-analysis-advocate.js';\nexport type { TaskConstraints, RequiredCapabilities } from './task-analysis-advocate.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Reasoning vs Knowledge classification (arXiv:2502.19130).\n */\nexport type ReasoningKnowledgeType = 'reasoning' | 'knowledge' | 'unknown';\n\n/**\n * Complexity levels for routing (RouteLLM).\n */\nexport type ComplexityLevel = 'simple' | 'moderate' | 'complex' | 'expert';\n\n/**\n * 9-type task taxonomy for capability-based routing.\n */\nexport type TaskTypeCategory =\n | 'architecture'\n | 'code_implementation'\n | 'code_review'\n | 'security_review'\n | 'test_generation'\n | 'documentation'\n | 'large_codebase'\n | 'bulk_operations'\n | 'general';\n\n/**\n * Task capability flags.\n */\nexport interface TaskCapabilities {\n readonly parallelizable: boolean;\n readonly multimodal: boolean;\n readonly codeGeneration: boolean;\n readonly budgetSensitive: boolean;\n readonly highContext: boolean;\n}\n\n/**\n * Unified analysis result combining all views.\n */\nexport interface TaskAnalysisResult {\n /** Reasoning vs knowledge classification */\n readonly reasoningType: ReasoningKnowledgeType;\n readonly reasoningConfidence: number;\n /** Complexity level */\n readonly complexity: ComplexityLevel;\n readonly complexityScore: number;\n /** Task type category */\n readonly taskType: TaskTypeCategory;\n readonly taskTypeConfidence: number;\n /** Capability flags */\n readonly capabilities: TaskCapabilities;\n /** Estimated token count */\n readonly estimatedTokens: number;\n /** Matched signals for observability */\n readonly matchedSignals: readonly string[];\n /** Ambiguity score (0=clear, 1=highly ambiguous). Issue #903. */\n readonly ambiguityScore: number;\n /** Extracted constraints (time, quality, scope). Issue #903. */\n readonly constraints: TaskConstraints;\n /** Inferred required capabilities (tools, experts). Issue #903. */\n readonly requiredCapabilities: RequiredCapabilities;\n /** Detected product type from task content (optional) */\n readonly detectedProductType?: ProductType;\n /** Confidence in the detected product type (0-1, optional) */\n readonly productTypeConfidence?: number;\n}\n\n/**\n * Configuration for SharedTaskAnalyzer.\n */\nexport interface SharedTaskAnalyzerConfig {\n readonly logger?: ILogger;\n /** Minimum confidence for non-unknown reasoning type (default: 0.3) */\n readonly minReasoningConfidence?: number;\n /** Minimum confidence for task type (default: 0.2) */\n readonly minTaskTypeConfidence?: number;\n}\n\n/**\n * Shared task analyzer interface.\n */\nexport interface ISharedTaskAnalyzer {\n analyze(task: Task | string): TaskAnalysisResult;\n getReasoningType(task: Task | string): { type: ReasoningKnowledgeType; confidence: number };\n getComplexity(task: Task | string): { level: ComplexityLevel; score: number };\n getTaskType(task: Task | string): { type: TaskTypeCategory; confidence: number };\n getCapabilities(task: Task | string): TaskCapabilities;\n estimateTokens(task: Task | string): number;\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/** Token estimation constants */\nconst TOKENS_PER_CHAR = 0.25;\nconst BASE_TOKEN_OVERHEAD = 500;\n\n/**\n * Unified task analyzer implementation.\n */\nexport class SharedTaskAnalyzer implements ISharedTaskAnalyzer {\n private readonly logger: ILogger;\n private readonly minReasoningConfidence: number;\n private readonly minTaskTypeConfidence: number;\n\n constructor(config?: SharedTaskAnalyzerConfig) {\n this.logger = config?.logger ?? createLogger({ component: 'SharedTaskAnalyzer' });\n this.minReasoningConfidence = config?.minReasoningConfidence ?? 0.3;\n this.minTaskTypeConfidence = config?.minTaskTypeConfidence ?? 0.2;\n }\n\n analyze(task: Task | string): TaskAnalysisResult {\n const content = this.extractContent(task);\n const matchedSignals: string[] = [];\n\n const reasoning = this.computeReasoningType(content, matchedSignals);\n const complexity = this.computeComplexity(content, matchedSignals);\n const taskType = this.computeTaskType(content, matchedSignals);\n const capabilities = this.computeCapabilities(content, matchedSignals);\n const estimatedTokens = this.computeTokens(content);\n const productType = detectProductType(content, matchedSignals);\n const ambiguityScore = computeAmbiguityScore(content, matchedSignals);\n const constraints = extractConstraints(content, matchedSignals);\n const requiredCapabilities = inferRequiredCapabilities(\n taskType.type,\n capabilities,\n matchedSignals\n );\n\n this.logger.debug('Task analyzed', {\n reasoningType: reasoning.type,\n complexity: complexity.level,\n taskType: taskType.type,\n ambiguityScore,\n detectedProductType: productType?.type,\n signals: matchedSignals.length,\n });\n\n const result: TaskAnalysisResult = {\n reasoningType: reasoning.type,\n reasoningConfidence: reasoning.confidence,\n complexity: complexity.level,\n complexityScore: complexity.score,\n taskType: taskType.type,\n taskTypeConfidence: taskType.confidence,\n capabilities,\n estimatedTokens,\n matchedSignals,\n ambiguityScore,\n constraints,\n requiredCapabilities,\n };\n\n if (productType !== undefined) {\n return {\n ...result,\n detectedProductType: productType.type,\n productTypeConfidence: productType.confidence,\n };\n }\n\n return result;\n }\n\n getReasoningType(task: Task | string): { type: ReasoningKnowledgeType; confidence: number } {\n const content = this.extractContent(task);\n return this.computeReasoningType(content, []);\n }\n\n getComplexity(task: Task | string): { level: ComplexityLevel; score: number } {\n const content = this.extractContent(task);\n return this.computeComplexity(content, []);\n }\n\n getTaskType(task: Task | string): { type: TaskTypeCategory; confidence: number } {\n const content = this.extractContent(task);\n return this.computeTaskType(content, []);\n }\n\n getCapabilities(task: Task | string): TaskCapabilities {\n const content = this.extractContent(task);\n return this.computeCapabilities(content, []);\n }\n\n estimateTokens(task: Task | string): number {\n const content = this.extractContent(task);\n return this.computeTokens(content);\n }\n\n private extractContent(task: Task | string): string {\n if (typeof task === 'string') return task;\n // Extract text from task description and relevant context\n const parts = [task.description];\n const ctx = task.context;\n if (ctx.workingDirectory !== undefined && ctx.workingDirectory !== '') {\n parts.push(ctx.workingDirectory);\n }\n if (ctx.files !== undefined && ctx.files.length > 0) {\n parts.push(ctx.files.join(' '));\n }\n return parts.join(' ').trim();\n }\n\n private computeReasoningType(\n content: string,\n signals: string[]\n ): { type: ReasoningKnowledgeType; confidence: number } {\n const lower = content.toLowerCase();\n let reasoningScore = 0;\n let knowledgeScore = 0;\n\n for (const p of REASONING_PATTERNS) {\n if (p.pattern.test(lower)) {\n reasoningScore += p.weight;\n signals.push(`reasoning:${p.name}`);\n }\n }\n\n for (const p of KNOWLEDGE_PATTERNS) {\n if (p.pattern.test(lower)) {\n knowledgeScore += p.weight;\n signals.push(`knowledge:${p.name}`);\n }\n }\n\n const total = reasoningScore + knowledgeScore;\n if (total === 0) return { type: 'unknown', confidence: 0 };\n\n const reasoningRatio = reasoningScore / total;\n const confidence = Math.abs(reasoningScore - knowledgeScore) / total;\n\n if (confidence < this.minReasoningConfidence) {\n return { type: 'unknown', confidence };\n }\n\n return {\n type: reasoningRatio > 0.5 ? 'reasoning' : 'knowledge',\n confidence,\n };\n }\n\n private computeComplexity(\n content: string,\n signals: string[]\n ): { level: ComplexityLevel; score: number } {\n const lower = content.toLowerCase();\n let score = 0;\n\n // Length factor (0-0.25)\n const lengthScore = Math.min(content.length / 2000, 1) * 0.25;\n score += lengthScore;\n\n // Complexity keywords (0-0.4) — divisor of 3 ensures even 2 keyword hits\n // produce meaningful signal (0.27) instead of being lost in noise\n const complexityMatches = HIGH_COMPLEXITY_KEYWORDS.filter((k) => lower.includes(k));\n const keywordScore = Math.min(complexityMatches.length / 3, 1) * 0.4;\n score += keywordScore;\n complexityMatches.forEach((k) => signals.push(`complexity:${k}`));\n\n // Multi-step indicators (0-0.2)\n const multiStepPatterns = [/first.*then/i, /step \\d/i, /after that/i, /finally/i];\n const multiStepMatches = multiStepPatterns.filter((p) => p.test(lower)).length;\n score += Math.min(multiStepMatches / 3, 1) * 0.2;\n if (multiStepMatches > 0) signals.push('complexity:multi-step');\n\n // Question depth (0-0.15)\n const questionCount = (content.match(/\\?/g) ?? []).length;\n score += Math.min(questionCount / 4, 1) * 0.15;\n\n // Normalize to 0-1\n const normalizedScore = Math.min(score, 1);\n\n const level: ComplexityLevel =\n normalizedScore < 0.25\n ? 'simple'\n : normalizedScore < 0.5\n ? 'moderate'\n : normalizedScore < 0.75\n ? 'complex'\n : 'expert';\n\n return { level, score: normalizedScore };\n }\n\n private computeTaskType(\n content: string,\n signals: string[]\n ): { type: TaskTypeCategory; confidence: number } {\n const lower = content.toLowerCase();\n const scores: Record<TaskTypeCategory, number> = {\n architecture: 0,\n code_implementation: 0,\n code_review: 0,\n security_review: 0,\n test_generation: 0,\n documentation: 0,\n large_codebase: 0,\n bulk_operations: 0,\n general: 0.1, // Base score for general\n };\n\n for (const [type, keywords] of Object.entries(TASK_TYPE_KEYWORDS) as Array<\n [TaskTypeCategory, readonly string[]]\n >) {\n for (const keyword of keywords) {\n if (lower.includes(keyword)) {\n scores[type] += 1;\n signals.push(`taskType:${type}:${keyword}`);\n }\n }\n }\n\n let maxType: TaskTypeCategory = 'general';\n let maxScore = scores.general;\n for (const [type, score] of Object.entries(scores) as Array<[TaskTypeCategory, number]>) {\n if (score > maxScore) {\n maxType = type;\n maxScore = score;\n }\n }\n\n const totalScore = Object.values(scores).reduce((a, b) => a + b, 0);\n const confidence = totalScore > 0 ? maxScore / totalScore : 0;\n\n if (confidence < this.minTaskTypeConfidence) {\n return { type: 'general', confidence };\n }\n\n return { type: maxType, confidence };\n }\n\n private computeCapabilities(content: string, signals: string[]): TaskCapabilities {\n const lower = content.toLowerCase();\n const budgetKeywords = ['cost', 'budget', 'cheap'];\n const highContextKeywords = ['entire', 'whole', 'all files'];\n\n const capabilities: TaskCapabilities = {\n parallelizable: PARALLEL_KEYWORDS.some((k) => lower.includes(k)),\n multimodal: MULTIMODAL_KEYWORDS.some((k) => lower.includes(k)),\n codeGeneration: CODE_GEN_KEYWORDS.some((k) => lower.includes(k)),\n budgetSensitive: budgetKeywords.some((k) => lower.includes(k)),\n highContext: highContextKeywords.some((k) => lower.includes(k)) || content.length > 1000,\n };\n\n // Add matched capability signals\n const capabilityNames: Array<keyof TaskCapabilities> = [\n 'parallelizable',\n 'multimodal',\n 'codeGeneration',\n 'budgetSensitive',\n 'highContext',\n ];\n for (const cap of capabilityNames) {\n if (capabilities[cap]) signals.push(`capability:${cap}`);\n }\n\n return capabilities;\n }\n\n private computeTokens(content: string): number {\n return Math.ceil(content.length * TOKENS_PER_CHAR + BASE_TOKEN_OVERHEAD);\n }\n}\n\n/**\n * Creates a shared task analyzer instance.\n */\nexport function createSharedTaskAnalyzer(config?: SharedTaskAnalyzerConfig): ISharedTaskAnalyzer {\n return new SharedTaskAnalyzer(config);\n}\n","/**\n * Capability Gap Detector (Issue #906)\n *\n * Cross-checks required capabilities from SharedTaskAnalyzer against\n * available system capabilities (MCP tools, expert roles, workflows).\n *\n * Deterministic — no external calls needed. Uses static registries.\n *\n * @module core/task-analysis/capability-gap-detector\n */\n\nimport type { RequiredCapabilities } from './task-analysis-advocate.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Result of capability gap analysis.\n */\nexport interface CapabilityGapReport {\n /** Capabilities that exist and can fulfill the request */\n readonly available: AvailableCapabilities;\n /** Capabilities needed but not available */\n readonly gaps: readonly CapabilityGap[];\n /** Whether all required capabilities are available */\n readonly allSatisfied: boolean;\n}\n\n/**\n * Available capabilities that matched requirements.\n */\nexport interface AvailableCapabilities {\n readonly tools: readonly string[];\n readonly experts: readonly string[];\n}\n\n/**\n * A single capability gap with suggestion.\n */\nexport interface CapabilityGap {\n readonly type: 'tool' | 'expert';\n readonly name: string;\n readonly suggestion: string;\n}\n\n// ============================================================================\n// Static Registries — kept in sync with canonical sources\n// ============================================================================\n\n/** All 20 registered MCP tools */\nconst AVAILABLE_TOOLS: ReadonlySet<string> = new Set([\n 'orchestrate',\n 'create_expert',\n 'execute_expert',\n 'run_workflow',\n 'delegate_to_model',\n 'list_experts',\n 'list_workflows',\n 'consensus_vote',\n 'research_query',\n 'research_add',\n 'research_discover',\n 'research_analyze',\n 'research_catalog_review',\n 'memory_query',\n 'memory_stats',\n 'weather_report',\n 'issue_triage',\n 'run_graph_workflow',\n 'execute_spec',\n 'registry_import',\n 'query_trace',\n]);\n\n/** All 10 expert role names */\nconst AVAILABLE_EXPERTS: ReadonlySet<string> = new Set([\n 'code_expert',\n 'architecture_expert',\n 'security_expert',\n 'documentation_expert',\n 'testing_expert',\n 'devops_expert',\n 'research_expert',\n 'pm_expert',\n 'ux_expert',\n 'infrastructure_expert',\n]);\n\n/** Suggestions for common gaps */\nconst TOOL_SUGGESTIONS: Readonly<Record<string, string>> = {\n code_analysis: 'Use create_expert with code_expert role instead',\n deploy: 'Use run_graph_workflow with a custom deployment template',\n monitor: 'Use weather_report for CLI performance monitoring',\n};\n\nconst EXPERT_SUGGESTIONS: Readonly<Record<string, string>> = {\n data_expert: 'Use research_expert for data analysis tasks',\n ml_expert: 'Use code_expert with ML-focused system prompt',\n frontend_expert: 'Use ux_expert for UI concerns, code_expert for implementation',\n};\n\n// ============================================================================\n// Gap Detection\n// ============================================================================\n\n/**\n * Detect capability gaps by comparing required vs available.\n */\nexport function detectCapabilityGaps(required: RequiredCapabilities): CapabilityGapReport {\n const availableTools: string[] = [];\n const availableExperts: string[] = [];\n const gaps: CapabilityGap[] = [];\n\n for (const tool of required.tools) {\n if (AVAILABLE_TOOLS.has(tool)) {\n availableTools.push(tool);\n } else {\n gaps.push({\n type: 'tool',\n name: tool,\n suggestion:\n TOOL_SUGGESTIONS[tool] ?? 'No direct equivalent — consider orchestrate for complex tasks',\n });\n }\n }\n\n for (const expert of required.experts) {\n if (AVAILABLE_EXPERTS.has(expert)) {\n availableExperts.push(expert);\n } else {\n gaps.push({\n type: 'expert',\n name: expert,\n suggestion: EXPERT_SUGGESTIONS[expert] ?? 'Use create_expert with a custom configuration',\n });\n }\n }\n\n return {\n available: { tools: availableTools, experts: availableExperts },\n gaps,\n allSatisfied: gaps.length === 0,\n };\n}\n\n/**\n * Get the count of available tools.\n */\nexport function getAvailableToolCount(): number {\n return AVAILABLE_TOOLS.size;\n}\n\n/**\n * Get the count of available experts.\n */\nexport function getAvailableExpertCount(): number {\n return AVAILABLE_EXPERTS.size;\n}\n","/**\n * nexus-agents/utils - Math Utilities\n *\n * Common mathematical utility functions extracted from multiple modules.\n * Consolidates the clamp pattern: Math.max(min, Math.min(max, value))\n *\n * @module utils/math-utils\n */\n\n// ============================================================================\n// Clamping\n// ============================================================================\n\n/**\n * Clamp a value between min and max bounds.\n *\n * This consolidates the common pattern:\n * `Math.max(min, Math.min(max, value))`\n *\n * @param value - The value to clamp\n * @param min - Minimum bound (inclusive)\n * @param max - Maximum bound (inclusive)\n * @returns The clamped value\n *\n * @example\n * ```typescript\n * clamp(150, 0, 100); // Returns 100\n * clamp(-10, 0, 100); // Returns 0\n * clamp(50, 0, 100); // Returns 50\n * ```\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\n/**\n * Clamp a value between 0 and 1 (unit interval).\n *\n * Shorthand for `clamp(value, 0, 1)`.\n *\n * @param value - The value to clamp\n * @returns The value clamped to [0, 1]\n *\n * @example\n * ```typescript\n * clamp01(1.5); // Returns 1\n * clamp01(-0.5); // Returns 0\n * clamp01(0.7); // Returns 0.7\n * ```\n */\nexport function clamp01(value: number): number {\n return clamp(value, 0, 1);\n}\n\n/**\n * Clamp a score value between 0 and 10.\n *\n * Shorthand for `clamp(value, 0, 10)`.\n *\n * @param value - The score to clamp\n * @returns The score clamped to [0, 10]\n */\nexport function clampScore(value: number): number {\n return clamp(value, 0, 10);\n}\n\n/**\n * Clamp a percentage value between 0 and 100.\n *\n * Shorthand for `clamp(value, 0, 100)`.\n *\n * @param value - The percentage to clamp\n * @returns The percentage clamped to [0, 100]\n */\nexport function clampPercent(value: number): number {\n return clamp(value, 0, 100);\n}\n","/**\n * Task Profile Adapter\n *\n * Provides compatibility bridge between SharedTaskAnalyzer's TaskAnalysisResult\n * and the legacy TaskProfile type used by router components.\n *\n * This adapter enables gradual migration from deprecated task-analyzer.ts\n * to the unified SharedTaskAnalyzer (ADR-0004, Issue #574, Issue #586).\n *\n * @module core/task-analysis/task-profile-adapter\n * (Source: Issue #586 - Migrate routers to SharedTaskAnalyzer)\n */\n\nimport type {\n TaskAnalysisResult as SharedTaskAnalysisResult,\n TaskTypeCategory,\n ComplexityLevel,\n} from './shared-task-analyzer.js';\nimport type { ProductType } from '../../config/product-matrix/types.js';\nimport { clamp } from '../../utils/math-utils.js';\n\n/**\n * Legacy TaskProfile type for backward compatibility.\n *\n * This mirrors the type from cli-adapters/task-analyzer.ts to enable\n * gradual migration without breaking existing router code.\n */\nexport interface TaskProfile {\n /** Estimated input tokens required */\n readonly contextRequired: number;\n /** Reasoning complexity on 0-10 scale */\n readonly reasoningComplexity: number;\n /** Whether task involves code generation */\n readonly codeGeneration: boolean;\n /** Whether task involves multimodal content (images, etc.) */\n readonly multimodal: boolean;\n /** Whether task can be split into parallel subtasks */\n readonly parallelizable: boolean;\n /** Whether cost should be minimized */\n readonly budgetSensitive: boolean;\n /** Primary task type classification */\n readonly taskType: TaskTypeCategory;\n /** Detected product type from task content (optional) */\n readonly detectedProductType?: ProductType;\n}\n\n/**\n * Converts TaskAnalysisResult to legacy TaskProfile format.\n *\n * This enables existing code that expects TaskProfile to work with\n * the new SharedTaskAnalyzer without modification.\n *\n * @param analysis - Result from SharedTaskAnalyzer.analyze()\n * @returns TaskProfile compatible with legacy router code\n *\n * @example\n * ```typescript\n * import { createSharedTaskAnalyzer, taskAnalysisResultToTaskProfile } from 'nexus-agents/core';\n *\n * const analyzer = createSharedTaskAnalyzer();\n * const analysis = analyzer.analyze(task);\n * const profile = taskAnalysisResultToTaskProfile(analysis);\n * // profile.reasoningComplexity is 0-10 scale\n * ```\n */\nexport function taskAnalysisResultToTaskProfile(analysis: SharedTaskAnalysisResult): TaskProfile {\n const profile: TaskProfile = {\n // Token estimation - add 500 offset for legacy compatibility\n // Legacy used BASE_TOKEN_OVERHEAD=1000, new uses 500\n contextRequired: analysis.estimatedTokens + 500,\n\n // Convert 0-1 complexity score to 0-10 scale\n reasoningComplexity: Math.round(analysis.complexityScore * 10),\n\n // Capability flags map directly\n codeGeneration: analysis.capabilities.codeGeneration,\n multimodal: analysis.capabilities.multimodal,\n parallelizable: analysis.capabilities.parallelizable,\n budgetSensitive: analysis.capabilities.budgetSensitive,\n\n // Task type maps directly (same enum values)\n taskType: analysis.taskType,\n\n // Product type detection (optional, only set when detected)\n ...(analysis.detectedProductType !== undefined && {\n detectedProductType: analysis.detectedProductType,\n }),\n };\n\n return profile;\n}\n\n/**\n * Summarizes a TaskProfile for logging (legacy compatibility).\n *\n * @param profile - TaskProfile to summarize\n * @returns Human-readable summary string\n */\nexport function summarizeTaskProfile(profile: TaskProfile): string {\n const flags: string[] = [];\n if (profile.codeGeneration) flags.push('code');\n if (profile.multimodal) flags.push('multimodal');\n if (profile.parallelizable) flags.push('parallel');\n if (profile.budgetSensitive) flags.push('budget');\n\n const productSuffix =\n profile.detectedProductType !== undefined ? ` | Product: ${profile.detectedProductType}` : '';\n\n return `Type: ${profile.taskType} | Complexity: ${String(profile.reasoningComplexity)}/10 | Tokens: ~${String(profile.contextRequired)}${flags.length > 0 ? ` | Flags: ${flags.join(', ')}` : ''}${productSuffix}`;\n}\n\n/**\n * Converts TaskAnalysisResult to BanditContext for LinUCB routing.\n *\n * Replaces taskProfileToBanditContext() from composite-router-helpers.ts.\n *\n * @param analysis - Result from SharedTaskAnalyzer.analyze()\n * @returns BanditContext for LinUCB bandit algorithm\n */\nexport interface BanditContext {\n readonly taskComplexity: number;\n readonly contextLengthNormalized: number;\n readonly isCodeTask: number;\n readonly isReasoningTask: number;\n readonly budgetUtilization: number;\n readonly timePressure: number;\n}\n\nexport function taskAnalysisResultToBanditContext(\n analysis: SharedTaskAnalysisResult,\n options: { budgetUtilization?: number; timePressure?: number } = {}\n): BanditContext {\n return {\n // Complexity score already 0-1\n taskComplexity: analysis.complexityScore,\n\n // Normalize token count (100K max for scaling)\n contextLengthNormalized: Math.min(analysis.estimatedTokens / 100_000, 1),\n\n // Binary flags as 0/1\n isCodeTask: analysis.capabilities.codeGeneration ? 1 : 0,\n isReasoningTask:\n analysis.reasoningType === 'reasoning' ? 1 : analysis.complexityScore > 0.5 ? 0.5 : 0,\n\n // External context (default mid-range if not provided)\n budgetUtilization: options.budgetUtilization ?? 0.5,\n timePressure: options.timePressure ?? 0.3,\n };\n}\n\n// ============================================================================\n// Expert Selector Adapter (ADR-0004, Issue #593)\n// ============================================================================\n\n/**\n * Legacy TaskDomain type for expert-selector compatibility.\n * Maps to domain values used by expert definitions.\n */\nexport type ExpertTaskDomain =\n | 'code'\n | 'security'\n | 'architecture'\n | 'documentation'\n | 'testing'\n | 'infrastructure'\n | 'general';\n\n/**\n * Legacy TaskComplexity type for expert-selector compatibility.\n */\nexport type ExpertTaskComplexity = 'low' | 'medium' | 'high';\n\n/**\n * Legacy TaskAnalysisResult type for expert-selector compatibility.\n *\n * This mirrors the type from agents/experts/task-analyzer-types.ts\n * to enable migration without changing expert definitions.\n */\nexport interface ExpertTaskAnalysisResult {\n /** Primary domain of the task */\n readonly domain: ExpertTaskDomain;\n /** Task complexity level */\n readonly complexity: ExpertTaskComplexity;\n /** Required capabilities for the task */\n readonly requiredCapabilities: readonly string[];\n /** Keywords extracted from the task */\n readonly keywords: readonly string[];\n /** Estimated effort on 1-10 scale */\n readonly estimatedEffort: number;\n /** Secondary domains if task spans multiple areas */\n readonly secondaryDomains: readonly ExpertTaskDomain[];\n /** Confidence in the analysis (0-1) */\n readonly confidence: number;\n}\n\n/**\n * Maps TaskTypeCategory to ExpertTaskDomain.\n */\nfunction mapTaskTypeToDomain(taskType: TaskTypeCategory): ExpertTaskDomain {\n const mapping: Record<TaskTypeCategory, ExpertTaskDomain> = {\n architecture: 'architecture',\n code_implementation: 'code',\n code_review: 'code',\n security_review: 'security',\n test_generation: 'testing',\n documentation: 'documentation',\n large_codebase: 'code',\n bulk_operations: 'infrastructure',\n general: 'general',\n };\n return mapping[taskType];\n}\n\n/**\n * Maps ComplexityLevel to ExpertTaskComplexity.\n */\nfunction mapComplexityLevel(level: ComplexityLevel): ExpertTaskComplexity {\n const mapping: Record<ComplexityLevel, ExpertTaskComplexity> = {\n simple: 'low',\n moderate: 'medium',\n complex: 'high',\n expert: 'high',\n };\n return mapping[level];\n}\n\n/**\n * Extracts required capabilities from analysis.\n * Uses capability names matching expert-defaults.ts definitions.\n */\nfunction extractRequiredCapabilities(analysis: SharedTaskAnalysisResult): string[] {\n const capabilities: string[] = [];\n\n // Always include task_execution as base capability\n capabilities.push('task_execution');\n\n // Map capability flags to expert capability strings\n if (analysis.capabilities.codeGeneration) capabilities.push('code_generation');\n\n // Map reasoning type to capabilities\n if (analysis.reasoningType === 'reasoning') {\n capabilities.push('research');\n }\n\n // Map complexity to capabilities\n if (analysis.complexity === 'complex' || analysis.complexity === 'expert') {\n capabilities.push('collaboration');\n }\n\n // Map task type to capabilities\n const taskTypeCapabilities: Record<TaskTypeCategory, string[]> = {\n architecture: ['research', 'collaboration'],\n code_implementation: ['code_generation', 'tool_use'],\n code_review: ['code_review'],\n security_review: ['code_review', 'research'],\n test_generation: ['code_generation', 'code_review', 'tool_use'],\n documentation: ['research', 'tool_use'],\n large_codebase: ['tool_use'],\n bulk_operations: ['tool_use'],\n general: [],\n };\n capabilities.push(...taskTypeCapabilities[analysis.taskType]);\n\n return [...new Set(capabilities)];\n}\n\n/**\n * Extracts keywords from matched signals.\n */\nfunction extractKeywords(analysis: SharedTaskAnalysisResult): string[] {\n return analysis.matchedSignals.map((signal) => {\n // Extract keyword part from signal (format: \"category:keyword\" or \"category:type:keyword\")\n const parts = signal.split(':');\n return parts[parts.length - 1] ?? signal;\n });\n}\n\n/**\n * Strong security-related signals that indicate a security-focused task.\n * These keywords override the base domain detection.\n */\nconst STRONG_SECURITY_SIGNALS = [\n 'security',\n 'vulnerability',\n 'vulnerabilities',\n 'audit',\n 'authentication',\n 'authorization',\n 'exploit',\n 'penetration',\n 'xss',\n 'sql injection',\n 'csrf',\n 'attack',\n 'threat',\n 'malware',\n 'encryption',\n 'cryptograph',\n];\n\n/**\n * Detects if task is primarily security-focused based on strong signals.\n */\nfunction isSecurityFocused(analysis: SharedTaskAnalysisResult): boolean {\n const signals = analysis.matchedSignals.join(' ').toLowerCase();\n let securityScore = 0;\n\n for (const keyword of STRONG_SECURITY_SIGNALS) {\n if (signals.includes(keyword)) {\n securityScore++;\n }\n }\n\n // Also check if task type suggests security review\n if (\n (analysis.taskType === 'code_review' || analysis.taskType === 'security_review') &&\n securityScore > 0\n ) {\n securityScore++;\n }\n\n // Require at least 2 security signals to override primary domain\n return securityScore >= 2;\n}\n\n/**\n * Checks if security should be a secondary domain.\n */\nfunction shouldAddSecuritySecondary(signals: string, primaryDomain: ExpertTaskDomain): boolean {\n return (\n primaryDomain !== 'security' &&\n (signals.includes('security') || signals.includes('vulnerabilit'))\n );\n}\n\n/**\n * Checks if testing should be a secondary domain.\n */\nfunction shouldAddTestingSecondary(signals: string, taskType: TaskTypeCategory): boolean {\n return signals.includes('test') && taskType !== 'test_generation';\n}\n\n/**\n * Checks if documentation should be a secondary domain.\n */\nfunction shouldAddDocumentationSecondary(signals: string, taskType: TaskTypeCategory): boolean {\n return signals.includes('doc') && taskType !== 'documentation';\n}\n\n/**\n * Checks if architecture should be a secondary domain.\n */\nfunction shouldAddArchitectureSecondary(signals: string, taskType: TaskTypeCategory): boolean {\n return (signals.includes('design') || signals.includes('pattern')) && taskType !== 'architecture';\n}\n\n/**\n * Detects secondary domains from analysis signals.\n */\nfunction detectSecondaryDomains(\n analysis: SharedTaskAnalysisResult,\n primaryDomain: ExpertTaskDomain\n): ExpertTaskDomain[] {\n const secondary: ExpertTaskDomain[] = [];\n const signals = analysis.matchedSignals.join(' ').toLowerCase();\n\n if (shouldAddSecuritySecondary(signals, primaryDomain)) secondary.push('security');\n if (shouldAddTestingSecondary(signals, analysis.taskType)) secondary.push('testing');\n if (shouldAddDocumentationSecondary(signals, analysis.taskType)) secondary.push('documentation');\n if (shouldAddArchitectureSecondary(signals, analysis.taskType)) secondary.push('architecture');\n\n // If security became primary, add original domain as secondary\n if (primaryDomain === 'security') {\n const baseDomain = mapTaskTypeToDomain(analysis.taskType);\n if (baseDomain !== 'security' && baseDomain !== 'general') {\n secondary.push(baseDomain);\n }\n }\n\n return secondary;\n}\n\n/**\n * Determines the primary domain, promoting security when appropriate.\n */\nfunction determinePrimaryDomain(analysis: SharedTaskAnalysisResult): ExpertTaskDomain {\n // Check for strong security focus first\n if (isSecurityFocused(analysis)) {\n return 'security';\n }\n\n return mapTaskTypeToDomain(analysis.taskType);\n}\n\n/**\n * Converts SharedTaskAnalysisResult to ExpertTaskAnalysisResult.\n *\n * This adapter enables expert-selector.ts to use SharedTaskAnalyzer\n * without changing expert definitions that expect TaskDomain and\n * TaskComplexity values.\n *\n * @param analysis - Result from SharedTaskAnalyzer.analyze()\n * @returns ExpertTaskAnalysisResult compatible with expert-selector\n *\n * @example\n * ```typescript\n * import { createSharedTaskAnalyzer, toExpertTaskAnalysisResult } from 'nexus-agents/core';\n *\n * const analyzer = createSharedTaskAnalyzer();\n * const analysis = analyzer.analyze(task);\n * const expertAnalysis = toExpertTaskAnalysisResult(analysis);\n * // expertAnalysis.domain is TaskDomain compatible\n * ```\n */\nexport function toExpertTaskAnalysisResult(\n analysis: SharedTaskAnalysisResult\n): ExpertTaskAnalysisResult {\n const primaryDomain = determinePrimaryDomain(analysis);\n\n return {\n domain: primaryDomain,\n complexity: mapComplexityLevel(analysis.complexity),\n requiredCapabilities: extractRequiredCapabilities(analysis),\n keywords: extractKeywords(analysis),\n estimatedEffort: clamp(Math.round(analysis.complexityScore * 10), 1, 10),\n secondaryDomains: detectSecondaryDomains(analysis, primaryDomain),\n confidence: Math.max(analysis.taskTypeConfidence, analysis.reasoningConfidence),\n };\n}\n","/**\n * Injectable Random Provider\n *\n * Provides a deterministic interface for random number generation.\n * Supports seeded randomness for reproducible tests and builds.\n *\n * @module core/random-provider\n * (Source: System Mandate - Determinism improvement)\n */\n\nimport { randomBytes, randomInt as cryptoRandomInt } from 'node:crypto';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Interface for random number generation.\n * Inject this instead of using Math.random() directly.\n */\nexport interface IRandomProvider {\n /**\n * Generate a random number between 0 (inclusive) and 1 (exclusive).\n * Equivalent to Math.random() but potentially seeded.\n */\n random(): number;\n\n /**\n * Generate a random integer between min (inclusive) and max (exclusive).\n */\n randomInt(min: number, max: number): number;\n\n /**\n * Generate a random string of given length.\n */\n randomString(length: number): string;\n\n /**\n * Pick a random element from an array.\n */\n randomChoice<T>(items: readonly T[]): T | undefined;\n\n /**\n * Shuffle an array (returns new array).\n */\n shuffle<T>(items: readonly T[]): T[];\n\n /**\n * Generate a random UUID v4.\n */\n uuid(): string;\n}\n\n/**\n * Configuration for random provider.\n */\nexport interface RandomProviderConfig {\n /**\n * Seed for deterministic randomness.\n * If not set, uses Math.random() (non-deterministic).\n */\n readonly seed?: number;\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\nconst CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789';\n\n/** Largest multiple of CHARS.length that fits in a byte (252 = 36 * 7). */\nconst UNBIASED_LIMIT = CHARS.length * Math.floor(256 / CHARS.length);\n\n/**\n * System random provider using crypto.randomBytes().\n * Cryptographically secure, non-deterministic.\n */\nexport class SystemRandomProvider implements IRandomProvider {\n random(): number {\n // Use crypto.randomInt for uniform integer, then map to [0,1)\n return cryptoRandomInt(0x100000000) / 0x100000000;\n }\n\n randomInt(min: number, max: number): number {\n return cryptoRandomInt(min, max);\n }\n\n randomString(length: number): string {\n if (length === 0) return '';\n let result = '';\n while (result.length < length) {\n // Over-provision to reduce iterations (most bytes pass)\n const needed = length - result.length;\n const bytes = randomBytes(needed + 4);\n for (let i = 0; i < bytes.length && result.length < length; i++) {\n const b = bytes[i] ?? 0;\n // Rejection sampling: discard bytes >= UNBIASED_LIMIT to eliminate modulo bias\n if (b < UNBIASED_LIMIT) {\n result += CHARS[b % CHARS.length] ?? '';\n }\n }\n }\n return result;\n }\n\n randomChoice<T>(items: readonly T[]): T | undefined {\n if (items.length === 0) return undefined;\n return items[this.randomInt(0, items.length)];\n }\n\n shuffle<T>(items: readonly T[]): T[] {\n const result = [...items];\n for (let i = result.length - 1; i > 0; i--) {\n const j = this.randomInt(0, i + 1);\n const temp = result[i];\n const swap = result[j];\n if (temp !== undefined && swap !== undefined) {\n result[i] = swap;\n result[j] = temp;\n }\n }\n return result;\n }\n\n uuid(): string {\n const hex = (): string => this.randomInt(0, 16).toString(16);\n const s4 = (): string => hex() + hex() + hex() + hex();\n return `${s4()}${s4()}-${s4()}-4${hex()}${hex()}${hex()}-${hex()}${hex()}${hex()}${hex()}-${s4()}${s4()}${s4()}`;\n }\n}\n\n/**\n * Seeded random provider using mulberry32 algorithm.\n * Deterministic given the same seed.\n */\nexport class SeededRandomProvider implements IRandomProvider {\n private state: number;\n\n constructor(seed: number) {\n this.state = seed;\n }\n\n /**\n * Mulberry32 PRNG - simple, fast, good distribution.\n */\n random(): number {\n this.state = (this.state + 0x6d2b79f5) | 0;\n let t = Math.imul(this.state ^ (this.state >>> 15), 1 | this.state);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n }\n\n randomInt(min: number, max: number): number {\n return Math.floor(this.random() * (max - min)) + min;\n }\n\n randomString(length: number): string {\n let result = '';\n for (let i = 0; i < length; i++) {\n const char = CHARS[this.randomInt(0, CHARS.length)];\n if (char !== undefined) {\n result += char;\n }\n }\n return result;\n }\n\n randomChoice<T>(items: readonly T[]): T | undefined {\n if (items.length === 0) return undefined;\n return items[this.randomInt(0, items.length)];\n }\n\n shuffle<T>(items: readonly T[]): T[] {\n const result = [...items];\n for (let i = result.length - 1; i > 0; i--) {\n const j = this.randomInt(0, i + 1);\n const temp = result[i];\n const swap = result[j];\n if (temp !== undefined && swap !== undefined) {\n result[i] = swap;\n result[j] = temp;\n }\n }\n return result;\n }\n\n uuid(): string {\n const hex = (): string => this.randomInt(0, 16).toString(16);\n const s4 = (): string => hex() + hex() + hex() + hex();\n return `${s4()}${s4()}-${s4()}-4${hex()}${hex()}${hex()}-${hex()}${hex()}${hex()}${hex()}-${s4()}${s4()}${s4()}`;\n }\n\n /**\n * Reset the PRNG to a new seed.\n */\n reset(seed: number): void {\n this.state = seed;\n }\n}\n\n// ============================================================================\n// Global Instance\n// ============================================================================\n\nlet globalRandomProvider: IRandomProvider = new SystemRandomProvider();\n\n/**\n * Get the global random provider instance.\n */\nexport function getRandomProvider(): IRandomProvider {\n return globalRandomProvider;\n}\n\n/**\n * Set the global random provider instance.\n * Use for testing or deterministic mode.\n */\nexport function setRandomProvider(provider: IRandomProvider): void {\n globalRandomProvider = provider;\n}\n\n/**\n * Reset the global random provider to system random.\n */\nexport function resetRandomProvider(): void {\n globalRandomProvider = new SystemRandomProvider();\n}\n\n/**\n * Creates a random provider.\n */\nexport function createRandomProvider(config?: RandomProviderConfig): IRandomProvider {\n if (config?.seed !== undefined) {\n return new SeededRandomProvider(config.seed);\n }\n return new SystemRandomProvider();\n}\n","/**\n * nexus-agents/core - Token Estimator\n *\n * Unified token estimation service to replace duplicated implementations.\n * Supports provider-specific adjustments for Claude, OpenAI, and Gemini.\n *\n * @module core/token-estimator\n * (Source: Issue #574 - Router consolidation, LOOP H redundancy elimination)\n */\n\n/**\n * Provider identifiers for token estimation adjustment.\n */\nexport type TokenEstimatorProvider = 'claude' | 'openai' | 'gemini' | 'generic';\n\n/**\n * Characters per token by provider.\n * Based on empirical observations:\n * - Claude: ~3.5 chars/token (custom tokenizer)\n * - OpenAI: ~4 chars/token (tiktoken)\n * - Gemini: ~4 chars/token (SentencePiece)\n * - Generic: ~4 chars/token (conservative default)\n */\nconst CHARS_PER_TOKEN: Record<TokenEstimatorProvider, number> = {\n claude: 3.5,\n openai: 4.0,\n gemini: 4.0,\n generic: 4.0,\n};\n\n/**\n * Token estimation result with input/output breakdown.\n */\nexport interface TokenEstimate {\n /** Estimated input tokens */\n readonly input: number;\n /** Estimated output tokens */\n readonly output: number;\n /** Total estimated tokens */\n readonly total: number;\n /** Provider used for estimation */\n readonly provider: TokenEstimatorProvider;\n}\n\n/**\n * Options for token estimation.\n */\nexport interface TokenEstimateOptions {\n /** Provider to use for estimation (affects chars/token ratio) */\n provider?: TokenEstimatorProvider;\n /** Expected output multiplier relative to input (default: 0.5) */\n outputMultiplier?: number;\n /** Fixed output token estimate (overrides multiplier) */\n fixedOutput?: number;\n}\n\n/**\n * Interface for token estimation service.\n */\nexport interface ITokenEstimator {\n /** Estimate tokens for a single text string */\n estimateText(text: string, provider?: TokenEstimatorProvider): number;\n\n /** Estimate input/output tokens for a task */\n estimateTask(\n description: string,\n options?: TokenEstimateOptions\n ): TokenEstimate;\n\n /** Get the chars/token ratio for a provider */\n getCharsPerToken(provider?: TokenEstimatorProvider): number;\n}\n\n/**\n * Token estimator implementation.\n * Provides consistent token estimation across the codebase.\n */\nexport class TokenEstimator implements ITokenEstimator {\n private readonly defaultProvider: TokenEstimatorProvider;\n\n constructor(defaultProvider: TokenEstimatorProvider = 'generic') {\n this.defaultProvider = defaultProvider;\n }\n\n /**\n * Estimate tokens for a text string.\n *\n * @param text - Text to estimate tokens for\n * @param provider - Provider for estimation (uses default if not specified)\n * @returns Estimated token count\n */\n estimateText(text: string, provider?: TokenEstimatorProvider): number {\n const p = provider ?? this.defaultProvider;\n const charsPerToken = CHARS_PER_TOKEN[p];\n return Math.ceil(text.length / charsPerToken);\n }\n\n /**\n * Estimate input and output tokens for a task.\n *\n * @param description - Task description\n * @param options - Estimation options\n * @returns Token estimate with input/output breakdown\n */\n estimateTask(\n description: string,\n options?: TokenEstimateOptions\n ): TokenEstimate {\n const provider = options?.provider ?? this.defaultProvider;\n const outputMultiplier = options?.outputMultiplier ?? 0.5;\n\n const inputTokens = this.estimateText(description, provider);\n const outputTokens = options?.fixedOutput ?? Math.ceil(inputTokens * outputMultiplier);\n\n return {\n input: inputTokens,\n output: outputTokens,\n total: inputTokens + outputTokens,\n provider,\n };\n }\n\n /**\n * Get the characters per token ratio for a provider.\n *\n * @param provider - Provider to get ratio for\n * @returns Characters per token\n */\n getCharsPerToken(provider?: TokenEstimatorProvider): number {\n return CHARS_PER_TOKEN[provider ?? this.defaultProvider];\n }\n}\n\n/**\n * Singleton instance for shared usage.\n * Use createTokenEstimator() for custom configurations.\n */\nlet defaultEstimator: TokenEstimator | undefined;\n\n/**\n * Gets the shared token estimator instance.\n *\n * @returns Shared TokenEstimator instance\n */\nexport function getTokenEstimator(): ITokenEstimator {\n defaultEstimator ??= new TokenEstimator();\n return defaultEstimator;\n}\n\n/**\n * Creates a new token estimator with the specified configuration.\n *\n * @param defaultProvider - Default provider for estimation\n * @returns New TokenEstimator instance\n */\nexport function createTokenEstimator(\n defaultProvider?: TokenEstimatorProvider\n): ITokenEstimator {\n return new TokenEstimator(defaultProvider);\n}\n\n/**\n * Resets the shared token estimator instance.\n * Useful for testing.\n *\n * @internal\n */\nexport function resetTokenEstimator(): void {\n defaultEstimator = undefined;\n}\n\n/**\n * Quick estimation function for simple use cases.\n * Uses the shared estimator with generic provider.\n *\n * @param text - Text to estimate tokens for\n * @returns Estimated token count\n */\nexport function estimateTokens(text: string): number {\n return getTokenEstimator().estimateText(text);\n}\n\n/**\n * Quick estimation function with provider specification.\n *\n * @param text - Text to estimate tokens for\n * @param provider - Provider for estimation\n * @returns Estimated token count\n */\nexport function estimateTokensForProvider(\n text: string,\n provider: TokenEstimatorProvider\n): number {\n return getTokenEstimator().estimateText(text, provider);\n}\n","/**\n * nexus-agents/config - Model Config Helpers\n *\n * Derived helper functions that read from the canonical model registry.\n * All model metadata consumers should import from here instead of\n * maintaining their own hardcoded tables.\n *\n * @module config/model-config-helpers\n * (Source: Issue #807)\n */\n\nimport {\n DEFAULT_MODEL_CAPABILITIES,\n DEFAULT_MODEL_PER_CLI,\n getModelCapabilities,\n} from './model-capabilities.js';\nimport type {\n ModelId,\n ModelCapability,\n CliNameLiteral,\n Pricing,\n QualityScores,\n} from './model-capabilities-types.js';\n\n// ---------------------------------------------------------------------------\n// Single-Model Lookups\n// ---------------------------------------------------------------------------\n\n/** Get pricing for a model, or undefined if not set. */\nexport function getModelPricing(modelId: ModelId): Pricing | undefined {\n return getModelCapabilities(modelId)?.pricing;\n}\n\n/** Get display name for a model. Falls back to the modelId string. */\nexport function getModelDisplayName(modelId: ModelId): string {\n return getModelCapabilities(modelId)?.displayName ?? modelId;\n}\n\n/**\n * Get context window for a model.\n *\n * Unknown ids fall through to the fail-closed 8 K default (#2177) instead\n * of the previous silent 200 K fall-through — the old value silently\n * masked routing-critical metadata for Bedrock / custom endpoints / new\n * vendor releases. Callers passing through the ModelId closed enum hit\n * the canonical T1 path; the 8 K branch fires only when a caller casts a\n * raw string to ModelId (type-lying), which is the same latent bug the\n * recent codex-5.2 `cliModelName` regression surfaced.\n *\n * Callers that need full tier resolution (T2 bundled, T3 overlay)\n * should call `CapabilityDiscovery.resolve(id)` directly — #2176.\n */\nexport function getModelContextWindow(modelId: ModelId): number {\n return getModelCapabilities(modelId)?.contextWindow ?? 8_192;\n}\n\n/** Get max output tokens for a model, or undefined if not set. */\nexport function getModelMaxOutput(modelId: ModelId): number | undefined {\n return getModelCapabilities(modelId)?.maxOutputTokens;\n}\n\n/** Get quality scores for a model, or undefined if not set. */\nexport function getModelQualityScores(modelId: ModelId): QualityScores | undefined {\n return getModelCapabilities(modelId)?.qualityScores;\n}\n\n/** Get the default (strongest) model for a given CLI tool. */\nexport function getDefaultModelForCli(cli: CliNameLiteral): ModelId {\n return DEFAULT_MODEL_PER_CLI[cli];\n}\n\n/** Get the model name the CLI binary expects (e.g., 'gemini-2.5-pro'). */\nexport function getCliModelName(modelId: ModelId): string {\n const cap = getModelCapabilities(modelId);\n return cap?.cliModelName ?? cap?.cliAlias ?? modelId;\n}\n\n/**\n * Resolve a CLI alias (e.g., 'opus') or legacy version-suffix name (e.g.,\n * 'claude-opus-4') to its canonical ModelId. Resolution order:\n * 1. cliAlias match ('opus' → claude-opus)\n * 2. id match ('claude-opus' → claude-opus)\n * 3. aliases[] membership (legacy version names — #2199 Child 5)\n */\nexport function resolveCliAlias(alias: string): ModelId | undefined {\n return DEFAULT_MODEL_CAPABILITIES.models.find(\n (m) => m.cliAlias === alias || m.id === alias || (m.aliases?.includes(alias) ?? false)\n )?.id;\n}\n\n// ---------------------------------------------------------------------------\n// Bulk Builders — derive typed structures for downstream consumers\n// ---------------------------------------------------------------------------\n\n/**\n * Capability profile shape used by delegate-to-model and types-capability.\n * Matches the CapabilityProfile interface in both modules.\n */\ninterface CapabilityProfileShape {\n readonly reasoning: number;\n readonly contextWindow: number;\n readonly codeGeneration: number;\n readonly speed: number;\n readonly cost: number;\n}\n\n/**\n * Build capability profiles for all models (keyed by ModelId).\n * Used by delegate-to-model-types.ts to replace MODEL_CAPABILITIES.\n */\nexport function buildCapabilityProfiles(): Record<string, CapabilityProfileShape> {\n const result: Record<string, CapabilityProfileShape> = {};\n for (const model of DEFAULT_MODEL_CAPABILITIES.models) {\n const q = model.qualityScores;\n if (q !== undefined) {\n result[model.id] = {\n reasoning: q.reasoning,\n contextWindow: model.contextWindow,\n codeGeneration: q.codeGeneration,\n speed: q.speed,\n cost: q.cost,\n };\n }\n }\n return result;\n}\n\n/**\n * Build capability profiles keyed by CLI name (using default model per CLI).\n * Used by types-capability.ts to replace DEFAULT_CAPABILITIES.\n */\nexport function buildCliCapabilityProfiles(): Record<CliNameLiteral, CapabilityProfileShape> {\n const result = {} as Record<CliNameLiteral, CapabilityProfileShape>;\n for (const [cli, modelId] of Object.entries(DEFAULT_MODEL_PER_CLI) as Array<\n [CliNameLiteral, ModelId]\n >) {\n const model = getModelCapabilities(modelId);\n const q = model?.qualityScores;\n if (model !== undefined && q !== undefined) {\n result[cli] = {\n reasoning: q.reasoning,\n contextWindow: model.contextWindow,\n codeGeneration: q.codeGeneration,\n speed: q.speed,\n cost: q.cost,\n };\n }\n }\n return result;\n}\n\n/**\n * TOPSIS model profile shape matching TopsisModelProfile interface.\n */\ninterface TopsisProfileShape {\n readonly cliName: CliNameLiteral;\n readonly capabilities: CapabilityProfileShape;\n readonly costPerMillionInput: number;\n readonly costPerMillionOutput: number;\n readonly averageLatencyMs: number;\n readonly qualityScore: number;\n}\n\n/** Average latency estimates per CLI (ms). */\nconst CLI_AVG_LATENCY: Record<CliNameLiteral, number> = {\n claude: 800,\n gemini: 400,\n codex: 500,\n opencode: 600,\n};\n\n/**\n * Build TOPSIS model profiles for the default model of each CLI.\n * Used by topsis-types.ts to replace DEFAULT_MODEL_PROFILES.\n */\nexport function buildTopsisProfiles(): readonly TopsisProfileShape[] {\n const profiles: TopsisProfileShape[] = [];\n for (const [cli, modelId] of Object.entries(DEFAULT_MODEL_PER_CLI) as Array<\n [CliNameLiteral, ModelId]\n >) {\n const model = getModelCapabilities(modelId);\n const q = model?.qualityScores;\n const p = model?.pricing;\n if (model === undefined || q === undefined || p === undefined) continue;\n profiles.push({\n cliName: cli,\n capabilities: {\n reasoning: q.reasoning,\n contextWindow: model.contextWindow,\n codeGeneration: q.codeGeneration,\n speed: q.speed,\n cost: q.cost,\n },\n costPerMillionInput: p.inputPer1M,\n costPerMillionOutput: p.outputPer1M,\n averageLatencyMs: CLI_AVG_LATENCY[cli],\n qualityScore: (q.reasoning + q.codeGeneration) / 2,\n });\n }\n return profiles;\n}\n\n/**\n * ModelInfo shape matching the ModelInfo interface in types-capability.ts.\n */\nexport interface ModelInfoShape {\n readonly id: string;\n readonly name: string;\n readonly contextWindow: number;\n readonly maxOutput?: number;\n readonly costPerMillionInput?: number;\n readonly costPerMillionOutput?: number;\n}\n\n// ---------------------------------------------------------------------------\n// CLI-Model Lookups — shared helpers for adapter getModelInfo()\n// ---------------------------------------------------------------------------\n\n/**\n * Search the canonical registry by CLI name + CLI model identifier.\n *\n * Matches against (in order):\n * 1. `cliModelName` ('gemini-2.5-pro', 'claude-opus-4-6')\n * 2. `cliAlias` ('opus', 'sonnet', 'haiku')\n * 3. `id` — registry identifier ('gemini-pro', 'claude-opus') (#2200 Child 2)\n * 4. `aliases[]` membership — legacy / version-suffix names that resolve\n * to this entry (#2200 Child 1)\n */\nexport function findCanonicalModel(\n cli: CliNameLiteral,\n cliModelName: string\n): ModelCapability | undefined {\n return DEFAULT_MODEL_CAPABILITIES.models.find(\n (m) =>\n m.cliName === cli &&\n (m.cliModelName === cliModelName ||\n m.cliAlias === cliModelName ||\n m.id === cliModelName ||\n (m.aliases?.includes(cliModelName) ?? false))\n );\n}\n\n/**\n * Build a ModelInfoShape from the canonical registry for a given CLI model name.\n * Returns undefined if the model is not in the registry.\n */\nexport function buildModelInfo(\n cli: CliNameLiteral,\n cliModelName: string\n): ModelInfoShape | undefined {\n const cap = findCanonicalModel(cli, cliModelName);\n if (cap === undefined) return undefined;\n const info: ModelInfoShape = {\n id: cliModelName,\n name: cap.displayName,\n contextWindow: cap.contextWindow,\n };\n if (cap.maxOutputTokens !== undefined) {\n (info as { maxOutput: number }).maxOutput = cap.maxOutputTokens;\n }\n if (cap.pricing !== undefined) {\n (info as { costPerMillionInput: number }).costPerMillionInput = cap.pricing.inputPer1M;\n (info as { costPerMillionOutput: number }).costPerMillionOutput = cap.pricing.outputPer1M;\n }\n return info;\n}\n\n/**\n * Build mock model info for each CLI (using default model per CLI).\n * Used by testing/adapters/mock-adapter-helpers.ts to replace MODEL_INFO_BY_NAME.\n */\nexport function buildMockModelInfo(): Record<CliNameLiteral, ModelInfoShape> {\n const result = {} as Record<CliNameLiteral, ModelInfoShape>;\n for (const [cli, modelId] of Object.entries(DEFAULT_MODEL_PER_CLI) as Array<\n [CliNameLiteral, ModelId]\n >) {\n const model = getModelCapabilities(modelId);\n if (model === undefined) continue;\n const info: ModelInfoShape = {\n id: model.id,\n name: model.displayName,\n contextWindow: model.contextWindow,\n };\n // Only set optional properties when values exist (exactOptionalPropertyTypes)\n if (model.maxOutputTokens !== undefined) {\n (info as { maxOutput: number }).maxOutput = model.maxOutputTokens;\n }\n if (model.pricing !== undefined) {\n (info as { costPerMillionInput: number }).costPerMillionInput = model.pricing.inputPer1M;\n (info as { costPerMillionOutput: number }).costPerMillionOutput = model.pricing.outputPer1M;\n }\n result[cli] = info;\n }\n return result;\n}\n","/**\n * nexus-agents/cli-adapters - Capability Type Definitions\n *\n * Capability types: ModelInfo, CapabilityProfile, CliTask, ICliAdapter, etc.\n *\n * (Source: cli-project_plan.md v2.1.0)\n * (Source: docs/research/cli-integration-architecture.md)\n */\n\nimport type { Result, ILogger } from '../core/index.js';\nimport type {\n CliName,\n CliTransport,\n CliResponse,\n CliError,\n TokenUsage,\n HealthStatus,\n CapacityStatus,\n} from './types-core.js';\n\n/**\n * Model information from CLI.\n */\nexport interface ModelInfo {\n /** Model identifier */\n readonly id: string;\n /** Model display name */\n readonly name: string;\n /** Maximum context window in tokens */\n readonly contextWindow: number;\n /** Maximum output tokens */\n readonly maxOutput?: number;\n /** Cost per 1M input tokens */\n readonly costPerMillionInput?: number;\n /** Cost per 1M output tokens */\n readonly costPerMillionOutput?: number;\n}\n\n/**\n * Base adapter constructor options shared by all CLI adapters.\n * CLI-specific adapters extend this with additional fields.\n */\nexport interface BaseAdapterOptions {\n /** Model to use (defaults to the CLI's default from the canonical registry) */\n readonly model?: string;\n /** Custom logger instance */\n readonly logger?: ILogger;\n}\n\n/**\n * Capability profile for task routing.\n * (Source: cli-project_plan.md Capability Matching Matrix)\n */\nexport interface CapabilityProfile {\n /** Complex reasoning ability (0-10) */\n readonly reasoning: number;\n /** Maximum context window in tokens */\n readonly contextWindow: number;\n /** Code generation quality (0-10) */\n readonly codeGeneration: number;\n /** Response speed (0-10, higher = faster) */\n readonly speed: number;\n /** Cost efficiency (0-10, higher = cheaper) */\n readonly cost: number;\n}\n\n/**\n * Task to execute on a CLI.\n */\nexport interface CliTask {\n /** Task content/prompt */\n readonly content: string;\n /** Optional system prompt */\n readonly systemPrompt?: string;\n /** Preferred model (if any) */\n readonly model?: string;\n /** Session ID for continuation */\n readonly sessionId?: string;\n /** Maximum tokens to generate */\n readonly maxTokens?: number;\n /** Timeout in milliseconds */\n readonly timeoutMs?: number;\n /** Additional CLI-specific options */\n readonly options?: Record<string, unknown>;\n}\n\n/**\n * Execution options for CLI adapters.\n */\nexport interface ExecutionOptions {\n /** Timeout in milliseconds */\n readonly timeoutMs?: number;\n /** Whether to allow retries */\n readonly allowRetry?: boolean;\n /** Maximum retry attempts */\n readonly maxRetries?: number;\n /** Whether to track usage */\n readonly trackUsage?: boolean;\n /** Progress callback invoked on subprocess stdout activity (Issue #1087). */\n readonly onProgress?: (() => void) | undefined;\n}\n\n/**\n * CLI adapter interface.\n * Abstracts CLI integration with transport-agnostic execution.\n * (Source: cli-project_plan.md v2.1.0, Phase 2)\n */\nexport interface ICliAdapter {\n /** CLI name */\n readonly name: CliName;\n /** Transport type */\n readonly transport: CliTransport;\n /** Capability profile */\n readonly capabilities: CapabilityProfile;\n\n /**\n * Executes a task on the CLI.\n *\n * @param task - Task to execute\n * @param options - Execution options\n * @returns Result with response or error\n */\n execute(task: CliTask, options?: ExecutionOptions): Promise<Result<CliResponse, CliError>>;\n\n /**\n * Performs a health check on the CLI.\n *\n * @returns Health status including version compatibility\n */\n healthCheck(): Promise<HealthStatus>;\n\n /**\n * Gets current capacity/rate limit status.\n *\n * @returns Capacity status\n */\n getCapacity(): Promise<CapacityStatus>;\n\n /**\n * Gets CLI version.\n *\n * @returns Version string\n */\n getVersion(): Promise<string>;\n\n /**\n * Gets model information.\n *\n * @returns Model info\n */\n getModelInfo(): ModelInfo;\n\n /**\n * Initializes the adapter (e.g., MCP connection).\n * Called before first use.\n */\n initialize(): Promise<void>;\n\n /**\n * Cleans up resources (e.g., subprocess, MCP connection).\n * Called on shutdown.\n */\n dispose(): Promise<void>;\n}\n\n/**\n * Response parser interface for defensive parsing.\n * (Source: docs/research/cli-integration-architecture.md)\n */\nexport interface ICliResponseParser<T = unknown> {\n /** Parser name (for logging) */\n readonly name: string;\n /** Supported version range (semver) */\n readonly supportedVersionRange: string;\n\n /**\n * Parses raw CLI output to typed response.\n *\n * @param raw - Raw CLI output\n * @returns Parsed response or null if unrecognized\n */\n parse(raw: string): T | null;\n\n /**\n * Extracts just the response text (most stable field).\n *\n * @param raw - Raw CLI output\n * @returns Response text or null\n */\n extractResponse(raw: string): string | null;\n\n /**\n * Extracts token usage (may not be present).\n *\n * @param raw - Raw CLI output\n * @returns Token usage or null\n */\n extractUsage(raw: string): TokenUsage | null;\n\n /**\n * Extracts session ID (for resumption).\n *\n * @param raw - Raw CLI output\n * @returns Session ID or null\n */\n extractSessionId(raw: string): string | null;\n}\n\n/**\n * Version requirements for CLIs.\n */\nexport interface VersionRequirements {\n /** Minimum supported version */\n readonly minimum: string;\n /** Recommended version */\n readonly recommended: string;\n /** Known breaking versions */\n readonly breaking: readonly string[];\n}\n\n/**\n * CLI version requirements.\n * (Source: docs/research/cli-integration-architecture.md)\n */\nexport const CLI_VERSION_REQUIREMENTS: Record<CliName, VersionRequirements> = {\n claude: {\n minimum: '2.0.0',\n recommended: '2.0.76',\n breaking: [],\n },\n gemini: {\n minimum: '0.20.0',\n recommended: '0.22.5',\n breaking: [],\n },\n codex: {\n minimum: '0.70.0',\n recommended: '0.77.0',\n breaking: [],\n },\n opencode: {\n minimum: '0.1.0',\n recommended: '0.1.0',\n breaking: [],\n },\n} as const;\n\n/**\n * Default capability profiles for each CLI.\n * Derived from the canonical model registry (Issue #807).\n */\n\nimport { buildCliCapabilityProfiles } from '../config/model-config-helpers.js';\n\nexport const DEFAULT_CAPABILITIES: Record<CliName, CapabilityProfile> =\n buildCliCapabilityProfiles();\n","/**\n * nexus-agents/cli-adapters - Routing Memory Types\n *\n * Interface contract for memory↔routing integration.\n * Enables MobiMem Evolution (#149) and Preference-Trained Routing (#148).\n *\n * Moved from core/types/routing-memory.ts to fix circular dependency (#286).\n * This module belongs in cli-adapters since it's fundamentally about routing.\n *\n * @module cli-adapters/routing-memory-types\n * (Source: Issue #238, Consensus Vote APPROVED 75%)\n * (Source: docs/proposals/interface-contract-238.md)\n */\n\nimport type { Result } from '../core/result.js';\nimport type { CliName } from './types-core.js';\nimport type { BudgetConstraint } from './types-routing.js';\n\n// ============================================================================\n// Error Types\n// ============================================================================\n\n/**\n * Error type for routing memory operations.\n * Self-contained to avoid cross-module dependencies.\n */\nexport type RoutingMemoryErrorCode =\n | 'STORAGE_FAILED'\n | 'RETRIEVAL_FAILED'\n | 'EXPORT_FAILED'\n | 'IMPORT_FAILED'\n | 'INVALID_DATA';\n\nexport class RoutingMemoryError extends Error {\n public readonly code: RoutingMemoryErrorCode;\n\n constructor(\n message: string,\n code: RoutingMemoryErrorCode = 'STORAGE_FAILED',\n public override readonly cause?: unknown\n ) {\n super(message);\n this.name = 'RoutingMemoryError';\n this.code = code;\n }\n}\n\n// ============================================================================\n// Preference Storage Types (#148 - Preference-Trained Routing)\n// ============================================================================\n\n/**\n * Summary of task profile for storage (avoids circular deps with TaskProfile).\n */\nexport interface TaskProfileSummary {\n /** Estimated reasoning complexity (0-1) */\n readonly reasoningComplexity: number;\n /** Context tokens required */\n readonly contextRequired: number;\n /** Whether code generation is primary task */\n readonly codeGeneration: boolean;\n /** Task type classification */\n readonly taskType: 'reasoning' | 'knowledge' | 'code' | 'mixed';\n}\n\n/**\n * Record of a routing decision.\n */\nexport interface RoutingDecisionRecord {\n /** Unique decision ID */\n readonly id: string;\n /** When the decision was made */\n readonly timestamp: Date;\n /** Associated task ID */\n readonly taskId: string;\n /** Task type classification */\n readonly taskType: string;\n /** Summary of task profile */\n readonly taskProfile: TaskProfileSummary;\n /** CLI selected for execution */\n readonly selectedCli: CliName;\n /** Confidence score (0-1) */\n readonly confidence: number;\n /** Alternative CLIs considered */\n readonly alternatives: readonly CliName[];\n /** Reasoning for selection */\n readonly reason: string;\n /** Budget constraint applied (if any) */\n readonly budgetConstraint?: BudgetConstraint;\n}\n\n/**\n * Record of a task outcome.\n */\nexport interface TaskOutcomeRecord {\n /** Associated decision ID */\n readonly decisionId: string;\n /** Whether task succeeded */\n readonly success: boolean;\n /** Quality score (0-1) */\n readonly qualityScore: number;\n /** Execution duration in milliseconds */\n readonly durationMs: number;\n /** Token usage */\n readonly tokenUsage: number;\n /** Number of retries */\n readonly retryCount: number;\n /** Error category (if failed) */\n readonly errorCategory?: string;\n}\n\n/**\n * Explicit preference signal from human or AI feedback.\n */\nexport interface PreferenceSignal {\n /** Source of the preference */\n readonly source: 'human' | 'ai' | 'implicit';\n /** Preferred CLI for this task type */\n readonly preferred: CliName;\n /** Rejected CLI (if comparative preference) */\n readonly rejected?: CliName;\n /** Optional reasoning */\n readonly reason?: string;\n /** Confidence in the preference (0-1) */\n readonly confidence: number;\n}\n\n/**\n * Combined preference record for training.\n */\nexport interface PreferenceRecord {\n /** The routing decision */\n readonly decision: RoutingDecisionRecord;\n /** The task outcome */\n readonly outcome: TaskOutcomeRecord;\n /** Explicit preference (if provided) */\n readonly preference?: PreferenceSignal;\n /** Computed reward signal */\n readonly computedReward: number;\n}\n\n/**\n * Filter for preference queries.\n */\nexport interface PreferenceFilter {\n /** Filter by task type */\n readonly taskType?: string;\n /** Filter by CLI name */\n readonly cliName?: CliName;\n /** Records after this date */\n readonly since?: Date;\n /** Records before this date */\n readonly until?: Date;\n /** Minimum quality score */\n readonly minQuality?: number;\n /** Filter by preference source */\n readonly preferenceSource?: 'human' | 'ai' | 'implicit';\n}\n\n// ============================================================================\n// Experience Memory Types (#149 - MobiMem Evolution)\n// ============================================================================\n\n/**\n * Step within an experience record.\n */\nexport interface ExperienceStep {\n /** Step index */\n readonly index: number;\n /** Action taken */\n readonly action: string;\n /** Observation/result */\n readonly observation: string;\n /** Duration in milliseconds */\n readonly durationMs: number;\n}\n\n/**\n * Experience record for MobiMem Evolution.\n */\nexport interface ExperienceRecord {\n /** Unique experience ID */\n readonly id: string;\n /** When the experience occurred */\n readonly timestamp: Date;\n /** Task type */\n readonly taskType: string;\n /** Description of the task */\n readonly taskDescription: string;\n /** Steps taken during execution */\n readonly steps: readonly ExperienceStep[];\n /** Whether the task succeeded */\n readonly success: boolean;\n /** Key learnings from this experience */\n readonly learnings: string;\n}\n\n// ============================================================================\n// Action Memory Types (#149 - MobiMem Evolution)\n// ============================================================================\n\n/**\n * Action record for caching successful patterns.\n */\nexport interface ActionRecord {\n /** Unique action ID */\n readonly id: string;\n /** Task type this action applies to */\n readonly taskType: string;\n /** Pattern description */\n readonly pattern: string;\n /** Number of times this action was used */\n readonly usageCount: number;\n /** Success rate (0-1) */\n readonly successRate: number;\n /** Average duration in milliseconds */\n readonly avgDurationMs: number;\n /** Last time this action was used */\n readonly lastUsed: Date;\n}\n\n// ============================================================================\n// Export/Import Types\n// ============================================================================\n\n/**\n * Export format for routing memory.\n * Version field enables future schema migrations.\n */\nexport interface RoutingMemoryExport {\n /** Schema version */\n readonly version: '1.0';\n /** When the export was created */\n readonly exportedAt: Date;\n /** Preference records */\n readonly preferences: readonly PreferenceRecord[];\n /** Experience records */\n readonly experiences: readonly ExperienceRecord[];\n /** Action records */\n readonly actions: readonly ActionRecord[];\n}\n\n/**\n * Statistics for routing memory.\n */\nexport interface RoutingMemoryStats {\n /** Total preference records */\n readonly preferenceCount: number;\n /** Total experience records */\n readonly experienceCount: number;\n /** Total action records */\n readonly actionCount: number;\n /** Oldest record timestamp */\n readonly oldestRecord: Date | null;\n /** Newest record timestamp */\n readonly newestRecord: Date | null;\n /** Estimated storage size in bytes */\n readonly totalStorageBytes: number;\n}\n\n// ============================================================================\n// Main Interface\n// ============================================================================\n\n/**\n * Memory interface for routing-related data.\n * Bridges memory backend and routing systems.\n *\n * This interface enables:\n * - #148 Preference-Trained Routing: Store preferences and outcomes\n * - #149 MobiMem Evolution: Store experiences and action patterns\n *\n * @example\n * ```typescript\n * const routingMemory = createRoutingMemory(memoryBackend);\n *\n * // Store a routing decision and outcome\n * await routingMemory.storePreference(decision, outcome, preference);\n *\n * // Get preferences for training\n * const prefs = await routingMemory.getPreferences({ taskType: 'code' }, 100);\n *\n * // Store experience for MobiMem\n * await routingMemory.storeExperience(experience);\n * ```\n */\nexport interface IRoutingMemory {\n // ===========================================================================\n // Preference Storage (#148 - Preference-Trained Routing)\n // ===========================================================================\n\n /**\n * Store a routing decision with its outcome for preference learning.\n * @param decision - The routing decision made\n * @param outcome - The task outcome (success, quality, duration)\n * @param preference - Optional explicit preference signal\n */\n storePreference(\n decision: RoutingDecisionRecord,\n outcome: TaskOutcomeRecord,\n preference?: PreferenceSignal\n ): Promise<Result<void, RoutingMemoryError>>;\n\n /**\n * Retrieve preference data for training.\n * @param filter - Filter criteria for preferences\n * @param limit - Maximum records to return\n */\n getPreferences(\n filter: PreferenceFilter,\n limit: number\n ): Promise<Result<PreferenceRecord[], RoutingMemoryError>>;\n\n // ===========================================================================\n // Experience Memory (#149 - MobiMem Evolution)\n // ===========================================================================\n\n /**\n * Store an experience record for evolution.\n * @param experience - The experience to store\n */\n storeExperience(experience: ExperienceRecord): Promise<Result<void, RoutingMemoryError>>;\n\n /**\n * Retrieve relevant experiences for a task.\n * @param query - Semantic query for experience retrieval\n * @param limit - Maximum experiences to return\n */\n getExperiences(\n query: string,\n limit: number\n ): Promise<Result<ExperienceRecord[], RoutingMemoryError>>;\n\n // ===========================================================================\n // Action Memory (#149 - MobiMem Evolution)\n // ===========================================================================\n\n /**\n * Store a successful action pattern.\n * @param action - The action pattern to cache\n */\n storeAction(action: ActionRecord): Promise<Result<void, RoutingMemoryError>>;\n\n /**\n * Retrieve cached actions for a task type.\n * @param taskType - Type of task\n * @param limit - Maximum actions to return\n */\n getActions(taskType: string, limit: number): Promise<Result<ActionRecord[], RoutingMemoryError>>;\n\n // ===========================================================================\n // Export/Import\n // ===========================================================================\n\n /**\n * Export all routing memory for training or backup.\n */\n export(): Promise<Result<RoutingMemoryExport, RoutingMemoryError>>;\n\n /**\n * Import routing memory from export.\n * @param data - The exported data to import\n */\n import(data: RoutingMemoryExport): Promise<Result<void, RoutingMemoryError>>;\n\n // ===========================================================================\n // Statistics\n // ===========================================================================\n\n /**\n * Get memory statistics.\n */\n getStats(): Promise<Result<RoutingMemoryStats, RoutingMemoryError>>;\n}\n","/**\n * Budget utilities for cost estimation and token counting.\n *\n * CANONICAL SOURCE for token costs across the codebase.\n * Other modules should import from here or align their constants.\n *\n * @module cli-adapters/budget-utils\n * (Source: Issue #102, arXiv:2508.21141 - EMNLP 2025)\n */\n\nimport type { CliName } from './types.js';\n\n/**\n * Token cost estimates per 1M tokens (USD).\n * Based on public pricing as of 2025-01.\n */\nexport const TOKEN_COSTS: Record<CliName, { input: number; output: number }> = {\n claude: { input: 3.0, output: 15.0 },\n gemini: { input: 0.075, output: 0.3 },\n codex: { input: 2.5, output: 10.0 },\n opencode: { input: 2.0, output: 8.0 },\n};\n\n/**\n * Estimate tokens from task content.\n * Uses rough approximation of 4 characters per token.\n */\nexport function estimateTokens(content: string): number {\n return Math.ceil(content.length / 4);\n}\n\n/**\n * Estimate cost for a task based on estimated tokens.\n */\nexport function estimateCost(model: CliName, inputTokens: number, outputTokens: number): number {\n const costs = TOKEN_COSTS[model];\n const inputCost = (inputTokens / 1_000_000) * costs.input;\n const outputCost = (outputTokens / 1_000_000) * costs.output;\n return inputCost + outputCost;\n}\n\n/**\n * Format tokens with K/M suffix for readability.\n */\nexport function formatTokens(tokens: number): string {\n if (tokens >= 1_000_000) {\n return `${(tokens / 1_000_000).toFixed(1)}M`;\n }\n if (tokens >= 1_000) {\n return `${(tokens / 1_000).toFixed(1)}K`;\n }\n return String(tokens);\n}\n","/**\n * Budget warning generation utilities.\n *\n * @module cli-adapters/budget-warnings\n * (Source: Issue #102, arXiv:2508.21141 - EMNLP 2025)\n */\n\nimport type { BudgetWarning, SessionBudget } from './types.js';\n\n/**\n * Warning thresholds configuration.\n */\nexport interface WarningThresholds {\n readonly info: number;\n readonly warning: number;\n readonly critical: number;\n}\n\n/**\n * Get warning level based on utilization and thresholds.\n */\nexport function getWarningLevel(\n utilization: number,\n thresholds: WarningThresholds\n): BudgetWarning['level'] | null {\n if (utilization >= thresholds.critical) return 'critical';\n if (utilization >= thresholds.warning) return 'warning';\n if (utilization >= thresholds.info) return 'info';\n return null;\n}\n\n/**\n * Create a token budget warning.\n */\nexport function createTokenWarning(\n utilization: number,\n thresholds: WarningThresholds,\n remaining: number\n): BudgetWarning | null {\n const level = getWarningLevel(utilization, thresholds);\n if (level === null) return null;\n\n const pct = String(Math.round(utilization));\n const message =\n level === 'critical'\n ? `Token budget ${pct}% utilized after this task`\n : level === 'warning'\n ? `Token budget approaching limit (${pct}%)`\n : `Token budget ${pct}% utilized`;\n\n return {\n level,\n message,\n constraint: 'tokens',\n utilizationPercent: utilization,\n estimatedRemaining: remaining,\n };\n}\n\n/**\n * Create a cost budget warning.\n */\nexport function createCostWarning(\n utilization: number,\n thresholds: WarningThresholds,\n remaining: number\n): BudgetWarning | null {\n const level = getWarningLevel(utilization, thresholds);\n if (level === null || level === 'info') return null; // Only warning/critical for cost\n\n const pct = String(Math.round(utilization));\n const message =\n level === 'critical'\n ? `Cost budget ${pct}% utilized after this task`\n : `Cost budget approaching limit (${pct}%)`;\n\n return {\n level,\n message,\n constraint: 'cost',\n utilizationPercent: utilization,\n estimatedRemaining: remaining,\n };\n}\n\n/**\n * Generate all applicable warnings for a budget operation.\n */\nexport function generateBudgetWarnings(\n currentBudget: SessionBudget,\n estimatedTokens: number,\n estimatedCostUsd: number,\n rawThresholds: Partial<WarningThresholds>\n): BudgetWarning[] {\n const thresholds: WarningThresholds = {\n info: rawThresholds.info ?? 50,\n warning: rawThresholds.warning ?? 75,\n critical: rawThresholds.critical ?? 90,\n };\n\n const warnings: BudgetWarning[] = [];\n\n // Token budget warnings\n const projectedTokenUtilization =\n ((currentBudget.tokensUsed + estimatedTokens) / currentBudget.tokenBudget) * 100;\n const tokenWarning = createTokenWarning(\n projectedTokenUtilization,\n thresholds,\n currentBudget.tokensRemaining - estimatedTokens\n );\n if (tokenWarning !== null) {\n warnings.push(tokenWarning);\n }\n\n // Cost budget warnings\n const projectedCostUtilization =\n ((currentBudget.costSpentUsd + estimatedCostUsd) / currentBudget.costBudgetUsd) * 100;\n const costWarning = createCostWarning(\n projectedCostUtilization,\n thresholds,\n currentBudget.costRemainingUsd - estimatedCostUsd\n );\n if (costWarning !== null) {\n warnings.push(costWarning);\n }\n\n return warnings;\n}\n","/**\n * Budget error creation utilities.\n *\n * @module cli-adapters/budget-errors\n * (Source: Issue #102, arXiv:2508.21141 - EMNLP 2025)\n */\n\nimport type {\n BudgetConstraint,\n SessionBudget,\n BudgetExceededError,\n BudgetRoutingResult,\n} from './types.js';\nimport { DEFAULT_CLI } from '../config/model-capabilities-types.js';\n\n/**\n * Determine which constraint was exceeded.\n */\nexport function determineExceededConstraint(\n budget: BudgetConstraint,\n result: BudgetRoutingResult,\n currentBudget: SessionBudget\n): {\n constraint: 'tokens' | 'cost' | 'latency';\n limit: number;\n current: number;\n suggestion: string;\n} {\n if (budget.maxTokens !== undefined && result.estimatedTokens > budget.maxTokens) {\n return {\n constraint: 'tokens',\n limit: budget.maxTokens,\n current: result.estimatedTokens,\n suggestion: 'Reduce task complexity or increase token budget',\n };\n }\n if (budget.maxCostUsd !== undefined && result.estimatedCostUsd > budget.maxCostUsd) {\n return {\n constraint: 'cost',\n limit: budget.maxCostUsd,\n current: result.estimatedCostUsd,\n suggestion: 'Use a cheaper model or increase cost budget',\n };\n }\n if (currentBudget.tokensRemaining < result.estimatedTokens) {\n return {\n constraint: 'tokens',\n limit: currentBudget.tokenBudget,\n current: currentBudget.tokensUsed + result.estimatedTokens,\n suggestion: 'Wait for budget reset or increase session budget',\n };\n }\n return {\n constraint: 'cost',\n limit: currentBudget.costBudgetUsd,\n current: currentBudget.costSpentUsd + result.estimatedCostUsd,\n suggestion: 'Wait for budget reset or increase session budget',\n };\n}\n\n/**\n * Create a budget exceeded error.\n */\nexport function createBudgetExceededError(\n budget: BudgetConstraint,\n result: BudgetRoutingResult,\n currentBudget: SessionBudget\n): BudgetExceededError {\n const { constraint, limit, current, suggestion } = determineExceededConstraint(\n budget,\n result,\n currentBudget\n );\n return {\n code: 'BUDGET_EXCEEDED',\n message: `Budget constraint exceeded: ${constraint}`,\n cli: DEFAULT_CLI,\n retryable: false,\n constraint,\n limit,\n current,\n suggestion,\n };\n}\n","/**\n * Budget-constrained task router implementation.\n * Based on PILOT pattern (arXiv:2508.21141) for cost-efficient task routing.\n *\n * Routes tasks with respect to token, cost, and latency budgets.\n * Provides budget tracking, warnings, and enforcement options.\n *\n * @module cli-adapters/budget-router\n * (Source: Issue #102, arXiv:2508.21141 - EMNLP 2025)\n */\n\nimport type { Result } from '../core/index.js';\nimport { getTimeProvider } from '../core/index.js';\nimport { createLogger } from '../core/logger.js';\nimport type {\n IBudgetRouter,\n BudgetConstraint,\n SessionBudget,\n BudgetExceededError,\n BudgetWarning,\n BudgetRoutingResult,\n BudgetRouterOptions,\n CliTask,\n CliResponse,\n CliError,\n CliName,\n ICliAdapter,\n} from './types.js';\nimport { DEFAULT_CAPABILITIES } from './types.js';\nimport { estimateTokens, estimateCost } from './budget-utils.js';\nimport { generateBudgetWarnings } from './budget-warnings.js';\nimport { createBudgetExceededError } from './budget-errors.js';\n\nconst logger = createLogger({ component: 'budget-router' });\n\n/**\n * Default budget router configuration.\n */\nconst DEFAULT_OPTIONS: Required<BudgetRouterOptions> = {\n defaultConstraints: {\n maxTokens: 100000,\n maxCostUsd: 1.0,\n maxLatencyMs: 60000,\n },\n sessionBudget: {\n tokenBudget: 1000000,\n costBudgetUsd: 10.0,\n resetIntervalMs: 3600000, // 1 hour\n },\n warningThresholds: {\n info: 50,\n warning: 75,\n critical: 90,\n },\n enforceHardLimits: true,\n};\n\n/**\n * Budget-constrained task router.\n * Implements budget-aware routing with session tracking and enforcement.\n */\nexport class BudgetRouter implements IBudgetRouter {\n private readonly adapters: Map<CliName, ICliAdapter>;\n private readonly options: Required<BudgetRouterOptions>;\n private tokensUsed = 0;\n private costSpentUsd = 0;\n private sessionStartedAt: Date;\n private resetTimer?: ReturnType<typeof setTimeout>;\n\n constructor(adapters: Map<CliName, ICliAdapter>, options?: BudgetRouterOptions) {\n this.adapters = adapters;\n this.options = { ...DEFAULT_OPTIONS, ...options };\n this.sessionStartedAt = new Date(getTimeProvider().now());\n\n // Set up auto-reset timer if configured\n const resetInterval = this.options.sessionBudget.resetIntervalMs ?? 3600000;\n if (resetInterval > 0) {\n this.scheduleReset();\n }\n }\n\n /**\n * Get current session budget status.\n */\n getSessionBudget(): SessionBudget {\n const sessionBudget = this.options.sessionBudget;\n const tokenBudget = sessionBudget.tokenBudget ?? 1000000;\n const costBudgetUsd = sessionBudget.costBudgetUsd ?? 10.0;\n const resetIntervalMs = sessionBudget.resetIntervalMs ?? 3600000;\n\n const tokensRemaining = Math.max(0, tokenBudget - this.tokensUsed);\n const costRemainingUsd = Math.max(0, costBudgetUsd - this.costSpentUsd);\n\n const tokenUtilization = tokenBudget > 0 ? (this.tokensUsed / tokenBudget) * 100 : 0;\n const costUtilization = costBudgetUsd > 0 ? (this.costSpentUsd / costBudgetUsd) * 100 : 0;\n const utilizationPercent = Math.max(tokenUtilization, costUtilization);\n\n const resetsAt =\n resetIntervalMs > 0 ? new Date(this.sessionStartedAt.getTime() + resetIntervalMs) : undefined;\n\n const result: SessionBudget = {\n tokenBudget,\n costBudgetUsd,\n tokensUsed: this.tokensUsed,\n costSpentUsd: this.costSpentUsd,\n tokensRemaining,\n costRemainingUsd,\n utilizationPercent,\n startedAt: this.sessionStartedAt,\n };\n\n if (resetsAt !== undefined) {\n return { ...result, resetsAt };\n }\n return result;\n }\n\n /**\n * Update session budget after task completion.\n */\n updateBudget(usage: { tokens?: number; costUsd?: number }): void {\n if (usage.tokens !== undefined) {\n this.tokensUsed += usage.tokens;\n }\n if (usage.costUsd !== undefined) {\n this.costSpentUsd += usage.costUsd;\n }\n\n logger.debug('Budget updated', {\n tokensUsed: this.tokensUsed,\n costSpentUsd: this.costSpentUsd,\n });\n }\n\n /**\n * Reset session budget.\n */\n resetBudget(): void {\n this.tokensUsed = 0;\n this.costSpentUsd = 0;\n this.sessionStartedAt = new Date(getTimeProvider().now());\n logger.info('Budget reset');\n\n // Reschedule reset timer\n const resetInterval = this.options.sessionBudget.resetIntervalMs ?? 3600000;\n if (resetInterval > 0) {\n this.scheduleReset();\n }\n }\n\n /**\n * Check if task is within budget constraints.\n */\n checkBudget(task: CliTask, constraint?: BudgetConstraint): BudgetRoutingResult {\n const budget = { ...this.options.defaultConstraints, ...constraint };\n\n // Estimate tokens for this task\n const estimatedInputTokens = estimateTokens(task.content);\n const estimatedOutputTokens = task.maxTokens ?? estimatedInputTokens * 2;\n const estimatedTokens = estimatedInputTokens + estimatedOutputTokens;\n\n // Find the best adapter within budget\n const adapter = this.selectAdapterWithinBudget(budget, estimatedTokens);\n const estimatedCostUsd = adapter\n ? estimateCost(adapter.name, estimatedInputTokens, estimatedOutputTokens)\n : 0;\n\n // Check budget constraints\n const currentBudget = this.getSessionBudget();\n const withinBudget = this.checkConstraints(budget, estimatedTokens, estimatedCostUsd);\n\n // Generate warnings\n const warnings = generateBudgetWarnings(\n currentBudget,\n estimatedTokens,\n estimatedCostUsd,\n this.options.warningThresholds\n );\n\n // Project budget after task\n const projectedBudget = this.projectBudget(estimatedTokens, estimatedCostUsd);\n\n return {\n adapter,\n withinBudget,\n estimatedCostUsd,\n estimatedTokens,\n warnings,\n projectedBudget,\n };\n }\n\n /**\n * Route task with budget awareness.\n */\n routeWithBudget(\n task: CliTask,\n budget?: BudgetConstraint\n ): Promise<Result<BudgetRoutingResult, BudgetExceededError>> {\n const result = this.checkBudget(task, budget);\n\n if (!result.withinBudget && this.options.enforceHardLimits) {\n const currentBudget = this.getSessionBudget();\n const error = createBudgetExceededError(\n budget ?? this.options.defaultConstraints,\n result,\n currentBudget\n );\n return Promise.resolve({ ok: false, error });\n }\n\n logger.debug('Budget routing decision', {\n withinBudget: result.withinBudget,\n adapter: result.adapter?.name,\n estimatedCost: result.estimatedCostUsd,\n warnings: result.warnings.length,\n });\n\n return Promise.resolve({ ok: true, value: result });\n }\n\n /**\n * Execute task with budget tracking.\n */\n async executeWithBudget(\n task: CliTask,\n budget?: BudgetConstraint\n ): Promise<Result<CliResponse & { budgetAfter: SessionBudget }, CliError>> {\n // First, route with budget check\n const routingResult = await this.routeWithBudget(task, budget);\n if (!routingResult.ok) {\n return routingResult;\n }\n\n const { adapter, estimatedTokens, estimatedCostUsd, warnings } = routingResult.value;\n if (!adapter) {\n return this.createNoAdapterError();\n }\n\n this.logWarnings(warnings);\n\n // Execute the task\n const result = await this.executeAndTrack(adapter, task, estimatedTokens, estimatedCostUsd);\n return result;\n }\n\n private createNoAdapterError(): Result<CliResponse & { budgetAfter: SessionBudget }, CliError> {\n return {\n ok: false,\n error: {\n code: 'NOT_FOUND',\n message: 'No adapter available within budget constraints',\n cli: 'claude',\n retryable: false,\n },\n };\n }\n\n private logWarnings(warnings: readonly BudgetWarning[]): void {\n for (const warning of warnings) {\n if (warning.level === 'critical') {\n logger.warn('Budget critical warning', { warning });\n } else {\n logger.debug('Budget warning', { warning });\n }\n }\n }\n\n private async executeAndTrack(\n adapter: ICliAdapter,\n task: CliTask,\n estimatedTokens: number,\n estimatedCostUsd: number\n ): Promise<Result<CliResponse & { budgetAfter: SessionBudget }, CliError>> {\n const startTime = getTimeProvider().now();\n const result = await adapter.execute(task);\n\n if (!result.ok) {\n return result;\n }\n\n const actualTokens = result.value.usage?.totalTokens ?? estimatedTokens;\n const actualCostUsd = result.value.costUsd ?? estimatedCostUsd;\n\n this.updateBudget({ tokens: actualTokens, costUsd: actualCostUsd });\n\n const budgetAfter = this.getSessionBudget();\n const durationMs = getTimeProvider().now() - startTime;\n\n logger.info('Task executed with budget tracking', {\n adapter: adapter.name,\n actualTokens,\n actualCostUsd,\n durationMs,\n budgetUtilization: Math.round(budgetAfter.utilizationPercent),\n });\n\n return { ok: true, value: { ...result.value, durationMs, budgetAfter } };\n }\n\n /**\n * Clean up resources.\n */\n dispose(): void {\n if (this.resetTimer) {\n clearTimeout(this.resetTimer);\n }\n }\n\n // Private helpers\n\n private scheduleReset(): void {\n if (this.resetTimer) {\n clearTimeout(this.resetTimer);\n }\n const resetInterval = this.options.sessionBudget.resetIntervalMs ?? 3600000;\n this.resetTimer = setTimeout(() => {\n this.resetBudget();\n }, resetInterval);\n }\n\n private selectAdapterWithinBudget(\n budget: BudgetConstraint,\n estimatedTokens: number\n ): ICliAdapter | null {\n // Sort adapters by cost efficiency (higher = cheaper)\n const sortedAdapters = [...this.adapters].sort((a, b) => {\n const capA = DEFAULT_CAPABILITIES[a[0]];\n const capB = DEFAULT_CAPABILITIES[b[0]];\n return capB.cost - capA.cost; // Prefer cheaper models\n });\n\n for (const [name, adapter] of sortedAdapters) {\n const estimatedCost = estimateCost(name, estimatedTokens / 2, estimatedTokens / 2);\n const caps = DEFAULT_CAPABILITIES[name];\n\n // Check if adapter can handle the task within budget\n const withinTokenBudget =\n budget.maxTokens === undefined || estimatedTokens <= budget.maxTokens;\n const withinCostBudget =\n budget.maxCostUsd === undefined || estimatedCost <= budget.maxCostUsd;\n const withinContextWindow = estimatedTokens <= caps.contextWindow;\n\n if (withinTokenBudget && withinCostBudget && withinContextWindow) {\n return adapter;\n }\n }\n\n return null;\n }\n\n private checkConstraints(\n budget: BudgetConstraint,\n estimatedTokens: number,\n estimatedCostUsd: number\n ): boolean {\n const currentBudget = this.getSessionBudget();\n\n // Check per-task constraints\n if (budget.maxTokens !== undefined && estimatedTokens > budget.maxTokens) {\n return false;\n }\n if (budget.maxCostUsd !== undefined && estimatedCostUsd > budget.maxCostUsd) {\n return false;\n }\n\n // Check session budget\n if (currentBudget.tokensRemaining < estimatedTokens) {\n return false;\n }\n if (currentBudget.costRemainingUsd < estimatedCostUsd) {\n return false;\n }\n\n return true;\n }\n\n private projectBudget(estimatedTokens: number, estimatedCostUsd: number): SessionBudget {\n const current = this.getSessionBudget();\n return {\n ...current,\n tokensUsed: current.tokensUsed + estimatedTokens,\n costSpentUsd: current.costSpentUsd + estimatedCostUsd,\n tokensRemaining: Math.max(0, current.tokensRemaining - estimatedTokens),\n costRemainingUsd: Math.max(0, current.costRemainingUsd - estimatedCostUsd),\n utilizationPercent: Math.max(\n ((current.tokensUsed + estimatedTokens) / current.tokenBudget) * 100,\n ((current.costSpentUsd + estimatedCostUsd) / current.costBudgetUsd) * 100\n ),\n };\n }\n}\n\n/** Create a budget router instance. */\nexport function createBudgetRouter(\n adapters: Map<CliName, ICliAdapter>,\n opts?: BudgetRouterOptions\n): IBudgetRouter {\n return new BudgetRouter(adapters, opts);\n}\n","/**\n * nexus-agents/cli-adapters - TOPSIS Types\n *\n * Types for TOPSIS (Technique for Order of Preference by Similarity\n * to Ideal Solution) multi-criteria decision making algorithm.\n *\n * @module cli-adapters/topsis-types\n * (Source: arXiv:2509.07571, Issue #146)\n */\n\nimport type { CliName, CapabilityProfile } from './types.js';\n\n/**\n * A criterion for multi-criteria decision making.\n */\nexport interface TopsisCredential {\n /** Criterion name (e.g., 'cost', 'latency', 'quality') */\n readonly name: string;\n /** Weight for this criterion (0-1, should sum to 1 across all criteria) */\n readonly weight: number;\n /** Whether higher values are better (true) or lower is better (false) */\n readonly beneficial: boolean;\n}\n\n/**\n * Extended model profile with additional metrics for TOPSIS.\n */\nexport interface TopsisModelProfile {\n /** CLI adapter name */\n readonly cliName: CliName;\n /** Base capability profile */\n readonly capabilities: CapabilityProfile;\n /** Cost per 1M input tokens in USD */\n readonly costPerMillionInput: number;\n /** Cost per 1M output tokens in USD */\n readonly costPerMillionOutput: number;\n /** Average latency in milliseconds (first token) */\n readonly averageLatencyMs: number;\n /** Quality score (0-10, derived from capabilities) */\n readonly qualityScore: number;\n}\n\n/**\n * Default criteria weights for TOPSIS routing.\n * Sum to 1.0.\n */\nexport const DEFAULT_TOPSIS_CRITERIA: readonly TopsisCredential[] = [\n { name: 'quality', weight: 0.5, beneficial: true },\n { name: 'cost', weight: 0.3, beneficial: false },\n { name: 'latency', weight: 0.2, beneficial: false },\n] as const;\n\n/**\n * TOPSIS criteria for plan billing mode.\n * Cost weight is zero (monthly plan makes cost irrelevant),\n * redistributed to quality. Sum to 1.0.\n */\nexport const PLAN_BILLING_TOPSIS_CRITERIA: readonly TopsisCredential[] = [\n { name: 'quality', weight: 0.8, beneficial: true },\n { name: 'cost', weight: 0.0, beneficial: false },\n { name: 'latency', weight: 0.2, beneficial: false },\n] as const;\n\n/**\n * Configuration for TOPSIS router.\n */\nexport interface TopsisConfig {\n /** Criteria with weights (must sum to 1.0) */\n readonly criteria: readonly TopsisCredential[];\n /** Minimum acceptable quality score (0-10) */\n readonly minQualityThreshold: number;\n /** Maximum acceptable latency in ms (optional) */\n readonly maxLatencyMs?: number;\n /** Maximum acceptable cost per request in USD (optional) */\n readonly maxCostPerRequest?: number;\n /** Whether to log detailed scoring info */\n readonly verbose: boolean;\n}\n\n/**\n * Task-category-aware TOPSIS criteria weights (#1491).\n * Different task types benefit from different quality/cost/latency tradeoffs.\n * Derived from weather report data (6,164 tasks observed).\n *\n * API billing mode weights (cost-aware):\n */\nexport const TASK_CATEGORY_TOPSIS_CRITERIA: Readonly<Record<string, readonly TopsisCredential[]>> =\n {\n // Architecture: quality is paramount (47% success rate shows bad routing hurts)\n architecture: [\n { name: 'quality', weight: 0.7, beneficial: true },\n { name: 'cost', weight: 0.1, beneficial: false },\n { name: 'latency', weight: 0.2, beneficial: false },\n ],\n // Code: balanced, slight quality emphasis\n code_implementation: DEFAULT_TOPSIS_CRITERIA,\n // Code review: quality matters more than speed\n code_review: [\n { name: 'quality', weight: 0.6, beneficial: true },\n { name: 'cost', weight: 0.2, beneficial: false },\n { name: 'latency', weight: 0.2, beneficial: false },\n ],\n // Testing: latency matters for quick feedback loops\n test_generation: [\n { name: 'quality', weight: 0.4, beneficial: true },\n { name: 'cost', weight: 0.2, beneficial: false },\n { name: 'latency', weight: 0.4, beneficial: false },\n ],\n // Documentation: balanced\n documentation: DEFAULT_TOPSIS_CRITERIA,\n // Large codebase: context window quality critical\n large_codebase: [\n { name: 'quality', weight: 0.6, beneficial: true },\n { name: 'cost', weight: 0.2, beneficial: false },\n { name: 'latency', weight: 0.2, beneficial: false },\n ],\n // Bulk operations: latency/cost dominant\n bulk_operations: [\n { name: 'quality', weight: 0.3, beneficial: true },\n { name: 'cost', weight: 0.4, beneficial: false },\n { name: 'latency', weight: 0.3, beneficial: false },\n ],\n // General: default weights\n general: DEFAULT_TOPSIS_CRITERIA,\n } as const;\n\n/**\n * Plan billing mode overrides for task-category weights.\n * Cost weight is zeroed and redistributed to quality.\n */\nexport const TASK_CATEGORY_PLAN_CRITERIA: Readonly<Record<string, readonly TopsisCredential[]>> = {\n architecture: [\n { name: 'quality', weight: 0.85, beneficial: true },\n { name: 'cost', weight: 0.0, beneficial: false },\n { name: 'latency', weight: 0.15, beneficial: false },\n ],\n code_implementation: PLAN_BILLING_TOPSIS_CRITERIA,\n code_review: [\n { name: 'quality', weight: 0.8, beneficial: true },\n { name: 'cost', weight: 0.0, beneficial: false },\n { name: 'latency', weight: 0.2, beneficial: false },\n ],\n test_generation: [\n { name: 'quality', weight: 0.55, beneficial: true },\n { name: 'cost', weight: 0.0, beneficial: false },\n { name: 'latency', weight: 0.45, beneficial: false },\n ],\n documentation: PLAN_BILLING_TOPSIS_CRITERIA,\n large_codebase: PLAN_BILLING_TOPSIS_CRITERIA,\n bulk_operations: [\n { name: 'quality', weight: 0.6, beneficial: true },\n { name: 'cost', weight: 0.0, beneficial: false },\n { name: 'latency', weight: 0.4, beneficial: false },\n ],\n general: PLAN_BILLING_TOPSIS_CRITERIA,\n} as const;\n\n/**\n * Gets TOPSIS criteria for a task category and billing mode.\n * Falls back to default criteria if category not found.\n */\nexport function getCriteriaForTaskCategory(\n taskType: string,\n billingMode: 'api' | 'plan' = 'api'\n): readonly TopsisCredential[] {\n const map = billingMode === 'plan' ? TASK_CATEGORY_PLAN_CRITERIA : TASK_CATEGORY_TOPSIS_CRITERIA;\n return (\n map[taskType] ??\n (billingMode === 'plan' ? PLAN_BILLING_TOPSIS_CRITERIA : DEFAULT_TOPSIS_CRITERIA)\n );\n}\n\n/**\n * Default TOPSIS configuration.\n */\nexport const DEFAULT_TOPSIS_CONFIG: TopsisConfig = {\n criteria: DEFAULT_TOPSIS_CRITERIA,\n minQualityThreshold: 5,\n verbose: false,\n};\n\n/**\n * TOPSIS scoring result for a single model.\n */\nexport interface TopsisScore {\n /** Model identifier */\n readonly cliName: CliName;\n /** Raw values for each criterion */\n readonly rawValues: Readonly<Record<string, number>>;\n /** Normalized values for each criterion */\n readonly normalizedValues: Readonly<Record<string, number>>;\n /** Weighted normalized values */\n readonly weightedValues: Readonly<Record<string, number>>;\n /** Distance to positive ideal solution (PIS) */\n readonly distanceToPIS: number;\n /** Distance to negative ideal solution (NIS) */\n readonly distanceToNIS: number;\n /** Relative closeness to ideal (0-1, higher is better) */\n readonly closenessScore: number;\n}\n\n/**\n * TOPSIS routing decision result.\n */\nexport interface TopsisResult {\n /** Selected model */\n readonly selectedModel: CliName;\n /** All model scores in ranked order */\n readonly scores: readonly TopsisScore[];\n /** Positive ideal solution values */\n readonly positiveIdeal: Readonly<Record<string, number>>;\n /** Negative ideal solution values */\n readonly negativeIdeal: Readonly<Record<string, number>>;\n /** Whether cost was optimized significantly */\n readonly costOptimized: boolean;\n /** Estimated cost savings vs best quality model */\n readonly estimatedSavingsPercent: number;\n /** Reasoning for the selection */\n readonly reasoning: string;\n}\n\n/**\n * Default model profiles based on known CLI characteristics.\n * Derived from the canonical model registry (Issue #807).\n */\n\nimport { buildTopsisProfiles } from '../config/model-config-helpers.js';\n\nexport const DEFAULT_MODEL_PROFILES: readonly TopsisModelProfile[] = buildTopsisProfiles();\n","/**\n * nexus-agents/cli-adapters - TOPSIS Helper Functions\n *\n * Extracted mathematical utilities for TOPSIS calculations.\n *\n * @module cli-adapters/topsis-helpers\n */\n\nimport type { CliName } from './types.js';\nimport type { TopsisModelProfile, TopsisConfig, TopsisScore } from './topsis-types.js';\n\n/**\n * Estimates cost for a request based on token counts.\n */\nexport function estimateCost(\n profile: TopsisModelProfile,\n inputTokens: number,\n outputTokens: number\n): number {\n const inputCost = (inputTokens / 1_000_000) * profile.costPerMillionInput;\n const outputCost = (outputTokens / 1_000_000) * profile.costPerMillionOutput;\n return inputCost + outputCost;\n}\n\n/**\n * Calculates sum of squares for each criterion.\n */\nexport function calculateSumOfSquares(\n matrix: Map<CliName, Record<string, number>>,\n criteria: TopsisConfig['criteria']\n): Record<string, number> {\n const sumOfSquares: Record<string, number> = {};\n for (const criterion of criteria) {\n sumOfSquares[criterion.name] = 0;\n }\n\n for (const values of matrix.values()) {\n for (const criterion of criteria) {\n const val = values[criterion.name] ?? 0;\n sumOfSquares[criterion.name] = (sumOfSquares[criterion.name] ?? 0) + val * val;\n }\n }\n return sumOfSquares;\n}\n\n/**\n * Calculates normalization factors from sum of squares.\n */\nexport function calculateNormFactors(\n sumOfSquares: Record<string, number>,\n criteria: TopsisConfig['criteria']\n): Record<string, number> {\n const normFactors: Record<string, number> = {};\n for (const criterion of criteria) {\n normFactors[criterion.name] = Math.sqrt(sumOfSquares[criterion.name] ?? 0);\n }\n return normFactors;\n}\n\n/**\n * Calculates Euclidean distance between weighted values and ideal.\n */\nexport function calculateDistance(\n values: Record<string, number>,\n ideal: Record<string, number>,\n criteria: TopsisConfig['criteria']\n): number {\n let sumSquares = 0;\n for (const criterion of criteria) {\n const diff = (values[criterion.name] ?? 0) - (ideal[criterion.name] ?? 0);\n sumSquares += diff * diff;\n }\n return Math.sqrt(sumSquares);\n}\n\n/**\n * Calculates cost savings percentage compared to highest quality model.\n */\nexport function calculateSavings(\n profiles: readonly TopsisModelProfile[],\n selected: CliName\n): number {\n const selectedProfile = profiles.find((p) => p.cliName === selected);\n const highestQuality = profiles.reduce((best, p) =>\n p.qualityScore > best.qualityScore ? p : best\n );\n\n if (selectedProfile === undefined || selected === highestQuality.cliName) {\n return 0;\n }\n\n const selectedCost = estimateCost(selectedProfile, 1000, 500);\n const maxCost = estimateCost(highestQuality, 1000, 500);\n\n return maxCost > 0 ? ((maxCost - selectedCost) / maxCost) * 100 : 0;\n}\n\n/**\n * Generates human-readable reasoning for the selection.\n */\nexport function generateReasoning(\n best: TopsisScore,\n ranked: TopsisScore[],\n savings: number\n): string {\n const parts: string[] = [];\n\n parts.push(`Selected \"${best.cliName}\" with closeness score ${best.closenessScore.toFixed(3)}`);\n\n if (ranked.length > 1 && ranked[1] !== undefined) {\n const runnerUp = ranked[1];\n const diff = best.closenessScore - runnerUp.closenessScore;\n parts.push(`(${(diff * 100).toFixed(1)}% better than ${runnerUp.cliName})`);\n }\n\n if (savings > 10) {\n parts.push(`Cost savings: ${savings.toFixed(1)}% vs highest quality model`);\n }\n\n return parts.join('. ');\n}\n","/**\n * nexus-agents/cli-adapters - TOPSIS Multi-Criteria Router\n *\n * Implementation of TOPSIS (Technique for Order of Preference by Similarity\n * to Ideal Solution) for Pareto-optimal model selection balancing\n * performance vs cost.\n *\n * @module cli-adapters/topsis-router\n * (Source: arXiv:2509.07571, Issue #146)\n */\n\nimport type { ILogger } from '../core/index.js';\nimport { createLogger } from '../core/index.js';\nimport type { CliName } from './types.js';\nimport type {\n TopsisModelProfile,\n TopsisConfig,\n TopsisScore,\n TopsisResult,\n} from './topsis-types.js';\nimport { DEFAULT_TOPSIS_CONFIG, DEFAULT_MODEL_PROFILES } from './topsis-types.js';\n/** Tolerance for weight sum validation (weights must sum to 1.0 ± this). */\nconst WEIGHT_SUM_TOLERANCE = 0.01;\n\n/** Default expected input tokens when not specified. */\nconst DEFAULT_INPUT_TOKENS = 1000;\n\n/** Default expected output tokens when not specified. */\nconst DEFAULT_OUTPUT_TOKENS = 500;\n\nimport {\n estimateCost,\n calculateSumOfSquares,\n calculateNormFactors,\n calculateDistance,\n calculateSavings,\n generateReasoning,\n} from './topsis-helpers.js';\n\n// Re-export helpers for backward compatibility\nexport {\n estimateCost,\n calculateSumOfSquares,\n calculateNormFactors,\n calculateDistance,\n calculateSavings,\n generateReasoning,\n} from './topsis-helpers.js';\n\n/**\n * Options for selecting a model with TOPSIS.\n */\nexport interface SelectModelOptions {\n /** Profiles to evaluate (defaults to DEFAULT_MODEL_PROFILES) */\n profiles?: readonly TopsisModelProfile[];\n /** Expected input tokens for cost calculation */\n expectedInputTokens?: number;\n /** Expected output tokens for cost calculation */\n expectedOutputTokens?: number;\n}\n\n/**\n * TOPSIS Router for multi-criteria model selection.\n */\nexport class TopsisRouter {\n private readonly config: TopsisConfig;\n private readonly logger: ILogger;\n\n constructor(config: Partial<TopsisConfig> = {}, logger?: ILogger) {\n this.config = { ...DEFAULT_TOPSIS_CONFIG, ...config };\n this.logger = logger ?? createLogger({ component: 'TopsisRouter' });\n this.validateWeights();\n }\n\n /**\n * Validates that criteria weights sum to 1.0 (within tolerance).\n */\n private validateWeights(): void {\n const sum = this.config.criteria.reduce((acc, c) => acc + c.weight, 0);\n if (Math.abs(sum - 1.0) > WEIGHT_SUM_TOLERANCE) {\n throw new Error(`Criteria weights must sum to 1.0, got ${sum.toFixed(3)}`);\n }\n }\n\n /**\n * Selects the optimal model using TOPSIS algorithm.\n */\n selectModel(opts: SelectModelOptions = {}): TopsisResult {\n const profiles = opts.profiles ?? DEFAULT_MODEL_PROFILES;\n const inputTokens = opts.expectedInputTokens ?? DEFAULT_INPUT_TOKENS;\n const outputTokens = opts.expectedOutputTokens ?? DEFAULT_OUTPUT_TOKENS;\n\n // Step 1: Build decision matrix\n const matrix = this.buildDecisionMatrix(profiles, inputTokens, outputTokens);\n\n // Step 2: Normalize the matrix\n const normalized = this.normalizeMatrix(matrix);\n\n // Step 3: Apply weights\n const weighted = this.applyWeights(normalized);\n\n // Step 4: Find ideal solutions\n const { positive, negative } = this.findIdealSolutions(weighted);\n\n // Step 5: Calculate distances and scores\n const scores = this.calculateScoresOpts({\n profiles,\n matrices: { raw: matrix, normalized, weighted },\n ideals: { positive, negative },\n });\n\n // Step 6: Rank and select\n const ranked = [...scores].sort((a, b) => b.closenessScore - a.closenessScore);\n const best = ranked[0];\n\n if (best === undefined) {\n throw new Error('No models available for selection');\n }\n\n // Calculate savings\n const costSavings = calculateSavings(profiles, best.cliName);\n\n const result: TopsisResult = {\n selectedModel: best.cliName,\n scores: ranked,\n positiveIdeal: positive,\n negativeIdeal: negative,\n costOptimized: costSavings > 10,\n estimatedSavingsPercent: costSavings,\n reasoning: generateReasoning(best, ranked, costSavings),\n };\n\n this.logResult(result);\n return result;\n }\n\n /**\n * Builds the decision matrix from model profiles.\n */\n private buildDecisionMatrix(\n profiles: readonly TopsisModelProfile[],\n inputTokens: number,\n outputTokens: number\n ): Map<CliName, Record<string, number>> {\n const matrix = new Map<CliName, Record<string, number>>();\n\n for (const profile of profiles) {\n const cost = estimateCost(profile, inputTokens, outputTokens);\n const values: Record<string, number> = {\n quality: profile.qualityScore,\n cost: cost,\n latency: profile.averageLatencyMs,\n };\n matrix.set(profile.cliName, values);\n }\n\n return matrix;\n }\n\n /**\n * Normalizes the decision matrix using vector normalization.\n */\n private normalizeMatrix(\n matrix: Map<CliName, Record<string, number>>\n ): Map<CliName, Record<string, number>> {\n const sumOfSquares = calculateSumOfSquares(matrix, this.config.criteria);\n const normFactors = calculateNormFactors(sumOfSquares, this.config.criteria);\n\n const normalized = new Map<CliName, Record<string, number>>();\n for (const [cli, values] of matrix) {\n const normalizedValues: Record<string, number> = {};\n for (const criterion of this.config.criteria) {\n const factor = normFactors[criterion.name] ?? 1;\n normalizedValues[criterion.name] = factor > 0 ? (values[criterion.name] ?? 0) / factor : 0;\n }\n normalized.set(cli, normalizedValues);\n }\n\n return normalized;\n }\n\n /**\n * Applies weights to normalized matrix.\n */\n private applyWeights(\n normalized: Map<CliName, Record<string, number>>\n ): Map<CliName, Record<string, number>> {\n const weighted = new Map<CliName, Record<string, number>>();\n\n for (const [cli, values] of normalized) {\n const weightedValues: Record<string, number> = {};\n for (const criterion of this.config.criteria) {\n weightedValues[criterion.name] = (values[criterion.name] ?? 0) * criterion.weight;\n }\n weighted.set(cli, weightedValues);\n }\n\n return weighted;\n }\n\n /**\n * Finds positive and negative ideal solutions.\n */\n private findIdealSolutions(weighted: Map<CliName, Record<string, number>>): {\n positive: Record<string, number>;\n negative: Record<string, number>;\n } {\n const positive: Record<string, number> = {};\n const negative: Record<string, number> = {};\n\n for (const criterion of this.config.criteria) {\n const values: number[] = [];\n for (const weightedValues of weighted.values()) {\n values.push(weightedValues[criterion.name] ?? 0);\n }\n\n if (values.length === 0) {\n positive[criterion.name] = 0;\n negative[criterion.name] = 0;\n continue;\n }\n\n if (criterion.beneficial) {\n positive[criterion.name] = Math.max(...values);\n negative[criterion.name] = Math.min(...values);\n } else {\n positive[criterion.name] = Math.min(...values);\n negative[criterion.name] = Math.max(...values);\n }\n }\n\n return { positive, negative };\n }\n\n /**\n * Options for calculating TOPSIS scores.\n */\n private calculateScoresOpts(opts: {\n profiles: readonly TopsisModelProfile[];\n matrices: {\n raw: Map<CliName, Record<string, number>>;\n normalized: Map<CliName, Record<string, number>>;\n weighted: Map<CliName, Record<string, number>>;\n };\n ideals: { positive: Record<string, number>; negative: Record<string, number> };\n }): TopsisScore[] {\n const { profiles, matrices, ideals } = opts;\n const scores: TopsisScore[] = [];\n\n for (const profile of profiles) {\n const score = this.calculateSingleScore(profile, matrices, ideals);\n scores.push(score);\n }\n\n return scores;\n }\n\n /**\n * Calculates TOPSIS score for a single model.\n */\n private calculateSingleScore(\n profile: TopsisModelProfile,\n matrices: {\n raw: Map<CliName, Record<string, number>>;\n normalized: Map<CliName, Record<string, number>>;\n weighted: Map<CliName, Record<string, number>>;\n },\n ideals: { positive: Record<string, number>; negative: Record<string, number> }\n ): TopsisScore {\n const cli = profile.cliName;\n const rawValues = matrices.raw.get(cli) ?? {};\n const normalizedValues = matrices.normalized.get(cli) ?? {};\n const weightedValues = matrices.weighted.get(cli) ?? {};\n\n const distToPIS = calculateDistance(weightedValues, ideals.positive, this.config.criteria);\n const distToNIS = calculateDistance(weightedValues, ideals.negative, this.config.criteria);\n const closeness = distToPIS + distToNIS > 0 ? distToNIS / (distToPIS + distToNIS) : 0;\n\n return {\n cliName: cli,\n rawValues,\n normalizedValues,\n weightedValues,\n distanceToPIS: distToPIS,\n distanceToNIS: distToNIS,\n closenessScore: closeness,\n };\n }\n\n /**\n * Logs the TOPSIS result.\n */\n private logResult(result: TopsisResult): void {\n this.logger.info('TOPSIS selection complete', {\n selected: result.selectedModel,\n costOptimized: result.costOptimized,\n savingsPercent: result.estimatedSavingsPercent.toFixed(1),\n });\n\n if (this.config.verbose) {\n for (const score of result.scores) {\n this.logger.debug('Model score', {\n cli: score.cliName,\n closeness: score.closenessScore.toFixed(3),\n distToPIS: score.distanceToPIS.toFixed(4),\n distToNIS: score.distanceToNIS.toFixed(4),\n });\n }\n }\n }\n\n /**\n * Gets the current configuration.\n */\n getConfig(): TopsisConfig {\n return this.config;\n }\n}\n\n/**\n * Creates a TOPSIS router with optional configuration.\n */\nexport function createTopsisRouter(config?: Partial<TopsisConfig>, logger?: ILogger): TopsisRouter {\n return new TopsisRouter(config, logger);\n}\n\n/**\n * Quick model selection using TOPSIS with default settings.\n */\nexport function selectModelWithTopsis(opts: SelectModelOptions = {}): TopsisResult {\n const router = createTopsisRouter();\n return router.selectModel(opts);\n}\n","/**\n * nexus-agents/cli-adapters - Budget Router Types\n *\n * Type definitions for budget-constrained routing based on PILOT pattern.\n *\n * @module cli-adapters/budget-router-types\n * (Source: Issue #102, arXiv:2401.02987)\n */\n\nimport { z } from 'zod';\n\n/**\n * Budget constraint for a routing decision.\n */\nexport interface BudgetConstraint {\n /** Maximum tokens to use for this task */\n readonly maxTokens?: number | undefined;\n /** Maximum cost in USD for this task */\n readonly maxCostUSD?: number | undefined;\n /** Maximum latency in milliseconds */\n readonly maxLatencyMs?: number | undefined;\n}\n\n/**\n * Zod schema for budget constraint validation.\n */\nexport const BudgetConstraintSchema = z.object({\n maxTokens: z.number().int().positive().optional(),\n maxCostUSD: z.number().positive().optional(),\n maxLatencyMs: z.number().positive().optional(),\n});\n\n/**\n * Session budget tracking.\n */\nexport interface SessionBudget {\n /** Total tokens budget for the session */\n readonly totalTokens: number;\n /** Total cost budget in USD */\n readonly totalCostUSD: number;\n /** Tokens used so far */\n usedTokens: number;\n /** Cost spent so far in USD */\n usedCostUSD: number;\n /** Session start time */\n readonly startTime: number;\n /** Session ID */\n readonly sessionId: string;\n}\n\n/**\n * Zod schema for session budget validation.\n */\nexport const SessionBudgetSchema = z.object({\n totalTokens: z.number().int().positive(),\n totalCostUSD: z.number().positive(),\n usedTokens: z.number().int().min(0).default(0),\n usedCostUSD: z.number().min(0).default(0),\n startTime: z.number().int().positive(),\n sessionId: z.string().min(1),\n});\n\n/**\n * Budget exhaustion warning level.\n */\nexport type BudgetWarningLevel = 'none' | 'low' | 'critical' | 'exhausted';\n\n/**\n * Budget status for a session.\n */\nexport interface BudgetStatus {\n /** Remaining tokens */\n readonly remainingTokens: number;\n /** Remaining cost in USD */\n readonly remainingCostUSD: number;\n /** Token utilization percentage (0-100) */\n readonly tokenUtilizationPercent: number;\n /** Cost utilization percentage (0-100) */\n readonly costUtilizationPercent: number;\n /** Warning level */\n readonly warningLevel: BudgetWarningLevel;\n}\n\n/**\n * Cost model for an adapter.\n */\nexport interface AdapterCostModel {\n /** Cost per 1K input tokens in USD */\n readonly inputTokenCost: number;\n /** Cost per 1K output tokens in USD */\n readonly outputTokenCost: number;\n /** Average latency in milliseconds */\n readonly avgLatencyMs: number;\n /** Quality score (0-1) */\n readonly qualityScore: number;\n}\n\n/**\n * Default cost models for known adapters.\n */\nexport const DEFAULT_COST_MODELS: Readonly<Record<string, AdapterCostModel>> = {\n claude: {\n inputTokenCost: 0.015,\n outputTokenCost: 0.075,\n avgLatencyMs: 2000,\n qualityScore: 0.95,\n },\n gemini: {\n inputTokenCost: 0.00125,\n outputTokenCost: 0.005,\n avgLatencyMs: 1500,\n qualityScore: 0.85,\n },\n codex: {\n inputTokenCost: 0.003,\n outputTokenCost: 0.015,\n avgLatencyMs: 1000,\n qualityScore: 0.8,\n },\n opencode: {\n inputTokenCost: 0.003,\n outputTokenCost: 0.012,\n avgLatencyMs: 1500,\n qualityScore: 0.82,\n },\n};\n\n/**\n * LinUCB bandit context for a routing decision.\n * Note: isCodeTask/isReasoningTask use numeric 0/1 for bandit algorithm compatibility.\n */\nexport interface BanditContext {\n /** Task complexity score (0-1) */\n readonly taskComplexity: number;\n /** Required context length normalized (0-1) */\n readonly contextLengthNormalized: number;\n /** Is code generation task (0 or 1) */\n readonly isCodeTask: number;\n /** Is reasoning task (0 to 1, supports fractional values) */\n readonly isReasoningTask: number;\n /** Budget utilization (0-1) */\n readonly budgetUtilization: number;\n /** Time pressure (0-1, higher = more urgent) */\n readonly timePressure: number;\n}\n\n/**\n * LinUCB bandit configuration.\n */\nexport interface LinUCBConfig {\n /** Number of arms (adapters) */\n readonly numArms: number;\n /** Feature dimension */\n readonly featureDim: number;\n /** Exploration parameter (higher = more exploration) */\n readonly alpha: number;\n /** Regularization parameter */\n readonly lambda: number;\n}\n\n/**\n * Default LinUCB configuration.\n */\nexport const DEFAULT_LINUCB_CONFIG: LinUCBConfig = {\n numArms: 4,\n featureDim: 6,\n alpha: 1.0,\n lambda: 1.0,\n};\n\n/**\n * Zod schema for LinUCB config validation.\n */\nexport const LinUCBConfigSchema = z.object({\n numArms: z.number().int().positive().default(4),\n featureDim: z.number().int().positive().default(6),\n alpha: z.number().positive().default(1.0),\n lambda: z.number().positive().default(1.0),\n});\n\n/**\n * Budget routing decision.\n */\nexport interface BudgetRoutingDecision {\n /** Selected adapter name */\n readonly adapterName: string;\n /** Estimated cost for this task */\n readonly estimatedCostUSD: number;\n /** Estimated tokens for this task */\n readonly estimatedTokens: number;\n /** UCB score for selection */\n readonly ucbScore: number;\n /** Confidence in selection (0-1) */\n readonly confidence: number;\n /** Reason for selection */\n readonly reason: string;\n /** Whether budget allows this selection */\n readonly budgetAllowed: boolean;\n}\n\n/**\n * Budget exceeded error details.\n */\nexport interface BudgetExceededDetails {\n /** Type of budget exceeded */\n readonly budgetType: 'tokens' | 'cost' | 'latency';\n /** Requested amount */\n readonly requested: number;\n /** Available amount */\n readonly available: number;\n /** Suggested alternative adapter */\n readonly suggestedAlternative?: string | undefined;\n}\n","/**\n * nexus-agents/cli-adapters - LinUCB Math Utilities\n *\n * Linear algebra and math helper functions for LinUCB bandit.\n *\n * @module cli-adapters/linucb-math\n * (Source: Issue #102)\n */\n\nimport type { BanditContext } from './budget-router-types.js';\n\n/**\n * Create identity matrix of given dimension.\n */\nexport function createIdentityMatrix(dim: number, lambda: number): number[][] {\n const matrix: number[][] = [];\n for (let i = 0; i < dim; i++) {\n const row: number[] = [];\n for (let j = 0; j < dim; j++) {\n row.push(i === j ? lambda : 0);\n }\n matrix.push(row);\n }\n return matrix;\n}\n\n/**\n * Create zero vector of given dimension.\n */\nexport function createZeroVector(dim: number): number[] {\n const vec: number[] = [];\n for (let i = 0; i < dim; i++) {\n vec.push(0);\n }\n return vec;\n}\n\n/**\n * Convert bandit context to feature vector.\n */\nexport function contextToFeatures(context: BanditContext): number[] {\n return [\n context.taskComplexity,\n context.contextLengthNormalized,\n context.isCodeTask,\n context.isReasoningTask,\n context.budgetUtilization,\n context.timePressure,\n ];\n}\n\n/**\n * Matrix-vector multiplication: A * x.\n */\nexport function matVecMul(A: readonly (readonly number[])[], x: readonly number[]): number[] {\n const result: number[] = [];\n for (const row of A) {\n let sum = 0;\n for (let j = 0; j < x.length; j++) {\n const rowVal = row[j];\n const xVal = x[j];\n if (rowVal !== undefined && xVal !== undefined) {\n sum += rowVal * xVal;\n }\n }\n result.push(sum);\n }\n return result;\n}\n\n/**\n * Dot product of two vectors.\n */\nexport function dotProduct(a: readonly number[], b: readonly number[]): number {\n let sum = 0;\n for (let i = 0; i < a.length; i++) {\n const aVal = a[i];\n const bVal = b[i];\n if (aVal !== undefined && bVal !== undefined) {\n sum += aVal * bVal;\n }\n }\n return sum;\n}\n\n/**\n * Outer product: x * x^T.\n */\nexport function outerProduct(x: readonly number[]): number[][] {\n const result: number[][] = [];\n for (let i = 0; i < x.length; i++) {\n const row: number[] = [];\n for (let j = 0; j < x.length; j++) {\n const xi = x[i];\n const xj = x[j];\n row.push(xi !== undefined && xj !== undefined ? xi * xj : 0);\n }\n result.push(row);\n }\n return result;\n}\n\n/**\n * Add two matrices element-wise.\n */\nexport function matrixAdd(\n A: readonly (readonly number[])[],\n B: readonly (readonly number[])[]\n): number[][] {\n const result: number[][] = [];\n for (let i = 0; i < A.length; i++) {\n const row: number[] = [];\n const aRow = A[i];\n const bRow = B[i];\n if (aRow === undefined || bRow === undefined) continue;\n for (let j = 0; j < aRow.length; j++) {\n const aVal = aRow[j];\n const bVal = bRow[j];\n row.push((aVal ?? 0) + (bVal ?? 0));\n }\n result.push(row);\n }\n return result;\n}\n\n/**\n * Add two vectors element-wise.\n */\nexport function vectorAdd(a: readonly number[], b: readonly number[]): number[] {\n const result: number[] = [];\n for (let i = 0; i < a.length; i++) {\n const aVal = a[i];\n const bVal = b[i];\n result.push((aVal ?? 0) + (bVal ?? 0));\n }\n return result;\n}\n\n/**\n * Scale vector by scalar.\n */\nexport function vectorScale(v: readonly number[], s: number): number[] {\n return v.map((x) => x * s);\n}\n\n/**\n * Create augmented matrix [A|I] for Gaussian elimination.\n */\nfunction createAugmentedMatrix(matrix: readonly (readonly number[])[]): number[][] {\n const n = matrix.length;\n const augmented: number[][] = [];\n for (let i = 0; i < n; i++) {\n const matrixRow = matrix[i];\n if (matrixRow === undefined) continue;\n const row: number[] = [...matrixRow];\n for (let j = 0; j < n; j++) {\n row.push(i === j ? 1 : 0);\n }\n augmented.push(row);\n }\n return augmented;\n}\n\n/**\n * Find pivot row with maximum absolute value for column.\n */\nfunction findPivotRow(augmented: number[][], col: number, n: number): number {\n let maxRow = col;\n const augmentedCol = augmented[col];\n if (augmentedCol === undefined) return col;\n\n let maxVal = Math.abs(augmentedCol[col] ?? 0);\n for (let row = col + 1; row < n; row++) {\n const augmentedRow = augmented[row];\n if (augmentedRow === undefined) continue;\n const val = Math.abs(augmentedRow[col] ?? 0);\n if (val > maxVal) {\n maxVal = val;\n maxRow = row;\n }\n }\n return maxRow;\n}\n\n/**\n * Scale a row by dividing by pivot.\n */\nfunction scaleRow(row: number[], pivot: number, width: number): void {\n for (let j = 0; j < width; j++) {\n const val = row[j];\n if (val !== undefined) row[j] = val / pivot;\n }\n}\n\n/**\n * Eliminate column in other rows using pivot row.\n */\nfunction eliminateColumn(augmented: number[][], col: number, pivotRow: number[], n: number): void {\n for (let row = 0; row < n; row++) {\n if (row === col) continue;\n const currentRow = augmented[row];\n if (currentRow === undefined) continue;\n const factor = currentRow[col] ?? 0;\n for (let j = 0; j < 2 * n; j++) {\n const currentVal = currentRow[j];\n const pivotVal = pivotRow[j];\n if (currentVal !== undefined && pivotVal !== undefined) {\n currentRow[j] = currentVal - factor * pivotVal;\n }\n }\n }\n}\n\n/**\n * Perform Gaussian elimination on augmented matrix.\n */\nfunction gaussianElimination(augmented: number[][], n: number): void {\n for (let col = 0; col < n; col++) {\n const maxRow = findPivotRow(augmented, col, n);\n const temp = augmented[col];\n const swapRow = augmented[maxRow];\n if (temp !== undefined && swapRow !== undefined) {\n augmented[col] = swapRow;\n augmented[maxRow] = temp;\n }\n\n const pivotRow = augmented[col];\n if (pivotRow === undefined) continue;\n const pivot = pivotRow[col] ?? 1;\n if (Math.abs(pivot) < 1e-10) continue;\n\n scaleRow(pivotRow, pivot, 2 * n);\n eliminateColumn(augmented, col, pivotRow, n);\n }\n}\n\n/**\n * Simple matrix inverse using Gaussian elimination.\n * For small matrices (6x6), this is sufficient.\n */\nexport function matrixInverse(matrix: readonly (readonly number[])[]): number[][] {\n const n = matrix.length;\n const augmented = createAugmentedMatrix(matrix);\n gaussianElimination(augmented, n);\n\n const result: number[][] = [];\n for (let i = 0; i < n; i++) {\n const augmentedRow = augmented[i];\n result.push(augmentedRow !== undefined ? augmentedRow.slice(n) : createZeroVector(n));\n }\n return result;\n}\n\n/**\n * Sherman-Morrison formula for incremental inverse update.\n *\n * Given A^(-1) and a vector x, computes (A + xx^T)^(-1) in O(d²) time\n * instead of O(d³) for full matrix inversion.\n *\n * Formula: (A + uv^T)^(-1) = A^(-1) - (A^(-1) u v^T A^(-1)) / (1 + v^T A^(-1) u)\n * For our case: u = v = x\n *\n * @param AInv - Current inverse matrix A^(-1)\n * @param x - Vector to add as rank-1 update (xx^T added to A)\n * @returns Updated inverse (A + xx^T)^(-1)\n *\n * (Source: Issue #254, PILOT paper section 3.2)\n */\nexport function shermanMorrisonUpdate(\n AInv: readonly (readonly number[])[],\n x: readonly number[]\n): number[][] {\n // Step 1: Compute AInv * x (O(d²))\n const AInvX = matVecMul(AInv, x);\n\n // Step 2: Compute x^T * AInv * x = dot(x, AInvX) (O(d))\n const xTAInvX = dotProduct(x, AInvX);\n\n // Step 3: Denominator = 1 + x^T * AInv * x\n const denom = 1 + xTAInvX;\n\n // Numerical stability check - if denominator is too small, fallback to identity\n if (Math.abs(denom) < 1e-10) {\n // Return a copy of AInv (no update) to avoid numerical instability\n return AInv.map((row) => [...row]);\n }\n\n // Step 4: Compute (AInv * x) * (AInv * x)^T / denom = outerProduct(AInvX) / denom\n // This is the correction term to subtract from AInv\n const correction = outerProduct(AInvX);\n const scaleFactor = 1 / denom;\n\n // Step 5: AInv_new = AInv - correction / denom\n const result: number[][] = [];\n for (let i = 0; i < AInv.length; i++) {\n const row: number[] = [];\n const aInvRow = AInv[i];\n const corrRow = correction[i];\n if (aInvRow === undefined || corrRow === undefined) continue;\n for (let j = 0; j < aInvRow.length; j++) {\n const aInvVal = aInvRow[j] ?? 0;\n const corrVal = corrRow[j] ?? 0;\n row.push(aInvVal - corrVal * scaleFactor);\n }\n result.push(row);\n }\n return result;\n}\n\n/**\n * Create scaled identity matrix inverse for initialization.\n * For A = λI, A^(-1) = (1/λ)I\n */\nexport function createIdentityMatrixInverse(dim: number, lambda: number): number[][] {\n const invLambda = 1 / lambda;\n const matrix: number[][] = [];\n for (let i = 0; i < dim; i++) {\n const row: number[] = [];\n for (let j = 0; j < dim; j++) {\n row.push(i === j ? invLambda : 0);\n }\n matrix.push(row);\n }\n return matrix;\n}\n","/**\n * nexus-agents/cli-adapters - LinUCB Bandit\n *\n * Linear Upper Confidence Bound bandit for budget-aware model selection.\n * Implements the PILOT pattern for lazy budget allocation.\n *\n * @module cli-adapters/linucb-bandit\n * (Source: Issue #102, arXiv:2401.02987)\n */\n\nimport type { BanditContext, LinUCBConfig } from './budget-router-types.js';\nimport { DEFAULT_LINUCB_CONFIG, LinUCBConfigSchema } from './budget-router-types.js';\nimport type { TaskOutcome } from '../orchestration/outcomes/outcome-types.js';\nimport {\n createIdentityMatrix,\n createIdentityMatrixInverse,\n createZeroVector,\n contextToFeatures,\n matVecMul,\n dotProduct,\n outerProduct,\n matrixAdd,\n vectorAdd,\n vectorScale,\n shermanMorrisonUpdate,\n} from './linucb-math.js';\n\n/** Reward value assigned on successful task completion. */\nconst SUCCESS_REWARD = 0.7;\n\n/** Reward value assigned on task failure. */\nconst FAILURE_REWARD = 0.1;\n\n/**\n * Arm state for LinUCB.\n */\ninterface ArmState {\n /** A matrix: d x d matrix for context covariance */\n A: number[][];\n /** A inverse: cached inverse for O(d²) updates via Sherman-Morrison */\n AInv: number[][];\n /** b vector: d-dimensional reward vector */\n b: number[];\n /** Number of times this arm was pulled */\n pullCount: number;\n /** Cumulative reward */\n cumulativeReward: number;\n}\n\n/**\n * LinUCB bandit for contextual multi-armed bandit problem.\n */\nexport class LinUCBBandit {\n private readonly config: LinUCBConfig;\n private readonly arms: ArmState[];\n private readonly armNames: readonly string[];\n\n constructor(armNames: readonly string[], config?: Partial<LinUCBConfig>) {\n this.armNames = armNames;\n this.config = LinUCBConfigSchema.parse({\n ...DEFAULT_LINUCB_CONFIG,\n numArms: armNames.length,\n ...config,\n });\n\n this.arms = armNames.map(() => ({\n A: createIdentityMatrix(this.config.featureDim, this.config.lambda),\n AInv: createIdentityMatrixInverse(this.config.featureDim, this.config.lambda),\n b: createZeroVector(this.config.featureDim),\n pullCount: 0,\n cumulativeReward: 0,\n }));\n }\n\n /**\n * Select an arm given the context.\n * Returns arm index and UCB score.\n */\n select(context: BanditContext): { armIndex: number; armName: string; ucbScore: number } {\n const features = contextToFeatures(context);\n let bestArm = 0;\n let bestUCB = -Infinity;\n\n for (let i = 0; i < this.arms.length; i++) {\n const arm = this.arms[i];\n if (arm === undefined) continue;\n\n const ucb = this.computeUCB(arm, features);\n if (ucb > bestUCB) {\n bestUCB = ucb;\n bestArm = i;\n }\n }\n\n return {\n armIndex: bestArm,\n armName: this.armNames[bestArm] ?? 'unknown',\n ucbScore: bestUCB,\n };\n }\n\n /**\n * Update arm with observed reward.\n * Uses Sherman-Morrison formula for O(d²) incremental inverse update.\n * (Source: Issue #254, PILOT paper section 3.2)\n */\n update(armIndex: number, context: BanditContext, reward: number): void {\n const arm = this.arms[armIndex];\n if (arm === undefined) return;\n\n const features = contextToFeatures(context);\n const xxT = outerProduct(features);\n const rx = vectorScale(features, reward);\n\n // Update A matrix (kept for reference/debugging)\n arm.A = matrixAdd(arm.A, xxT);\n\n // Update A inverse incrementally using Sherman-Morrison (O(d²) instead of O(d³))\n arm.AInv = shermanMorrisonUpdate(arm.AInv, features);\n\n arm.b = vectorAdd(arm.b, rx);\n arm.pullCount++;\n arm.cumulativeReward += reward;\n }\n\n /**\n * Compute UCB score for an arm given features.\n * Uses cached AInv for O(d²) computation instead of O(d³) matrix inverse.\n */\n private computeUCB(arm: ArmState, features: readonly number[]): number {\n // Use cached inverse (O(d²) matrix-vector multiply instead of O(d³) inversion)\n const theta = matVecMul(arm.AInv, arm.b);\n const expectedReward = dotProduct(theta, features);\n const AInvX = matVecMul(arm.AInv, features);\n const uncertainty = Math.sqrt(dotProduct(features, AInvX));\n return expectedReward + this.config.alpha * uncertainty;\n }\n\n /**\n * Get arm names.\n */\n getArmNames(): readonly string[] {\n return this.armNames;\n }\n\n /**\n * Get statistics for all arms.\n */\n getStats(): ReadonlyArray<{ name: string; pullCount: number; avgReward: number }> {\n return this.arms.map((arm, i) => ({\n name: this.armNames[i] ?? 'unknown',\n pullCount: arm.pullCount,\n avgReward: arm.pullCount > 0 ? arm.cumulativeReward / arm.pullCount : 0,\n }));\n }\n\n /**\n * Get detailed statistics for all arms including learned weights.\n * Useful for debugging and ML observability.\n */\n getDetailedStats(): ReadonlyArray<{\n name: string;\n pullCount: number;\n avgReward: number;\n cumulativeReward: number;\n learnedWeights: readonly number[];\n featureImportance: readonly { feature: string; importance: number }[];\n }> {\n const featureNames = [\n 'taskComplexity',\n 'contextLength',\n 'isCodeTask',\n 'isReasoningTask',\n 'budgetUtilization',\n 'timePressure',\n ];\n\n return this.arms.map((arm, i) => {\n // Use cached inverse (O(d²) instead of O(d³))\n const theta = matVecMul(arm.AInv, arm.b);\n const absWeights = theta.map(Math.abs);\n const totalWeight = absWeights.reduce((a, b) => a + b, 0) || 1;\n\n const featureImportance = featureNames.map((feature, idx) => ({\n feature,\n importance: (absWeights[idx] ?? 0) / totalWeight,\n }));\n\n featureImportance.sort((a, b) => b.importance - a.importance);\n\n return {\n name: this.armNames[i] ?? 'unknown',\n pullCount: arm.pullCount,\n avgReward: arm.pullCount > 0 ? arm.cumulativeReward / arm.pullCount : 0,\n cumulativeReward: arm.cumulativeReward,\n learnedWeights: theta,\n featureImportance,\n };\n });\n }\n\n /**\n * Get exploration statistics.\n */\n getExplorationStats(): {\n totalPulls: number;\n explorationRatio: number;\n armDistribution: ReadonlyArray<{ name: string; proportion: number }>;\n } {\n const stats = this.getStats();\n const totalPulls = stats.reduce((sum, s) => sum + s.pullCount, 0);\n\n const armDistribution = stats.map((s) => ({\n name: s.name,\n proportion: totalPulls > 0 ? s.pullCount / totalPulls : 1 / stats.length,\n }));\n\n // Exploration ratio: how evenly distributed pulls are (1 = perfectly even)\n const evenProportion = 1 / stats.length;\n const deviation = armDistribution.reduce(\n (sum, d) => sum + Math.abs(d.proportion - evenProportion),\n 0\n );\n const maxDeviation = 2 * (1 - evenProportion);\n const explorationRatio = maxDeviation > 0 ? 1 - deviation / maxDeviation : 1;\n\n return { totalPulls, explorationRatio, armDistribution };\n }\n\n /**\n * Seed priors for cold-start improvement (Epic #952, Phase 6).\n *\n * Simulates `observationCount` synthetic observations per arm using\n * a neutral context and the provided reward hint. This gives arms\n * a head start based on known quality signals while still allowing\n * LinUCB exploration to override the seeded priors.\n *\n * @param priors - Map of arm name to initial reward hint (0-1)\n * @param observationCount - Number of synthetic observations (default: 5, max: 20)\n */\n seedPriors(priors: ReadonlyMap<string, number>, observationCount = 5): void {\n const count = Math.min(observationCount, 20);\n const neutralContext: BanditContext = {\n taskComplexity: 0.5,\n contextLengthNormalized: 0.5,\n isCodeTask: 0,\n isReasoningTask: 0,\n budgetUtilization: 0.5,\n timePressure: 0.5,\n };\n\n for (let i = 0; i < this.armNames.length; i++) {\n const armName = this.armNames[i];\n if (armName === undefined) continue;\n const reward = priors.get(armName);\n if (reward === undefined) continue;\n const clampedReward = Math.max(0, Math.min(1, reward));\n for (let j = 0; j < count; j++) {\n this.update(i, neutralContext, clampedReward);\n }\n }\n }\n\n /**\n * Warm-start bandit from persisted task outcomes (Issue #1015).\n *\n * Replays historical outcomes through update() to reconstruct arm weights\n * from persisted data. Uses a neutral context (same as seedPriors) since\n * the original task context is not stored in TaskOutcome.\n *\n * @param outcomes - Persisted task outcomes to replay\n * @returns Number of outcomes successfully replayed\n */\n warmStart(outcomes: readonly TaskOutcome[]): number {\n const neutralContext: BanditContext = {\n taskComplexity: 0.5,\n contextLengthNormalized: 0.5,\n isCodeTask: 0,\n isReasoningTask: 0,\n budgetUtilization: 0.5,\n timePressure: 0.5,\n };\n\n let replayed = 0;\n for (const outcome of outcomes) {\n const armIndex = this.armNames.indexOf(outcome.cli);\n if (armIndex < 0) continue;\n const reward = outcome.success ? SUCCESS_REWARD : FAILURE_REWARD;\n this.update(armIndex, neutralContext, reward);\n replayed++;\n }\n return replayed;\n }\n\n /**\n * Reset all arm statistics.\n */\n reset(): void {\n for (const arm of this.arms) {\n arm.A = createIdentityMatrix(this.config.featureDim, this.config.lambda);\n arm.AInv = createIdentityMatrixInverse(this.config.featureDim, this.config.lambda);\n arm.b = createZeroVector(this.config.featureDim);\n arm.pullCount = 0;\n arm.cumulativeReward = 0;\n }\n }\n}\n\n/**\n * Create a LinUCB bandit instance.\n */\nexport function createLinUCBBandit(\n armNames: readonly string[],\n config?: Partial<LinUCBConfig>\n): LinUCBBandit {\n return new LinUCBBandit(armNames, config);\n}\n","/**\n * nexus-agents/cli-adapters - Preference Router Implementation\n *\n * Implements preference-trained routing (RouteLLM pattern) that learns\n * from human preference data to route queries optimally.\n *\n * @module cli-adapters/preference-router\n * (Source: Issue #148, arXiv:2406.18665)\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { createLogger, getTimeProvider } from '../core/index.js';\nimport type {\n PreferenceDataPoint,\n QueryFeatures,\n PreferencePrediction,\n PreferenceRoutingDecision,\n PreferenceRouterConfig,\n PreferenceModelStats,\n IPreferenceDataStore,\n} from './preference-router-types.js';\nimport {\n DEFAULT_PREFERENCE_ROUTER_CONFIG,\n PreferenceRouterConfigSchema,\n} from './preference-router-types.js';\nimport { InMemoryPreferenceStore } from './preference-router-store.js';\nimport { QueryFeatureExtractor } from './preference-router-extractor.js';\n\n// Re-export types and classes for backward compatibility\nexport type {\n PreferenceDataPoint,\n QueryFeatures,\n PreferencePrediction,\n PreferenceRoutingDecision,\n PreferenceRouterConfig,\n PreferenceModelStats,\n IPreferenceDataStore,\n} from './preference-router-types.js';\nexport { DEFAULT_PREFERENCE_ROUTER_CONFIG } from './preference-router-types.js';\nexport { InMemoryPreferenceStore } from './preference-router-store.js';\nexport { QueryFeatureExtractor } from './preference-router-extractor.js';\n\nconst logger = createLogger({ component: 'PreferenceRouter' });\n\n/**\n * Preference-trained router that learns from human preference data.\n */\nexport class PreferenceRouter {\n private readonly config: PreferenceRouterConfig;\n private readonly dataStore: IPreferenceDataStore;\n private readonly featureExtractor: QueryFeatureExtractor;\n\n constructor(config: Partial<PreferenceRouterConfig> = {}, dataStore?: IPreferenceDataStore) {\n const validated = PreferenceRouterConfigSchema.parse({\n ...DEFAULT_PREFERENCE_ROUTER_CONFIG,\n ...config,\n });\n this.config = validated;\n this.dataStore = dataStore ?? new InMemoryPreferenceStore(validated.maxDataPoints);\n this.featureExtractor = new QueryFeatureExtractor();\n\n logger.info('PreferenceRouter initialized', {\n strongModel: this.config.strongModel.cli,\n weakModel: this.config.weakModel.cli,\n threshold: this.config.routingThreshold,\n });\n }\n\n /**\n * Route a query to the optimal model based on learned preferences.\n */\n route(query: string): PreferenceRoutingDecision {\n const startTime = getTimeProvider().now();\n const features = this.featureExtractor.extract(query);\n const prediction = this.predict(features);\n\n const threshold = this.getDomainThreshold(features.domain);\n const useStrong = prediction.strongModelProbability >= threshold;\n\n const selectedTier = useStrong ? 'strong' : 'weak';\n const selectedConfig = useStrong ? this.config.strongModel : this.config.weakModel;\n\n const costSavings = useStrong ? 0 : this.calculateCostSavings();\n\n const decision: PreferenceRoutingDecision = {\n selectedTier,\n selectedCli: selectedConfig.cli,\n prediction,\n reason: this.generateReason(prediction, threshold, useStrong),\n routingLatencyMs: getTimeProvider().now() - startTime,\n estimatedCostSavings: costSavings,\n };\n\n logger.debug('Routing decision made', {\n tier: selectedTier,\n cli: selectedConfig.cli,\n probability: prediction.strongModelProbability,\n confidence: prediction.confidence,\n });\n\n return decision;\n }\n\n /**\n * Record a preference data point for online learning.\n */\n recordPreference(\n query: string,\n strongModelPreferred: boolean,\n strongModelQuality?: number,\n weakModelQuality?: number\n ): PreferenceDataPoint {\n const features = this.featureExtractor.extract(query);\n\n const dataPoint: PreferenceDataPoint = {\n id: randomUUID(),\n query,\n features,\n strongModelPreferred,\n strongModelQuality,\n weakModelQuality,\n recordedAt: new Date(getTimeProvider().now()),\n domain: features.domain,\n };\n\n if (this.config.enableOnlineLearning) {\n this.dataStore.store(dataPoint);\n logger.debug('Preference recorded', {\n strongPreferred: strongModelPreferred,\n domain: features.domain,\n });\n }\n\n return dataPoint;\n }\n\n /**\n * Get statistics about the learned preference model.\n */\n getStats(): PreferenceModelStats {\n return this.dataStore.getStats();\n }\n\n /**\n * Check if the router has enough data to make informed decisions.\n */\n hasMinimumData(): boolean {\n return this.dataStore.getAll().length >= this.config.minDataPoints;\n }\n\n private predict(features: QueryFeatures): PreferencePrediction {\n const similarPoints = this.dataStore.findSimilar(features, 20);\n\n if (similarPoints.length === 0) {\n // No data - use heuristic based on complexity\n return this.heuristicPrediction(features);\n }\n\n // Calculate weighted preference rate\n let weightedSum = 0;\n let totalWeight = 0;\n\n for (let i = 0; i < similarPoints.length; i++) {\n const point = similarPoints[i];\n if (point === undefined) continue;\n\n // Weight by position (more similar = higher weight)\n const weight = 1 / (i + 1);\n weightedSum += point.strongModelPreferred ? weight : 0;\n totalWeight += weight;\n }\n\n const probability = totalWeight > 0 ? weightedSum / totalWeight : 0.5;\n\n // Confidence based on number of similar points and data density\n const dataConfidence = Math.min(1, similarPoints.length / 10);\n const complexityConfidence = features.complexity > 0.5 ? 0.8 : 0.6;\n const confidence = (dataConfidence + complexityConfidence) / 2;\n\n return {\n strongModelProbability: probability,\n confidence,\n features,\n supportingDataPoints: similarPoints.length,\n };\n }\n\n private heuristicPrediction(features: QueryFeatures): PreferencePrediction {\n // Heuristic: Use strong model for complex, reasoning, or coding tasks\n let probability = 0.5;\n\n if (features.complexity > 0.7) probability += 0.2;\n if (features.requiresReasoning) probability += 0.15;\n if (features.requiresCode) probability += 0.1;\n if (features.hasAmbiguity) probability += 0.1;\n if (features.requiresCreativity) probability += 0.05;\n\n probability = Math.min(1, probability);\n\n return {\n strongModelProbability: probability,\n confidence: 0.3, // Low confidence for heuristic predictions\n features,\n supportingDataPoints: 0,\n };\n }\n\n private getDomainThreshold(domain: string): number {\n return this.config.domainThresholds?.[domain] ?? this.config.routingThreshold;\n }\n\n private calculateCostSavings(): number {\n const strongCost = this.config.strongModel.costPerMillionTokens;\n const weakCost = this.config.weakModel.costPerMillionTokens;\n return (strongCost - weakCost) / strongCost;\n }\n\n private generateReason(\n prediction: PreferencePrediction,\n threshold: number,\n useStrong: boolean\n ): string {\n const { features, confidence, supportingDataPoints } = prediction;\n\n if (supportingDataPoints === 0) {\n return useStrong\n ? `Heuristic: High complexity (${features.complexity.toFixed(2)}) suggests strong model needed`\n : `Heuristic: Low complexity (${features.complexity.toFixed(2)}) allows weak model usage`;\n }\n\n const dataSource = `Based on ${String(supportingDataPoints)} similar queries`;\n const confidenceNote = confidence > 0.7 ? 'high confidence' : 'moderate confidence';\n\n return useStrong\n ? `${dataSource} (${confidenceNote}): Strong model preferred for ${features.domain} tasks`\n : `${dataSource} (${confidenceNote}): Weak model sufficient for ${features.domain} tasks`;\n }\n}\n\n/**\n * Create a PreferenceRouter instance.\n */\nexport function createPreferenceRouter(\n config?: Partial<PreferenceRouterConfig>,\n dataStore?: IPreferenceDataStore\n): PreferenceRouter {\n return new PreferenceRouter(config, dataStore);\n}\n","/**\n * nexus-agents/cli-adapters - Preference Router Types\n *\n * Type definitions for preference-trained routing (RouteLLM pattern).\n * Uses human preference data to learn routing decisions.\n *\n * @module cli-adapters/preference-router-types\n * (Source: Issue #148, arXiv:2406.18665)\n */\n\nimport { z } from 'zod';\nimport type { CliName } from './types.js';\n\n/**\n * A single preference data point comparing model outputs.\n */\nexport interface PreferenceDataPoint {\n /** Unique identifier */\n readonly id: string;\n /** The input query */\n readonly query: string;\n /** Extracted query features */\n readonly features: QueryFeatures;\n /** Whether the strong model was preferred */\n readonly strongModelPreferred: boolean;\n /** Optional: actual strong model response quality score */\n readonly strongModelQuality?: number | undefined;\n /** Optional: actual weak model response quality score */\n readonly weakModelQuality?: number | undefined;\n /** When this preference was recorded */\n readonly recordedAt: Date;\n /** Domain or task category */\n readonly domain?: string | undefined;\n}\n\n/**\n * Features extracted from a query for preference prediction.\n */\nexport interface QueryFeatures {\n /** Query length in tokens (estimated) */\n readonly tokenCount: number;\n /** Complexity score (0-1) */\n readonly complexity: number;\n /** Whether query requires reasoning */\n readonly requiresReasoning: boolean;\n /** Whether query requires code generation */\n readonly requiresCode: boolean;\n /** Whether query requires creativity */\n readonly requiresCreativity: boolean;\n /** Whether query has ambiguity */\n readonly hasAmbiguity: boolean;\n /** Domain category */\n readonly domain: string;\n /** Keywords present (hashed for privacy) */\n readonly keywordSignature: string;\n}\n\n/**\n * Result of a preference prediction.\n */\nexport interface PreferencePrediction {\n /** Probability that strong model is significantly better */\n readonly strongModelProbability: number;\n /** Confidence in this prediction (0-1) */\n readonly confidence: number;\n /** Features used for prediction */\n readonly features: QueryFeatures;\n /** Number of similar data points used */\n readonly supportingDataPoints: number;\n}\n\n/**\n * Routing decision based on preference prediction.\n */\nexport interface PreferenceRoutingDecision {\n /** Selected model tier */\n readonly selectedTier: 'strong' | 'weak';\n /** Selected adapter */\n readonly selectedCli: CliName;\n /** Preference prediction details */\n readonly prediction: PreferencePrediction;\n /** Reason for selection */\n readonly reason: string;\n /** Routing decision time in ms */\n readonly routingLatencyMs: number;\n /** Cost savings compared to always using strong model */\n readonly estimatedCostSavings: number;\n}\n\n/**\n * Model tier configuration.\n */\nexport interface ModelTier {\n /** Tier name */\n readonly tier: 'strong' | 'weak';\n /** CLI adapter name */\n readonly cli: CliName;\n /** Cost per 1M tokens (input + output averaged) */\n readonly costPerMillionTokens: number;\n /** Quality baseline (0-1) */\n readonly qualityBaseline: number;\n}\n\n/**\n * Preference router configuration.\n */\nexport interface PreferenceRouterConfig {\n /** Strong model configuration */\n readonly strongModel: ModelTier;\n /** Weak model configuration */\n readonly weakModel: ModelTier;\n /** Threshold for routing to strong model (0-1) */\n readonly routingThreshold: number;\n /** Minimum data points before using learned routing */\n readonly minDataPoints: number;\n /** Maximum data points to store */\n readonly maxDataPoints: number;\n /** Whether to enable online learning */\n readonly enableOnlineLearning: boolean;\n /** Domain-specific threshold overrides */\n readonly domainThresholds?: Record<string, number> | undefined;\n}\n\n/**\n * Default preference router configuration.\n */\nexport const DEFAULT_PREFERENCE_ROUTER_CONFIG: PreferenceRouterConfig = {\n strongModel: {\n tier: 'strong',\n cli: 'claude',\n costPerMillionTokens: 9.0, // Average of input (3) + output (15)\n qualityBaseline: 0.95,\n },\n weakModel: {\n tier: 'weak',\n cli: 'gemini',\n costPerMillionTokens: 0.1875, // Average of input (0.075) + output (0.3)\n qualityBaseline: 0.75,\n },\n routingThreshold: 0.5,\n minDataPoints: 10,\n maxDataPoints: 10000,\n enableOnlineLearning: true,\n};\n\n/**\n * Zod schema for config validation.\n */\nexport const PreferenceRouterConfigSchema = z.object({\n strongModel: z.object({\n tier: z.literal('strong'),\n cli: z.enum(['claude', 'gemini', 'codex', 'opencode']),\n costPerMillionTokens: z.number().positive(),\n qualityBaseline: z.number().min(0).max(1),\n }),\n weakModel: z.object({\n tier: z.literal('weak'),\n cli: z.enum(['claude', 'gemini', 'codex', 'opencode']),\n costPerMillionTokens: z.number().positive(),\n qualityBaseline: z.number().min(0).max(1),\n }),\n routingThreshold: z.number().min(0).max(1).default(0.5),\n minDataPoints: z.number().int().positive().default(10),\n maxDataPoints: z.number().int().positive().default(10000),\n enableOnlineLearning: z.boolean().default(true),\n domainThresholds: z.record(z.string(), z.number().min(0).max(1)).optional(),\n});\n\n/**\n * Statistics about the preference router's learned model.\n */\nexport interface PreferenceModelStats {\n /** Total data points collected */\n readonly totalDataPoints: number;\n /** Data points by domain */\n readonly dataPointsByDomain: Record<string, number>;\n /** Average strong model preference rate */\n readonly strongModelPreferenceRate: number;\n /** Routing accuracy (if validation data available) */\n readonly routingAccuracy?: number;\n /** Estimated cost savings rate */\n readonly estimatedCostSavingsRate: number;\n /** Last updated timestamp */\n readonly lastUpdatedAt: Date;\n}\n\n/**\n * Interface for the preference data store.\n */\nexport interface IPreferenceDataStore {\n /** Store a new preference data point */\n store(dataPoint: PreferenceDataPoint): void;\n /** Get all data points */\n getAll(): readonly PreferenceDataPoint[];\n /** Get data points by domain */\n getByDomain(domain: string): readonly PreferenceDataPoint[];\n /** Find similar data points based on features */\n findSimilar(features: QueryFeatures, limit: number): readonly PreferenceDataPoint[];\n /** Get statistics */\n getStats(): PreferenceModelStats;\n /** Clear all data */\n clear(): void;\n}\n","/**\n * Preference Router Data Store\n *\n * In-memory storage for preference data points used by the PreferenceRouter.\n *\n * @module cli-adapters/preference-router-store\n * (Source: Issue #148, arXiv:2406.18665)\n */\n\nimport { getTimeProvider } from '../core/index.js';\nimport type {\n PreferenceDataPoint,\n QueryFeatures,\n PreferenceModelStats,\n IPreferenceDataStore,\n} from './preference-router-types.js';\n\n/**\n * In-memory preference data store implementation.\n */\nexport class InMemoryPreferenceStore implements IPreferenceDataStore {\n private readonly dataPoints: Map<string, PreferenceDataPoint> = new Map();\n private readonly maxSize: number;\n\n constructor(maxSize = 10000) {\n this.maxSize = maxSize;\n }\n\n store(dataPoint: PreferenceDataPoint): void {\n this.enforceLimit();\n this.dataPoints.set(dataPoint.id, dataPoint);\n }\n\n getAll(): readonly PreferenceDataPoint[] {\n return [...this.dataPoints.values()];\n }\n\n getByDomain(domain: string): readonly PreferenceDataPoint[] {\n const results: PreferenceDataPoint[] = [];\n for (const dp of this.dataPoints.values()) {\n if (dp.domain === domain) {\n results.push(dp);\n }\n }\n return results;\n }\n\n findSimilar(features: QueryFeatures, limit: number): readonly PreferenceDataPoint[] {\n const scored: Array<{ point: PreferenceDataPoint; similarity: number }> = [];\n\n for (const point of this.dataPoints.values()) {\n const similarity = this.calculateSimilarity(features, point.features);\n scored.push({ point, similarity });\n }\n\n return scored\n .sort((a, b) => b.similarity - a.similarity)\n .slice(0, limit)\n .map((s) => s.point);\n }\n\n getStats(): PreferenceModelStats {\n const domainCounts: Record<string, number> = {};\n let strongPreferred = 0;\n\n for (const point of this.dataPoints.values()) {\n const domain = point.domain ?? 'unknown';\n domainCounts[domain] = (domainCounts[domain] ?? 0) + 1;\n if (point.strongModelPreferred) {\n strongPreferred++;\n }\n }\n\n const total = this.dataPoints.size;\n return {\n totalDataPoints: total,\n dataPointsByDomain: domainCounts,\n strongModelPreferenceRate: total > 0 ? strongPreferred / total : 0,\n estimatedCostSavingsRate: total > 0 ? 1 - strongPreferred / total : 0,\n lastUpdatedAt: new Date(getTimeProvider().now()),\n };\n }\n\n clear(): void {\n this.dataPoints.clear();\n }\n\n private calculateSimilarity(a: QueryFeatures, b: QueryFeatures): number {\n let score = 0;\n const maxScore = 7;\n\n // Token count similarity (normalized)\n const tokenDiff = Math.abs(a.tokenCount - b.tokenCount);\n score += Math.max(0, 1 - tokenDiff / 1000);\n\n // Complexity similarity\n score += 1 - Math.abs(a.complexity - b.complexity);\n\n // Boolean feature matches\n if (a.requiresReasoning === b.requiresReasoning) score += 1;\n if (a.requiresCode === b.requiresCode) score += 1;\n if (a.requiresCreativity === b.requiresCreativity) score += 1;\n if (a.hasAmbiguity === b.hasAmbiguity) score += 1;\n\n // Domain match\n if (a.domain === b.domain) score += 1;\n\n return score / maxScore;\n }\n\n private enforceLimit(): void {\n if (this.dataPoints.size >= this.maxSize) {\n const oldest = [...this.dataPoints.entries()]\n .sort((a, b) => a[1].recordedAt.getTime() - b[1].recordedAt.getTime())\n .slice(0, Math.floor(this.maxSize * 0.1));\n\n for (const [id] of oldest) {\n this.dataPoints.delete(id);\n }\n }\n }\n}\n","/**\n * Preference Router Feature Extractor\n *\n * Extracts query features for preference-based routing decisions.\n *\n * @module cli-adapters/preference-router-extractor\n * (Source: Issue #148, arXiv:2406.18665)\n */\n\nimport { createHash } from 'node:crypto';\nimport type { QueryFeatures } from './preference-router-types.js';\n\n// =============================================================================\n// KEYWORDS\n// =============================================================================\n\nconst CODE_KEYWORDS = [\n 'function',\n 'class',\n 'import',\n 'export',\n 'const',\n 'let',\n 'var',\n 'implement',\n 'refactor',\n 'debug',\n 'compile',\n 'test',\n 'typescript',\n 'javascript',\n 'python',\n 'code',\n];\n\nconst REASONING_KEYWORDS = [\n 'analyze',\n 'compare',\n 'evaluate',\n 'why',\n 'how',\n 'explain',\n 'reason',\n 'logic',\n 'prove',\n 'deduce',\n 'infer',\n];\n\nconst CREATIVITY_KEYWORDS = [\n 'create',\n 'design',\n 'imagine',\n 'brainstorm',\n 'innovative',\n 'creative',\n 'story',\n 'write',\n 'compose',\n];\n\nconst AMBIGUITY_INDICATORS = [\n 'maybe',\n 'might',\n 'could',\n 'or',\n 'possibly',\n 'uncertain',\n 'unclear',\n 'depends',\n];\n\n// =============================================================================\n// FEATURE EXTRACTOR\n// =============================================================================\n\n/**\n * Feature extractor for queries.\n */\nexport class QueryFeatureExtractor {\n extract(query: string): QueryFeatures {\n const lowerQuery = query.toLowerCase();\n const words = lowerQuery.split(/\\s+/);\n const tokenCount = this.estimateTokens(query);\n\n return {\n tokenCount,\n complexity: this.calculateComplexity(query, words),\n requiresReasoning: this.hasKeywords(words, REASONING_KEYWORDS),\n requiresCode: this.hasKeywords(words, CODE_KEYWORDS),\n requiresCreativity: this.hasKeywords(words, CREATIVITY_KEYWORDS),\n hasAmbiguity: this.hasKeywords(words, AMBIGUITY_INDICATORS),\n domain: this.detectDomain(words),\n keywordSignature: this.generateKeywordSignature(words),\n };\n }\n\n private estimateTokens(text: string): number {\n // Rough estimate: ~4 chars per token on average\n return Math.ceil(text.length / 4);\n }\n\n private calculateComplexity(query: string, words: string[]): number {\n let complexity = 0;\n\n // Length factor (0-0.3)\n complexity += Math.min(0.3, words.length / 100);\n\n // Sentence structure (0-0.2)\n const sentences = query.split(/[.!?]+/).filter(Boolean);\n complexity += Math.min(0.2, sentences.length / 10);\n\n // Technical terms (0-0.3)\n const technicalCount =\n this.countKeywords(words, CODE_KEYWORDS) + this.countKeywords(words, REASONING_KEYWORDS);\n complexity += Math.min(0.3, technicalCount / 20);\n\n // Question depth (0-0.2)\n const questionWords = words.filter((w) =>\n ['what', 'why', 'how', 'when', 'where', 'which'].includes(w)\n );\n complexity += Math.min(0.2, questionWords.length / 5);\n\n return Math.min(1, complexity);\n }\n\n private hasKeywords(words: string[], keywords: string[]): boolean {\n return words.some((w) => keywords.includes(w));\n }\n\n private countKeywords(words: string[], keywords: string[]): number {\n return words.filter((w) => keywords.includes(w)).length;\n }\n\n private detectDomain(words: string[]): string {\n const domainScores: Record<string, number> = {\n coding: this.countKeywords(words, CODE_KEYWORDS),\n reasoning: this.countKeywords(words, REASONING_KEYWORDS),\n creative: this.countKeywords(words, CREATIVITY_KEYWORDS),\n };\n\n let maxDomain = 'general';\n let maxScore = 0;\n\n for (const [domain, score] of Object.entries(domainScores)) {\n if (score > maxScore) {\n maxScore = score;\n maxDomain = domain;\n }\n }\n\n return maxDomain;\n }\n\n private generateKeywordSignature(words: string[]): string {\n const allKeywords = [...CODE_KEYWORDS, ...REASONING_KEYWORDS, ...CREATIVITY_KEYWORDS];\n\n const presentKeywords = words.filter((w) => allKeywords.includes(w)).sort();\n\n return createHash('sha256').update(presentKeywords.join(',')).digest('hex').slice(0, 16);\n }\n}\n","/**\n * nexus-agents/cli-adapters - ZeroRouter Types\n *\n * Type definitions for the ZeroRouter universal difficulty space routing.\n * ZeroRouter creates a unified difficulty metric across diverse task types,\n * enabling better model selection across domains.\n *\n * @module cli-adapters/zero-router-types\n * (Source: Issue #338)\n */\n\nimport { z } from 'zod';\nimport type { CliName } from './types-core.js';\n\n/**\n * Difficulty dimensions for task analysis.\n * Each dimension represents a different aspect of task difficulty.\n */\nexport const DifficultyDimensionSchema = z.enum([\n 'reasoning',\n 'knowledge',\n 'creativity',\n 'precision',\n 'context_length',\n]);\n\nexport type DifficultyDimension = z.infer<typeof DifficultyDimensionSchema>;\n\n/**\n * All difficulty dimensions for iteration.\n */\nexport const DIFFICULTY_DIMENSIONS: readonly DifficultyDimension[] = [\n 'reasoning',\n 'knowledge',\n 'creativity',\n 'precision',\n 'context_length',\n] as const;\n\n/**\n * Difficulty space representation (normalized 0-1 across all dimensions).\n */\nexport const DifficultySpaceSchema = z.object({\n /** Reasoning difficulty: logical complexity, multi-step inference (0-1) */\n reasoning: z.number().min(0).max(1),\n /** Knowledge difficulty: domain expertise required (0-1) */\n knowledge: z.number().min(0).max(1),\n /** Creativity difficulty: novel generation, open-endedness (0-1) */\n creativity: z.number().min(0).max(1),\n /** Precision difficulty: accuracy requirements, error tolerance (0-1) */\n precision: z.number().min(0).max(1),\n /** Context length difficulty: amount of context to process (0-1) */\n context_length: z.number().min(0).max(1),\n});\n\nexport type DifficultySpace = z.infer<typeof DifficultySpaceSchema>;\n\n/**\n * Difficulty level classification based on aggregate score.\n */\nexport type DifficultyLevel = 'easy' | 'medium' | 'hard';\n\n/**\n * Threshold configuration type.\n */\nexport interface DifficultyThresholds {\n readonly easyUpperBound: number;\n readonly hardLowerBound: number;\n}\n\n/**\n * Default difficulty thresholds for classification.\n * - easy: aggregate difficulty < 0.3\n * - medium: aggregate difficulty 0.3 - 0.7\n * - hard: aggregate difficulty > 0.7\n */\nexport const DEFAULT_DIFFICULTY_THRESHOLDS: DifficultyThresholds = {\n easyUpperBound: 0.3,\n hardLowerBound: 0.7,\n};\n\n/**\n * Model tier based on capability/cost trade-off.\n */\nexport type ModelTier = 'fast' | 'balanced' | 'powerful';\n\n/**\n * Mapping from difficulty level to recommended model tier.\n */\nexport const DEFAULT_DIFFICULTY_TO_TIER: Record<DifficultyLevel, ModelTier> = {\n easy: 'fast',\n medium: 'balanced',\n hard: 'powerful',\n} as const;\n\n/**\n * Mapping from model tier to CLI preference order.\n */\nexport const DEFAULT_TIER_TO_CLIS: Record<ModelTier, CliName[]> = {\n fast: ['gemini', 'codex', 'opencode', 'claude'],\n balanced: ['codex', 'opencode', 'gemini', 'claude'],\n powerful: ['claude', 'codex', 'opencode', 'gemini'],\n};\n\n/**\n * Weight configuration for difficulty aggregation.\n */\nexport const DifficultyWeightsSchema = z.object({\n reasoning: z.number().min(0).max(1),\n knowledge: z.number().min(0).max(1),\n creativity: z.number().min(0).max(1),\n precision: z.number().min(0).max(1),\n context_length: z.number().min(0).max(1),\n});\n\nexport type DifficultyWeights = z.infer<typeof DifficultyWeightsSchema>;\n\n/**\n * Default weights for difficulty aggregation.\n * Reasoning and precision weighted higher as they most impact model selection.\n */\nexport const DEFAULT_DIFFICULTY_WEIGHTS: DifficultyWeights = {\n reasoning: 0.3,\n knowledge: 0.15,\n creativity: 0.15,\n precision: 0.25,\n context_length: 0.15,\n} as const;\n\n/**\n * Result of difficulty estimation.\n */\nexport interface DifficultyEstimate {\n /** Difficulty values per dimension (all 0-1) */\n readonly dimensions: DifficultySpace;\n /** Aggregated difficulty score (0-1) */\n readonly aggregateScore: number;\n /** Classified difficulty level */\n readonly level: DifficultyLevel;\n /** Recommended model tier based on difficulty */\n readonly recommendedTier: ModelTier;\n /** Confidence in the estimate (0-1) */\n readonly confidence: number;\n /** Dominant difficulty dimension */\n readonly dominantDimension: DifficultyDimension;\n}\n\n/**\n * Outcome record for calibration.\n */\nexport interface DifficultyOutcome {\n /** Task content hash (for deduplication) */\n readonly taskHash: string;\n /** Estimated difficulty at routing time */\n readonly estimatedDifficulty: number;\n /** CLI that was selected */\n readonly selectedCli: CliName;\n /** Whether the task succeeded */\n readonly success: boolean;\n /** Quality score if available (0-1) */\n readonly qualityScore?: number;\n /** Actual execution time in ms */\n readonly executionTimeMs?: number;\n /** Timestamp of the outcome */\n readonly timestamp: number;\n}\n\n/**\n * Calibration statistics for self-improvement.\n */\nexport interface CalibrationStats {\n /** Total outcomes recorded */\n readonly totalOutcomes: number;\n /** Mean absolute error of difficulty estimates */\n readonly meanAbsoluteError: number;\n /** Correlation between estimated difficulty and actual success rate */\n readonly difficultySuccessCorrelation: number;\n /** Success rate by difficulty level */\n readonly successRateByLevel: Readonly<Record<DifficultyLevel, number>>;\n /** Average quality score by difficulty level */\n readonly avgQualityByLevel: Readonly<Record<DifficultyLevel, number>>;\n /** Calibration bias (-1 to 1, negative = underestimating difficulty) */\n readonly calibrationBias: number;\n}\n\n/**\n * Configuration for ZeroRouter.\n */\nexport const ZeroRouterConfigSchema = z.object({\n /** Difficulty thresholds for level classification */\n thresholds: z\n .object({\n easyUpperBound: z.number().min(0).max(1),\n hardLowerBound: z.number().min(0).max(1),\n })\n .default(DEFAULT_DIFFICULTY_THRESHOLDS),\n /** Weights for difficulty aggregation */\n weights: DifficultyWeightsSchema.default(DEFAULT_DIFFICULTY_WEIGHTS),\n /** Mapping from difficulty level to model tier */\n difficultyToTier: z\n .record(z.enum(['easy', 'medium', 'hard']), z.enum(['fast', 'balanced', 'powerful']))\n .default(DEFAULT_DIFFICULTY_TO_TIER),\n /** Mapping from model tier to CLI preference order */\n tierToClis: z\n .record(\n z.enum(['fast', 'balanced', 'powerful']),\n z.array(z.enum(['claude', 'gemini', 'codex', 'opencode']))\n )\n .default(DEFAULT_TIER_TO_CLIS),\n /** Enable adaptive calibration from outcomes */\n enableCalibration: z.boolean().default(true),\n /** Maximum outcomes to store for calibration */\n maxCalibrationOutcomes: z.number().int().positive().default(1000),\n /** Minimum outcomes before applying calibration adjustments */\n minCalibrationOutcomes: z.number().int().positive().default(50),\n /** Verbose logging */\n verbose: z.boolean().default(false),\n});\n\nexport type ZeroRouterConfig = z.infer<typeof ZeroRouterConfigSchema>;\n\n/**\n * Default ZeroRouter configuration.\n */\nexport const DEFAULT_ZERO_ROUTER_CONFIG: ZeroRouterConfig = {\n thresholds: DEFAULT_DIFFICULTY_THRESHOLDS,\n weights: DEFAULT_DIFFICULTY_WEIGHTS,\n difficultyToTier: DEFAULT_DIFFICULTY_TO_TIER,\n tierToClis: DEFAULT_TIER_TO_CLIS,\n enableCalibration: true,\n maxCalibrationOutcomes: 1000,\n minCalibrationOutcomes: 50,\n verbose: false,\n};\n\n/**\n * Routing decision from ZeroRouter.\n */\nexport interface ZeroRoutingDecision {\n /** Estimated difficulty */\n readonly difficulty: DifficultyEstimate;\n /** Selected CLI based on difficulty */\n readonly selectedCli: CliName;\n /** Recommended model tier */\n readonly tier: ModelTier;\n /** Alternative CLIs in preference order */\n readonly alternatives: readonly CliName[];\n /** Reasoning for the decision */\n readonly reason: string;\n /** Whether calibration was applied */\n readonly calibrationApplied: boolean;\n /** Calibration adjustment applied (if any) */\n readonly calibrationAdjustment?: number | undefined;\n}\n\n/**\n * Error from ZeroRouter operations.\n */\nexport class ZeroRoutingError extends Error {\n readonly code: 'ESTIMATION_FAILED' | 'CALIBRATION_FAILED' | 'NO_AVAILABLE_CLIS';\n\n constructor(message: string, code: ZeroRoutingError['code'], cause?: Error) {\n super(message, { cause });\n this.name = 'ZeroRoutingError';\n this.code = code;\n }\n}\n","/**\n * nexus-agents/cli-adapters - Difficulty Estimators\n *\n * Dimension-specific difficulty estimation functions.\n * Extracted from difficulty-space.ts to maintain file size limits.\n *\n * @module cli-adapters/difficulty-estimators\n * (Source: Issue #339)\n */\n\nimport type { TaskProfile } from '../core/index.js';\nimport { clamp, clamp01 } from '../utils/math-utils.js';\n\n// ============================================================================\n// Constants for normalization\n// ============================================================================\n\n/** Maximum expected context tokens for normalization */\nconst MAX_CONTEXT_TOKENS = 50_000;\n\n/** Maximum expected complexity score from task analyzer */\nconst MAX_COMPLEXITY_SCORE = 10;\n\n/** Keywords indicating high reasoning requirements */\nconst REASONING_KEYWORDS = [\n 'analyze',\n 'reason',\n 'logic',\n 'infer',\n 'deduce',\n 'prove',\n 'theorem',\n 'algorithm',\n 'optimize',\n 'trade-off',\n 'compare',\n 'evaluate',\n 'decision',\n 'strategy',\n 'plan',\n 'debug',\n 'diagnose',\n 'investigate',\n] as const;\n\n/** Keywords indicating high knowledge requirements */\nconst KNOWLEDGE_KEYWORDS = [\n 'domain',\n 'expert',\n 'specialist',\n 'technical',\n 'advanced',\n 'specific',\n 'industry',\n 'regulation',\n 'compliance',\n 'standard',\n 'protocol',\n 'specification',\n 'scientific',\n 'medical',\n 'legal',\n 'financial',\n] as const;\n\n/** Keywords indicating high creativity requirements */\nconst CREATIVITY_KEYWORDS = [\n 'creative',\n 'novel',\n 'innovative',\n 'unique',\n 'original',\n 'design',\n 'brainstorm',\n 'ideate',\n 'imagine',\n 'invent',\n 'generate',\n 'create',\n 'compose',\n 'write',\n 'story',\n 'artistic',\n] as const;\n\n/** Keywords indicating high precision requirements */\nconst PRECISION_KEYWORDS = [\n 'exact',\n 'precise',\n 'accurate',\n 'correct',\n 'verify',\n 'validate',\n 'test',\n 'error',\n 'bug',\n 'fix',\n 'security',\n 'critical',\n 'production',\n 'reliable',\n 'robust',\n 'type-safe',\n] as const;\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Counts keyword matches in text.\n */\nfunction countKeywordMatches(text: string, keywords: readonly string[]): number {\n const lower = text.toLowerCase();\n let count = 0;\n for (const keyword of keywords) {\n if (lower.includes(keyword)) {\n count++;\n }\n }\n return count;\n}\n\n/**\n * Normalizes keyword count to 0-1 difficulty.\n */\nfunction normalizeKeywordCount(count: number, saturationPoint: number): number {\n if (count === 0) return 0;\n const ratio = count / saturationPoint;\n const raw = ratio * (2 - ratio);\n return clamp(raw, 0.2, 1);\n}\n\n/**\n * Normalizes a value to the 0-1 range.\n */\nfunction normalize(value: number, min: number, max: number): number {\n if (max === min) return 0.5;\n const normalized = (value - min) / (max - min);\n return clamp01(normalized);\n}\n\n// ============================================================================\n// Dimension-Specific Estimators\n// ============================================================================\n\n/**\n * Estimates reasoning difficulty from task content.\n */\nexport function estimateReasoningDifficulty(content: string, profile?: TaskProfile): number {\n let difficulty = profile !== undefined ? profile.reasoningComplexity / MAX_COMPLEXITY_SCORE : 0.5;\n\n const keywordCount = countKeywordMatches(content, REASONING_KEYWORDS);\n const keywordFactor = normalizeKeywordCount(keywordCount, 5);\n\n const reasoningTasks = ['architecture', 'code_review', 'large_codebase'];\n const taskTypeBonus =\n profile !== undefined && reasoningTasks.includes(profile.taskType) ? 0.15 : 0;\n\n difficulty = difficulty * 0.5 + keywordFactor * 0.35 + taskTypeBonus + 0.15 * difficulty;\n\n return clamp01(difficulty);\n}\n\n/**\n * Estimates knowledge difficulty from task content.\n */\nexport function estimateKnowledgeDifficulty(content: string, profile?: TaskProfile): number {\n const keywordCount = countKeywordMatches(content, KNOWLEDGE_KEYWORDS);\n let difficulty = normalizeKeywordCount(keywordCount, 4);\n\n const knowledgeTasks = ['documentation', 'architecture'];\n if (profile !== undefined && knowledgeTasks.includes(profile.taskType)) {\n difficulty = Math.min(1, difficulty + 0.2);\n }\n\n if (content.length > 2000) {\n difficulty = Math.min(1, difficulty + 0.1);\n }\n\n return difficulty;\n}\n\n/**\n * Estimates creativity difficulty from task content.\n */\nexport function estimateCreativityDifficulty(content: string, profile?: TaskProfile): number {\n const keywordCount = countKeywordMatches(content, CREATIVITY_KEYWORDS);\n let difficulty = normalizeKeywordCount(keywordCount, 4);\n\n if (\n profile !== undefined &&\n profile.codeGeneration &&\n profile.taskType === 'code_implementation'\n ) {\n difficulty = Math.min(1, difficulty + 0.25);\n }\n\n if (profile?.taskType === 'architecture') {\n difficulty = Math.min(1, difficulty + 0.2);\n }\n\n return difficulty;\n}\n\n/**\n * Estimates precision difficulty from task content.\n */\nexport function estimatePrecisionDifficulty(content: string, profile?: TaskProfile): number {\n const keywordCount = countKeywordMatches(content, PRECISION_KEYWORDS);\n let difficulty = normalizeKeywordCount(keywordCount, 4);\n\n const precisionTasks = ['test_generation', 'code_review'];\n if (profile !== undefined && precisionTasks.includes(profile.taskType)) {\n difficulty = Math.min(1, difficulty + 0.3);\n }\n\n if (profile?.codeGeneration === true) {\n difficulty = Math.min(1, difficulty + 0.15);\n }\n\n return difficulty;\n}\n\n/**\n * Estimates context length difficulty from task content.\n */\nexport function estimateContextLengthDifficulty(content: string, profile?: TaskProfile): number {\n const estimatedTokens =\n profile !== undefined\n ? profile.contextRequired\n : Math.max(content.length * 0.3, content.length / 4);\n\n const baseNormalized = normalize(estimatedTokens, 0, MAX_CONTEXT_TOKENS);\n\n if (profile?.taskType === 'large_codebase') {\n return Math.min(1, baseNormalized + 0.2);\n }\n\n if (content.length > 5000) {\n return Math.min(1, baseNormalized + 0.15);\n }\n\n return baseNormalized;\n}\n","/**\n * nexus-agents/cli-adapters - Difficulty Space\n *\n * Functions for mapping tasks to the universal difficulty space.\n * Each dimension is normalized to 0-1 for consistent comparison.\n *\n * @module cli-adapters/difficulty-space\n * (Source: Issue #338)\n */\n\nimport type { CliTask } from './types-capability.js';\nimport { clamp01 } from '../utils/math-utils.js';\nimport type { TaskProfile } from '../core/index.js';\nimport {\n type DifficultySpace,\n type DifficultyDimension,\n type DifficultyWeights,\n type DifficultyLevel,\n type DifficultyThresholds,\n DIFFICULTY_DIMENSIONS,\n DEFAULT_DIFFICULTY_WEIGHTS,\n DEFAULT_DIFFICULTY_THRESHOLDS,\n} from './zero-router-types.js';\n\n// Re-export dimension estimators for backward compatibility\nexport {\n estimateReasoningDifficulty,\n estimateKnowledgeDifficulty,\n estimateCreativityDifficulty,\n estimatePrecisionDifficulty,\n estimateContextLengthDifficulty,\n} from './difficulty-estimators.js';\n\n// Import for internal use\nimport {\n estimateReasoningDifficulty,\n estimateKnowledgeDifficulty,\n estimateCreativityDifficulty,\n estimatePrecisionDifficulty,\n estimateContextLengthDifficulty,\n} from './difficulty-estimators.js';\n\n// ============================================================================\n// Normalization Functions\n// ============================================================================\n\n/**\n * Normalizes a value to the 0-1 range.\n *\n * @param value - Value to normalize\n * @param min - Minimum expected value\n * @param max - Maximum expected value\n * @returns Normalized value between 0 and 1\n */\nexport function normalize(value: number, min: number, max: number): number {\n if (max === min) return 0.5;\n const normalized = (value - min) / (max - min);\n return clamp01(normalized);\n}\n\n// ============================================================================\n// Main Estimation Functions\n// ============================================================================\n\n/**\n * Maps a task to the universal difficulty space.\n *\n * @param task - CLI task to analyze\n * @param profile - Optional pre-computed task profile\n * @returns Difficulty space with all dimensions normalized to 0-1\n */\nexport function estimateDifficultySpace(task: CliTask, profile?: TaskProfile): DifficultySpace {\n const content = task.content + (task.systemPrompt ?? '');\n\n return {\n reasoning: estimateReasoningDifficulty(content, profile),\n knowledge: estimateKnowledgeDifficulty(content, profile),\n creativity: estimateCreativityDifficulty(content, profile),\n precision: estimatePrecisionDifficulty(content, profile),\n context_length: estimateContextLengthDifficulty(content, profile),\n };\n}\n\n/**\n * Aggregates difficulty dimensions into a single score.\n *\n * @param space - Difficulty space to aggregate\n * @param weights - Weights for each dimension (should sum to 1)\n * @returns Aggregate difficulty score (0-1)\n */\nexport function aggregateDifficulty(\n space: DifficultySpace,\n weights: DifficultyWeights = DEFAULT_DIFFICULTY_WEIGHTS\n): number {\n let sum = 0;\n let weightSum = 0;\n\n for (const dim of DIFFICULTY_DIMENSIONS) {\n sum += space[dim] * weights[dim];\n weightSum += weights[dim];\n }\n\n // Normalize by weight sum to handle non-normalized weights\n return weightSum > 0 ? sum / weightSum : 0;\n}\n\n/**\n * Finds the dominant (highest) difficulty dimension.\n *\n * @param space - Difficulty space to analyze\n * @returns The dimension with highest difficulty\n */\nexport function findDominantDimension(space: DifficultySpace): DifficultyDimension {\n let maxDim: DifficultyDimension = 'reasoning';\n let maxValue = space.reasoning;\n\n for (const dim of DIFFICULTY_DIMENSIONS) {\n if (space[dim] > maxValue) {\n maxValue = space[dim];\n maxDim = dim;\n }\n }\n\n return maxDim;\n}\n\n/**\n * Classifies aggregate difficulty into a level.\n *\n * @param aggregateScore - Aggregate difficulty score (0-1)\n * @param thresholds - Optional custom thresholds\n * @returns Difficulty level classification\n */\nexport function classifyDifficultyLevel(\n aggregateScore: number,\n thresholds: DifficultyThresholds = DEFAULT_DIFFICULTY_THRESHOLDS\n): DifficultyLevel {\n if (aggregateScore < thresholds.easyUpperBound) {\n return 'easy';\n }\n if (aggregateScore > thresholds.hardLowerBound) {\n return 'hard';\n }\n return 'medium';\n}\n\n/**\n * Calculates confidence in the difficulty estimate.\n * Higher when dimensions are consistent, lower when spread out.\n *\n * @param space - Difficulty space to analyze\n * @returns Confidence score (0-1)\n */\nexport function calculateEstimateConfidence(space: DifficultySpace): number {\n const values = DIFFICULTY_DIMENSIONS.map((dim) => space[dim]);\n const mean = values.reduce((a, b) => a + b, 0) / values.length;\n\n // Calculate standard deviation\n const variance = values.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / values.length;\n const stdDev = Math.sqrt(variance);\n\n // Lower variance = higher confidence\n // Max stdDev for 0-1 values is ~0.5\n const normalizedStdDev = stdDev / 0.5;\n const confidence = 1 - normalizedStdDev;\n\n return clamp01(confidence);\n}\n\n/**\n * Creates a human-readable summary of the difficulty space.\n *\n * @param space - Difficulty space to summarize\n * @returns Human-readable summary string\n */\nexport function summarizeDifficultySpace(space: DifficultySpace): string {\n const parts: string[] = [];\n\n for (const dim of DIFFICULTY_DIMENSIONS) {\n const value = space[dim];\n const level = value < 0.3 ? 'low' : value > 0.7 ? 'high' : 'med';\n parts.push(`${dim}:${level}`);\n }\n\n return parts.join(' | ');\n}\n","/**\n * nexus-agents/cli-adapters - ZeroRouter Calibration Helpers\n *\n * Helper functions for ZeroRouter calibration and statistics.\n * Extracted from zero-router.ts to maintain file size limits.\n *\n * @module cli-adapters/zero-router-calibration\n * (Source: Issue #338, #339)\n */\n\nimport type {\n DifficultyOutcome,\n DifficultyLevel,\n DifficultyThresholds,\n} from './zero-router-types.js';\nimport { classifyDifficultyLevel } from './difficulty-space.js';\nimport { clamp } from '../utils/math-utils.js';\n\n/**\n * Groups outcomes by difficulty level.\n */\nexport function groupOutcomesByLevel(\n outcomes: readonly DifficultyOutcome[],\n thresholds: DifficultyThresholds\n): Record<DifficultyLevel, DifficultyOutcome[]> {\n const groups: Record<DifficultyLevel, DifficultyOutcome[]> = {\n easy: [],\n medium: [],\n hard: [],\n };\n\n for (const outcome of outcomes) {\n const level = classifyDifficultyLevel(outcome.estimatedDifficulty, thresholds);\n groups[level].push(outcome);\n }\n\n return groups;\n}\n\n/**\n * Calculates success rate for each difficulty level.\n */\nexport function calculateSuccessRateByLevel(\n groups: Record<DifficultyLevel, readonly DifficultyOutcome[]>\n): Record<DifficultyLevel, number> {\n const result: Record<DifficultyLevel, number> = { easy: 0, medium: 0, hard: 0 };\n\n for (const level of ['easy', 'medium', 'hard'] as DifficultyLevel[]) {\n const levelOutcomes = groups[level];\n if (levelOutcomes.length > 0) {\n const successes = levelOutcomes.filter((o) => o.success).length;\n result[level] = successes / levelOutcomes.length;\n }\n }\n\n return result;\n}\n\n/**\n * Calculates average quality score for each difficulty level.\n */\nexport function calculateAvgQualityByLevel(\n groups: Record<DifficultyLevel, readonly DifficultyOutcome[]>\n): Record<DifficultyLevel, number> {\n const result: Record<DifficultyLevel, number> = { easy: 0, medium: 0, hard: 0 };\n\n for (const level of ['easy', 'medium', 'hard'] as DifficultyLevel[]) {\n const levelOutcomes = groups[level];\n const withQuality = levelOutcomes.filter((o) => o.qualityScore !== undefined);\n if (withQuality.length > 0) {\n const qualitySum = withQuality.reduce((sum, o) => sum + (o.qualityScore ?? 0), 0);\n result[level] = qualitySum / withQuality.length;\n }\n }\n\n return result;\n}\n\n/**\n * Calculates mean absolute error between estimated and actual difficulty.\n */\nexport function calculateMeanAbsoluteError(outcomes: readonly DifficultyOutcome[]): number {\n if (outcomes.length === 0) return 0;\n\n // MAE between estimated difficulty and inferred actual difficulty\n let totalError = 0;\n for (const outcome of outcomes) {\n // Use quality score as proxy for actual difficulty if available\n // Otherwise, use success as binary indicator\n const actualDifficulty =\n outcome.qualityScore !== undefined\n ? 1 - outcome.qualityScore // High quality = easier task\n : outcome.success\n ? 0.3 // Success suggests reasonable difficulty\n : 0.8; // Failure suggests high difficulty\n\n totalError += Math.abs(outcome.estimatedDifficulty - actualDifficulty);\n }\n\n return totalError / outcomes.length;\n}\n\n/**\n * Calculates Pearson correlation between difficulty and success rate.\n * Negative correlation expected: higher difficulty = lower success.\n */\nexport function calculateDifficultySuccessCorrelation(\n outcomes: readonly DifficultyOutcome[]\n): number {\n if (outcomes.length < 2) return 0;\n\n // Calculate Pearson correlation between difficulty and success rate\n const difficulties = outcomes.map((o) => o.estimatedDifficulty);\n const successes: number[] = outcomes.map((o) => (o.success ? 1 : 0));\n\n const n = difficulties.length;\n const sumD = difficulties.reduce((a, b) => a + b, 0);\n const sumS = successes.reduce((a: number, b: number) => a + b, 0);\n const sumDS = difficulties.reduce((sum, d, i) => sum + d * (successes[i] ?? 0), 0);\n const sumD2 = difficulties.reduce((sum, d) => sum + d * d, 0);\n const sumS2 = successes.reduce((sum: number, s: number) => sum + s * s, 0);\n\n const numerator = n * sumDS - sumD * sumS;\n const denominator = Math.sqrt((n * sumD2 - sumD * sumD) * (n * sumS2 - sumS * sumS));\n\n if (denominator === 0) return 0;\n\n return numerator / denominator;\n}\n\n/**\n * Updates calibration bias based on recorded outcomes.\n *\n * @param outcomes - Array of recorded outcomes\n * @returns New calibration bias value (clamped to [-0.2, 0.2])\n */\nexport function calculateCalibrationBias(outcomes: readonly DifficultyOutcome[]): number {\n if (outcomes.length < 10) {\n return 0;\n }\n\n // Calculate bias: difference between estimated and actual difficulty\n // Actual difficulty is inferred from success rate\n // Low success = task was harder than estimated (positive bias needed)\n // High success = task was easier than estimated (negative bias needed)\n\n let biasSum = 0;\n let count = 0;\n\n for (const outcome of outcomes) {\n // Infer actual difficulty from success (failure indicates harder task)\n const actualDifficulty = outcome.success ? outcome.estimatedDifficulty : 1.0;\n const error = actualDifficulty - outcome.estimatedDifficulty;\n biasSum += error;\n count++;\n }\n\n // Small learning rate to prevent overcorrection\n const learningRate = 0.1;\n const rawBias = count > 0 ? biasSum / count : 0;\n const bias = rawBias * learningRate;\n\n // Clamp bias to reasonable range\n return clamp(bias, -0.2, 0.2);\n}\n\n/**\n * Simple hash function for task deduplication.\n */\nexport function hashTaskContent(content: string): string {\n let hash = 0;\n for (let i = 0; i < content.length; i++) {\n const char = content.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(16);\n}\n\n/**\n * Options for building routing reason string.\n */\nexport interface BuildRoutingReasonOptions {\n readonly level: DifficultyLevel;\n readonly aggregateScore: number;\n readonly dominantDimension: string;\n readonly recommendedTier: string;\n readonly selectedCli: string;\n readonly calibrationApplied: boolean;\n readonly calibrationBias: number;\n}\n\n/**\n * Builds routing reason string.\n */\nexport function buildRoutingReason(options: BuildRoutingReasonOptions): string {\n const parts: string[] = [];\n\n parts.push(`Difficulty: ${options.level} (${(options.aggregateScore * 100).toFixed(1)}%)`);\n parts.push(`Dominant: ${options.dominantDimension}`);\n parts.push(`Tier: ${options.recommendedTier} → ${options.selectedCli}`);\n\n if (options.calibrationApplied) {\n parts.push(\n `(calibrated: ${options.calibrationBias > 0 ? '+' : ''}${(options.calibrationBias * 100).toFixed(1)}%)`\n );\n }\n\n return parts.join(' | ');\n}\n","/**\n * nexus-agents/cli-adapters - ZeroRouter\n *\n * Universal difficulty space routing for intelligent model selection.\n * Creates a unified difficulty metric across diverse task types,\n * enabling better model selection across domains.\n *\n * @module cli-adapters/zero-router\n * (Source: Issue #338)\n */\n\nimport {\n createLogger,\n type ILogger,\n createSharedTaskAnalyzer,\n taskAnalysisResultToTaskProfile,\n type TaskProfile,\n} from '../core/index.js';\nimport { clamp01 } from '../utils/math-utils.js';\nimport type { CliName, CliTask } from './types.js';\nimport type { Task } from '../core/types/agent.js';\nimport {\n type ZeroRouterConfig,\n type DifficultyEstimate,\n type DifficultyOutcome,\n type CalibrationStats,\n type ZeroRoutingDecision,\n type DifficultyLevel,\n type ModelTier,\n ZeroRouterConfigSchema,\n ZeroRoutingError,\n} from './zero-router-types.js';\nimport {\n estimateDifficultySpace,\n aggregateDifficulty,\n findDominantDimension,\n classifyDifficultyLevel,\n calculateEstimateConfidence,\n summarizeDifficultySpace,\n} from './difficulty-space.js';\nimport {\n groupOutcomesByLevel,\n calculateSuccessRateByLevel,\n calculateAvgQualityByLevel,\n calculateMeanAbsoluteError,\n calculateDifficultySuccessCorrelation,\n calculateCalibrationBias,\n hashTaskContent,\n buildRoutingReason,\n} from './zero-router-calibration.js';\n\n// Re-export types for consumers\nexport {\n ZeroRouterConfigSchema,\n ZeroRoutingError,\n DEFAULT_DIFFICULTY_THRESHOLDS,\n type ZeroRouterConfig,\n type DifficultyEstimate,\n type DifficultyOutcome,\n type CalibrationStats,\n type ZeroRoutingDecision,\n type DifficultyLevel,\n type ModelTier,\n type DifficultyThresholds,\n} from './zero-router-types.js';\n\n/** Module-level singleton — SharedTaskAnalyzer is stateless. */\nconst sharedAnalyzer = createSharedTaskAnalyzer();\n\n/**\n * Interface for ZeroRouter for dependency injection.\n */\nexport interface IZeroRouter {\n estimateDifficulty(task: CliTask): DifficultyEstimate;\n routeByDifficulty(task: CliTask, availableClis?: CliName[]): ZeroRoutingDecision;\n calibrate(outcome: DifficultyOutcome): void;\n getCalibrationStats(): CalibrationStats;\n getConfig(): ZeroRouterConfig;\n}\n\n/**\n * ZeroRouter implementation.\n *\n * Routes tasks based on a universal difficulty space that normalizes\n * task difficulty across different dimensions (reasoning, knowledge,\n * creativity, precision, context length).\n */\nexport class ZeroRouter implements IZeroRouter {\n private readonly config: ZeroRouterConfig;\n private readonly logger: ILogger;\n private readonly outcomes: DifficultyOutcome[] = [];\n private calibrationBias = 0;\n\n constructor(config?: Partial<ZeroRouterConfig>, logger?: ILogger) {\n this.config = ZeroRouterConfigSchema.parse(config ?? {});\n this.logger = logger ?? createLogger({ component: 'ZeroRouter' });\n\n this.logger.debug('ZeroRouter initialized', {\n thresholds: this.config.thresholds,\n enableCalibration: this.config.enableCalibration,\n });\n }\n\n /**\n * Estimates difficulty for a task.\n *\n * @param task - CLI task to analyze\n * @returns Difficulty estimate with all dimensions and aggregate score\n */\n estimateDifficulty(task: CliTask): DifficultyEstimate {\n const taskProfile = this.analyzeTaskProfile(task);\n const dimensions = estimateDifficultySpace(task, taskProfile);\n\n // Aggregate with configured weights\n let aggregateScore = aggregateDifficulty(dimensions, this.config.weights);\n\n // Apply calibration adjustment if enabled and sufficient data\n let calibrationApplied = false;\n if (this.config.enableCalibration && this.hasMinimumCalibrationData()) {\n aggregateScore = this.applyCalibrationAdjustment(aggregateScore);\n calibrationApplied = true;\n }\n\n // Ensure bounds after calibration\n aggregateScore = clamp01(aggregateScore);\n\n const level = classifyDifficultyLevel(aggregateScore, this.config.thresholds);\n const recommendedTier = this.getTierForLevel(level);\n const confidence = calculateEstimateConfidence(dimensions);\n const dominantDimension = findDominantDimension(dimensions);\n\n const estimate: DifficultyEstimate = {\n dimensions,\n aggregateScore,\n level,\n recommendedTier,\n confidence,\n dominantDimension,\n };\n\n if (this.config.verbose) {\n this.logger.debug('Difficulty estimated', {\n aggregate: aggregateScore.toFixed(3),\n level,\n tier: recommendedTier,\n dominant: dominantDimension,\n calibrationApplied,\n summary: summarizeDifficultySpace(dimensions),\n });\n }\n\n return estimate;\n }\n\n /**\n * Routes a task based on difficulty.\n *\n * @param task - CLI task to route\n * @param availableClis - Optional list of available CLIs (filters selection)\n * @returns Routing decision with selected CLI and explanation\n */\n routeByDifficulty(task: CliTask, availableClis?: CliName[]): ZeroRoutingDecision {\n const difficulty = this.estimateDifficulty(task);\n const tier = difficulty.recommendedTier;\n const tierClis = this.config.tierToClis[tier];\n\n // Filter by available CLIs if provided\n let candidates = tierClis;\n if (availableClis !== undefined) {\n // Empty array means explicitly no CLIs available\n if (availableClis.length === 0) {\n throw new ZeroRoutingError('No CLIs available for routing', 'NO_AVAILABLE_CLIS');\n }\n candidates = tierClis.filter((cli) => availableClis.includes(cli));\n // Fall back to any available if no tier match\n if (candidates.length === 0) {\n candidates = availableClis;\n }\n }\n\n if (candidates.length === 0) {\n throw new ZeroRoutingError('No CLIs available for routing', 'NO_AVAILABLE_CLIS');\n }\n\n const selectedCli = candidates[0] as CliName;\n const alternatives = candidates.slice(1);\n const calibrationApplied = this.config.enableCalibration && this.hasMinimumCalibrationData();\n\n const reason = buildRoutingReason({\n level: difficulty.level,\n aggregateScore: difficulty.aggregateScore,\n dominantDimension: difficulty.dominantDimension,\n recommendedTier: difficulty.recommendedTier,\n selectedCli,\n calibrationApplied,\n calibrationBias: this.calibrationBias,\n });\n\n return {\n difficulty,\n selectedCli,\n tier,\n alternatives,\n reason,\n calibrationApplied,\n calibrationAdjustment: calibrationApplied ? this.calibrationBias : undefined,\n };\n }\n\n /**\n * Records an outcome for calibration.\n *\n * @param outcome - Difficulty outcome with success/quality information\n */\n calibrate(outcome: DifficultyOutcome): void {\n if (!this.config.enableCalibration) {\n return;\n }\n\n this.outcomes.push(outcome);\n\n // Trim to max size\n while (this.outcomes.length > this.config.maxCalibrationOutcomes) {\n this.outcomes.shift();\n }\n\n // Recalculate calibration bias\n this.updateCalibrationBias();\n\n if (this.config.verbose) {\n this.logger.debug('Calibration outcome recorded', {\n estimated: outcome.estimatedDifficulty.toFixed(3),\n success: outcome.success,\n quality: outcome.qualityScore,\n totalOutcomes: this.outcomes.length,\n newBias: this.calibrationBias.toFixed(4),\n });\n }\n }\n\n /**\n * Gets calibration statistics.\n *\n * @returns Calibration statistics for observability\n */\n getCalibrationStats(): CalibrationStats {\n if (this.outcomes.length === 0) {\n return {\n totalOutcomes: 0,\n meanAbsoluteError: 0,\n difficultySuccessCorrelation: 0,\n successRateByLevel: { easy: 0, medium: 0, hard: 0 },\n avgQualityByLevel: { easy: 0, medium: 0, hard: 0 },\n calibrationBias: 0,\n };\n }\n\n const outcomesByLevel = groupOutcomesByLevel(this.outcomes, this.config.thresholds);\n const successRateByLevel = calculateSuccessRateByLevel(outcomesByLevel);\n const avgQualityByLevel = calculateAvgQualityByLevel(outcomesByLevel);\n const meanAbsoluteError = calculateMeanAbsoluteError(this.outcomes);\n const difficultySuccessCorrelation = calculateDifficultySuccessCorrelation(this.outcomes);\n\n return {\n totalOutcomes: this.outcomes.length,\n meanAbsoluteError,\n difficultySuccessCorrelation,\n successRateByLevel,\n avgQualityByLevel,\n calibrationBias: this.calibrationBias,\n };\n }\n\n /**\n * Gets current configuration.\n */\n getConfig(): ZeroRouterConfig {\n return { ...this.config };\n }\n\n // ============================================================================\n // Private Methods\n // ============================================================================\n\n private analyzeTaskProfile(task: CliTask): TaskProfile {\n // Convert CliTask to Task for the analyzer\n const internalTask: Task = {\n id: hashTaskContent(task.content),\n description: task.content,\n context: {\n history: [],\n metadata: {},\n },\n };\n const analysis = sharedAnalyzer.analyze(internalTask);\n return taskAnalysisResultToTaskProfile(analysis);\n }\n\n private getTierForLevel(level: DifficultyLevel): ModelTier {\n return this.config.difficultyToTier[level];\n }\n\n private hasMinimumCalibrationData(): boolean {\n return this.outcomes.length >= this.config.minCalibrationOutcomes;\n }\n\n private applyCalibrationAdjustment(score: number): number {\n // Apply bias correction: if we're underestimating, increase scores\n return score + this.calibrationBias;\n }\n\n private updateCalibrationBias(): void {\n this.calibrationBias = calculateCalibrationBias(this.outcomes);\n }\n}\n\n/**\n * Creates a ZeroRouter instance.\n *\n * @param config - Optional configuration\n * @param logger - Optional logger\n * @returns ZeroRouter instance\n */\nexport function createZeroRouter(\n config?: Partial<ZeroRouterConfig>,\n logger?: ILogger\n): IZeroRouter {\n return new ZeroRouter(config, logger);\n}\n\n/**\n * Quick function to estimate difficulty without creating a router instance.\n *\n * @param task - CLI task to analyze\n * @returns Difficulty estimate\n */\nexport function estimateTaskDifficulty(task: CliTask): DifficultyEstimate {\n const router = new ZeroRouter({ verbose: false, enableCalibration: false });\n return router.estimateDifficulty(task);\n}\n\n/**\n * Quick function to route by difficulty without creating a router instance.\n *\n * @param task - CLI task to route\n * @param availableClis - Optional list of available CLIs\n * @returns Routing decision\n */\nexport function routeByTaskDifficulty(\n task: CliTask,\n availableClis?: CliName[]\n): ZeroRoutingDecision {\n const router = new ZeroRouter({ verbose: false, enableCalibration: false });\n return router.routeByDifficulty(task, availableClis);\n}\n","/**\n * nexus-agents/cli-adapters - Latency Tracker Types\n *\n * Type definitions and Zod schemas for CLI latency tracking.\n * Tracks execution times for smarter routing decisions.\n *\n * @module cli-adapters/latency-tracker-types\n * (Source: Issue #361 - CLI latency tracking for routing)\n */\n\nimport { z } from 'zod';\nimport type { CliName } from './types-core.js';\n\n/**\n * Configuration schema for LatencyTracker.\n */\nexport const LatencyTrackerConfigSchema = z.object({\n /** Maximum number of samples to keep per CLI (default: 100) */\n windowSize: z.number().int().positive().default(100),\n /** Time-weighted decay factor (0-1, higher = more weight to recent) (default: 0.95) */\n decayFactor: z.number().min(0).max(1).default(0.95),\n /** Maximum age of samples in milliseconds before forced eviction (default: 3600000 = 1 hour) */\n maxSampleAgeMs: z.number().int().positive().default(3600000),\n /** Percentiles to calculate (default: [50, 95, 99]) */\n percentiles: z.array(z.number().min(0).max(100)).default([50, 95, 99]),\n});\n\nexport type LatencyTrackerConfig = z.infer<typeof LatencyTrackerConfigSchema>;\n\n/**\n * Default configuration for latency tracker.\n */\nexport const DEFAULT_LATENCY_TRACKER_CONFIG: LatencyTrackerConfig = {\n windowSize: 100,\n decayFactor: 0.95,\n maxSampleAgeMs: 3600000, // 1 hour\n percentiles: [50, 95, 99],\n};\n\n/**\n * A single latency measurement sample.\n */\nexport interface LatencySample {\n /** Duration of the operation in milliseconds */\n readonly durationMs: number;\n /** Timestamp when the measurement was recorded (monotonic) */\n readonly recordedAt: number;\n /** Whether the operation was successful */\n readonly success: boolean;\n}\n\n/**\n * Latency statistics for a single CLI.\n */\nexport interface LatencyStats {\n /** Number of samples in the window */\n readonly count: number;\n /** Arithmetic mean of latencies */\n readonly avg: number;\n /** Minimum latency observed */\n readonly min: number;\n /** Maximum latency observed */\n readonly max: number;\n /** 50th percentile (median) */\n readonly p50: number;\n /** 95th percentile */\n readonly p95: number;\n /** 99th percentile */\n readonly p99: number;\n /** Standard deviation */\n readonly stdDev: number;\n /** Time-weighted average (recent samples weighted more) */\n readonly weightedAvg: number;\n /** Success rate (0-1) */\n readonly successRate: number;\n /** Timestamp of the oldest sample */\n readonly oldestSampleAt: number | undefined;\n /** Timestamp of the newest sample */\n readonly newestSampleAt: number | undefined;\n}\n\n/**\n * Empty stats for CLIs with no measurements.\n */\nexport const EMPTY_LATENCY_STATS: LatencyStats = {\n count: 0,\n avg: 0,\n min: 0,\n max: 0,\n p50: 0,\n p95: 0,\n p99: 0,\n stdDev: 0,\n weightedAvg: 0,\n successRate: 0,\n oldestSampleAt: undefined,\n newestSampleAt: undefined,\n};\n\n/**\n * Latency-based routing score for a CLI.\n */\nexport interface LatencyScore {\n /** The CLI being scored */\n readonly cli: CliName;\n /** Normalized score (0-1, higher is better/faster) */\n readonly score: number;\n /** Confidence in the score (0-1, based on sample count) */\n readonly confidence: number;\n /** Raw weighted average latency */\n readonly weightedAvgMs: number;\n /** Whether enough data exists for reliable scoring */\n readonly hasReliableData: boolean;\n}\n\n/**\n * Overall tracker statistics for observability.\n */\nexport interface LatencyTrackerStats {\n /** Stats per CLI */\n readonly perCli: Readonly<Record<CliName, LatencyStats>>;\n /** Total samples across all CLIs */\n readonly totalSamples: number;\n /** Total recordings made (including evicted) */\n readonly totalRecordings: number;\n /** Number of samples evicted due to age */\n readonly evictedByAge: number;\n /** Number of samples evicted due to window size */\n readonly evictedByWindow: number;\n}\n\n/**\n * Interface for latency tracker dependency injection.\n */\nexport interface ILatencyTracker {\n /** Record a latency measurement for a CLI */\n record(cli: CliName, durationMs: number, success?: boolean): void;\n\n /** Get statistics for a specific CLI */\n getStats(cli: CliName): LatencyStats;\n\n /** Get latency-based routing scores for all CLIs */\n getScores(clis: readonly CliName[]): readonly LatencyScore[];\n\n /** Get a single score for a CLI */\n getScore(cli: CliName): LatencyScore;\n\n /** Get overall tracker statistics */\n getTrackerStats(): LatencyTrackerStats;\n\n /** Clear all samples for a specific CLI */\n clear(cli: CliName): void;\n\n /** Clear all samples for all CLIs */\n clearAll(): void;\n}\n\n/**\n * Error thrown by latency tracker operations.\n */\nexport class LatencyTrackerError extends Error {\n readonly code: 'INVALID_DURATION' | 'CONFIG_ERROR';\n\n constructor(message: string, code: 'INVALID_DURATION' | 'CONFIG_ERROR') {\n super(message);\n this.name = 'LatencyTrackerError';\n this.code = code;\n }\n}\n","/**\n * nexus-agents/cli-adapters - Latency Tracker\n *\n * Tracks CLI execution latencies with rolling window statistics\n * and time-weighted decay for smarter routing decisions.\n *\n * @module cli-adapters/latency-tracker\n * (Source: Issue #361 - CLI latency tracking for routing)\n */\n\nimport type { CliName } from './types-core.js';\nimport { CLI_NAMES } from '../config/model-capabilities-types.js';\nimport { clamp01 } from '../utils/math-utils.js';\nimport {\n LatencyTrackerConfigSchema,\n LatencyTrackerError,\n EMPTY_LATENCY_STATS,\n type LatencyTrackerConfig,\n type LatencySample,\n type LatencyStats,\n type LatencyScore,\n type LatencyTrackerStats,\n type ILatencyTracker,\n} from './latency-tracker-types.js';\n\n// Re-export types for consumers\nexport {\n LatencyTrackerConfigSchema,\n LatencyTrackerError,\n EMPTY_LATENCY_STATS,\n DEFAULT_LATENCY_TRACKER_CONFIG,\n type LatencyTrackerConfig,\n type LatencySample,\n type LatencyStats,\n type LatencyScore,\n type LatencyTrackerStats,\n type ILatencyTracker,\n} from './latency-tracker-types.js';\n\n/** Minimum samples needed for reliable statistics */\nconst MIN_SAMPLES_FOR_RELIABILITY = 5;\n\n/** Minimum confidence score (based on sample count) */\nconst MIN_CONFIDENCE = 0.1;\n\n/** Maximum latency for normalization (10 minutes) */\nconst MAX_LATENCY_FOR_NORMALIZATION_MS = 600_000;\n\n/**\n * Calculates a specific percentile from sorted values.\n */\nfunction calculatePercentile(sortedValues: readonly number[], percentile: number): number {\n if (sortedValues.length === 0) return 0;\n if (sortedValues.length === 1) return sortedValues[0] ?? 0;\n\n const index = (percentile / 100) * (sortedValues.length - 1);\n const lower = Math.floor(index);\n const upper = Math.ceil(index);\n const fraction = index - lower;\n\n const lowerVal = sortedValues[lower] ?? 0;\n const upperVal = sortedValues[upper] ?? lowerVal;\n\n return lowerVal + fraction * (upperVal - lowerVal);\n}\n\n/**\n * Calculates standard deviation from values and mean.\n */\nfunction calculateStdDev(values: readonly number[], mean: number): number {\n if (values.length < 2) return 0;\n\n const squaredDiffs = values.map((v) => Math.pow(v - mean, 2));\n const avgSquaredDiff = squaredDiffs.reduce((a, b) => a + b, 0) / values.length;\n\n return Math.sqrt(avgSquaredDiff);\n}\n\n/**\n * Calculates time-weighted average with exponential decay.\n */\nfunction calculateWeightedAverage(\n samples: readonly LatencySample[],\n decayFactor: number,\n now: number\n): number {\n if (samples.length === 0) return 0;\n\n let weightedSum = 0;\n let weightSum = 0;\n\n for (const sample of samples) {\n // Weight decays exponentially based on age in minutes\n const ageMinutes = (now - sample.recordedAt) / 60_000;\n const weight = Math.pow(decayFactor, ageMinutes);\n\n weightedSum += sample.durationMs * weight;\n weightSum += weight;\n }\n\n return weightSum > 0 ? weightedSum / weightSum : 0;\n}\n\n/**\n * LatencyTracker implementation.\n *\n * Maintains a rolling window of latency samples per CLI with:\n * - Configurable window size\n * - Time-weighted decay for recent sample emphasis\n * - Percentile calculations (p50, p95, p99)\n * - Age-based sample eviction\n */\nexport class LatencyTracker implements ILatencyTracker {\n private readonly config: LatencyTrackerConfig;\n private readonly samples: Map<CliName, LatencySample[]> = new Map();\n private totalRecordings = 0;\n private evictedByAge = 0;\n private evictedByWindow = 0;\n\n constructor(config?: Partial<LatencyTrackerConfig>) {\n this.config = LatencyTrackerConfigSchema.parse(config ?? {});\n }\n\n /**\n * Records a latency measurement for a CLI.\n *\n * @param cli - The CLI that was executed\n * @param durationMs - Execution duration in milliseconds\n * @param success - Whether the execution was successful (default: true)\n * @throws LatencyTrackerError if durationMs is negative\n */\n record(cli: CliName, durationMs: number, success = true): void {\n if (durationMs < 0) {\n throw new LatencyTrackerError('Duration must be non-negative', 'INVALID_DURATION');\n }\n\n const now = performance.now();\n this.totalRecordings++;\n\n const sample: LatencySample = {\n durationMs,\n recordedAt: now,\n success,\n };\n\n let cliSamples = this.samples.get(cli);\n if (cliSamples === undefined) {\n cliSamples = [];\n this.samples.set(cli, cliSamples);\n }\n\n // Evict old samples before adding new one\n this.evictOldSamples(cliSamples, now);\n\n // Evict oldest if at capacity\n if (cliSamples.length >= this.config.windowSize) {\n cliSamples.shift();\n this.evictedByWindow++;\n }\n\n cliSamples.push(sample);\n }\n\n /**\n * Evicts samples older than maxSampleAgeMs.\n */\n private evictOldSamples(samples: LatencySample[], now: number): void {\n const cutoff = now - this.config.maxSampleAgeMs;\n let evicted = 0;\n\n while (samples.length > 0 && (samples[0]?.recordedAt ?? now) < cutoff) {\n samples.shift();\n evicted++;\n }\n\n this.evictedByAge += evicted;\n }\n\n /**\n * Gets latency statistics for a specific CLI.\n */\n getStats(cli: CliName): LatencyStats {\n const cliSamples = this.samples.get(cli);\n if (cliSamples === undefined || cliSamples.length === 0) {\n return EMPTY_LATENCY_STATS;\n }\n\n const now = performance.now();\n this.evictOldSamples(cliSamples, now);\n\n if (cliSamples.length === 0) {\n return EMPTY_LATENCY_STATS;\n }\n\n return this.computeStats(cliSamples, now);\n }\n\n /**\n * Computes statistics from samples.\n */\n private computeStats(samples: readonly LatencySample[], now: number): LatencyStats {\n const durations = samples.map((s) => s.durationMs);\n const sortedDurations = [...durations].sort((a, b) => a - b);\n\n const sum = durations.reduce((a, b) => a + b, 0);\n const avg = sum / durations.length;\n const min = sortedDurations[0] ?? 0;\n const max = sortedDurations[sortedDurations.length - 1] ?? 0;\n\n const successCount = samples.filter((s) => s.success).length;\n\n return {\n count: samples.length,\n avg,\n min,\n max,\n p50: calculatePercentile(sortedDurations, 50),\n p95: calculatePercentile(sortedDurations, 95),\n p99: calculatePercentile(sortedDurations, 99),\n stdDev: calculateStdDev(durations, avg),\n weightedAvg: calculateWeightedAverage(samples, this.config.decayFactor, now),\n successRate: samples.length > 0 ? successCount / samples.length : 0,\n oldestSampleAt: samples[0]?.recordedAt,\n newestSampleAt: samples[samples.length - 1]?.recordedAt,\n };\n }\n\n /**\n * Gets latency-based routing scores for multiple CLIs.\n * Higher scores indicate better (faster, more reliable) CLIs.\n */\n getScores(clis: readonly CliName[]): readonly LatencyScore[] {\n const scores = clis.map((cli) => this.getScore(cli));\n\n // Find the maximum weighted average for normalization\n const validScores = scores.filter((s) => s.hasReliableData);\n if (validScores.length === 0) {\n return scores;\n }\n\n const maxLatency = Math.max(\n ...validScores.map((s) => s.weightedAvgMs),\n MAX_LATENCY_FOR_NORMALIZATION_MS\n );\n\n // Normalize scores (faster = higher score)\n return scores.map((score) => {\n if (!score.hasReliableData) {\n return score;\n }\n\n const normalizedScore = 1 - score.weightedAvgMs / maxLatency;\n return {\n ...score,\n score: clamp01(normalizedScore),\n };\n });\n }\n\n /**\n * Gets a latency-based routing score for a single CLI.\n */\n getScore(cli: CliName): LatencyScore {\n const stats = this.getStats(cli);\n\n const hasReliableData = stats.count >= MIN_SAMPLES_FOR_RELIABILITY;\n const confidence = Math.min(1, stats.count / this.config.windowSize);\n\n // Base score on weighted average (will be normalized in getScores)\n // For individual scores, use inverse relationship: lower latency = higher score\n const rawScore =\n stats.weightedAvg > 0\n ? 1 - Math.min(stats.weightedAvg / MAX_LATENCY_FOR_NORMALIZATION_MS, 1)\n : 0.5; // Default to middle score for no data\n\n // Factor in success rate\n const adjustedScore = rawScore * stats.successRate;\n\n return {\n cli,\n score: hasReliableData ? adjustedScore : MIN_CONFIDENCE,\n confidence: hasReliableData ? confidence : MIN_CONFIDENCE,\n weightedAvgMs: stats.weightedAvg,\n hasReliableData,\n };\n }\n\n /**\n * Gets overall tracker statistics.\n */\n getTrackerStats(): LatencyTrackerStats {\n const perCli: Record<CliName, LatencyStats> = {\n claude: EMPTY_LATENCY_STATS,\n gemini: EMPTY_LATENCY_STATS,\n codex: EMPTY_LATENCY_STATS,\n opencode: EMPTY_LATENCY_STATS,\n };\n\n let totalSamples = 0;\n\n for (const cli of CLI_NAMES) {\n const stats = this.getStats(cli);\n perCli[cli] = stats;\n totalSamples += stats.count;\n }\n\n return {\n perCli,\n totalSamples,\n totalRecordings: this.totalRecordings,\n evictedByAge: this.evictedByAge,\n evictedByWindow: this.evictedByWindow,\n };\n }\n\n /**\n * Clears all samples for a specific CLI.\n */\n clear(cli: CliName): void {\n this.samples.delete(cli);\n }\n\n /**\n * Clears all samples for all CLIs.\n */\n clearAll(): void {\n this.samples.clear();\n this.totalRecordings = 0;\n this.evictedByAge = 0;\n this.evictedByWindow = 0;\n }\n}\n\n/**\n * Factory function to create a LatencyTracker instance.\n */\nexport function createLatencyTracker(config?: Partial<LatencyTrackerConfig>): ILatencyTracker {\n return new LatencyTracker(config);\n}\n","/**\n * nexus-agents/context - Routing Memory Bridge\n *\n * Bridges MobiMem's three modules (Profile, Experience, Action) with\n * the model routing system to enable learned routing based on history.\n *\n * @module context/routing-memory\n * @see Issue #461 - Implement routing memory bridge\n * @see Issue #148 - Preference-Trained Routing\n * @see Issue #149 - MobiMem Post-Deployment Evolution (arXiv:2512.15784)\n */\n\nimport { createLogger } from '../core/logger.js';\nimport { getTimeProvider } from '../core/index.js';\nimport type { ILogger } from '../core/logger.js';\nimport type { CliName } from '../cli-adapters/types.js';\nimport { CLI_NAMES } from '../config/model-capabilities-types.js';\nimport {\n MobiMem,\n type ExperienceEntry,\n type ActionStep,\n type ExecutionOutcome,\n} from './mobimem.js';\n\n/**\n * Performance metrics for a model on a task type.\n */\nexport interface ModelPerformance {\n /** Average quality score (0-1) */\n readonly avgQuality: number;\n /** Success rate (0-1) */\n readonly successRate: number;\n /** Average latency in milliseconds */\n readonly avgLatencyMs: number;\n /** Average tokens used */\n readonly avgTokens: number;\n /** Number of observations */\n readonly observations: number;\n}\n\n/**\n * Model preference with performance context.\n */\nexport interface ModelPreference {\n /** Model/CLI name */\n readonly model: CliName;\n /** Preference strength (0-1) */\n readonly strength: number;\n /** Historical performance */\n readonly performance: ModelPerformance;\n /** Confidence in this preference */\n readonly confidence: number;\n}\n\n/**\n * Experience pattern for workflow execution.\n */\nexport interface ExperiencePattern {\n /** Workflow or task type */\n readonly workflow: string;\n /** Sequence of models used */\n readonly modelSequence: readonly CliName[];\n /** Success rate for this pattern */\n readonly successRate: number;\n /** Average total duration */\n readonly avgDurationMs: number;\n /** How often this pattern was used */\n readonly usageCount: number;\n}\n\n/**\n * Cached action result.\n */\nexport interface CachedActionResult {\n /** Action signature/hash */\n readonly action: string;\n /** Cached result */\n readonly result: unknown;\n /** Model that produced the result */\n readonly model: CliName;\n /** When cached */\n readonly cachedAt: Date;\n /** Time saved by using cache (ms) */\n readonly timeSavedMs: number;\n}\n\n/**\n * Configuration for routing memory.\n */\nexport interface RoutingMemoryConfig {\n /** Minimum observations before considering preference */\n readonly minObservations: number;\n /** Confidence threshold for preferences */\n readonly confidenceThreshold: number;\n /** Success rate threshold for experience patterns */\n readonly successRateThreshold: number;\n /** Maximum age for cached actions (ms) */\n readonly actionCacheMaxAgeMs: number;\n /** Logger instance */\n readonly logger?: ILogger;\n}\n\n/**\n * Default routing memory configuration.\n */\nexport const DEFAULT_ROUTING_MEMORY_CONFIG: RoutingMemoryConfig = {\n minObservations: 5,\n confidenceThreshold: 0.6,\n successRateThreshold: 0.7,\n actionCacheMaxAgeMs: 3600_000, // 1 hour\n};\n\n/**\n * Interface for routing memory operations.\n */\nexport interface IRoutingMemory {\n /** Store model preference for a task type */\n storePreference(model: CliName, taskType: string, performance: ModelPerformance): void;\n\n /** Get preferences for a task type */\n getPreferences(taskType: string): readonly ModelPreference[];\n\n /** Record workflow execution experience */\n recordExperience(\n workflow: string,\n models: readonly CliName[],\n success: boolean,\n metrics: { durationMs: number; tokensUsed: number; qualityScore?: number }\n ): void;\n\n /** Get experience patterns for a workflow type */\n getExperiencePatterns(workflow: string): readonly ExperiencePattern[];\n\n /** Cache an action result */\n cacheAction(action: string, model: CliName, result: unknown, durationMs: number): void;\n\n /** Get cached action result if available */\n getCachedAction(action: string): CachedActionResult | undefined;\n\n /** Get routing recommendation based on history */\n getRecommendation(taskType: string): CliName | undefined;\n\n /** Get statistics */\n getStats(): RoutingMemoryStats;\n}\n\n/**\n * Statistics for routing memory.\n */\nexport interface RoutingMemoryStats {\n readonly totalPreferences: number;\n readonly totalExperiences: number;\n readonly cacheHits: number;\n readonly cacheMisses: number;\n readonly recommendationsMade: number;\n}\n\n/**\n * Routing Memory Bridge implementation.\n *\n * Connects MobiMem's three modules to the routing system:\n * - Profile Memory: Stores model preferences per task type\n * - Experience Memory: Tracks workflow execution patterns\n * - Action Cache: Provides fast retrieval of successful results\n */\nexport class RoutingMemory implements IRoutingMemory {\n private readonly mobimem: MobiMem;\n private readonly config: RoutingMemoryConfig;\n private readonly logger: ILogger;\n\n // Statistics\n private cacheHits = 0;\n private cacheMisses = 0;\n private recommendationsMade = 0;\n\n constructor(config?: Partial<RoutingMemoryConfig>, mobimem?: MobiMem) {\n this.config = { ...DEFAULT_ROUTING_MEMORY_CONFIG, ...config };\n this.logger = this.config.logger ?? createLogger({ component: 'RoutingMemory' });\n this.mobimem = mobimem ?? new MobiMem();\n\n this.logger.info('RoutingMemory initialized', {\n minObservations: this.config.minObservations,\n confidenceThreshold: this.config.confidenceThreshold,\n });\n }\n\n storePreference(model: CliName, taskType: string, performance: ModelPerformance): void {\n // Store in MobiMem's profile memory using observe()\n const preferenceKey = `model_preference:${taskType}`;\n const entityId = `routing:${model}`;\n\n // Use observe() which handles incrementing observation count and updating confidence\n const entry = this.mobimem.profile.observe(entityId, 'agent', preferenceKey, {\n model,\n performance,\n updatedAt: getTimeProvider().nowIso(),\n });\n\n this.logger.debug('Stored model preference', {\n model,\n taskType,\n confidence: entry.confidence,\n observations: entry.observationCount,\n });\n }\n\n getPreferences(taskType: string): readonly ModelPreference[] {\n const preferenceKey = `model_preference:${taskType}`;\n const preferences: ModelPreference[] = [];\n\n for (const model of CLI_NAMES) {\n const entityId = `routing:${model}`;\n const entry = this.mobimem.profile.getPreference(entityId, preferenceKey);\n\n if (entry !== null && entry.observationCount >= this.config.minObservations) {\n const value = entry.preferenceValue as {\n model: CliName;\n performance: ModelPerformance;\n };\n\n preferences.push({\n model: value.model,\n strength: this.calculateStrength(value.performance),\n performance: value.performance,\n confidence: entry.confidence,\n });\n }\n }\n\n // Sort by strength (descending)\n return preferences.sort((a, b) => b.strength - a.strength);\n }\n\n recordExperience(\n workflow: string,\n models: readonly CliName[],\n success: boolean,\n metrics: { durationMs: number; tokensUsed: number; qualityScore?: number }\n ): void {\n // Create context signature from model sequence\n const contextSignature = models.join('->');\n\n // Build action sequence matching ActionStep interface\n const actionSequence: ActionStep[] = models.map((model, index) => ({\n index,\n actionType: 'model_route',\n parameters: { model },\n durationMs: Math.floor(metrics.durationMs / models.length),\n success,\n }));\n\n // Build outcome matching ExecutionOutcome interface\n const outcome: ExecutionOutcome =\n metrics.qualityScore !== undefined\n ? {\n success,\n qualityScore: metrics.qualityScore,\n totalDurationMs: metrics.durationMs,\n tokensUsed: metrics.tokensUsed,\n }\n : {\n success,\n totalDurationMs: metrics.durationMs,\n tokensUsed: metrics.tokensUsed,\n };\n\n // Store in MobiMem's experience memory using recordExecution()\n this.mobimem.experience.recordExecution(workflow, actionSequence, outcome, contextSignature);\n\n this.logger.debug('Recorded routing experience', {\n workflow,\n models: models.join('->'),\n success,\n durationMs: metrics.durationMs,\n });\n }\n\n getExperiencePatterns(workflow: string): readonly ExperiencePattern[] {\n const experiences = this.mobimem.experience.findPatterns(workflow);\n\n return experiences\n .filter((exp) => exp.successRate >= this.config.successRateThreshold)\n .map((exp) => this.mapExperienceToPattern(exp));\n }\n\n cacheAction(action: string, model: CliName, result: unknown, durationMs: number): void {\n // Cache using input object that includes action signature and model\n const input = { actionSignature: action, model };\n this.mobimem.action.cache(input, result, durationMs);\n\n this.logger.debug('Cached action result', { action: action.slice(0, 50), model, durationMs });\n }\n\n getCachedAction(action: string): CachedActionResult | undefined {\n // Look up using the same input structure used for caching\n // Note: We try with undefined model first, then specific models\n for (const model of CLI_NAMES) {\n const input = { actionSignature: action, model };\n const entry = this.mobimem.action.get(input);\n\n if (entry !== null) {\n // MobiMem's get() already handles expiration internally\n this.cacheHits++;\n const inputData = entry.input as { actionSignature: string; model: CliName };\n\n return {\n action,\n result: entry.result,\n model: inputData.model,\n cachedAt: entry.cachedAt,\n timeSavedMs: entry.timeSavedMs,\n };\n }\n }\n\n this.cacheMisses++;\n return undefined;\n }\n\n getRecommendation(taskType: string): CliName | undefined {\n const preferences = this.getPreferences(taskType);\n\n // Return highest-strength preference above threshold\n const top = preferences[0];\n if (top !== undefined && top.confidence >= this.config.confidenceThreshold) {\n this.recommendationsMade++;\n\n this.logger.debug('Generated routing recommendation', {\n taskType,\n recommended: top.model,\n confidence: top.confidence,\n strength: top.strength,\n });\n\n return top.model;\n }\n\n return undefined;\n }\n\n getStats(): RoutingMemoryStats {\n const mobiStats = this.mobimem.getStats();\n\n return {\n totalPreferences: mobiStats.profile.totalEntries,\n totalExperiences: mobiStats.experience.totalPatterns,\n cacheHits: this.cacheHits,\n cacheMisses: this.cacheMisses,\n recommendationsMade: this.recommendationsMade,\n };\n }\n\n // ========================================================================\n // Private Helpers\n // ========================================================================\n\n /**\n * Calculate preference strength from performance metrics.\n */\n private calculateStrength(performance: ModelPerformance): number {\n // Weighted combination of performance factors\n const qualityWeight = 0.4;\n const successWeight = 0.3;\n const speedWeight = 0.2;\n const efficiencyWeight = 0.1;\n\n // Normalize latency (lower is better, cap at 10s)\n const normalizedLatency = 1 - Math.min(performance.avgLatencyMs / 10000, 1);\n\n // Normalize tokens (lower is better, cap at 100k)\n const normalizedTokens = 1 - Math.min(performance.avgTokens / 100000, 1);\n\n return (\n performance.avgQuality * qualityWeight +\n performance.successRate * successWeight +\n normalizedLatency * speedWeight +\n normalizedTokens * efficiencyWeight\n );\n }\n\n /**\n * Map MobiMem experience entry to routing pattern.\n */\n private mapExperienceToPattern(exp: ExperienceEntry): ExperiencePattern {\n const models = exp.actionSequence\n .filter((step) => step.actionType === 'model_route')\n .map((step) => (step.parameters as { model: CliName }).model);\n\n const avgDuration = exp.outcome.totalDurationMs;\n\n return {\n workflow: exp.taskType,\n modelSequence: models,\n successRate: exp.successRate,\n avgDurationMs: avgDuration,\n usageCount: exp.attemptCount,\n };\n }\n}\n\n/**\n * Create a routing memory instance.\n */\nexport function createRoutingMemory(\n config?: Partial<RoutingMemoryConfig>,\n mobimem?: MobiMem\n): IRoutingMemory {\n return new RoutingMemory(config, mobimem);\n}\n","/**\n * Unified Router Stage Interface\n *\n * Provides a composable pipeline architecture for routing decisions.\n * Each stage can filter, score, or transform the routing context.\n *\n * Per ADR-0005, this consolidates 7 router implementations into\n * a unified stage-based pipeline.\n *\n * @module cli-adapters/routing/router-stage\n * (Source: Issue #574, ADR-0005)\n */\n\nimport { z } from 'zod';\nimport { CliNameSchema, type CliNameLiteral } from '../../config/model-capabilities-types.js';\nimport type { Result } from '../../core/result.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * CLI adapter names for routing.\n * Derived from canonical source: config/model-capabilities-types.ts CliNameLiteral\n */\nexport type CliName = CliNameLiteral;\n\n/**\n * Routing context passed through pipeline stages.\n */\nexport interface RoutingContext {\n /** Original task description */\n readonly task: string;\n /** Task metadata */\n readonly metadata: Record<string, unknown> | undefined;\n /** Available CLI adapters to route to */\n readonly availableClis: readonly CliName[];\n /** Candidate scores accumulated by stages */\n readonly scores: Map<CliName, number>;\n /** Candidates filtered out by stages */\n readonly filtered: Map<CliName, string>;\n /** Signals collected from stages */\n readonly signals: string[];\n /** Stage execution trace */\n readonly trace: StageTrace[];\n}\n\n/**\n * Trace entry for a single stage execution.\n */\nexport interface StageTrace {\n readonly stageName: string;\n readonly durationMs: number;\n readonly action: 'filter' | 'score' | 'transform' | 'skip';\n readonly details: string | undefined;\n}\n\n/**\n * Result from a single routing stage.\n */\nexport interface StageResult {\n /** Updated context (immutable pattern - return new context) */\n readonly context: RoutingContext;\n /** Whether to continue to next stage */\n readonly continuesPipeline: boolean;\n /** Optional early decision (stops pipeline) */\n readonly decision?: RoutingDecision;\n}\n\n/**\n * Error from a routing stage.\n */\nexport interface StageError {\n readonly stage: string;\n readonly code: 'invalid_input' | 'no_candidates' | 'stage_failed' | 'timeout';\n readonly message: string;\n readonly cause: Error | undefined;\n}\n\n/**\n * Final routing decision.\n */\nexport interface RoutingDecision {\n /** Selected CLI adapter */\n readonly selectedCli: CliName;\n /** Confidence score (0-1) */\n readonly confidence: number;\n /** Human-readable reason */\n readonly reason: string;\n /** Alternative candidates in ranked order */\n readonly alternatives: readonly CliName[];\n /** Total routing time in ms */\n readonly routingTimeMs: number;\n /** Execution trace through pipeline */\n readonly trace: readonly StageTrace[];\n}\n\n/**\n * Outcome for feedback/calibration.\n */\nexport interface RoutingOutcome {\n /** The CLI that was selected */\n readonly selectedCli: CliName;\n /** The original task */\n readonly task: string;\n /** Whether the task succeeded */\n readonly success: boolean;\n /** Quality score (0-1) if available */\n readonly qualityScore?: number;\n /** Latency in ms */\n readonly latencyMs?: number;\n /** Tokens used */\n readonly tokensUsed?: number;\n}\n\n/**\n * Configuration for a routing stage.\n */\nexport interface StageConfig {\n /** Whether this stage is enabled */\n readonly enabled: boolean;\n /** Stage priority (lower = earlier in pipeline) */\n readonly priority: number;\n /** Stage-specific configuration */\n readonly options?: Record<string, unknown>;\n}\n\n// ============================================================================\n// Interfaces\n// ============================================================================\n\n/**\n * A single stage in the routing pipeline.\n *\n * Stages can:\n * - Filter out candidates (set filtered map)\n * - Score candidates (update scores map)\n * - Transform context (add signals, metadata)\n * - Make early decisions (return decision in result)\n */\nexport interface IRouterStage {\n /** Unique stage name */\n readonly name: string;\n\n /** Stage priority (lower = earlier) */\n readonly priority: number;\n\n /**\n * Check if this stage can handle the given context.\n * Returning false skips the stage.\n */\n canHandle(ctx: RoutingContext): boolean;\n\n /**\n * Execute the routing stage.\n * Returns updated context or early decision.\n */\n route(ctx: RoutingContext): Promise<Result<StageResult, StageError>>;\n\n /**\n * Record outcome for learning/calibration (optional).\n */\n recordOutcome?(outcome: RoutingOutcome): void;\n\n /**\n * Get stage statistics (optional).\n */\n getStats?(): Record<string, unknown>;\n}\n\n/**\n * Composable routing pipeline.\n */\nexport interface IRoutingPipeline {\n /**\n * Execute the full pipeline.\n */\n execute(\n task: string,\n metadata?: Record<string, unknown>\n ): Promise<Result<RoutingDecision, StageError>>;\n\n /**\n * Add a stage to the pipeline.\n */\n addStage(stage: IRouterStage): void;\n\n /**\n * Remove a stage by name.\n */\n removeStage(name: string): boolean;\n\n /**\n * Get all stages in execution order.\n */\n getStages(): readonly IRouterStage[];\n\n /**\n * Record outcome for all stages that support feedback.\n */\n recordOutcome(outcome: RoutingOutcome): void;\n\n /**\n * Get pipeline statistics.\n */\n getStats(): PipelineStats;\n}\n\n/**\n * Pipeline execution statistics.\n */\nexport interface PipelineStats {\n readonly totalRoutings: number;\n readonly averageLatencyMs: number;\n readonly successRate: number;\n readonly stageStats: Record<string, Record<string, unknown>>;\n}\n\n// ============================================================================\n// Zod Schemas\n// ============================================================================\n\n// CliNameSchema imported from config/model-capabilities-types.ts (canonical source)\nexport { CliNameSchema } from '../../config/model-capabilities-types.js';\n\nexport const StageConfigSchema = z.object({\n enabled: z.boolean().default(true),\n priority: z.number().int().min(0).max(100).default(50),\n options: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const RoutingOutcomeSchema = z.object({\n selectedCli: CliNameSchema,\n task: z.string(),\n success: z.boolean(),\n qualityScore: z.number().min(0).max(1).optional(),\n latencyMs: z.number().int().positive().optional(),\n tokensUsed: z.number().int().positive().optional(),\n});\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Creates an initial routing context.\n */\nexport function createRoutingContext(\n task: string,\n availableClis: readonly CliName[] = ['claude', 'gemini', 'codex', 'opencode'],\n metadata?: Record<string, unknown>\n): RoutingContext {\n return {\n task,\n metadata,\n availableClis,\n scores: new Map(availableClis.map((cli) => [cli, 0])),\n filtered: new Map(),\n signals: [],\n trace: [],\n };\n}\n\n/**\n * Creates a stage error.\n */\nexport function createStageError(\n stage: string,\n code: StageError['code'],\n message: string,\n cause?: Error\n): StageError {\n return { stage, code, message, cause };\n}\n\n/**\n * Adds a trace entry to the context.\n */\nexport function addTrace(\n ctx: RoutingContext,\n stageName: string,\n durationMs: number,\n action: StageTrace['action'],\n details?: string\n): RoutingContext {\n return {\n ...ctx,\n trace: [...ctx.trace, { stageName, durationMs, action, details }],\n };\n}\n\n/**\n * Filters a candidate from the context.\n */\nexport function filterCandidate(ctx: RoutingContext, cli: CliName, reason: string): RoutingContext {\n const newFiltered = new Map(ctx.filtered);\n newFiltered.set(cli, reason);\n return { ...ctx, filtered: newFiltered };\n}\n\n/**\n * Updates a candidate's score in the context.\n */\nexport function updateScore(ctx: RoutingContext, cli: CliName, scoreDelta: number): RoutingContext {\n const newScores = new Map(ctx.scores);\n newScores.set(cli, (newScores.get(cli) ?? 0) + scoreDelta);\n return { ...ctx, scores: newScores };\n}\n\n/**\n * Gets remaining (non-filtered) candidates.\n */\nexport function getRemainingCandidates(ctx: RoutingContext): CliName[] {\n return ctx.availableClis.filter((cli) => !ctx.filtered.has(cli));\n}\n\n/**\n * Selects the best candidate based on scores.\n */\nexport function selectBestCandidate(\n ctx: RoutingContext\n): { cli: CliName; score: number } | undefined {\n const remaining = getRemainingCandidates(ctx);\n const first = remaining[0];\n if (first === undefined) return undefined;\n\n let bestCli: CliName = first;\n let bestScore = ctx.scores.get(bestCli) ?? 0;\n\n for (const cli of remaining) {\n const score = ctx.scores.get(cli) ?? 0;\n if (score > bestScore) {\n bestCli = cli;\n bestScore = score;\n }\n }\n\n return { cli: bestCli, score: bestScore };\n}\n","/**\n * Confidence Router Types and Constants\n *\n * Type definitions and configuration constants for confidence-aware\n * cascade routing based on SATER pattern.\n *\n * @module cli-adapters/confidence-router-types\n * (Source: Issue #99, arXiv:2510.05164 - EMNLP 2025)\n */\n\nimport type { CliResponse, ConfidenceEstimate, CascadeOptions } from './types.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Response cache entry for avoiding redundant model calls.\n */\nexport interface CacheEntry {\n readonly response: CliResponse;\n readonly confidence: ConfidenceEstimate;\n readonly timestamp: number;\n}\n\n/**\n * Task complexity levels for confidence estimation.\n */\nexport type TaskComplexity = 'simple' | 'moderate' | 'complex';\n\n/**\n * Cache statistics for monitoring.\n */\nexport interface CacheStats {\n readonly size: number;\n readonly maxSize: number;\n readonly maxAgeMs: number;\n}\n\n// =============================================================================\n// Default Configuration\n// =============================================================================\n\n/**\n * Default cascade configuration.\n */\nexport const DEFAULT_CASCADE_OPTIONS: Required<CascadeOptions> = {\n confidenceThreshold: 0.7,\n fastModel: 'gemini', // Gemini Flash for speed/cost\n expensiveModel: 'claude', // Claude for quality\n maxEscalations: 2,\n cacheResponses: true,\n};\n\n// =============================================================================\n// Confidence Indicators\n// =============================================================================\n\n/**\n * Hedging phrases that indicate low confidence in responses.\n * Static patterns only (no user-provided RegExp - ReDoS prevention).\n */\nexport const HEDGING_PHRASES = [\n 'i think',\n 'i believe',\n 'probably',\n 'maybe',\n 'might be',\n 'could be',\n 'possibly',\n 'not sure',\n 'uncertain',\n 'i guess',\n \"i'm not certain\",\n 'it seems',\n 'appears to',\n 'likely',\n 'unlikely',\n] as const;\n\n/**\n * Uncertainty indicators that suggest the model lacks confidence.\n */\nexport const UNCERTAINTY_INDICATORS = [\n 'however',\n 'although',\n 'but',\n 'on the other hand',\n 'alternatively',\n 'caveat',\n 'note that',\n 'be aware',\n 'keep in mind',\n 'disclaimer',\n] as const;\n\n// =============================================================================\n// Complexity Indicators\n// =============================================================================\n\n/**\n * Keywords indicating complex tasks.\n */\nexport const COMPLEX_TASK_INDICATORS = [\n 'design',\n 'architecture',\n 'implement',\n 'optimize',\n 'refactor',\n 'security',\n 'performance',\n 'scalable',\n 'distributed',\n 'algorithm',\n] as const;\n\n/**\n * Keywords indicating simple tasks.\n */\nexport const SIMPLE_TASK_INDICATORS = [\n 'fix',\n 'add',\n 'remove',\n 'update',\n 'change',\n 'simple',\n 'basic',\n 'quick',\n] as const;\n\n// =============================================================================\n// Confidence Weights\n// =============================================================================\n\n/**\n * Weights for confidence factor calculation (from SATER paper).\n */\nexport const CONFIDENCE_WEIGHTS = {\n length: 0.2,\n hedging: 0.3,\n structure: 0.25,\n uncertainty: 0.25,\n} as const;\n\n/**\n * Expected word count ranges by task complexity.\n */\nexport const EXPECTED_WORD_COUNTS: Record<TaskComplexity, { min: number; max: number }> = {\n simple: { min: 20, max: 200 },\n moderate: { min: 50, max: 500 },\n complex: { min: 100, max: 1000 },\n} as const;\n","/**\n * Confidence Cascade Stage\n *\n * Routes based on task complexity and model confidence profiles.\n * Simpler tasks can use faster/cheaper models; complex tasks escalate.\n *\n * @module cli-adapters/routing/stages/confidence-cascade-stage\n * (Source: ADR-0005, Issue #99, arXiv:2510.05164 - SATER pattern)\n */\n\nimport type { Result } from '../../../core/result.js';\nimport type { ILogger } from '../../../core/index.js';\nimport { ok, createLogger, getTimeProvider } from '../../../core/index.js';\nimport type {\n IRouterStage,\n RoutingContext,\n StageResult,\n StageError,\n RoutingOutcome,\n CliName,\n} from '../router-stage.js';\nimport { addTrace, updateScore, getRemainingCandidates } from '../router-stage.js';\nimport {\n type TaskComplexity,\n COMPLEX_TASK_INDICATORS,\n SIMPLE_TASK_INDICATORS,\n} from '../../confidence-router-types.js';\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\n/**\n * Confidence profile for each CLI based on typical performance.\n */\nconst CLI_CONFIDENCE_PROFILES: Record<CliName, { simpleScore: number; complexScore: number }> = {\n claude: { simpleScore: 0.7, complexScore: 1.0 }, // Best for complex reasoning\n gemini: { simpleScore: 1.0, complexScore: 0.6 }, // Fast for simple tasks\n codex: { simpleScore: 0.8, complexScore: 0.9 }, // Good for code tasks\n opencode: { simpleScore: 0.8, complexScore: 0.7 }, // Multi-provider proxy\n};\n\n/**\n * Configuration for the confidence cascade stage.\n */\nexport interface ConfidenceCascadeConfig {\n /** Threshold for escalating to more capable model */\n readonly escalationThreshold: number;\n /** Weight for complexity-based scoring */\n readonly complexityWeight: number;\n /** Enable debug logging */\n readonly debug: boolean;\n}\n\nconst DEFAULT_CONFIG: ConfidenceCascadeConfig = {\n escalationThreshold: 0.7,\n complexityWeight: 0.3,\n debug: false,\n};\n\n// ============================================================================\n// Stage Implementation\n// ============================================================================\n\n/**\n * Confidence Cascade Stage for complexity-aware routing.\n * Runs early (priority 10) to establish baseline confidence scores.\n */\nexport class ConfidenceCascadeStage implements IRouterStage {\n readonly name = 'confidence-cascade';\n readonly priority = 10; // Runs earliest - sets foundation\n\n private readonly config: ConfidenceCascadeConfig;\n private readonly logger: ILogger;\n private routingsCount = 0;\n private escalationCount = 0;\n private complexityDistribution = { simple: 0, moderate: 0, complex: 0 };\n\n constructor(config: Partial<ConfidenceCascadeConfig> = {}, logger?: ILogger) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.logger = logger ?? createLogger({ component: 'ConfidenceCascadeStage' });\n }\n\n canHandle(ctx: RoutingContext): boolean {\n return getRemainingCandidates(ctx).length > 0;\n }\n\n route(ctx: RoutingContext): Promise<Result<StageResult, StageError>> {\n const time = getTimeProvider();\n const startTime = time.now();\n const remaining = getRemainingCandidates(ctx);\n\n this.routingsCount++;\n\n const complexity = this.estimateComplexity(ctx.task);\n this.complexityDistribution[complexity]++;\n\n let updatedCtx = ctx;\n const scores: Array<{ cli: CliName; score: number }> = [];\n\n for (const cli of remaining) {\n const score = this.calculateConfidenceScore(cli, complexity);\n scores.push({ cli, score });\n updatedCtx = updateScore(updatedCtx, cli, score * this.config.complexityWeight);\n }\n\n const shouldEscalate = this.checkEscalation(scores, complexity);\n if (shouldEscalate) {\n this.escalationCount++;\n }\n\n const signals = this.buildSignals(ctx.signals, complexity, shouldEscalate, scores);\n const durationMs = time.now() - startTime;\n\n const finalCtx = addTrace(\n updatedCtx,\n this.name,\n durationMs,\n 'score',\n `Complexity: ${complexity}, escalate: ${String(shouldEscalate)}`\n );\n\n this.logger.debug('Confidence cascade complete', {\n complexity,\n shouldEscalate,\n scores: scores.map((s) => `${s.cli}:${s.score.toFixed(2)}`),\n });\n\n return Promise.resolve(ok({ context: { ...finalCtx, signals }, continuesPipeline: true }));\n }\n\n recordOutcome(outcome: RoutingOutcome): void {\n this.logger.debug('Confidence outcome recorded', {\n cli: outcome.selectedCli,\n success: outcome.success,\n qualityScore: outcome.qualityScore,\n });\n }\n\n getStats(): Record<string, unknown> {\n return {\n routingsCount: this.routingsCount,\n escalationCount: this.escalationCount,\n escalationRate: this.routingsCount > 0 ? this.escalationCount / this.routingsCount : 0,\n complexityDistribution: { ...this.complexityDistribution },\n config: {\n escalationThreshold: this.config.escalationThreshold,\n complexityWeight: this.config.complexityWeight,\n },\n };\n }\n\n /**\n * Estimate task complexity from content.\n */\n private estimateComplexity(task: string): TaskComplexity {\n const content = task.toLowerCase();\n const wordCount = content.split(/\\s+/).length;\n\n const complexCount = COMPLEX_TASK_INDICATORS.filter((i) => content.includes(i)).length;\n const simpleCount = SIMPLE_TASK_INDICATORS.filter((i) => content.includes(i)).length;\n\n if (wordCount > 100 || complexCount >= 2) {\n return 'complex';\n } else if (wordCount < 30 || simpleCount >= 2) {\n return 'simple';\n }\n return 'moderate';\n }\n\n /**\n * Calculate confidence score for a CLI based on task complexity.\n */\n private calculateConfidenceScore(cli: CliName, complexity: TaskComplexity): number {\n const profile = CLI_CONFIDENCE_PROFILES[cli];\n\n switch (complexity) {\n case 'simple':\n return profile.simpleScore;\n case 'complex':\n return profile.complexScore;\n case 'moderate':\n // Blend simple and complex scores\n return (profile.simpleScore + profile.complexScore) / 2;\n }\n }\n\n /**\n * Check if task should escalate to more capable model.\n */\n private checkEscalation(\n scores: Array<{ cli: CliName; score: number }>,\n complexity: TaskComplexity\n ): boolean {\n if (complexity === 'simple') return false;\n\n const maxScore = Math.max(...scores.map((s) => s.score));\n return maxScore < this.config.escalationThreshold;\n }\n\n /**\n * Build routing signals for the context.\n */\n private buildSignals(\n existing: string[],\n complexity: TaskComplexity,\n shouldEscalate: boolean,\n scores: Array<{ cli: CliName; score: number }>\n ): string[] {\n const signals = [...existing];\n\n signals.push(`confidence:complexity-${complexity}`);\n\n if (shouldEscalate) {\n signals.push('confidence:should-escalate');\n }\n\n const best = [...scores].sort((a, b) => b.score - a.score)[0];\n if (best !== undefined) {\n signals.push(`confidence:best-${best.cli}`);\n }\n\n return signals;\n }\n}\n\n/**\n * Creates a confidence cascade stage.\n */\nexport function createConfidenceCascadeStage(\n config?: Partial<ConfidenceCascadeConfig>,\n logger?: ILogger\n): ConfidenceCascadeStage {\n return new ConfidenceCascadeStage(config, logger);\n}\n","/**\n * Type definitions for the Task Specialization Matrix.\n *\n * Maps high-level task categories to preferred CLI tools based on\n * model strengths, inspired by StrongDM's Weather Report approach.\n *\n * @module config/task-specialization-types\n * (Source: Issue #858 — Multi-model task specialization)\n */\n\nimport { z } from 'zod';\nimport { CliNameSchema } from './model-capabilities-types.js';\nimport type { CliNameLiteral } from './model-capabilities-types.js';\n\n/**\n * High-level task categories for CLI specialization routing.\n */\nexport const TASK_CATEGORIES = [\n 'architecture',\n 'code_generation',\n 'code_review',\n 'research',\n 'security_review',\n 'planning',\n 'documentation',\n 'testing',\n 'devops',\n 'exploration',\n] as const;\n\nexport const TaskCategorySchema = z.enum(TASK_CATEGORIES);\nexport type TaskCategory = z.infer<typeof TaskCategorySchema>;\n\n/**\n * A single task specialization entry mapping a category to CLI preferences.\n */\nexport const TaskSpecializationSchema = z.object({\n /** Task category identifier */\n category: TaskCategorySchema,\n /** Primary CLI recommendation */\n primaryCli: CliNameSchema,\n /** Secondary CLI fallback */\n secondaryCli: CliNameSchema,\n /** Why this CLI is preferred for this task type */\n reasoning: z.string(),\n /** Keywords that trigger this category detection */\n keywords: z.array(z.string()).min(1),\n /** Bonus score applied when this category matches (0-20) */\n bonus: z.number().min(0).max(20),\n});\n\nexport type TaskSpecialization = z.infer<typeof TaskSpecializationSchema>;\n\n/**\n * Result of looking up a task's specialization.\n */\nexport interface SpecializationMatch {\n /** Matched category */\n readonly category: TaskCategory;\n /** Recommended primary CLI */\n readonly primaryCli: CliNameLiteral;\n /** Fallback CLI */\n readonly secondaryCli: CliNameLiteral;\n /** Score bonus for the preferred model */\n readonly bonus: number;\n}\n","/**\n * Task Specialization Matrix — maps task categories to optimal CLIs.\n *\n * Based on real-world model strengths (inspired by StrongDM Weather Report):\n * - Claude: strongest reasoning, architecture, security analysis\n * - Codex: strongest code generation, testing, implementation\n * - Gemini: largest context, deep research, documentation\n *\n * @module config/task-specialization\n * (Source: Issue #858 — Multi-model task specialization)\n */\n\nimport type {\n TaskSpecialization,\n TaskCategory,\n SpecializationMatch,\n} from './task-specialization-types.js';\nimport { TASK_CATEGORIES } from './task-specialization-types.js';\n\n// Re-export types for consumer convenience\nexport type {\n TaskSpecialization,\n TaskCategory,\n SpecializationMatch,\n} from './task-specialization-types.js';\nexport {\n TASK_CATEGORIES,\n TaskCategorySchema,\n TaskSpecializationSchema,\n} from './task-specialization-types.js';\n\n/**\n * Canonical task specialization matrix.\n *\n * Each entry maps a task category to the CLI best suited for it,\n * with keywords for automatic detection and a score bonus.\n */\nexport const TASK_SPECIALIZATION_MATRIX: readonly TaskSpecialization[] = [\n {\n category: 'architecture',\n primaryCli: 'gemini',\n secondaryCli: 'claude',\n reasoning:\n 'Gemini primary (66.7%, n=24) for architecture. Claude secondary (43.6%, n=220). Weather data 2026-03-09.',\n keywords: ['architect', 'design', 'system design', 'trade-off', 'adr'],\n bonus: 10,\n },\n {\n category: 'code_generation',\n primaryCli: 'codex',\n secondaryCli: 'claude',\n reasoning:\n 'Codex primary (91.9%, n=408) for code generation with sandboxed execution. Confirmed per weather data (#1454)',\n keywords: ['implement', 'generate code', 'write function', 'build feature'],\n bonus: 15,\n },\n {\n category: 'code_review',\n primaryCli: 'codex',\n secondaryCli: 'claude',\n reasoning:\n 'Codex primary (88.3%, n=94) for code review; Claude secondary. Bonus aligned per weather data (#1454)',\n keywords: ['review code', 'code review', 'pull request', 'pr review'],\n bonus: 15,\n },\n {\n category: 'research',\n primaryCli: 'gemini',\n secondaryCli: 'claude',\n reasoning: 'Gemini has deep_research feature and 1M token context for synthesis',\n keywords: ['research', 'investigate', 'literature', 'survey', 'state of the art'],\n bonus: 15,\n },\n {\n category: 'security_review',\n primaryCli: 'codex',\n secondaryCli: 'claude',\n reasoning:\n 'Weather 2026-03-09: claude 44.9% (n=385, declining), codex 60% (n=5), gemini 50% (n=14). Codex primary, claude secondary. Low bonus — no CLI is clearly dominant.',\n keywords: [\n 'security review',\n 'security analysis',\n 'security audit',\n 'security flaw',\n 'vulnerability assessment',\n 'threat model',\n 'cve',\n 'audit security',\n 'owasp',\n 'injection',\n 'xss',\n 'csrf',\n 'security',\n 'vulnerability',\n ],\n bonus: 5,\n },\n {\n category: 'planning',\n primaryCli: 'claude',\n secondaryCli: 'codex',\n reasoning:\n 'Claude primary (92.0%, n=274) for planning and task decomposition. Confirmed per weather data (#1454)',\n keywords: ['plan', 'sprint', 'roadmap', 'decompose', 'prioritize'],\n bonus: 10,\n },\n {\n category: 'documentation',\n primaryCli: 'gemini',\n secondaryCli: 'claude',\n reasoning: 'Gemini can process entire codebases (1M context) for comprehensive docs',\n keywords: ['document', 'documentation', 'readme', 'api docs', 'write docs'],\n bonus: 10,\n },\n {\n category: 'testing',\n primaryCli: 'codex',\n secondaryCli: 'claude',\n reasoning:\n 'Codex primary (91.6%, n=143) for test writing with sandbox execution. Bonus aligned per weather data (#1454)',\n keywords: ['test', 'write tests', 'test coverage', 'unit test', 'integration test'],\n bonus: 15,\n },\n {\n category: 'devops',\n primaryCli: 'claude',\n secondaryCli: 'gemini',\n reasoning: 'Claude excels at infrastructure reasoning and CI/CD configuration',\n keywords: [\n 'devops',\n 'ci/cd',\n 'deploy',\n 'infrastructure',\n 'docker',\n 'kubernetes',\n 'pipeline',\n 'helm',\n 'terraform',\n 'ansible',\n 'makefile',\n 'dockerfile',\n 'github actions',\n 'workflow',\n 'concourse',\n 'jenkins',\n 'argocd',\n 'vulnerability scan',\n 'security scan',\n 'sast',\n 'dast',\n 'zap',\n 'semgrep',\n 'grype',\n 'fork',\n 'kind',\n 'cluster',\n 'namespace',\n 'ingress',\n 'monitoring',\n ],\n bonus: 10,\n },\n {\n category: 'exploration',\n primaryCli: 'gemini',\n secondaryCli: 'codex',\n reasoning:\n 'Gemini primary (98.5%, n=202) for exploration with 1M context. Claude removed as secondary (63.5% vs 98.5%, n=340) per #1462',\n keywords: ['explore', 'navigate', 'find', 'discover', 'scan codebase'],\n bonus: 15,\n },\n] as const;\n\n/** Index for O(1) category lookup. */\nconst CATEGORY_INDEX = new Map<TaskCategory, TaskSpecialization>(\n TASK_SPECIALIZATION_MATRIX.map((s) => [s.category, s])\n);\n\n/**\n * Get specialization for a known task category.\n */\nexport function getSpecialization(category: TaskCategory): TaskSpecialization {\n const spec = CATEGORY_INDEX.get(category);\n if (!spec) throw new Error(`Unknown category: ${category}`);\n return spec;\n}\n\n/**\n * Detect task category from free-text task description.\n * Uses best-match scoring: counts keyword hits weighted by keyword length\n * (multi-word keywords like \"security scan\" score higher than \"security\").\n * Breaks ties by matrix order.\n */\nexport function detectTaskCategory(task: string): SpecializationMatch | null {\n const taskLower = task.toLowerCase();\n let bestSpec: TaskSpecialization | undefined;\n let bestScore = 0;\n\n for (const spec of TASK_SPECIALIZATION_MATRIX) {\n let score = 0;\n for (const kw of spec.keywords) {\n if (taskLower.includes(kw)) {\n // Multi-word keywords score higher (more specific match)\n score += kw.split(/\\s+/).length;\n }\n }\n if (score > bestScore) {\n bestScore = score;\n bestSpec = spec;\n }\n }\n\n if (bestSpec === undefined) return null;\n\n return {\n category: bestSpec.category,\n primaryCli: bestSpec.primaryCli,\n secondaryCli: bestSpec.secondaryCli,\n bonus: bestSpec.bonus,\n };\n}\n\n/**\n * Get all task categories.\n */\nexport function getTaskCategories(): readonly TaskCategory[] {\n return TASK_CATEGORIES;\n}\n","/**\n * Capability Match Stage\n *\n * Scores candidates based on capability profile matching to task requirements.\n * Uses weighted multi-criteria scoring based on task type.\n *\n * @module cli-adapters/routing/stages/capability-match-stage\n * (Source: ADR-0005, arXiv:2508.21141 - PILOT pattern)\n */\n\nimport type { Result } from '../../../core/result.js';\nimport type { ILogger } from '../../../core/index.js';\nimport { ok, createLogger, getTimeProvider } from '../../../core/index.js';\nimport type {\n IRouterStage,\n RoutingContext,\n StageResult,\n StageError,\n RoutingOutcome,\n CliName,\n} from '../router-stage.js';\nimport { addTrace, updateScore, getRemainingCandidates } from '../router-stage.js';\nimport { detectTaskCategory } from '../../../config/task-specialization.js';\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\n/**\n * Task type categories for capability matching.\n */\ntype TaskType = 'reasoning' | 'code' | 'creative' | 'general';\n\n/**\n * Capability dimensions for scoring.\n */\ninterface CapabilityProfile {\n readonly reasoning: number; // 0-10\n readonly codeGeneration: number; // 0-10\n readonly speed: number; // 0-10\n readonly costEfficiency: number; // 0-10\n}\n\n/**\n * Capability weights by dimension.\n */\ninterface CapabilityWeights {\n readonly reasoning: number;\n readonly codeGeneration: number;\n readonly speed: number;\n readonly costEfficiency: number;\n}\n\n/**\n * CLI capability profiles (0-10 scale).\n */\nconst CLI_CAPABILITIES: Record<CliName, CapabilityProfile> = {\n claude: { reasoning: 10, codeGeneration: 8, speed: 5, costEfficiency: 3 },\n gemini: { reasoning: 7, codeGeneration: 7, speed: 9, costEfficiency: 9 },\n codex: { reasoning: 6, codeGeneration: 10, speed: 8, costEfficiency: 7 },\n opencode: { reasoning: 7, codeGeneration: 8, speed: 7, costEfficiency: 6 },\n};\n\n/**\n * Task type indicators for classification.\n */\nconst TASK_TYPE_INDICATORS: Record<TaskType, string[]> = {\n reasoning: ['analyze', 'explain', 'why', 'reason', 'think', 'consider', 'evaluate', 'compare'],\n code: ['implement', 'code', 'function', 'class', 'bug', 'fix', 'refactor', 'test', 'debug'],\n creative: ['write', 'create', 'design', 'generate', 'story', 'content', 'draft'],\n general: ['help', 'what', 'how', 'show', 'list', 'find', 'search'],\n};\n\n/**\n * Cross-attention matrix: for each task feature, weights each capability dimension.\n * Entry [feature][capability] = attention weight (how important capability is for feature).\n * Rows sum to 1.0 (softmax-normalized). Each row is a CapabilityWeights.\n *\n * This implements a simplified cross-attention mechanism (arXiv:2508.21141 PILOT)\n * where task features attend to model capabilities via learned/configured weights.\n */\ntype AttentionMatrix = Record<TaskType, CapabilityWeights>;\n\n/**\n * Default attention matrix — manually tuned from outcome data.\n * Each row defines how a task feature attends to capability dimensions.\n */\nconst DEFAULT_ATTENTION: AttentionMatrix = {\n reasoning: { reasoning: 0.5, codeGeneration: 0.2, speed: 0.1, costEfficiency: 0.2 },\n code: { reasoning: 0.2, codeGeneration: 0.5, speed: 0.1, costEfficiency: 0.2 },\n creative: { reasoning: 0.3, codeGeneration: 0.1, speed: 0.2, costEfficiency: 0.4 },\n general: { reasoning: 0.25, codeGeneration: 0.25, speed: 0.25, costEfficiency: 0.25 },\n};\n\n/**\n * Configuration for the capability match stage.\n */\nexport interface CapabilityMatchConfig {\n /** Weight for capability scoring in overall score */\n readonly capabilityWeight: number;\n /** Bonus for task-type specialization */\n readonly specializationBonus: number;\n /** Enable debug logging */\n readonly debug: boolean;\n /** Custom attention matrix (overrides default cross-attention weights) */\n readonly attention?: AttentionMatrix;\n}\n\nconst DEFAULT_CONFIG: CapabilityMatchConfig = {\n capabilityWeight: 0.4,\n specializationBonus: 0.15,\n debug: false,\n};\n\n// ============================================================================\n// Stage Implementation\n// ============================================================================\n\n/**\n * Capability Match Stage for task-aware routing.\n * Runs after confidence (priority 35) to add capability-based scoring.\n */\nexport class CapabilityMatchStage implements IRouterStage {\n readonly name = 'capability-match';\n readonly priority = 35; // After confidence, before zero\n\n private readonly config: CapabilityMatchConfig;\n private readonly logger: ILogger;\n private routingsCount = 0;\n private taskTypeDistribution: Record<TaskType, number> = {\n reasoning: 0,\n code: 0,\n creative: 0,\n general: 0,\n };\n\n constructor(config: Partial<CapabilityMatchConfig> = {}, logger?: ILogger) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.logger = logger ?? createLogger({ component: 'CapabilityMatchStage' });\n }\n\n canHandle(ctx: RoutingContext): boolean {\n return getRemainingCandidates(ctx).length > 0;\n }\n\n route(ctx: RoutingContext): Promise<Result<StageResult, StageError>> {\n const time = getTimeProvider();\n const startTime = time.now();\n const remaining = getRemainingCandidates(ctx);\n\n this.routingsCount++;\n\n const taskType = this.classifyTaskType(ctx.task);\n this.taskTypeDistribution[taskType]++;\n\n const weights = this.getCapabilityWeights(taskType);\n let updatedCtx = ctx;\n const scores: Array<{ cli: CliName; score: number; dominant: string }> = [];\n\n for (const cli of remaining) {\n const { score, dominant } = this.calculateCapabilityMatch(cli, weights, taskType, ctx.task);\n scores.push({ cli, score, dominant });\n updatedCtx = updateScore(updatedCtx, cli, score * this.config.capabilityWeight);\n }\n\n const signals = this.buildSignals(ctx.signals, taskType, scores);\n const durationMs = time.now() - startTime;\n\n const finalCtx = addTrace(\n updatedCtx,\n this.name,\n durationMs,\n 'score',\n `TaskType: ${taskType}, candidates: ${String(remaining.length)}`\n );\n\n this.logger.debug('Capability match complete', {\n taskType,\n scores: scores.map((s) => `${s.cli}:${s.score.toFixed(2)}(${s.dominant})`),\n });\n\n return Promise.resolve(ok({ context: { ...finalCtx, signals }, continuesPipeline: true }));\n }\n\n recordOutcome(outcome: RoutingOutcome): void {\n this.logger.debug('Capability outcome recorded', {\n cli: outcome.selectedCli,\n success: outcome.success,\n qualityScore: outcome.qualityScore,\n });\n }\n\n getStats(): Record<string, unknown> {\n return {\n routingsCount: this.routingsCount,\n taskTypeDistribution: { ...this.taskTypeDistribution },\n config: {\n capabilityWeight: this.config.capabilityWeight,\n specializationBonus: this.config.specializationBonus,\n attentionSource: this.config.attention !== undefined ? 'custom' : 'default',\n },\n };\n }\n\n /**\n * Classify task type from content.\n */\n private classifyTaskType(task: string): TaskType {\n const content = task.toLowerCase();\n const counts: Record<TaskType, number> = { reasoning: 0, code: 0, creative: 0, general: 0 };\n\n for (const [type, indicators] of Object.entries(TASK_TYPE_INDICATORS)) {\n counts[type as TaskType] = indicators.filter((i) => content.includes(i)).length;\n }\n\n const maxCount = Math.max(...Object.values(counts));\n if (maxCount === 0) return 'general';\n\n const entries = Object.entries(counts) as Array<[TaskType, number]>;\n const sorted = entries.sort((a, b) => b[1] - a[1]);\n return sorted[0]?.[0] ?? 'general';\n }\n\n /**\n * Get capability weights via cross-attention lookup.\n * Each task type attends to capability dimensions with configured weights.\n */\n private getCapabilityWeights(taskType: TaskType): CapabilityWeights {\n const attention = this.config.attention ?? DEFAULT_ATTENTION;\n return attention[taskType];\n }\n\n /**\n * Calculate capability match score for a CLI.\n */\n private calculateCapabilityMatch(\n cli: CliName,\n weights: CapabilityWeights,\n taskType: TaskType,\n taskContent: string\n ): { score: number; dominant: string } {\n const caps = CLI_CAPABILITIES[cli];\n\n // Normalize capabilities to 0-1 scale\n const normalized = {\n reasoning: caps.reasoning / 10,\n codeGeneration: caps.codeGeneration / 10,\n speed: caps.speed / 10,\n costEfficiency: caps.costEfficiency / 10,\n };\n\n // Calculate weighted score\n let score =\n normalized.reasoning * weights.reasoning +\n normalized.codeGeneration * weights.codeGeneration +\n normalized.speed * weights.speed +\n normalized.costEfficiency * weights.costEfficiency;\n\n // Add specialization bonus from task specialization matrix\n score += this.getSpecializationBonus(cli, taskContent);\n\n // Find dominant capability\n const capEntries = Object.entries(normalized);\n const sorted = capEntries.sort((a, b) => b[1] - a[1]);\n const dominant = sorted[0]?.[0] ?? 'balanced';\n\n return { score: Math.min(1, score), dominant };\n }\n\n /**\n * Gets specialization bonus for a CLI based on the task specialization matrix.\n * Uses detectTaskCategory() from the canonical matrix for full 10-category coverage.\n */\n private getSpecializationBonus(cli: CliName, taskContent: string): number {\n const match = detectTaskCategory(taskContent);\n if (match === null) return 0;\n\n if (cli === match.primaryCli) return this.config.specializationBonus;\n if (cli === match.secondaryCli) return this.config.specializationBonus * 0.5;\n return 0;\n }\n\n /**\n * Build routing signals for the context.\n */\n private buildSignals(\n existing: string[],\n taskType: TaskType,\n scores: Array<{ cli: CliName; score: number; dominant: string }>\n ): string[] {\n const signals = [...existing];\n\n signals.push(`capability:task-${taskType}`);\n\n const best = [...scores].sort((a, b) => b.score - a.score)[0];\n if (best !== undefined) {\n signals.push(`capability:best-${best.cli}`);\n signals.push(`capability:dominant-${best.dominant}`);\n }\n\n return signals;\n }\n}\n\n/**\n * Creates a capability match stage.\n */\nexport function createCapabilityMatchStage(\n config?: Partial<CapabilityMatchConfig>,\n logger?: ILogger\n): CapabilityMatchStage {\n return new CapabilityMatchStage(config, logger);\n}\n","/**\n * Quality Constraint Stage\n *\n * Applies quality constraints to filter candidates that don't meet\n * minimum quality, cost, or latency requirements.\n *\n * @module cli-adapters/routing/stages/quality-constraint-stage\n * (Source: ADR-0005, arXiv:2508.21141 - PILOT pattern)\n */\n\nimport type { Result } from '../../../core/result.js';\nimport type { ILogger } from '../../../core/index.js';\nimport { ok, createLogger, getTimeProvider } from '../../../core/index.js';\nimport type {\n IRouterStage,\n RoutingContext,\n StageResult,\n StageError,\n RoutingOutcome,\n CliName,\n} from '../router-stage.js';\nimport { addTrace, filterCandidate, getRemainingCandidates } from '../router-stage.js';\nimport { buildTopsisProfiles } from '../../../config/model-config-helpers.js';\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\n/**\n * Quality profile for each CLI.\n */\ninterface QualityProfile {\n readonly qualityScore: number; // 0-1 overall quality\n readonly costPer1kTokens: number; // USD\n readonly avgLatencyMs: number; // Milliseconds\n}\n\n/** Max quality score from model registry (reasoning + codeGeneration are 0-10 each). */\nconst MAX_QUALITY = 10;\n\n/**\n * Derive quality profiles from the canonical model registry.\n * Quality scores normalized from 0-10 to 0-1.\n * Pricing converted from per-million to per-1k tokens.\n */\nfunction deriveQualityProfiles(): Record<CliName, QualityProfile> {\n const profiles = buildTopsisProfiles();\n const result: Record<string, QualityProfile> = {};\n for (const p of profiles) {\n result[p.cliName] = {\n qualityScore: p.qualityScore / MAX_QUALITY,\n costPer1kTokens: p.costPerMillionInput / 1000,\n avgLatencyMs: p.averageLatencyMs,\n };\n }\n return result;\n}\n\n/** Lazy-initialized profiles derived from model registry. */\nlet cachedProfiles: Record<CliName, QualityProfile> | undefined;\n\nfunction getQualityProfiles(): Record<CliName, QualityProfile> {\n cachedProfiles ??= deriveQualityProfiles();\n return cachedProfiles;\n}\n\n/**\n * Configuration for the quality constraint stage.\n */\nexport interface QualityConstraintConfig {\n /** Minimum quality score (0-1) */\n readonly minQuality: number;\n /** Maximum cost per task in USD */\n readonly maxCostUsd: number;\n /** Maximum latency in milliseconds */\n readonly maxLatencyMs: number;\n /** Expected tokens for cost estimation */\n readonly expectedTokens: number;\n /** Allow fallback to highest quality if all filtered */\n readonly allowFallback: boolean;\n}\n\nconst DEFAULT_CONFIG: QualityConstraintConfig = {\n minQuality: 0.7,\n maxCostUsd: 1.0,\n maxLatencyMs: 10000,\n expectedTokens: 1500,\n allowFallback: true,\n};\n\n// ============================================================================\n// Stage Implementation\n// ============================================================================\n\n/**\n * Quality Constraint Stage for constraint-based filtering.\n * Runs near end (priority 75) to apply final quality gates.\n */\nexport class QualityConstraintStage implements IRouterStage {\n readonly name = 'quality-constraint';\n readonly priority = 75; // Near end, before latency\n\n private readonly config: QualityConstraintConfig;\n private readonly logger: ILogger;\n private routingsCount = 0;\n private filteredCount = 0;\n private fallbackCount = 0;\n private constraintViolations = { quality: 0, cost: 0, latency: 0 };\n\n constructor(config: Partial<QualityConstraintConfig> = {}, logger?: ILogger) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.logger = logger ?? createLogger({ component: 'QualityConstraintStage' });\n }\n\n canHandle(ctx: RoutingContext): boolean {\n return getRemainingCandidates(ctx).length > 0;\n }\n\n route(ctx: RoutingContext): Promise<Result<StageResult, StageError>> {\n const time = getTimeProvider();\n const startTime = time.now();\n const remaining = getRemainingCandidates(ctx);\n\n this.routingsCount++;\n\n let updatedCtx = ctx;\n const eligible: CliName[] = [];\n const violations: Array<{ cli: CliName; reason: string }> = [];\n\n for (const cli of remaining) {\n const result = this.checkConstraints(cli);\n if (result.meets) {\n eligible.push(cli);\n } else {\n updatedCtx = filterCandidate(updatedCtx, cli, result.reason);\n violations.push({ cli, reason: result.reason });\n this.filteredCount++;\n this.trackViolation(result.violated);\n }\n }\n\n // Handle fallback if all filtered\n let usedFallback = false;\n if (eligible.length === 0 && this.config.allowFallback && remaining.length > 0) {\n const fallback = this.selectFallback(remaining);\n if (fallback !== undefined) {\n eligible.push(fallback);\n usedFallback = true;\n this.fallbackCount++;\n // Remove from filtered\n const newFiltered = new Map(updatedCtx.filtered);\n newFiltered.delete(fallback);\n updatedCtx = { ...updatedCtx, filtered: newFiltered };\n }\n }\n\n const signals = this.buildSignals(ctx.signals, eligible, violations, usedFallback);\n const durationMs = time.now() - startTime;\n\n const finalCtx = addTrace(\n updatedCtx,\n this.name,\n durationMs,\n 'filter',\n `Eligible: ${String(eligible.length)}/${String(remaining.length)}, fallback: ${String(usedFallback)}`\n );\n\n this.logger.debug('Quality constraint complete', {\n eligible: eligible.length,\n filtered: violations.length,\n usedFallback,\n });\n\n return Promise.resolve(\n ok({ context: { ...finalCtx, signals }, continuesPipeline: eligible.length > 0 })\n );\n }\n\n recordOutcome(outcome: RoutingOutcome): void {\n this.logger.debug('Quality outcome recorded', {\n cli: outcome.selectedCli,\n success: outcome.success,\n qualityScore: outcome.qualityScore,\n latencyMs: outcome.latencyMs,\n });\n }\n\n getStats(): Record<string, unknown> {\n return {\n routingsCount: this.routingsCount,\n filteredCount: this.filteredCount,\n fallbackCount: this.fallbackCount,\n filterRate: this.routingsCount > 0 ? this.filteredCount / this.routingsCount : 0,\n constraintViolations: { ...this.constraintViolations },\n config: {\n minQuality: this.config.minQuality,\n maxCostUsd: this.config.maxCostUsd,\n maxLatencyMs: this.config.maxLatencyMs,\n },\n };\n }\n\n /**\n * Check if a CLI meets all constraints.\n */\n private checkConstraints(cli: CliName): {\n meets: boolean;\n reason: string;\n violated: 'quality' | 'cost' | 'latency' | null;\n } {\n const profile = getQualityProfiles()[cli];\n\n // Check quality\n if (profile.qualityScore < this.config.minQuality) {\n return {\n meets: false,\n reason: `Quality ${profile.qualityScore.toFixed(2)} < min ${this.config.minQuality.toFixed(2)}`,\n violated: 'quality',\n };\n }\n\n // Check cost\n const estimatedCost = (this.config.expectedTokens / 1000) * profile.costPer1kTokens;\n if (estimatedCost > this.config.maxCostUsd) {\n return {\n meets: false,\n reason: `Cost $${estimatedCost.toFixed(4)} > max $${this.config.maxCostUsd.toFixed(2)}`,\n violated: 'cost',\n };\n }\n\n // Check latency\n if (profile.avgLatencyMs > this.config.maxLatencyMs) {\n return {\n meets: false,\n reason: `Latency ${String(profile.avgLatencyMs)}ms > max ${String(this.config.maxLatencyMs)}ms`,\n violated: 'latency',\n };\n }\n\n return { meets: true, reason: '', violated: null };\n }\n\n /**\n * Track which constraint was violated.\n */\n private trackViolation(violated: 'quality' | 'cost' | 'latency' | null): void {\n if (violated !== null) {\n this.constraintViolations[violated]++;\n }\n }\n\n /**\n * Select fallback as highest quality candidate.\n */\n private selectFallback(candidates: CliName[]): CliName | undefined {\n const sorted = [...candidates].sort((a, b) => {\n const profileA = getQualityProfiles()[a];\n const profileB = getQualityProfiles()[b];\n return profileB.qualityScore - profileA.qualityScore;\n });\n return sorted[0];\n }\n\n /**\n * Build routing signals for the context.\n */\n private buildSignals(\n existing: string[],\n eligible: CliName[],\n violations: Array<{ cli: CliName; reason: string }>,\n usedFallback: boolean\n ): string[] {\n const signals = [...existing];\n\n if (eligible.length > 0) {\n signals.push('quality:meets-constraints');\n }\n\n if (violations.length > 0) {\n signals.push(`quality:filtered-${String(violations.length)}`);\n\n // Track which constraints were violated\n const violationTypes = new Set(\n violations.map((v) => {\n if (v.reason.includes('Quality')) return 'quality';\n if (v.reason.includes('Cost')) return 'cost';\n if (v.reason.includes('Latency')) return 'latency';\n return 'unknown';\n })\n );\n\n for (const type of violationTypes) {\n signals.push(`quality:constraint-${type}`);\n }\n }\n\n if (usedFallback) {\n signals.push('quality:used-fallback');\n }\n\n return signals;\n }\n}\n\n/**\n * Creates a quality constraint stage.\n */\nexport function createQualityConstraintStage(\n config?: Partial<QualityConstraintConfig>,\n logger?: ILogger\n): QualityConstraintStage {\n return new QualityConstraintStage(config, logger);\n}\n\n/** Reset cached profiles (for testing). */\nexport function resetQualityProfileCache(): void {\n cachedProfiles = undefined;\n}\n","/**\n * Resource Strategy Stage\n *\n * Implements resource-aware strategy oscillation for the routing pipeline.\n * Dynamically adjusts model scoring based on budget utilization level,\n * oscillating between aggressive (prefer quality) and conservative (prefer cost)\n * strategies as resources deplete.\n *\n * @module cli-adapters/routing/stages/resource-strategy-stage\n * (Source: Issue #998 — Resource-aware strategy oscillation in routing pipeline)\n */\n\nimport type { Result } from '../../../core/result.js';\nimport type { ILogger } from '../../../core/index.js';\nimport { ok, createLogger, getTimeProvider } from '../../../core/index.js';\nimport type {\n IRouterStage,\n RoutingContext,\n StageResult,\n StageError,\n RoutingOutcome,\n CliName,\n} from '../router-stage.js';\nimport { addTrace, updateScore, getRemainingCandidates } from '../router-stage.js';\n\n/**\n * Resource strategy tier determining routing behavior.\n */\nexport type ResourceTier = 'aggressive' | 'balanced' | 'conservative' | 'critical';\n\n/**\n * Configuration for the resource strategy stage.\n */\nexport interface ResourceStrategyConfig {\n /** Threshold above which aggressive tier activates (0-1) */\n readonly aggressiveThreshold: number;\n /** Threshold above which balanced tier activates (0-1) */\n readonly balancedThreshold: number;\n /** Threshold above which conservative tier activates (0-1) */\n readonly conservativeThreshold: number;\n /** Score boost for quality-oriented CLIs in aggressive mode */\n readonly aggressiveBoost: number;\n /** Score boost for cost-efficient CLIs in conservative mode */\n readonly conservativeBoost: number;\n /** Score boost for cheapest CLI in critical mode */\n readonly criticalBoost: number;\n}\n\nconst DEFAULT_CONFIG: ResourceStrategyConfig = {\n aggressiveThreshold: 0.75,\n balancedThreshold: 0.5,\n conservativeThreshold: 0.25,\n aggressiveBoost: 5,\n conservativeBoost: 5,\n criticalBoost: 8,\n};\n\n/**\n * Quality ranking per CLI (higher = better quality, higher cost).\n */\nconst CLI_QUALITY_RANK: Record<CliName, number> = {\n claude: 3,\n codex: 2,\n opencode: 1.5,\n gemini: 1,\n};\n\n/**\n * Cost efficiency ranking per CLI (higher = cheaper).\n */\nconst CLI_COST_RANK: Record<CliName, number> = {\n gemini: 3,\n codex: 2,\n opencode: 2,\n claude: 1,\n};\n\n/**\n * Computes the current resource tier from a utilization level.\n */\nexport function computeResourceTier(\n resourceLevel: number,\n config: ResourceStrategyConfig = DEFAULT_CONFIG\n): ResourceTier {\n if (resourceLevel >= config.aggressiveThreshold) return 'aggressive';\n if (resourceLevel >= config.balancedThreshold) return 'balanced';\n if (resourceLevel >= config.conservativeThreshold) return 'conservative';\n return 'critical';\n}\n\n/**\n * Computes score adjustments for each CLI based on resource tier.\n */\nexport function computeScoreAdjustments(\n tier: ResourceTier,\n candidates: readonly CliName[],\n config: ResourceStrategyConfig = DEFAULT_CONFIG\n): Map<CliName, number> {\n const adjustments = new Map<CliName, number>();\n\n for (const cli of candidates) {\n switch (tier) {\n case 'aggressive':\n // Boost quality-oriented CLIs (claude gets most, gemini least)\n adjustments.set(cli, CLI_QUALITY_RANK[cli] * (config.aggressiveBoost / 3));\n break;\n case 'balanced':\n // No adjustment — let other stages decide\n adjustments.set(cli, 0);\n break;\n case 'conservative':\n // Boost cost-efficient CLIs (gemini gets most, claude least)\n adjustments.set(cli, CLI_COST_RANK[cli] * (config.conservativeBoost / 3));\n break;\n case 'critical':\n // Strongly boost cheapest CLI\n adjustments.set(cli, CLI_COST_RANK[cli] * (config.criticalBoost / 3));\n break;\n }\n }\n\n return adjustments;\n}\n\n/**\n * Resource Strategy Stage for budget-aware routing oscillation.\n *\n * Reads budget utilization from context signals (populated by BudgetStage)\n * and adjusts candidate scores based on resource availability.\n */\nexport class ResourceStrategyStage implements IRouterStage {\n readonly name = 'resource-strategy';\n readonly priority = 55; // After preference (50), before TOPSIS (60)\n\n private readonly config: ResourceStrategyConfig;\n private readonly logger: ILogger;\n private routingsCount = 0;\n private tierHistory: ResourceTier[] = [];\n\n constructor(config: Partial<ResourceStrategyConfig> = {}, logger?: ILogger) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.logger = logger ?? createLogger({ component: 'ResourceStrategyStage' });\n }\n\n canHandle(ctx: RoutingContext): boolean {\n return getRemainingCandidates(ctx).length > 1;\n }\n\n route(ctx: RoutingContext): Promise<Result<StageResult, StageError>> {\n return Promise.resolve(this.routeSync(ctx));\n }\n\n private routeSync(ctx: RoutingContext): Result<StageResult, StageError> {\n const start = getTimeProvider().now();\n const candidates = getRemainingCandidates(ctx);\n\n const resourceLevel = this.extractResourceLevel(ctx);\n\n if (resourceLevel === undefined) {\n const elapsed = getTimeProvider().now() - start;\n const updated = addTrace(ctx, this.name, elapsed, 'skip', 'no budget data');\n return ok({ context: updated, continuesPipeline: true });\n }\n\n const tier = computeResourceTier(resourceLevel, this.config);\n const adjustments = computeScoreAdjustments(tier, candidates, this.config);\n\n let updated = ctx;\n for (const [cli, delta] of adjustments) {\n if (delta !== 0) {\n updated = updateScore(updated, cli, delta);\n }\n }\n\n updated = {\n ...updated,\n signals: [\n ...updated.signals,\n `resource-strategy:tier=${tier}`,\n `resource-strategy:level=${resourceLevel.toFixed(2)}`,\n ],\n };\n\n const elapsed = getTimeProvider().now() - start;\n updated = addTrace(\n updated,\n this.name,\n elapsed,\n 'score',\n `tier=${tier} level=${resourceLevel.toFixed(2)}`\n );\n\n this.routingsCount++;\n this.tierHistory.push(tier);\n if (this.tierHistory.length > 100) {\n this.tierHistory = this.tierHistory.slice(-100);\n }\n\n this.logger.debug('Resource strategy applied', {\n tier,\n resourceLevel,\n adjustments: Object.fromEntries(adjustments),\n });\n\n return ok({ context: updated, continuesPipeline: true });\n }\n\n recordOutcome(_outcome: RoutingOutcome): void {\n // Future: could adjust thresholds based on outcome quality per tier\n }\n\n getStats(): Record<string, unknown> {\n const tierCounts: Record<string, number> = {};\n for (const t of this.tierHistory) {\n tierCounts[t] = (tierCounts[t] ?? 0) + 1;\n }\n return {\n routingsCount: this.routingsCount,\n config: this.config,\n tierDistribution: tierCounts,\n currentTier:\n this.tierHistory.length > 0 ? this.tierHistory[this.tierHistory.length - 1] : null,\n };\n }\n\n /**\n * Extracts resource level (0-1) from context signals or metadata.\n * Looks for budget utilization signals added by BudgetStage.\n */\n private extractResourceLevel(ctx: RoutingContext): number | undefined {\n // Check signals for budget utilization (added by budget-stage)\n for (const signal of ctx.signals) {\n if (signal.startsWith('budget:utilization=')) {\n const value = parseFloat(signal.slice('budget:utilization='.length));\n if (!isNaN(value)) {\n // Budget utilization is spent ratio — resource level is inverse\n return Math.max(0, Math.min(1, 1 - value));\n }\n }\n }\n\n // Check metadata for explicit resource level\n const meta = ctx.metadata;\n if (meta !== undefined) {\n const level = meta['resourceLevel'];\n if (typeof level === 'number' && level >= 0 && level <= 1) {\n return level;\n }\n }\n\n return undefined;\n }\n}\n\n/**\n * Factory function for creating ResourceStrategyStage.\n */\nexport function createResourceStrategyStage(\n config?: Partial<ResourceStrategyConfig>,\n logger?: ILogger\n): ResourceStrategyStage {\n return new ResourceStrategyStage(config, logger);\n}\n","/**\n * Distilled Rule Stage\n *\n * Applies score adjustments from automatically distilled routing rules.\n * Rules are produced by StrategyDistiller from observed task outcomes.\n *\n * Score-only stage (no filtering): penalize, boost, or avoid adjustments\n * scaled by rule confidence. Runs at priority 45 (after ZeroRouter 40,\n * before Preference 50).\n *\n * @module cli-adapters/routing/stages/distilled-rule-stage\n * (Source: Issue #999 - Automatic Strategy Distillation)\n */\n\nimport type { Result } from '../../../core/result.js';\nimport type { ILogger } from '../../../core/index.js';\nimport { ok, createLogger, getTimeProvider } from '../../../core/index.js';\nimport type {\n IRouterStage,\n RoutingContext,\n StageResult,\n StageError,\n RoutingOutcome,\n CliName,\n} from '../router-stage.js';\nimport { addTrace, updateScore, getRemainingCandidates } from '../router-stage.js';\nimport type { StrategyDistiller } from '../../../learning/strategy-distiller.js';\nimport type { DistilledRule, StrategyAction } from '../../../learning/strategy-distiller-types.js';\n\n/** Score deltas per action type. */\nconst ACTION_DELTAS: Readonly<Record<StrategyAction, number>> = {\n penalize: -5,\n boost: 5,\n avoid: -10,\n};\n\n/** Configuration for the distilled rule stage. */\nexport interface DistilledRuleStageConfig {\n /** Penalty score for penalize action (default: -5) */\n readonly penaltyDelta: number;\n /** Boost score for boost action (default: 5) */\n readonly boostDelta: number;\n /** Avoid score for avoid action (default: -10) */\n readonly avoidDelta: number;\n}\n\nconst DEFAULT_CONFIG: DistilledRuleStageConfig = {\n penaltyDelta: ACTION_DELTAS.penalize,\n boostDelta: ACTION_DELTAS.boost,\n avoidDelta: ACTION_DELTAS.avoid,\n};\n\n/**\n * Routing stage that applies distilled rules as score adjustments.\n */\nexport class DistilledRuleStage implements IRouterStage {\n readonly name = 'distilled-rule';\n readonly priority = 45;\n\n private readonly distiller: StrategyDistiller;\n private readonly config: DistilledRuleStageConfig;\n private readonly logger: ILogger;\n private rulesAppliedCount = 0;\n\n constructor(\n distiller: StrategyDistiller,\n config?: Partial<DistilledRuleStageConfig>,\n logger?: ILogger\n ) {\n this.distiller = distiller;\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.logger = logger ?? createLogger({ component: 'DistilledRuleStage' });\n }\n\n canHandle(ctx: RoutingContext): boolean {\n const candidates = getRemainingCandidates(ctx);\n if (candidates.length <= 1) return false;\n const activeRules = this.distiller.getRules('active');\n return activeRules.length > 0;\n }\n\n route(ctx: RoutingContext): Promise<Result<StageResult, StageError>> {\n return Promise.resolve(this.routeSync(ctx));\n }\n\n recordOutcome(outcome: RoutingOutcome): void {\n this.distiller.onOutcome();\n this.logger.debug('Forwarded outcome to distiller', {\n cli: outcome.selectedCli,\n success: outcome.success,\n });\n }\n\n getStats(): Record<string, unknown> {\n const distillerStats = this.distiller.getStats();\n return {\n rulesAppliedCount: this.rulesAppliedCount,\n activeRuleCount: distillerStats.ruleCountByStatus.active,\n totalRules: distillerStats.totalRules,\n };\n }\n\n private routeSync(ctx: RoutingContext): Result<StageResult, StageError> {\n const start = getTimeProvider().now();\n const candidates = getRemainingCandidates(ctx);\n const activeRules = this.distiller.getRules('active');\n\n if (activeRules.length === 0) {\n const elapsed = getTimeProvider().now() - start;\n const updated = addTrace(ctx, this.name, elapsed, 'skip', 'no active rules');\n return ok({ context: updated, continuesPipeline: true });\n }\n\n // Extract task category from signals\n const category = this.extractCategory(ctx);\n\n let updated = ctx;\n let applied = 0;\n\n for (const cli of candidates) {\n const matchingRules = this.findMatchingRules(activeRules, cli, category);\n for (const rule of matchingRules) {\n const delta = this.computeDelta(rule);\n updated = updateScore(updated, cli, delta);\n updated = {\n ...updated,\n signals: [...updated.signals, `distilled-rule:applied=${rule.id}`],\n };\n applied++;\n }\n }\n\n this.rulesAppliedCount += applied;\n\n const elapsed = getTimeProvider().now() - start;\n updated = addTrace(\n updated,\n this.name,\n elapsed,\n 'score',\n `applied=${String(applied)} rules=${String(activeRules.length)}`\n );\n\n this.logger.debug('Distilled rules applied', { applied, candidates: candidates.length });\n\n return ok({ context: updated, continuesPipeline: true });\n }\n\n private findMatchingRules(\n rules: readonly DistilledRule[],\n cli: CliName,\n category: string | undefined\n ): DistilledRule[] {\n return rules.filter(\n (r) => r.cli === cli && (category === undefined || r.category === category)\n );\n }\n\n private computeDelta(rule: DistilledRule): number {\n const baseDelta =\n rule.action === 'penalize'\n ? this.config.penaltyDelta\n : rule.action === 'boost'\n ? this.config.boostDelta\n : this.config.avoidDelta;\n return baseDelta * rule.confidence;\n }\n\n private extractCategory(ctx: RoutingContext): string | undefined {\n for (const signal of ctx.signals) {\n if (signal.startsWith('task-category:')) {\n return signal.slice('task-category:'.length);\n }\n if (signal.startsWith('capability:type=')) {\n return signal.slice('capability:type='.length);\n }\n }\n return undefined;\n }\n}\n\n/** Factory function for creating DistilledRuleStage. */\nexport function createDistilledRuleStage(\n distiller: StrategyDistiller,\n config?: Partial<DistilledRuleStageConfig>,\n logger?: ILogger\n): DistilledRuleStage {\n return new DistilledRuleStage(distiller, config, logger);\n}\n","/**\n * KNN Routing Stage\n *\n * Scores candidates using K-Nearest Neighbors over historical routing\n * experience patterns from RoutingMemory. For each candidate CLI,\n * retrieves similar past tasks and weights by success rate.\n *\n * @module cli-adapters/routing/stages/knn-routing-stage\n * (Source: arXiv:2507.05370 — KNN-based model routing)\n */\n\nimport type { Result } from '../../../core/result.js';\nimport type { ILogger } from '../../../core/index.js';\nimport { ok, createLogger, getTimeProvider } from '../../../core/index.js';\nimport type {\n IRouterStage,\n RoutingContext,\n StageResult,\n StageError,\n RoutingOutcome,\n CliName,\n} from '../router-stage.js';\nimport { addTrace, updateScore, getRemainingCandidates } from '../router-stage.js';\nimport type { IRoutingMemory, ExperiencePattern } from '../../../context/routing-memory.js';\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\n/** Number of nearest neighbors to consider. */\nconst DEFAULT_K = 5;\n\n/** Weight applied to KNN scores in overall routing. */\nconst DEFAULT_KNN_WEIGHT = 0.3;\n\n/** Minimum experience patterns needed to produce a score. */\nconst MIN_PATTERNS = 2;\n\n/**\n * Task type keywords for similarity matching.\n * Maps task content keywords to canonical workflow types.\n */\nconst WORKFLOW_KEYWORDS: ReadonlyArray<readonly [string, readonly string[]]> = [\n ['coding', ['code', 'implement', 'function', 'class', 'refactor']],\n ['review', ['review', 'audit', 'check', 'inspect']],\n ['testing', ['test', 'spec', 'coverage', 'assert']],\n ['documentation', ['document', 'explain', 'describe', 'readme']],\n ['debugging', ['debug', 'fix', 'bug', 'error', 'issue']],\n ['research', ['research', 'investigate', 'explore', 'analyze']],\n ['planning', ['plan', 'design', 'architect', 'strategy']],\n ['security', ['security', 'vulnerability', 'threat', 'pentest']],\n];\n\n/**\n * Configuration for the KNN routing stage.\n */\nexport interface KnnRoutingConfig {\n /** Number of nearest neighbors to use */\n readonly k: number;\n /** Weight for KNN scoring in overall score */\n readonly knnWeight: number;\n /** Enable debug logging */\n readonly debug: boolean;\n}\n\nconst DEFAULT_CONFIG: KnnRoutingConfig = {\n k: DEFAULT_K,\n knnWeight: DEFAULT_KNN_WEIGHT,\n debug: false,\n};\n\n// ============================================================================\n// Distance calculation\n// ============================================================================\n\n/**\n * Computes cosine similarity between two keyword-frequency vectors.\n * Returns 0-1 where 1 = identical.\n */\nexport function cosineSimilarity(\n a: ReadonlyMap<string, number>,\n b: ReadonlyMap<string, number>\n): number {\n let dotProduct = 0;\n let normA = 0;\n let normB = 0;\n\n for (const [key, valA] of a) {\n normA += valA * valA;\n const valB = b.get(key) ?? 0;\n dotProduct += valA * valB;\n }\n for (const [, valB] of b) {\n normB += valB * valB;\n }\n\n const denom = Math.sqrt(normA) * Math.sqrt(normB);\n return denom > 0 ? dotProduct / denom : 0;\n}\n\n/**\n * Extracts a keyword-frequency vector from task content.\n */\nexport function extractKeywordVector(content: string): Map<string, number> {\n const lower = content.toLowerCase();\n const vec = new Map<string, number>();\n\n for (const [workflow, keywords] of WORKFLOW_KEYWORDS) {\n let count = 0;\n for (const kw of keywords) {\n if (lower.includes(kw)) count++;\n }\n if (count > 0) vec.set(workflow, count);\n }\n\n return vec;\n}\n\n// ============================================================================\n// Stage Implementation\n// ============================================================================\n\n/**\n * KNN Routing Stage for experience-based routing.\n * Runs after capability match (priority 38) to add experience-based scoring.\n */\nexport class KnnRoutingStage implements IRouterStage {\n readonly name = 'knn-routing';\n readonly priority = 38; // After capability-match(35), before zero(40)\n\n private readonly config: KnnRoutingConfig;\n private readonly logger: ILogger;\n private readonly memory: IRoutingMemory;\n private routingsCount = 0;\n private matchCount = 0;\n\n constructor(memory: IRoutingMemory, config: Partial<KnnRoutingConfig> = {}, logger?: ILogger) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.memory = memory;\n this.logger = logger ?? createLogger({ component: 'KnnRoutingStage' });\n }\n\n canHandle(ctx: RoutingContext): boolean {\n return getRemainingCandidates(ctx).length > 0;\n }\n\n route(ctx: RoutingContext): Promise<Result<StageResult, StageError>> {\n const time = getTimeProvider();\n const startTime = time.now();\n const remaining = getRemainingCandidates(ctx);\n this.routingsCount++;\n\n const taskVector = extractKeywordVector(ctx.task);\n const workflows = this.inferWorkflows(ctx.task);\n const knnScores = this.computeKnnScores(remaining, workflows, taskVector);\n\n let updatedCtx = ctx;\n for (const [cli, score] of knnScores) {\n updatedCtx = updateScore(updatedCtx, cli, score * this.config.knnWeight);\n }\n\n const signals = [...ctx.signals];\n if (knnScores.size > 0) {\n this.matchCount++;\n signals.push('knn:experience-matched');\n } else {\n signals.push('knn:cold-start');\n }\n\n const durationMs = time.now() - startTime;\n const finalCtx = addTrace(\n updatedCtx,\n this.name,\n durationMs,\n 'score',\n `Workflows: ${workflows.join(',')}, matches: ${String(knnScores.size)}`\n );\n\n this.logger.debug('KNN routing complete', {\n workflows,\n knnScores: [...knnScores].map(([c, s]) => `${c}:${s.toFixed(3)}`),\n });\n\n return Promise.resolve(ok({ context: { ...finalCtx, signals }, continuesPipeline: true }));\n }\n\n recordOutcome(outcome: RoutingOutcome): void {\n this.logger.debug('KNN outcome recorded', {\n cli: outcome.selectedCli,\n success: outcome.success,\n });\n }\n\n getStats(): Record<string, unknown> {\n return {\n routingsCount: this.routingsCount,\n matchCount: this.matchCount,\n hitRate: this.routingsCount > 0 ? this.matchCount / this.routingsCount : 0,\n config: { k: this.config.k, knnWeight: this.config.knnWeight },\n };\n }\n\n /**\n * Infer workflow types from task content for experience lookup.\n */\n private inferWorkflows(content: string): string[] {\n const lower = content.toLowerCase();\n const matches: string[] = [];\n\n for (const [workflow, keywords] of WORKFLOW_KEYWORDS) {\n if (keywords.some((kw) => lower.includes(kw))) {\n matches.push(workflow);\n }\n }\n\n return matches.length > 0 ? matches : ['general'];\n }\n\n /**\n * Compute KNN scores for candidate CLIs based on experience patterns.\n */\n private computeKnnScores(\n candidates: readonly CliName[],\n workflows: readonly string[],\n taskVector: ReadonlyMap<string, number>\n ): Map<CliName, number> {\n const scores = new Map<CliName, number>();\n const allPatterns = this.gatherPatterns(workflows);\n\n if (allPatterns.length < MIN_PATTERNS) return scores;\n\n // Compute similarity + rank patterns\n const ranked = this.rankBySimilarity(allPatterns, taskVector);\n const topK = ranked.slice(0, this.config.k);\n\n // Aggregate scores per CLI from top-K\n for (const cli of candidates) {\n const cliPatterns = topK.filter((p) => p.pattern.modelSequence.includes(cli));\n if (cliPatterns.length === 0) continue;\n\n const weightedScore = cliPatterns.reduce(\n (sum, p) => sum + p.similarity * p.pattern.successRate,\n 0\n );\n const totalWeight = cliPatterns.reduce((sum, p) => sum + p.similarity, 0);\n if (totalWeight > 0) {\n scores.set(cli, weightedScore / totalWeight);\n }\n }\n\n return scores;\n }\n\n /** Gather experience patterns from memory across workflows. */\n private gatherPatterns(workflows: readonly string[]): ExperiencePattern[] {\n const patterns: ExperiencePattern[] = [];\n for (const wf of workflows) {\n patterns.push(...this.memory.getExperiencePatterns(wf));\n }\n return patterns;\n }\n\n /** Rank patterns by cosine similarity to the task vector. */\n private rankBySimilarity(\n patterns: readonly ExperiencePattern[],\n taskVector: ReadonlyMap<string, number>\n ): Array<{ pattern: ExperiencePattern; similarity: number }> {\n return patterns\n .map((pattern) => {\n const patternVector = new Map<string, number>();\n patternVector.set(pattern.workflow, 1);\n return { pattern, similarity: cosineSimilarity(taskVector, patternVector) };\n })\n .sort((a, b) => b.similarity - a.similarity);\n }\n}\n\n/**\n * Creates a KNN routing stage.\n */\nexport function createKnnRoutingStage(\n memory: IRoutingMemory,\n config?: Partial<KnnRoutingConfig>,\n logger?: ILogger\n): KnnRoutingStage {\n return new KnnRoutingStage(memory, config, logger);\n}\n","/**\n * Type definitions for the Strategy Distiller.\n *\n * Defines the shape of distilled routing rules that are automatically\n * extracted from observed task outcomes. Rules capture patterns like\n * \"CLI X fails on category Y\" and translate them into routing score\n * adjustments.\n *\n * @module learning/strategy-distiller-types\n * (Source: Issue #999 - Automatic Strategy Distillation)\n */\n\nimport type { CliName } from '../cli-adapters/types.js';\n\n/** Status lifecycle for a distilled rule. */\nexport type RuleStatus = 'draft' | 'active' | 'promoted' | 'expired';\n\n/** The type of pattern detected from outcomes. */\nexport type PatternType = 'failure-rate' | 'success-rate' | 'latency-spike';\n\n/** Action to take when a rule matches a routing candidate. */\nexport type StrategyAction = 'penalize' | 'boost' | 'avoid';\n\n/**\n * A distilled routing rule extracted from outcome patterns.\n *\n * Rules are fingerprinted by `patternType:cli:category` to prevent\n * duplicates and cap total rules at a bounded maximum.\n */\nexport interface DistilledRule {\n /** Fingerprint: `${patternType}:${cli}:${category}` */\n readonly id: string;\n /** What kind of pattern triggered this rule */\n readonly patternType: PatternType;\n /** Which CLI this rule applies to */\n readonly cli: CliName;\n /** Task category this rule applies to */\n readonly category: string;\n /** What routing action to take */\n readonly action: StrategyAction;\n /** Confidence 0-1, computed via sigmoid(observations, center=30) */\n readonly confidence: number;\n /** Number of observations that informed this rule */\n readonly observationCount: number;\n /** The metric value (failure rate, success rate, or p90/median ratio) */\n readonly metric: number;\n /** Current lifecycle status */\n readonly status: RuleStatus;\n /** Epoch ms when rule was first created */\n readonly createdAt: number;\n /** Epoch ms when rule was last updated */\n readonly updatedAt: number;\n /** Security: tainted rules never promote to RoutingMemory */\n readonly tainted: boolean;\n}\n\n/** Configuration for the strategy distiller. */\nexport interface DistillerConfig {\n /** Distill every N outcomes (default: 50) */\n readonly triggerThreshold: number;\n /** Minimum observations before creating a draft rule (default: 3) */\n readonly minObservationsForDraft: number;\n /** Minimum observations before activating a rule (default: 5) */\n readonly minObservationsForActive: number;\n /** Confidence threshold for promotion to RoutingMemory (default: 0.7) */\n readonly promotionConfidence: number;\n /** Failure rate above which a failure pattern is detected (default: 0.6) */\n readonly failureRateThreshold: number;\n /** Success rate above which a success pattern is detected (default: 0.8) */\n readonly successRateThreshold: number;\n /** p90/median ratio above which a latency spike is detected (default: 2.0) */\n readonly latencyRatioThreshold: number;\n /** Maximum number of rules to store (default: 90) */\n readonly maxRules: number;\n /** Rule expiry time in ms (default: 24h) */\n readonly ruleExpiryMs: number;\n}\n\n/** Default distiller configuration. */\nexport const DEFAULT_DISTILLER_CONFIG: DistillerConfig = {\n triggerThreshold: 50,\n minObservationsForDraft: 3,\n minObservationsForActive: 5,\n promotionConfidence: 0.7,\n failureRateThreshold: 0.6,\n successRateThreshold: 0.8,\n latencyRatioThreshold: 2.0,\n maxRules: 90,\n ruleExpiryMs: 24 * 60 * 60 * 1000,\n};\n\n/** Statistics returned by StrategyDistiller.getStats(). */\nexport interface DistillerStats {\n /** Number of rules in each status */\n readonly ruleCountByStatus: Readonly<Record<RuleStatus, number>>;\n /** Total number of rules */\n readonly totalRules: number;\n /** Epoch ms of last distillation run */\n readonly lastDistillAt: number | undefined;\n /** Number of outcomes processed since last distillation */\n readonly outcomesSinceLastDistill: number;\n}\n","/**\n * Strategy Distiller — Automatic routing rule extraction from outcomes.\n *\n * Monitors OutcomeStore data and distills recurring patterns into\n * routing rules. Three pattern detectors identify failure rates,\n * success rates, and latency spikes per (cli, category) group.\n *\n * Rules progress through a lifecycle: draft -> active -> promoted -> expired.\n * Tainted rules (from untrusted input) never promote.\n *\n * @module learning/strategy-distiller\n * (Source: Issue #999 - Automatic Strategy Distillation)\n */\n\nimport type { ILogger } from '../core/index.js';\nimport { createLogger, getTimeProvider } from '../core/index.js';\nimport type { CliName } from '../cli-adapters/types.js';\nimport type { TaskOutcome } from '../orchestration/outcomes/outcome-types.js';\nimport type { OutcomeStore } from '../orchestration/outcomes/outcome-store.js';\nimport type { IRoutingMemory, ModelPerformance } from '../context/routing-memory.js';\nimport type {\n DistilledRule,\n DistillerConfig,\n DistillerStats,\n PatternType,\n RuleStatus,\n StrategyAction,\n} from './strategy-distiller-types.js';\nimport { DEFAULT_DISTILLER_CONFIG } from './strategy-distiller-types.js';\n\n// ============================================================================\n// Helpers — pure functions\n// ============================================================================\n\n/** Sigmoid confidence: 1 / (1 + exp(-(n - center) / 5)) */\nexport function sigmoidConfidence(observations: number, center: number = 30): number {\n const raw = 1 / (1 + Math.exp(-(observations - center) / 5));\n return Math.max(0, Math.min(1, raw));\n}\n\n/** Build a fingerprint ID for a rule. */\nfunction ruleFingerprint(patternType: PatternType, cli: CliName, category: string): string {\n return `${patternType}:${cli}:${category}`;\n}\n\n/** Group outcomes by (cli, category). */\ninterface OutcomeGroup {\n readonly cli: CliName;\n readonly category: string;\n readonly outcomes: readonly TaskOutcome[];\n}\n\nfunction groupOutcomes(outcomes: readonly TaskOutcome[]): OutcomeGroup[] {\n const map = new Map<string, TaskOutcome[]>();\n for (const o of outcomes) {\n const key = `${o.cli}:${o.category}`;\n const list = map.get(key);\n if (list !== undefined) {\n list.push(o);\n } else {\n map.set(key, [o]);\n }\n }\n const groups: OutcomeGroup[] = [];\n for (const [key, list] of map) {\n const [cli, category] = key.split(':') as [CliName, string];\n groups.push({ cli, category, outcomes: list });\n }\n return groups;\n}\n\n/** Compute p90 duration from a sorted array of durations. */\nfunction percentile(sorted: readonly number[], p: number): number {\n if (sorted.length === 0) return 0;\n const idx = Math.ceil((p / 100) * sorted.length) - 1;\n return sorted[Math.max(0, idx)] ?? 0;\n}\n\n// ============================================================================\n// Pattern Detectors — pure functions\n// ============================================================================\n\ninterface DetectedPattern {\n readonly cli: CliName;\n readonly category: string;\n readonly patternType: PatternType;\n readonly action: StrategyAction;\n readonly metric: number;\n readonly observationCount: number;\n}\n\n/** Detect groups with failure rate above threshold. */\nexport function detectFailurePatterns(\n groups: readonly OutcomeGroup[],\n threshold: number\n): DetectedPattern[] {\n const patterns: DetectedPattern[] = [];\n for (const g of groups) {\n const failCount = g.outcomes.filter((o) => !o.success).length;\n const failRate = failCount / g.outcomes.length;\n if (failRate >= threshold) {\n patterns.push({\n cli: g.cli,\n category: g.category,\n patternType: 'failure-rate',\n action: failRate >= 0.8 ? 'avoid' : 'penalize',\n metric: failRate,\n observationCount: g.outcomes.length,\n });\n }\n }\n return patterns;\n}\n\n/** Detect groups with success rate above threshold. */\nexport function detectSuccessPatterns(\n groups: readonly OutcomeGroup[],\n threshold: number\n): DetectedPattern[] {\n const patterns: DetectedPattern[] = [];\n for (const g of groups) {\n const successCount = g.outcomes.filter((o) => o.success).length;\n const successRate = successCount / g.outcomes.length;\n if (successRate >= threshold) {\n patterns.push({\n cli: g.cli,\n category: g.category,\n patternType: 'success-rate',\n action: 'boost',\n metric: successRate,\n observationCount: g.outcomes.length,\n });\n }\n }\n return patterns;\n}\n\n/** Detect groups with latency spike (p90/median > threshold). */\nexport function detectLatencyPatterns(\n groups: readonly OutcomeGroup[],\n threshold: number\n): DetectedPattern[] {\n const patterns: DetectedPattern[] = [];\n for (const g of groups) {\n const durations = g.outcomes.map((o) => o.durationMs).sort((a, b) => a - b);\n if (durations.length < 3) continue;\n\n const median = percentile(durations, 50);\n const p90 = percentile(durations, 90);\n if (median <= 0) continue;\n\n const ratio = p90 / median;\n if (ratio >= threshold) {\n patterns.push({\n cli: g.cli,\n category: g.category,\n patternType: 'latency-spike',\n action: 'penalize',\n metric: ratio,\n observationCount: g.outcomes.length,\n });\n }\n }\n return patterns;\n}\n\n// ============================================================================\n// StrategyDistiller\n// ============================================================================\n\n/**\n * Distills outcome patterns into routing rules.\n *\n * Subscribe to OutcomeFeedbackCollector.onOutcomeProcessed() and call\n * onOutcome() for each processed outcome. Distillation triggers\n * automatically every `triggerThreshold` outcomes.\n */\nexport class StrategyDistiller {\n private readonly config: DistillerConfig;\n private readonly outcomeStore: OutcomeStore;\n private readonly logger: ILogger;\n private readonly rules = new Map<string, DistilledRule>();\n private outcomeCounter = 0;\n private lastDistillAt: number | undefined;\n\n constructor(outcomeStore: OutcomeStore, logger?: ILogger, config?: Partial<DistillerConfig>) {\n this.outcomeStore = outcomeStore;\n this.config = { ...DEFAULT_DISTILLER_CONFIG, ...config };\n this.logger = logger ?? createLogger({ component: 'StrategyDistiller' });\n }\n\n /** Called for each processed outcome. Triggers distillation at threshold. */\n onOutcome(): void {\n this.outcomeCounter++;\n if (this.outcomeCounter >= this.config.triggerThreshold) {\n this.distill();\n this.outcomeCounter = 0;\n }\n }\n\n /** Run distillation on current OutcomeStore data. */\n distill(): void {\n const now = getTimeProvider().now();\n const outcomes = this.outcomeStore.query();\n const groups = groupOutcomes(outcomes);\n\n // Expire old rules first\n this.expireRules(now);\n\n // Detect all patterns\n const failurePatterns = detectFailurePatterns(groups, this.config.failureRateThreshold);\n const successPatterns = detectSuccessPatterns(groups, this.config.successRateThreshold);\n const latencyPatterns = detectLatencyPatterns(groups, this.config.latencyRatioThreshold);\n\n const allPatterns = [...failurePatterns, ...successPatterns, ...latencyPatterns];\n\n for (const pattern of allPatterns) {\n this.upsertRule(pattern, now);\n }\n\n // Enforce max rules bound\n this.enforceMaxRules();\n\n this.lastDistillAt = now;\n this.logger.debug('Distillation complete', {\n rulesTotal: this.rules.size,\n patternsFound: allPatterns.length,\n outcomesAnalyzed: outcomes.length,\n });\n }\n\n /** Get rules filtered by status. */\n getRules(status?: RuleStatus): readonly DistilledRule[] {\n const all = [...this.rules.values()];\n if (status === undefined) return all;\n return all.filter((r) => r.status === status);\n }\n\n /** Get distiller statistics. */\n getStats(): DistillerStats {\n const countByStatus: Record<RuleStatus, number> = {\n draft: 0,\n active: 0,\n promoted: 0,\n expired: 0,\n };\n for (const rule of this.rules.values()) {\n countByStatus[rule.status]++;\n }\n return {\n ruleCountByStatus: countByStatus,\n totalRules: this.rules.size,\n lastDistillAt: this.lastDistillAt,\n outcomesSinceLastDistill: this.outcomeCounter,\n };\n }\n\n /**\n * Promote high-confidence rules to RoutingMemory.\n * Rules must be active, non-tainted, with sufficient observations and confidence.\n */\n promote(routingMemory: IRoutingMemory): number {\n let promoted = 0;\n for (const [id, rule] of this.rules) {\n if (rule.status !== 'active') continue;\n if (rule.tainted) continue;\n if (rule.observationCount < this.config.minObservationsForActive) continue;\n if (rule.confidence < this.config.promotionConfidence) continue;\n\n const performance = this.ruleToPerformance(rule);\n routingMemory.storePreference(rule.cli, rule.category, performance);\n\n this.rules.set(id, { ...rule, status: 'promoted', updatedAt: getTimeProvider().now() });\n promoted++;\n\n this.logger.info('Promoted distilled rule to RoutingMemory', {\n ruleId: id,\n cli: rule.cli,\n category: rule.category,\n confidence: rule.confidence,\n });\n }\n return promoted;\n }\n\n // ==========================================================================\n // Protected — for subclass hydration (Issue #1009)\n // ==========================================================================\n\n /** Load pre-existing rules (e.g., from disk). Used by PersistentStrategyDistiller. */\n protected loadRules(rules: readonly DistilledRule[]): void {\n for (const rule of rules) {\n this.rules.set(rule.id, rule);\n }\n }\n\n // ==========================================================================\n // Private\n // ==========================================================================\n\n private upsertRule(pattern: DetectedPattern, now: number): void {\n const id = ruleFingerprint(pattern.patternType, pattern.cli, pattern.category);\n const existing = this.rules.get(id);\n\n const confidence = sigmoidConfidence(pattern.observationCount);\n const status = this.computeStatus(pattern.observationCount, existing?.status);\n\n if (existing !== undefined) {\n this.rules.set(id, {\n ...existing,\n action: pattern.action,\n confidence,\n observationCount: pattern.observationCount,\n metric: pattern.metric,\n status,\n updatedAt: now,\n });\n } else {\n this.rules.set(id, {\n id,\n patternType: pattern.patternType,\n cli: pattern.cli,\n category: pattern.category,\n action: pattern.action,\n confidence,\n observationCount: pattern.observationCount,\n metric: pattern.metric,\n status,\n createdAt: now,\n updatedAt: now,\n tainted: false,\n });\n }\n }\n\n private computeStatus(observations: number, existing?: RuleStatus): RuleStatus {\n // Never downgrade promoted rules\n if (existing === 'promoted') return 'promoted';\n if (observations >= this.config.minObservationsForActive) return 'active';\n if (observations >= this.config.minObservationsForDraft) return 'draft';\n return 'draft';\n }\n\n private expireRules(now: number): void {\n for (const [id, rule] of this.rules) {\n if (rule.status === 'promoted') continue;\n if (now - rule.updatedAt > this.config.ruleExpiryMs) {\n this.rules.set(id, { ...rule, status: 'expired', updatedAt: now });\n }\n }\n }\n\n private enforceMaxRules(): void {\n if (this.rules.size <= this.config.maxRules) return;\n\n // Evict expired first, then lowest-confidence\n const sorted = [...this.rules.entries()].sort((a, b) => {\n // Expired rules sort first for eviction\n if (a[1].status === 'expired' && b[1].status !== 'expired') return -1;\n if (b[1].status === 'expired' && a[1].status !== 'expired') return 1;\n // Then by confidence ascending (lowest evicted first)\n return a[1].confidence - b[1].confidence;\n });\n\n const excess = this.rules.size - this.config.maxRules;\n for (let i = 0; i < excess; i++) {\n const entry = sorted[i];\n if (entry !== undefined) {\n this.rules.delete(entry[0]);\n }\n }\n }\n\n /** Convert rule metrics into ModelPerformance for RoutingMemory. */\n private ruleToPerformance(rule: DistilledRule): ModelPerformance {\n const successRate = rule.patternType === 'success-rate' ? rule.metric : 1 - rule.metric;\n return {\n avgQuality: rule.confidence,\n successRate: Math.max(0, Math.min(1, successRate)),\n avgLatencyMs: 0,\n avgTokens: 0,\n observations: rule.observationCount,\n };\n }\n}\n\n/** Factory function for creating StrategyDistiller. */\nexport function createStrategyDistiller(\n outcomeStore: OutcomeStore,\n logger?: ILogger,\n config?: Partial<DistillerConfig>\n): StrategyDistiller {\n return new StrategyDistiller(outcomeStore, logger, config);\n}\n\n// ============================================================================\n// Persistent factory registration (Issue #1009)\n// ============================================================================\n\ntype DistillerFactory = (outcomeStore: OutcomeStore, logger: ILogger) => StrategyDistiller;\nlet persistentDistillerFactory: DistillerFactory | undefined;\n\n/**\n * Register a factory for creating PersistentStrategyDistiller instances.\n * Called from strategy-distiller-persistence.ts at import time to break\n * the circular dependency with composite-router.\n */\nexport function registerPersistentDistillerFactory(factory: DistillerFactory): void {\n persistentDistillerFactory = factory;\n}\n\n/**\n * Create a persistent distiller if the factory is registered, else a plain one.\n * Used by CompositeRouter when NEXUS_PERSIST_LEARNING=true.\n */\nexport function createPersistentDistillerOrFallback(\n outcomeStore: OutcomeStore,\n logger: ILogger\n): StrategyDistiller {\n if (persistentDistillerFactory !== undefined) {\n return persistentDistillerFactory(outcomeStore, logger);\n }\n return new StrategyDistiller(outcomeStore, logger);\n}\n","/**\n * Type definitions for task outcome tracking.\n *\n * Records the result of each model delegation or consensus vote\n * to enable performance measurement across CLIs and task categories.\n *\n * @module orchestration/outcomes/outcome-types\n * (Source: Issue #861 — Task outcome tracking)\n */\n\nimport { z } from 'zod';\nimport { CliNameSchema } from '../../config/model-capabilities-types.js';\nimport { TaskCategorySchema } from '../../config/task-specialization-types.js';\nimport { createLogger } from '../../core/index.js';\n\nconst logger = createLogger({ component: 'outcome-error-taxonomy' });\n\n// ============================================================================\n// Schemas\n// ============================================================================\n\n// CliNameSchema imported from config/model-capabilities-types.ts (canonical source)\n\n/** Source of the task outcome. */\nconst OutcomeSourceSchema = z.enum(['delegate', 'consensus', 'manual']);\n\n/** Failure category for failed task outcomes (Issue #1025). */\nexport const OutcomeFailureCategorySchema = z.enum([\n 'timeout',\n 'authentication',\n 'rate_limit',\n 'connection',\n 'crash',\n 'adapter_unavailable',\n 'validation',\n 'parse',\n 'execution',\n 'generic',\n 'unknown',\n]);\n\n/** Schema for a single recorded task outcome. */\nexport const TaskOutcomeSchema = z.object({\n id: z.string().min(1),\n cli: CliNameSchema,\n category: TaskCategorySchema,\n model: z.string().min(1),\n success: z.boolean(),\n durationMs: z.number().nonnegative(),\n timestamp: z.string().min(1),\n qualitySignals: z.array(z.string()).optional(),\n failureCategory: OutcomeFailureCategorySchema.optional(),\n errorMessage: z.string().max(500).optional(),\n source: OutcomeSourceSchema,\n /** Whether this outcome came from a triage-initiated retry (#1506). */\n wasRetried: z.boolean().optional(),\n /** Triage action taken on the failure (#1506). */\n triageAction: z.string().max(30).optional(),\n /** Routing stage that selected this CLI (#1785). */\n routingStage: z.string().max(50).optional(),\n /** Number of retry attempts before this outcome (#1785). */\n retryCount: z.number().int().nonnegative().optional(),\n});\n\n/** Schema for filtering outcomes. */\nexport const OutcomeQuerySchema = z.object({\n cli: CliNameSchema.optional(),\n category: TaskCategorySchema.optional(),\n source: OutcomeSourceSchema.optional(),\n success: z.boolean().optional(),\n failureCategory: OutcomeFailureCategorySchema.optional(),\n since: z.string().optional(),\n limit: z.number().int().positive().optional(),\n /** Exclude outcomes with any of these quality signals (#1680). */\n excludeQualitySignals: z.array(z.string()).optional(),\n});\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** A single recorded task execution outcome. */\nexport type TaskOutcome = z.infer<typeof TaskOutcomeSchema>;\n\n/** Filter for querying stored outcomes. */\nexport type OutcomeQuery = z.infer<typeof OutcomeQuerySchema>;\n\n/** Source of the outcome record. */\nexport type OutcomeSource = z.infer<typeof OutcomeSourceSchema>;\n\n/** Category of failure for failed outcomes (Issue #1025). */\nexport type OutcomeFailureCategory = z.infer<typeof OutcomeFailureCategorySchema>;\n\n// ============================================================================\n// Error Classification (Issue #1025)\n// ============================================================================\n\nconst TIMEOUT_PATTERNS = ['timeout', 'timed out', 'deadline exceeded', 'socket hang up', 'aborted'];\nconst AUTH_PATTERNS = [\n 'auth',\n 'unauthorized',\n 'forbidden',\n 'oauth',\n 'permission denied',\n '401',\n '403',\n];\nconst RATE_LIMIT_PATTERNS = [\n 'rate limit',\n 'too many requests',\n '429',\n 'throttl',\n 'quota exceeded',\n 'max retries',\n 'retry limit',\n];\nconst CONNECTION_PATTERNS = [\n 'connection',\n 'connect',\n 'econnrefused',\n 'enotfound',\n 'econnreset',\n 'dns',\n 'network',\n 'getaddrinfo',\n 'certificate',\n 'ssl',\n 'tls',\n 'proxy',\n 'epipe',\n 'etimedout',\n // HTTP 5xx — transient server errors, not execution failures (#1530)\n '500',\n '502',\n '503',\n '504',\n 'internal server error',\n 'bad gateway',\n 'service unavailable',\n // Port binding failures — transient, not execution errors (#subprocess-adapter parity)\n 'eaddrinuse',\n 'address already in use',\n];\nconst CRASH_PATTERNS = [\n 'crash',\n 'exited',\n 'killed',\n 'sigterm',\n 'sigkill',\n 'spawn error',\n 'out of memory',\n 'oom',\n 'enomem',\n 'fatal',\n 'segfault',\n 'heap',\n];\nconst ADAPTER_PATTERNS = [\n 'no model adapter',\n 'adapter unavailable',\n 'no adapter',\n 'model not found',\n 'no model',\n 'unknown model',\n 'model does not exist',\n];\nconst VALIDATION_PATTERNS = [\n 'validation',\n 'invalid input',\n 'parse error',\n 'zod',\n 'schema',\n 'unknown workflow',\n 'unknown template',\n 'unknown type',\n 'not recognized',\n 'available:',\n];\nconst PARSE_PATTERNS = [\n 'json parse',\n 'unexpected token',\n 'unexpected end of json',\n 'syntax error',\n 'failed to parse',\n 'cannot parse',\n 'ndjson',\n 'malformed',\n // Model output issues — not execution failures (#1530)\n 'empty response',\n 'no output',\n 'no content',\n 'truncated',\n 'incomplete',\n];\nconst EXECUTION_PATTERNS = [\n 'api error',\n 'apierror',\n 'sdk error',\n 'failed to',\n 'cannot',\n 'typeerror',\n 'referenceerror',\n 'assertion',\n 'expect',\n 'undefined is not',\n 'null is not',\n 'is not a function',\n 'unhandled',\n 'rejected',\n 'enoent',\n 'permission denied',\n 'eperm',\n 'eacces',\n 'command failed',\n 'non-zero exit',\n 'exit code',\n];\n// Generic catch-all patterns — separated from execution for observability (#1457)\nconst GENERIC_PATTERNS = [\n 'error:',\n 'error occurred',\n 'failed',\n 'failure',\n 'exception',\n 'not found',\n 'not supported',\n 'not implemented',\n 'not available',\n 'invalid',\n 'unable to',\n 'could not',\n 'unexpected',\n 'missing',\n 'unsupported',\n];\n\nfunction matchesAny(text: string, patterns: string[]): boolean {\n return patterns.some((p) => text.includes(p));\n}\n\n/** Classify execution vs generic catch-all patterns (#1457). */\nfunction classifyExecutionOrGeneric(text: string): OutcomeFailureCategory {\n if (matchesAny(text, EXECUTION_PATTERNS)) return 'execution';\n if (matchesAny(text, GENERIC_PATTERNS)) return 'generic';\n // Log unknown classifications for pattern analysis (#1499 diagnostics)\n logger.debug('Unclassified error string', { sample: text.slice(0, 200) });\n return 'unknown';\n}\n\n/**\n * Classifies a lowercase text string against all known failure patterns.\n * Order: most-specific categories first, broad execution/generic last (#1461).\n * Empty/whitespace-only strings default to 'execution' (#1475).\n */\nfunction classifyText(text: string): OutcomeFailureCategory {\n if (text.trim() === '') return 'execution';\n if (matchesAny(text, ADAPTER_PATTERNS)) return 'adapter_unavailable';\n if (matchesAny(text, AUTH_PATTERNS)) return 'authentication';\n if (matchesAny(text, RATE_LIMIT_PATTERNS)) return 'rate_limit';\n if (matchesAny(text, TIMEOUT_PATTERNS)) return 'timeout';\n if (matchesAny(text, CONNECTION_PATTERNS)) return 'connection';\n if (matchesAny(text, CRASH_PATTERNS)) return 'crash';\n if (matchesAny(text, VALIDATION_PATTERNS)) return 'validation';\n if (matchesAny(text, PARSE_PATTERNS)) return 'parse';\n return classifyExecutionOrGeneric(text);\n}\n\n/** Maximum length for extracted error messages to prevent unbounded strings. */\nconst MAX_ERROR_MESSAGE_LENGTH = 500;\n\n/**\n * Extracts a classifiable message string from a non-Error value.\n * Returns undefined if the value is truly unclassifiable (#1466).\n */\nexport function extractNonErrorMessage(error: unknown): string | undefined {\n if (error === null || error === undefined) return undefined;\n if (typeof error === 'string') {\n return error.slice(0, MAX_ERROR_MESSAGE_LENGTH);\n }\n if (typeof error === 'object') {\n const record = error as Record<string, unknown>;\n if (typeof record['message'] === 'string') {\n return record['message'].slice(0, MAX_ERROR_MESSAGE_LENGTH);\n }\n try {\n const json = JSON.stringify(error);\n return json.slice(0, MAX_ERROR_MESSAGE_LENGTH);\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\n/** Classifies an error into an OutcomeFailureCategory for recording. */\nexport function categorizeOutcomeError(error: unknown): OutcomeFailureCategory {\n if (error instanceof Error) {\n const text = `${error.message.toLowerCase()} ${error.name.toLowerCase()}`;\n return classifyText(text);\n }\n const extracted = extractNonErrorMessage(error);\n // Null/undefined/unserializable errors default to 'execution' (#1494).\n // Consistent with #1475 (empty strings → execution, not unknown).\n if (extracted === undefined) return 'execution';\n return classifyText(extracted.toLowerCase());\n}\n\n/** Classifies an error message string into an OutcomeFailureCategory. */\nexport function categorizeOutcomeErrorMessage(msg: string): OutcomeFailureCategory {\n return classifyText(msg.toLowerCase());\n}\n\n/** Aggregated stats for a group of outcomes. */\nexport interface GroupStats {\n readonly count: number;\n readonly successRate: number;\n readonly avgDurationMs: number;\n}\n\n/** Aggregated performance summary from recorded outcomes. */\nexport interface PerformanceSummary {\n readonly totalTasks: number;\n readonly successRate: number;\n readonly avgDurationMs: number;\n readonly byCli: ReadonlyMap<string, GroupStats>;\n readonly byCategory: ReadonlyMap<string, GroupStats>;\n}\n","/**\n * In-memory, append-only store for task outcomes.\n *\n * Provides bounded storage with FIFO eviction, filtering queries,\n * and aggregated performance summaries. Thread-safe for single-process\n * use (Node.js event loop).\n *\n * @module orchestration/outcomes/outcome-store\n * (Source: Issue #861 — Task outcome tracking)\n */\n\nimport type { TaskOutcome, OutcomeQuery, PerformanceSummary, GroupStats } from './outcome-types.js';\nimport { categorizeOutcomeErrorMessage } from './outcome-types.js';\nimport { isPersistenceEnabled } from '../../config/learning-persistence.js';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Default maximum stored outcomes before oldest are evicted. */\nconst DEFAULT_MAX_ENTRIES = 10_000;\n\n// ============================================================================\n// OutcomeStore\n// ============================================================================\n\nexport interface OutcomeStoreConfig {\n readonly maxEntries?: number;\n}\n\n/**\n * Auto-classifies failed outcomes that are missing a failureCategory.\n * Uses errorMessage if available; otherwise marks as 'execution' for non-success\n * outcomes (better default than 'unknown' for outcomes that failed but have no error info).\n */\nfunction autoClassify(outcome: TaskOutcome): TaskOutcome {\n if (outcome.success || outcome.failureCategory !== undefined) return outcome;\n if (typeof outcome.errorMessage === 'string' && outcome.errorMessage.length > 0) {\n return { ...outcome, failureCategory: categorizeOutcomeErrorMessage(outcome.errorMessage) };\n }\n // Failed outcome with no error info — classify as 'execution' (generic failure)\n return { ...outcome, failureCategory: 'execution' };\n}\n\n/** Check if outcome has a non-empty error message. */\nfunction hasErrorMessage(o: TaskOutcome): boolean {\n return typeof o.errorMessage === 'string' && o.errorMessage.length > 0;\n}\n\n/**\n * Bounded, append-only, in-memory store for task outcomes.\n * Evicts oldest entries when capacity is exceeded.\n */\nexport class OutcomeStore {\n private readonly entries: TaskOutcome[] = [];\n private readonly maxEntries: number;\n\n constructor(config?: OutcomeStoreConfig) {\n this.maxEntries = config?.maxEntries ?? DEFAULT_MAX_ENTRIES;\n }\n\n /** Append a new outcome. Auto-classifies failures missing failureCategory (#1441). */\n append(outcome: TaskOutcome): void {\n this.entries.push(autoClassify(outcome));\n this.enforceLimit();\n }\n\n /** Query outcomes with optional filters. */\n query(filter?: OutcomeQuery): readonly TaskOutcome[] {\n if (filter === undefined) return [...this.entries];\n const filtered = applyFilters(this.entries, filter);\n return filter.limit !== undefined ? filtered.slice(-filter.limit) : filtered;\n }\n\n /** Aggregate outcomes into a performance summary. */\n summarize(filter?: OutcomeQuery): PerformanceSummary {\n const outcomes = this.query(filter);\n\n if (outcomes.length === 0) {\n return {\n totalTasks: 0,\n successRate: 0,\n avgDurationMs: 0,\n byCli: new Map(),\n byCategory: new Map(),\n };\n }\n\n const successCount = outcomes.filter((o) => o.success).length;\n const totalDuration = outcomes.reduce((s, o) => s + o.durationMs, 0);\n\n return {\n totalTasks: outcomes.length,\n successRate: successCount / outcomes.length,\n avgDurationMs: totalDuration / outcomes.length,\n byCli: groupBy(outcomes, (o) => o.cli),\n byCategory: groupBy(outcomes, (o) => o.category),\n };\n }\n\n /** Number of stored outcomes. */\n get size(): number {\n return this.entries.length;\n }\n\n /** Remove all stored outcomes. */\n clear(): void {\n this.entries.length = 0;\n }\n\n /**\n * Backfill: reclassify all entries missing failureCategory (#1444).\n * Also reclassifies 'unknown' entries with no error message as 'execution'\n * (#1511) since 'unknown' with no diagnostic info is less useful than the\n * default 'execution' category.\n * Returns count of reclassified entries.\n */\n reclassifyAll(): number {\n let count = 0;\n for (let i = 0; i < this.entries.length; i++) {\n const entry = this.entries[i];\n if (entry === undefined || entry.success) continue;\n if (entry.failureCategory === undefined) {\n this.entries[i] = autoClassify(entry);\n count++;\n } else if (\n entry.failureCategory === 'unknown' ||\n entry.failureCategory === 'execution' ||\n entry.failureCategory === 'generic'\n ) {\n // Re-run classification with updated patterns (#1507, #1530, #1401)\n // Reclassifies execution/generic/unknown entries since pattern ownership changed:\n // HTTP 5xx → connection, empty response → parse (#1530),\n // \"service unavailable\" → connection, exit code patterns → specific categories.\n const newCategory = hasErrorMessage(entry)\n ? categorizeOutcomeErrorMessage(entry.errorMessage as string)\n : 'execution';\n if (newCategory !== entry.failureCategory) {\n this.entries[i] = { ...entry, failureCategory: newCategory };\n count++;\n }\n }\n }\n return count;\n }\n\n /**\n * Purge false failures with zero execution time (#1528).\n * Removes non-success entries with durationMs=0 — these are either:\n * - Skipped workers (circuit breaker, role auto-disable)\n * - Test-generated entries (E2E eval artifacts)\n * - Pre-execution short-circuits (validation, initialization)\n * Real model execution always takes >0ms.\n * Returns count of purged entries.\n */\n purgeSkippedWorkers(): number {\n const before = this.entries.length;\n let writeIdx = 0;\n for (let i = 0; i < this.entries.length; i++) {\n const entry = this.entries[i];\n if (entry === undefined) continue;\n const isZeroDurationFailure = !entry.success && entry.durationMs === 0;\n if (!isZeroDurationFailure) {\n this.entries[writeIdx] = entry;\n writeIdx++;\n }\n }\n this.entries.length = writeIdx;\n return before - writeIdx;\n }\n\n private enforceLimit(): void {\n if (this.entries.length > this.maxEntries) {\n const excess = this.entries.length - this.maxEntries;\n this.entries.splice(0, excess);\n }\n }\n}\n\n// ============================================================================\n// Singleton\n// ============================================================================\n\nlet singletonStore: OutcomeStore | undefined;\n\n/**\n * Get the shared OutcomeStore singleton.\n * Returns PersistentOutcomeStore when NEXUS_PERSIST_LEARNING=true\n * and the factory has been registered (import outcome-store-persistence first).\n */\nexport function getOutcomeStore(): OutcomeStore {\n if (singletonStore === undefined) {\n if (isPersistenceEnabled() && persistentFactory !== undefined) {\n singletonStore = persistentFactory();\n } else {\n singletonStore = new OutcomeStore();\n }\n }\n return singletonStore;\n}\n\n/** Reset the singleton (for testing). */\nexport function resetOutcomeStore(): void {\n singletonStore = undefined;\n}\n\n/**\n * Replace the singleton with a specific store instance.\n * Used by E2E eval to inject an in-memory store that won't pollute\n * the persistent outcome file (#1528).\n */\nexport function setOutcomeStore(store: OutcomeStore): void {\n singletonStore = store;\n}\n\n// ============================================================================\n// Persistent factory registration (Issue #1009)\n// ============================================================================\n\ntype OutcomeStoreFactory = () => OutcomeStore;\nlet persistentFactory: OutcomeStoreFactory | undefined;\n\n/**\n * Register a factory for creating PersistentOutcomeStore instances.\n * Called from outcome-store-persistence.ts at import time to break\n * the circular dependency.\n */\nexport function registerPersistentOutcomeStoreFactory(factory: OutcomeStoreFactory): void {\n persistentFactory = factory;\n}\n\n// ============================================================================\n// Context Helpers (#1711 — Central Workflow Hub)\n// ============================================================================\n\n/**\n * Build a human-readable outcome summary for planning context.\n * Returns empty string when no outcomes are available (cold start).\n * Includes success rate and recent failure patterns with categories.\n */\nexport function getOutcomeSummaryText(limit = 5): string {\n const store = getOutcomeStore();\n const summary = store.summarize();\n if (summary.totalTasks === 0) return '';\n const failures = store.query({ success: false, limit });\n const failLines = failures\n .map((f) => {\n const cat = f.failureCategory ?? 'unknown';\n const msg = f.errorMessage ?? '';\n return msg.length > 0 ? `${cat}: ${msg}` : cat;\n })\n .filter((l) => l.length > 0);\n const taskCount = String(summary.totalTasks);\n const pct = String(Math.round(summary.successRate * 100));\n const header = `## Outcome Context (${taskCount} tasks, ${pct}% success)`;\n const failSection = failLines.length > 0 ? `\\nRecent failures:\\n${failLines.join('\\n')}` : '';\n return `${header}${failSection}`;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/** Builds predicate functions from an OutcomeQuery filter. */\nfunction buildPredicates(filter: OutcomeQuery): Array<(o: TaskOutcome) => boolean> {\n const preds: Array<(o: TaskOutcome) => boolean> = [];\n if (filter.cli !== undefined) preds.push((o) => o.cli === filter.cli);\n if (filter.category !== undefined) preds.push((o) => o.category === filter.category);\n if (filter.source !== undefined) preds.push((o) => o.source === filter.source);\n if (filter.success !== undefined) preds.push((o) => o.success === filter.success);\n if (filter.failureCategory !== undefined) {\n preds.push((o) => o.failureCategory === filter.failureCategory);\n }\n if (filter.since !== undefined) {\n const since = filter.since;\n preds.push((o) => o.timestamp >= since);\n }\n if (filter.excludeQualitySignals !== undefined && filter.excludeQualitySignals.length > 0) {\n const excluded = new Set(filter.excludeQualitySignals);\n preds.push((o) => {\n const signals = o.qualitySignals;\n if (signals === undefined || signals.length === 0) return true;\n return !signals.some((s) => excluded.has(s));\n });\n }\n return preds;\n}\n\nfunction applyFilters(entries: readonly TaskOutcome[], filter: OutcomeQuery): TaskOutcome[] {\n const preds = buildPredicates(filter);\n return entries.filter((o) => preds.every((p) => p(o)));\n}\n\nfunction groupBy(\n outcomes: readonly TaskOutcome[],\n keyFn: (o: TaskOutcome) => string\n): ReadonlyMap<string, GroupStats> {\n const groups = new Map<string, TaskOutcome[]>();\n\n for (const o of outcomes) {\n const key = keyFn(o);\n const list = groups.get(key);\n if (list !== undefined) {\n list.push(o);\n } else {\n groups.set(key, [o]);\n }\n }\n\n const result = new Map<string, GroupStats>();\n for (const [key, list] of groups) {\n const sc = list.filter((o) => o.success).length;\n const td = list.reduce((s, o) => s + o.durationMs, 0);\n result.set(key, {\n count: list.length,\n successRate: sc / list.length,\n avgDurationMs: td / list.length,\n });\n }\n\n return result;\n}\n","/**\n * EventBus — V2 Pipeline Event Bus (Issue #912, Phase 4-2)\n *\n * In-memory event bus with bounded circular buffer.\n * Fire-and-forget emission — handler errors are caught and logged.\n *\n * @see docs/v2/08-observability-eventing.md\n * @module pipeline/event-bus\n */\nimport { getErrorMessage, createLogger } from '../core/index.js';\n\nimport type {\n PipelineEvent,\n EventFilter,\n EventHandler,\n Unsubscribe,\n IEventBus,\n} from './event-types.js';\n\nconst logger = createLogger({ component: 'EventBus' });\n\nconst DEFAULT_MAX_BUFFER = 10_000;\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\n/** Options for EventBus behavior. */\nexport interface EventBusOptions {\n readonly maxBufferSize?: number;\n}\n\n// ============================================================================\n// Subscription\n// ============================================================================\n\ninterface Subscription {\n readonly filter: EventFilter;\n readonly handler: EventHandler;\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/**\n * In-memory event bus with bounded circular buffer.\n *\n * Events are stored in a circular buffer. When the buffer is full,\n * the oldest events are evicted. Subscribers receive events that\n * match their filter. Handler errors are caught and logged.\n */\nexport class EventBus implements IEventBus {\n private readonly buffer: PipelineEvent[] = [];\n private readonly maxBuffer: number;\n private readonly subs: Subscription[] = [];\n private emitCount = 0;\n\n constructor(options?: EventBusOptions) {\n this.maxBuffer = options?.maxBufferSize ?? DEFAULT_MAX_BUFFER;\n }\n\n get totalEmitted(): number {\n return this.emitCount;\n }\n\n get bufferSize(): number {\n return this.buffer.length;\n }\n\n /** Number of active subscriptions (for observability/testing). */\n get subscriptionCount(): number {\n return this.subs.length;\n }\n\n emit(event: PipelineEvent): void {\n this.emitCount++;\n this.addToBuffer(event);\n this.notifySubscribers(event);\n }\n\n subscribe(filter: EventFilter, handler: EventHandler): Unsubscribe {\n const sub: Subscription = { filter, handler };\n this.subs.push(sub);\n return () => {\n const idx = this.subs.indexOf(sub);\n if (idx >= 0) this.subs.splice(idx, 1);\n };\n }\n\n query(filter: EventFilter, limit?: number): readonly PipelineEvent[] {\n let results = this.buffer.filter((e) => matchesFilter(e, filter));\n if (limit !== undefined) {\n results = results.slice(0, limit);\n }\n return results;\n }\n\n // ==========================================================================\n // Internal\n // ==========================================================================\n\n private addToBuffer(event: PipelineEvent): void {\n if (this.buffer.length >= this.maxBuffer) {\n this.buffer.shift();\n }\n this.buffer.push(event);\n }\n\n private notifySubscribers(event: PipelineEvent): void {\n // Snapshot to prevent issues from subscribe/unsubscribe during iteration\n const snapshot = [...this.subs];\n for (const sub of snapshot) {\n if (!matchesFilter(event, sub.filter)) continue;\n try {\n sub.handler(event);\n } catch (error: unknown) {\n const msg = getErrorMessage(error);\n logger.warn('Event handler error', { eventType: event.type, error: msg });\n }\n }\n }\n}\n\n// ============================================================================\n// Filter Matching\n// ============================================================================\n\n/** Check if an event matches a filter. */\nfunction matchesFilter(event: PipelineEvent, filter: EventFilter): boolean {\n if (!matchesType(event, filter)) return false;\n if (filter.taskId !== undefined && !matchesTaskId(event, filter.taskId)) return false;\n if (filter.executionId !== undefined && !matchesExecutionId(event, filter.executionId)) {\n return false;\n }\n if (filter.since !== undefined && event.timestamp < filter.since) return false;\n return true;\n}\n\nfunction matchesType(event: PipelineEvent, filter: EventFilter): boolean {\n if (filter.type === undefined) return true;\n if (typeof filter.type === 'string') {\n return event.type === filter.type;\n }\n if (!Array.isArray(filter.type)) return false;\n return (filter.type as readonly string[]).includes(event.type);\n}\n\n/**\n * Checks if a PipelineEvent has a taskId matching the expected value.\n *\n * Uses the `in` operator to narrow the discriminated union to variants\n * that carry a taskId field, avoiding `as unknown as` casts.\n */\nfunction matchesTaskId(event: PipelineEvent, taskId: string): boolean {\n return 'taskId' in event && event.taskId === taskId;\n}\n\n/**\n * Checks if a PipelineEvent has an executionId matching the expected value.\n */\nfunction matchesExecutionId(event: PipelineEvent, executionId: string): boolean {\n return 'executionId' in event && event.executionId === executionId;\n}\n\n// ============================================================================\n// Global Pipeline EventBus Singleton (#1173)\n// ============================================================================\n\nlet globalPipelineEventBus: IEventBus | undefined;\n\n/** Returns the global pipeline EventBus (created lazily on first call). */\nexport function getPipelineEventBus(): IEventBus {\n globalPipelineEventBus ??= new EventBus();\n return globalPipelineEventBus;\n}\n\n/** Resets the global pipeline EventBus (for testing). */\nexport function resetPipelineEventBus(): void {\n globalPipelineEventBus = undefined;\n}\n","/**\n * LinUCB bandit warm-up from task specialization matrix.\n *\n * Generates synthetic priors from the canonical TASK_SPECIALIZATION_MATRIX\n * and seeds the LinUCB bandit to reduce cold-start exploration time.\n *\n * @module cli/warm-up\n * (Source: Issue #1023 — Bootstrap LinUCB with synthetic outcomes)\n */\n\nimport { TASK_SPECIALIZATION_MATRIX } from '../config/task-specialization.js';\nimport { TASK_CATEGORIES } from '../config/task-specialization-types.js';\nimport { getOutcomeStore } from '../orchestration/outcomes/outcome-store.js';\nimport type { TaskOutcome } from '../orchestration/outcomes/outcome-types.js';\nimport { createLogger, type ILogger } from '../core/index.js';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Reward hint for the primary CLI (strong prior). */\nconst PRIMARY_REWARD = 0.85;\n\n/** Reward hint for the secondary CLI (moderate prior). */\nconst SECONDARY_REWARD = 0.6;\n\n/** Reward hint for other CLIs (weak/exploratory prior). */\nconst OTHER_REWARD = 0.35;\n\n/** Marker in qualitySignals to identify synthetic outcomes. */\nexport const SYNTHETIC_MARKER = 'synthetic:warm-up';\n\n/** All known CLI names for bandit arms. */\nconst CLI_NAMES = ['claude', 'gemini', 'codex', 'opencode'] as const;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface WarmUpResult {\n readonly seeded: number;\n readonly skipped: boolean;\n readonly reason?: string;\n}\n\n// ============================================================================\n// Core Logic\n// ============================================================================\n\n/**\n * Derive average reward hints per CLI from the task specialization matrix.\n *\n * For each category:\n * - Primary CLI gets reward 0.85\n * - Secondary CLI gets reward 0.6\n * - Other CLIs get reward 0.35\n *\n * Returns the average reward across all categories per CLI.\n */\nexport function generateSyntheticPriors(): ReadonlyMap<string, number> {\n const totals = new Map<string, number>();\n for (const cli of CLI_NAMES) {\n totals.set(cli, 0);\n }\n\n for (const spec of TASK_SPECIALIZATION_MATRIX) {\n for (const cli of CLI_NAMES) {\n const current = totals.get(cli) ?? 0;\n if (cli === spec.primaryCli) {\n totals.set(cli, current + PRIMARY_REWARD);\n } else if (cli === spec.secondaryCli) {\n totals.set(cli, current + SECONDARY_REWARD);\n } else {\n totals.set(cli, current + OTHER_REWARD);\n }\n }\n }\n\n const count = TASK_CATEGORIES.length;\n const priors = new Map<string, number>();\n for (const [cli, total] of totals) {\n priors.set(cli, total / count);\n }\n return priors;\n}\n\n/**\n * Seed the LinUCB bandit with synthetic priors and record synthetic outcomes.\n *\n * Idempotent: skips if OutcomeStore already contains outcomes with the\n * synthetic marker in qualitySignals.\n */\nexport function runWarmUp(logger?: ILogger): WarmUpResult {\n const log = logger ?? createLogger({ component: 'warm-up' });\n const store = getOutcomeStore();\n\n // Idempotency check: skip if synthetic outcomes already exist\n const existing = store.query();\n const hasSynthetic = existing.some((o) => o.qualitySignals?.includes(SYNTHETIC_MARKER) === true);\n if (hasSynthetic) {\n log.info('Warm-up skipped: synthetic outcomes already exist');\n return { seeded: 0, skipped: true, reason: 'synthetic outcomes already exist' };\n }\n\n const priors = generateSyntheticPriors();\n const now = new Date().toISOString();\n let seeded = 0;\n\n // Record one synthetic outcome per CLI per category\n for (const spec of TASK_SPECIALIZATION_MATRIX) {\n for (const cli of CLI_NAMES) {\n let reward: number;\n if (cli === spec.primaryCli) {\n reward = PRIMARY_REWARD;\n } else if (cli === spec.secondaryCli) {\n reward = SECONDARY_REWARD;\n } else {\n reward = OTHER_REWARD;\n }\n\n const outcome: TaskOutcome = {\n id: `synthetic-${cli}-${spec.category}`,\n cli,\n category: spec.category,\n model: `${cli}-default`,\n success: reward >= 0.5,\n durationMs: 0,\n timestamp: now,\n qualitySignals: [SYNTHETIC_MARKER],\n source: 'manual',\n };\n store.append(outcome);\n seeded++;\n }\n }\n\n log.info('LinUCB warm-up complete', {\n seeded,\n priors: Object.fromEntries(priors),\n });\n\n return { seeded, skipped: false };\n}\n","/**\n * nexus-agents/cli-adapters - CompositeRouter Types\n *\n * Type definitions for the CompositeRouter module.\n *\n * @module cli-adapters/composite-router-types\n * (Source: Issue #166, Epic #164)\n */\n\nimport { z } from 'zod';\nimport type { ICliAdapter, CliName } from './types.js';\nimport type { TaskProfile } from '../core/index.js';\nimport type { PreferenceRouterConfig } from './preference-router-types.js';\nimport type { ZeroRouterConfig, DifficultyEstimate, ModelTier } from './zero-router-types.js';\nimport type { LatencyTrackerConfig, LatencyTrackerStats } from './latency-tracker-types.js';\nimport type { RoutingMemoryConfig, RoutingMemoryStats } from '../context/routing-memory.js';\nimport type {\n RoutingRecord,\n OutcomeRecord,\n RoutingMetrics,\n} from '../observability/routing-metrics-types.js';\nimport type { IOrchestrationObserver } from '../agents/observability/orchestration-observer-types.js';\nimport type { ConfidenceCascadeConfig } from './routing/stages/confidence-cascade-stage.js';\nimport type { CapabilityMatchConfig } from './routing/stages/capability-match-stage.js';\nimport type { QualityConstraintConfig } from './routing/stages/quality-constraint-stage.js';\nimport type { ResourceStrategyConfig } from './routing/stages/resource-strategy-stage.js';\nimport type { DistilledRuleStageConfig } from './routing/stages/distilled-rule-stage.js';\n\n/**\n * Interface for routing metrics collection.\n * Allows dependency injection of RoutingMetricsCollector.\n * (Source: Issue #559 - Wire RoutingMetricsCollector to CompositeRouter)\n */\nexport interface IRoutingMetricsCollector {\n /** Record a routing decision. */\n recordDecision(record: RoutingRecord): void;\n /** Record an outcome for a routing decision. */\n recordOutcome(record: OutcomeRecord): void;\n /** Get metrics for a time period. */\n getMetrics(periodHours?: number): RoutingMetrics;\n}\n\n/**\n * Configuration schema for CompositeRouter.\n */\nexport const CompositeRouterConfigSchema = z.object({\n /** Enable confidence cascade stage (default: false) (Issue #755, ADR-0005) */\n enableConfidenceCascade: z.boolean().default(false),\n /** Enable budget filtering stage (default: true) */\n enableBudgetFilter: z.boolean().default(true),\n /** Enable capability match stage (default: false) (Issue #755, ADR-0005) */\n enableCapabilityMatch: z.boolean().default(false),\n /** Enable ZeroRouter difficulty-based routing stage (default: true) (Issue #473) */\n enableZeroRouter: z.boolean().default(true),\n /** Enable preference-trained routing stage (default: false) */\n enablePreferenceRouting: z.boolean().default(false),\n /** Enable TOPSIS ranking stage (default: true) */\n enableTopsisRanking: z.boolean().default(true),\n /** Enable LinUCB selection stage (default: true) */\n enableLinUCBSelection: z.boolean().default(true),\n /** Enable quality constraint stage (default: false) (Issue #755, ADR-0005) */\n enableQualityConstraint: z.boolean().default(false),\n /** Enable resource strategy stage for budget-aware oscillation (default: true) (Issue #998) */\n enableResourceStrategy: z.boolean().default(true),\n /** Enable strategy distillation for learned routing rules (default: false) (Issue #999) */\n enableStrategyDistillation: z.boolean().default(false),\n /** Enable latency tracking for routing decisions (default: true) (Issue #361) */\n enableLatencyTracking: z.boolean().default(true),\n /** Enable routing memory for learned routing (default: false) (Issue #463, #461) */\n enableRoutingMemory: z.boolean().default(false),\n /** Enable KNN experience-based routing (default: false) (arXiv:2507.05370) */\n enableKnnRouting: z.boolean().default(false),\n /** Weight for latency score in final routing (0-1, default: 0.2) */\n latencyScoreWeight: z.number().min(0).max(1).default(0.2),\n /** Budget constraints (optional) */\n budgetConstraints: z\n .object({\n maxTokens: z.number().positive(),\n maxCostUsd: z.number().positive(),\n maxLatencyMs: z.number().positive(),\n })\n .partial()\n .optional(),\n /** LinUCB exploration parameter (default: 1.0) */\n linucbAlpha: z.number().positive().default(1.0),\n /** Billing mode: 'plan' zeroes cost weight, 'api' preserves current behavior (default: 'plan') */\n billingMode: z.enum(['plan', 'api']).default('plan'),\n /** Enable capacity-aware load balancing (deprioritize exhausted CLIs) (default: true) (Issue #807) */\n enableCapacityBalancing: z.boolean().default(true),\n /** Maximum routing decision time in ms (default: 50) */\n maxDecisionTimeMs: z.number().positive().default(50),\n /** Minimum preference data points before using learned routing (default: 10) */\n preferenceMinDataPoints: z.number().int().positive().default(10),\n});\n\nexport type CompositeRouterConfig = z.infer<typeof CompositeRouterConfigSchema>;\n\n/**\n * Extended config type that includes preference router and ZeroRouter config.\n */\nexport interface CompositeRouterConfigWithPreference extends CompositeRouterConfig {\n /** Confidence cascade stage configuration (optional) (Issue #755) */\n confidenceCascadeConfig?: Partial<ConfidenceCascadeConfig>;\n /** Capability match stage configuration (optional) (Issue #755) */\n capabilityMatchConfig?: Partial<CapabilityMatchConfig>;\n /** Quality constraint stage configuration (optional) (Issue #755) */\n qualityConstraintConfig?: Partial<QualityConstraintConfig>;\n /** Resource strategy stage configuration (optional) (Issue #998) */\n resourceStrategyConfig?: Partial<ResourceStrategyConfig>;\n /** Distilled rule stage configuration (optional) (Issue #999) */\n distilledRuleStageConfig?: Partial<DistilledRuleStageConfig>;\n /** Preference router configuration (optional, uses defaults if not provided) */\n preferenceRouterConfig?: Partial<PreferenceRouterConfig>;\n /** ZeroRouter configuration (optional, uses defaults if not provided) */\n zeroRouterConfig?: Partial<ZeroRouterConfig>;\n /** Latency tracker configuration (optional, uses defaults if not provided) (Issue #361) */\n latencyTrackerConfig?: Partial<LatencyTrackerConfig>;\n /** Routing memory configuration (optional, uses defaults if not provided) (Issue #463) */\n routingMemoryConfig?: Partial<RoutingMemoryConfig>;\n /** Routing metrics collector for observability (optional) (Issue #559) */\n metricsCollector?: IRoutingMetricsCollector;\n /** Orchestration observer for routing decision tracking (optional) (Issue #587) */\n orchestrationObserver?: IOrchestrationObserver;\n}\n\n/**\n * Default configuration.\n */\nexport const DEFAULT_COMPOSITE_CONFIG: CompositeRouterConfig = {\n enableConfidenceCascade: false, // Issue #755 - New replacement stage (disabled for backward compatibility)\n enableBudgetFilter: true,\n enableCapabilityMatch: false, // Issue #755 - New replacement stage (disabled for backward compatibility)\n enableZeroRouter: true, // Issue #473 - Enable by default (699 lines of tests, fully implemented)\n enablePreferenceRouting: false,\n enableTopsisRanking: true,\n enableLinUCBSelection: true,\n enableQualityConstraint: false, // Issue #755 - New replacement stage (disabled for backward compatibility)\n enableResourceStrategy: true, // Issue #998 - Budget-aware strategy oscillation\n enableStrategyDistillation: false, // Issue #999 - Automatic strategy distillation (opt-in)\n enableLatencyTracking: true,\n enableRoutingMemory: false,\n enableKnnRouting: false, // arXiv:2507.05370 - KNN experience-based routing\n enableCapacityBalancing: true, // Issue #807 - Deprioritize exhausted CLIs\n latencyScoreWeight: 0.2,\n billingMode: 'plan',\n linucbAlpha: 1.0,\n maxDecisionTimeMs: 50,\n preferenceMinDataPoints: 10,\n};\n\n/**\n * Routing decision with full explanation.\n */\nexport interface CompositeRoutingDecision {\n /** Selected CLI adapter */\n readonly adapter: ICliAdapter;\n /** Selected CLI name */\n readonly cliName: CliName;\n /** Overall confidence in decision (0-1) */\n readonly confidence: number;\n /** Human-readable explanation */\n readonly reason: string;\n /** Stages executed */\n readonly stagesExecuted: readonly string[];\n /** Decision time in milliseconds */\n readonly decisionTimeMs: number;\n /** Budget feasibility (if budget filter enabled) */\n readonly withinBudget?: boolean | undefined;\n /** ZeroRouter difficulty estimate (if ZeroRouter enabled) */\n readonly difficultyEstimate?: DifficultyEstimate | undefined;\n /** ZeroRouter recommended model tier (if ZeroRouter enabled) */\n readonly difficultyTier?: ModelTier | undefined;\n /** Preference routing score (if preference routing enabled) */\n readonly preferenceScore?: number | undefined;\n /** Selected tier from preference routing */\n readonly preferenceTier?: 'strong' | 'weak' | undefined;\n /** TOPSIS score (if TOPSIS ranking enabled) */\n readonly topsisScore?: number | undefined;\n /** LinUCB UCB score (if LinUCB enabled) */\n readonly ucbScore?: number | undefined;\n /** Latency score (if latency tracking enabled) (Issue #361) */\n readonly latencyScore?: number | undefined;\n /** Alternative adapters in ranked order */\n readonly alternatives: readonly CliName[];\n /** Task analysis used for routing */\n readonly taskProfile: TaskProfile;\n}\n\n/**\n * Error from composite routing.\n */\nexport class CompositeRoutingError extends Error {\n readonly stage: string;\n\n constructor(message: string, stage: string, cause?: Error) {\n super(message, { cause });\n this.name = 'CompositeRoutingError';\n this.stage = stage;\n }\n}\n\n/**\n * Router statistics for observability.\n */\nexport interface CompositeRouterStats {\n /** Total routing decisions made */\n readonly totalDecisions: number;\n /** Decisions per CLI */\n readonly decisionsPerCli: Readonly<Record<CliName, number>>;\n /** Average decision time in ms */\n readonly avgDecisionTimeMs: number;\n /** Budget filter rejection rate */\n readonly budgetRejectionRate: number;\n /** Preference routing statistics */\n readonly preferenceStats?: {\n /** Whether preference routing is enabled */\n readonly enabled: boolean;\n /** Whether sufficient data for preference routing */\n readonly hasSufficientData: boolean;\n /** Total preference data points collected */\n readonly dataPointCount: number;\n /** Strong model preference rate */\n readonly strongModelPreferenceRate: number;\n };\n /** LinUCB arm statistics */\n readonly banditStats: ReadonlyArray<{ name: string; pullCount: number; avgReward: number }>;\n /** Latency tracking statistics (Issue #361) */\n readonly latencyStats?: LatencyTrackerStats | undefined;\n /** Routing memory statistics (Issue #463) */\n readonly routingMemoryStats?: RoutingMemoryStats | undefined;\n}\n\n/**\n * Internal pipeline result type.\n */\nexport interface PipelineResult {\n candidates: CliName[];\n withinBudget: boolean | undefined;\n difficultyEstimate: DifficultyEstimate | undefined;\n difficultyTier: ModelTier | undefined;\n preferenceScore: number | undefined;\n preferenceTier: 'strong' | 'weak' | undefined;\n topsisRanking: CliName[];\n topsisScore: number | undefined;\n selectedCli: CliName;\n ucbScore: number | undefined;\n latencyScore: number | undefined;\n /** Routing memory recommendation (Issue #489) */\n memoryRecommendation: CliName | undefined;\n /** Routing memory confidence (Issue #489) */\n memoryConfidence: number | undefined;\n /** Aggregated scores from async routing stages (Issue #1350) */\n stageScores?: ReadonlyMap<CliName, number> | undefined;\n /** Complexity estimate from confidence cascade stage (Issue #1350) */\n cascadeComplexity?: 'simple' | 'moderate' | 'complex' | undefined;\n /** Task type detected by capability match stage (Issue #1350) */\n capabilityTaskType?: string | undefined;\n /** CLIs filtered out by quality constraint stage with reasons (Issue #1350) */\n qualityFiltered?: ReadonlyMap<CliName, string> | undefined;\n /** Resource tier from resource strategy stage (Issue #1350) */\n resourceTier?: string | undefined;\n /** Number of distilled rules applied (Issue #1350) */\n distilledRulesApplied?: number | undefined;\n}\n\n/**\n * Parameters for building routing decision.\n */\nexport interface BuildDecisionParams {\n taskProfile: TaskProfile;\n selectedCli: CliName;\n candidates: CliName[];\n topsisRanking: CliName[];\n stagesExecuted: string[];\n startTime: number;\n withinBudget: boolean | undefined;\n difficultyEstimate: DifficultyEstimate | undefined;\n difficultyTier: ModelTier | undefined;\n preferenceScore: number | undefined;\n preferenceTier: 'strong' | 'weak' | undefined;\n topsisScore: number | undefined;\n ucbScore: number | undefined;\n latencyScore: number | undefined;\n}\n","/**\n * nexus-agents/cli-adapters - CompositeRouter Helper Functions\n *\n * Pure helper functions extracted from CompositeRouter to reduce file size.\n *\n * @module cli-adapters/composite-router-helpers\n * (Source: Issue #275, Epic #164, Issue #347)\n */\n\nimport type { Task } from '../core/types/agent.js';\nimport { getTimeProvider, type TaskProfile } from '../core/index.js';\nimport type { CliName, CliTask, BudgetConstraint } from './types.js';\nimport type { BanditContext } from './budget-router-types.js';\nimport type { TopsisModelProfile, TopsisResult } from './topsis-types.js';\nimport {\n DEFAULT_MODEL_PROFILES,\n DEFAULT_TOPSIS_CRITERIA,\n PLAN_BILLING_TOPSIS_CRITERIA,\n getCriteriaForTaskCategory,\n} from './topsis-types.js';\nimport type { BillingMode } from '../mcp/tools/delegate-to-model-types.js';\nimport type { BudgetRouter } from './budget-router.js';\nimport { TopsisRouter } from './topsis-router.js';\nimport type { CompositeRouterConfig } from './composite-router-types.js';\nimport type { IZeroRouter } from './zero-router.js';\nimport type { DifficultyEstimate, DifficultyOutcome, ModelTier } from './zero-router-types.js';\nimport { hashTaskContent } from './zero-router-calibration.js';\n\n/**\n * Adjusts model profile based on task characteristics.\n */\nexport function adjustProfileForTask(\n profile: TopsisModelProfile,\n taskProfile: TaskProfile\n): TopsisModelProfile {\n if (taskProfile.taskType === 'architecture' || taskProfile.reasoningComplexity > 7) {\n return { ...profile, qualityScore: Math.min(profile.qualityScore * 1.2, 10) };\n }\n if (taskProfile.taskType === 'bulk_operations' || taskProfile.contextRequired < 1000) {\n return { ...profile, averageLatencyMs: profile.averageLatencyMs * 0.8 };\n }\n return profile;\n}\n\n/**\n * Converts a task profile to LinUCB bandit context.\n */\nexport function taskProfileToBanditContext(profile: TaskProfile): BanditContext {\n return {\n taskComplexity: profile.reasoningComplexity / 10,\n contextLengthNormalized: Math.min(profile.contextRequired / 100000, 1),\n isCodeTask: profile.codeGeneration ? 1 : 0,\n isReasoningTask: profile.taskType === 'architecture' || profile.reasoningComplexity > 5 ? 1 : 0,\n budgetUtilization: 0.5,\n timePressure: 0.3,\n };\n}\n\n/**\n * Calculates routing confidence from multiple scores.\n */\nexport function calculateConfidence(\n topsisScore: number | undefined,\n ucbScore: number | undefined,\n candidateCount: number\n): number {\n const scores: number[] = [];\n if (topsisScore !== undefined) scores.push(topsisScore);\n if (ucbScore !== undefined) scores.push(Math.min(ucbScore / 10, 1));\n const baseConfidence = Math.min(0.5 + candidateCount * 0.1, 0.8);\n if (scores.length === 0) return baseConfidence;\n const avgScore = scores.reduce((a, b) => a + b, 0) / scores.length;\n return 0.3 * baseConfidence + 0.7 * avgScore;\n}\n\n/**\n * Options for building routing reason.\n */\nexport interface BuildReasonOptions {\n selectedCli: CliName;\n stages: string[];\n topsisScore?: number;\n ucbScore?: number;\n preferenceScore?: number;\n difficultyTier?: ModelTier;\n difficultyScore?: number;\n}\n\n/**\n * Builds a human-readable routing reason.\n */\nexport function buildReason(options: BuildReasonOptions): string {\n const { selectedCli, stages, topsisScore, ucbScore, preferenceScore, difficultyTier } = options;\n const difficultyScore = options.difficultyScore;\n const parts: string[] = ['Selected ' + selectedCli];\n if (stages.includes('budget-filter')) parts.push('within budget');\n if (difficultyTier !== undefined && difficultyScore !== undefined) {\n parts.push('difficulty ' + difficultyTier + ' (' + difficultyScore.toFixed(2) + ')');\n }\n if (preferenceScore !== undefined) parts.push('preference ' + preferenceScore.toFixed(2));\n if (topsisScore !== undefined) parts.push('TOPSIS score ' + topsisScore.toFixed(2));\n if (ucbScore !== undefined) parts.push('UCB score ' + ucbScore.toFixed(2));\n return parts.join(', ');\n}\n\n/**\n * Filters CLI candidates based on preference tier.\n */\nexport function filterByPreferenceTier(candidates: CliName[], tier: 'strong' | 'weak'): CliName[] {\n // Strong models: claude (opus, sonnet)\n // Weak models: gemini (flash), codex\n const strongModels: CliName[] = ['claude'];\n const weakModels: CliName[] = ['gemini', 'codex'];\n\n const preferred = tier === 'strong' ? strongModels : weakModels;\n const filtered = candidates.filter((c) => preferred.includes(c));\n\n // Return filtered if any match, otherwise return all candidates\n return filtered.length > 0 ? filtered : candidates;\n}\n\n/**\n * Converts a CliTask to internal Task format.\n */\nexport function cliTaskToTask(cliTask: CliTask): Task {\n return {\n id: 'task-' + String(getTimeProvider().now()),\n description: cliTask.content,\n context: {},\n };\n}\n\n/**\n * Budget filter result.\n */\nexport interface BudgetFilterResult {\n eligible: CliName[];\n withinBudget: boolean;\n}\n\n/**\n * Applies budget filtering to candidate CLIs.\n */\nexport function applyBudgetFilter(\n task: CliTask,\n candidates: CliName[],\n budgetRouter: BudgetRouter | undefined,\n config: CompositeRouterConfig\n): BudgetFilterResult {\n if (budgetRouter === undefined) {\n return { eligible: candidates, withinBudget: true };\n }\n\n const rawConstraints = config.budgetConstraints;\n const constraint: BudgetConstraint = {};\n if (rawConstraints?.maxTokens !== undefined) {\n (constraint as { maxTokens: number }).maxTokens = rawConstraints.maxTokens;\n }\n if (rawConstraints?.maxCostUsd !== undefined) {\n (constraint as { maxCostUsd: number }).maxCostUsd = rawConstraints.maxCostUsd;\n }\n if (rawConstraints?.maxLatencyMs !== undefined) {\n (constraint as { maxLatencyMs: number }).maxLatencyMs = rawConstraints.maxLatencyMs;\n }\n\n const result = budgetRouter.checkBudget(task, constraint);\n return { eligible: result.withinBudget ? candidates : [], withinBudget: result.withinBudget };\n}\n\n/**\n * TOPSIS ranking result.\n */\nexport interface TopsisRankingResult {\n ranking: CliName[];\n topScore: number;\n /** Number of candidates within the tolerance band of the top score. */\n toleranceBandSize?: number;\n}\n\n/**\n * Tolerance band percentage for TOPSIS scoring.\n * Candidates within this % of the top score are considered quality-equivalent.\n * Among equivalent candidates, the original ranking is preserved (TOPSIS tiebreak).\n * This prevents over-concentration on a single CLI and improves diversity.\n * (Source: Issue #1401 — tolerance-routing technique)\n */\nexport const TOPSIS_TOLERANCE_BAND_PERCENT = 0.05;\n\n/** Returns a TopsisRouter with task-category-aware criteria (#1491).\n * Only creates a new router when the criteria differ from the billing-mode default. */\nfunction selectTopsisRouter(\n router: TopsisRouter,\n billingMode: BillingMode,\n taskType?: string\n): TopsisRouter {\n if (taskType !== undefined) {\n const mode = billingMode === 'plan' ? 'plan' : 'api';\n const criteria = getCriteriaForTaskCategory(taskType, mode);\n const defaultCriteria =\n mode === 'plan' ? PLAN_BILLING_TOPSIS_CRITERIA : DEFAULT_TOPSIS_CRITERIA;\n // Only create a new router when category criteria differ from default\n if (criteria !== defaultCriteria) {\n return new TopsisRouter({ criteria });\n }\n }\n if (billingMode === 'plan') {\n return new TopsisRouter({ criteria: PLAN_BILLING_TOPSIS_CRITERIA });\n }\n return router;\n}\n\n// ---------------------------------------------------------------------------\n// Performance Floor Gate (Issue #1401 — consensus-approved Option A)\n// ---------------------------------------------------------------------------\n\n/** Minimum observed success rate before quality penalty applies. */\nexport const PERFORMANCE_FLOOR_THRESHOLD = 0.5;\n\n/** Minimum sample count required before the floor gate activates. */\nexport const PERFORMANCE_FLOOR_MIN_SAMPLES = 20;\n\n/** Quality score penalty applied to underperforming CLI+category pairs. */\nexport const PERFORMANCE_FLOOR_PENALTY = 3.0;\n\n/**\n * Performance data for a CLI on a specific task category.\n */\nexport interface PerformanceFloorEntry {\n successRate: number;\n sampleCount: number;\n}\n\n/**\n * Applies a quality penalty to CLI profiles whose observed success rate\n * for the current task category falls below PERFORMANCE_FLOOR_THRESHOLD.\n *\n * Only activates when sufficient samples exist (>= PERFORMANCE_FLOOR_MIN_SAMPLES)\n * to avoid penalizing CLIs with noisy small-sample data.\n *\n * This is a pre-TOPSIS adjustment that nudges routing away from\n * empirically underperforming CLI+category pairs. (#1401)\n */\nexport function applyPerformanceFloorPenalty(\n profiles: readonly TopsisModelProfile[],\n performanceData: ReadonlyMap<CliName, PerformanceFloorEntry>\n): TopsisModelProfile[] {\n if (performanceData.size === 0) return [...profiles];\n\n return profiles.map((p) => {\n const perf = performanceData.get(p.cliName);\n if (perf === undefined) return p;\n if (perf.sampleCount < PERFORMANCE_FLOOR_MIN_SAMPLES) return p;\n if (perf.successRate >= PERFORMANCE_FLOOR_THRESHOLD) return p;\n\n const penalized = Math.max(p.qualityScore - PERFORMANCE_FLOOR_PENALTY, 0);\n return { ...p, qualityScore: penalized };\n });\n}\n\n/** Max quality boost from stage scores: +15%. */\nconst STAGE_SCORE_MAX_BOOST = 0.15;\n\n/** Max quality penalty from stage scores: -10%. */\nconst STAGE_SCORE_MAX_PENALTY = 0.1;\n\n/**\n * Adjusts TOPSIS model profiles based on aggregated stage scores.\n * CLIs with above-average stage affinity get quality boosted (up to +15%),\n * below-average get quality reduced (down to -10%). (#1354)\n */\nexport function adjustProfileWithStageScores(\n profiles: readonly TopsisModelProfile[],\n stageScores: ReadonlyMap<CliName, number>\n): TopsisModelProfile[] {\n if (stageScores.size === 0) return [...profiles];\n\n // Calculate the mean score across all CLIs that have scores\n const scoreValues = [...stageScores.values()];\n const mean = scoreValues.reduce((a, b) => a + b, 0) / scoreValues.length;\n // Range for normalization: max deviation from mean\n const maxDev = Math.max(\n ...scoreValues.map((v) => Math.abs(v - mean)),\n 0.001 // prevent division by zero\n );\n\n return profiles.map((p) => {\n const score = stageScores.get(p.cliName);\n if (score === undefined) return p;\n\n const deviation = score - mean;\n // Normalize to [-1, 1] range\n const normalized = deviation / maxDev;\n // Map to boost/penalty: positive → boost, negative → penalty\n const multiplier =\n normalized >= 0\n ? 1 + normalized * STAGE_SCORE_MAX_BOOST\n : 1 + normalized * STAGE_SCORE_MAX_PENALTY;\n const adjustedQuality = Math.min(p.qualityScore * multiplier, 10);\n\n return { ...p, qualityScore: adjustedQuality };\n });\n}\n\n/** Options for TOPSIS ranking beyond the core required params. */\nexport interface TopsisRankingOptions {\n billingMode?: BillingMode;\n stageScores?: ReadonlyMap<CliName, number>;\n performanceData?: ReadonlyMap<CliName, PerformanceFloorEntry>;\n}\n\n/** Builds adjusted TOPSIS profiles from task, stage scores, and performance data. */\nfunction buildAdjustedProfiles(\n taskProfile: TaskProfile,\n candidates: CliName[],\n options?: TopsisRankingOptions\n): TopsisModelProfile[] {\n const profiles = DEFAULT_MODEL_PROFILES.filter((p) => candidates.includes(p.cliName));\n let adjusted = profiles.map((p) => adjustProfileForTask(p, taskProfile));\n if (options?.stageScores !== undefined && options.stageScores.size > 0) {\n adjusted = adjustProfileWithStageScores(adjusted, options.stageScores);\n }\n if (options?.performanceData !== undefined && options.performanceData.size > 0) {\n adjusted = applyPerformanceFloorPenalty(adjusted, options.performanceData);\n }\n return adjusted;\n}\n\n/**\n * Applies TOPSIS ranking to candidate CLIs.\n * Uses task-category-aware criteria weights when taskProfile.taskType is available (#1491).\n * When stageScores are provided, adjusts quality profiles before evaluation. (#1354)\n */\nexport function applyTopsisRanking(\n taskProfile: TaskProfile,\n candidates: CliName[],\n topsisRouter: TopsisRouter | undefined,\n options?: TopsisRankingOptions\n): TopsisRankingResult {\n if (topsisRouter === undefined) {\n return { ranking: candidates, topScore: 1.0 };\n }\n\n const billingMode = options?.billingMode ?? 'api';\n const router = selectTopsisRouter(topsisRouter, billingMode, taskProfile.taskType);\n const adjustedProfiles = buildAdjustedProfiles(taskProfile, candidates, options);\n const result: TopsisResult = router.selectModel({ profiles: adjustedProfiles });\n\n const scoreMap = new Map(result.scores.map((s) => [s.cliName, s.closenessScore]));\n const ranking = [...candidates].sort((a, b) => (scoreMap.get(b) ?? 0) - (scoreMap.get(a) ?? 0));\n const topScore = scoreMap.get(ranking[0] ?? 'claude') ?? 1.0;\n\n // Tolerance band: count how many candidates are within TOLERANCE_BAND_PERCENT of top\n const threshold = topScore * (1 - TOPSIS_TOLERANCE_BAND_PERCENT);\n const toleranceBandSize = ranking.filter((c) => (scoreMap.get(c) ?? 0) >= threshold).length;\n\n return { ranking, topScore, toleranceBandSize };\n}\n\n/**\n * Preference stage result.\n */\nexport interface PreferenceStageResult {\n preferenceScore: number | undefined;\n preferenceTier: 'strong' | 'weak' | undefined;\n preferredCandidates: CliName[];\n}\n\n/**\n * Default preference stage result when preference routing is disabled.\n */\nexport function defaultPreferenceStageResult(candidates: CliName[]): PreferenceStageResult {\n return {\n preferenceScore: undefined,\n preferenceTier: undefined,\n preferredCandidates: candidates,\n };\n}\n\n/**\n * ZeroRouter stage result.\n */\nexport interface ZeroRouterStageResult {\n difficultyEstimate: DifficultyEstimate | undefined;\n difficultyTier: ModelTier | undefined;\n filteredCandidates: CliName[];\n}\n\n/**\n * Default ZeroRouter stage result when ZeroRouter is disabled.\n */\nexport function defaultZeroRouterStageResult(candidates: CliName[]): ZeroRouterStageResult {\n return {\n difficultyEstimate: undefined,\n difficultyTier: undefined,\n filteredCandidates: candidates,\n };\n}\n\n/**\n * Maps model tier to preferred CLI order.\n * Fast tier prefers gemini/codex, Powerful tier prefers claude.\n */\nexport function filterByDifficultyTier(candidates: CliName[], tier: ModelTier): CliName[] {\n // Tier mappings aligned with ZeroRouter DEFAULT_TIER_TO_CLIS\n const tierPreferences: Record<ModelTier, CliName[]> = {\n fast: ['gemini', 'codex', 'claude'],\n balanced: ['codex', 'gemini', 'claude'],\n powerful: ['claude', 'codex', 'gemini'],\n };\n\n const preferred = tierPreferences[tier];\n // Sort candidates by tier preference order\n const sortedCandidates = [...candidates].sort((a, b) => {\n const aIndex = preferred.indexOf(a);\n const bIndex = preferred.indexOf(b);\n // If not in preference list, put at end\n const aPos = aIndex === -1 ? preferred.length : aIndex;\n const bPos = bIndex === -1 ? preferred.length : bIndex;\n return aPos - bPos;\n });\n\n return sortedCandidates;\n}\n\n/**\n * Applies ZeroRouter difficulty-based filtering to candidate CLIs.\n */\nexport function applyZeroRouterFilter(\n task: CliTask,\n candidates: CliName[],\n zeroRouter: IZeroRouter | undefined\n): ZeroRouterStageResult {\n if (zeroRouter === undefined || candidates.length === 0) {\n return defaultZeroRouterStageResult(candidates);\n }\n\n const decision = zeroRouter.routeByDifficulty(task, candidates);\n const difficultyEstimate = decision.difficulty;\n const difficultyTier = decision.tier;\n\n // Sort candidates by tier preference\n const filteredCandidates = filterByDifficultyTier(candidates, difficultyTier);\n\n return {\n difficultyEstimate,\n difficultyTier,\n filteredCandidates,\n };\n}\n\n/**\n * Builds a DifficultyOutcome object for calibration.\n */\nexport function buildDifficultyOutcome(\n taskContent: string,\n difficulty: number,\n selectedCli: CliName,\n success: boolean,\n qualityScore?: number\n): DifficultyOutcome {\n const base = {\n taskHash: hashTaskContent(taskContent),\n estimatedDifficulty: difficulty,\n selectedCli,\n success,\n timestamp: getTimeProvider().now(),\n };\n return qualityScore !== undefined ? { ...base, qualityScore } : base;\n}\n\n/**\n * Creates the routing decision result object.\n */\nexport interface BuildDecisionContext {\n selectedCli: CliName;\n candidates: CliName[];\n topsisRanking: CliName[];\n stagesExecuted: string[];\n decisionTimeMs: number;\n withinBudget: boolean | undefined;\n difficultyEstimate: DifficultyEstimate | undefined;\n difficultyTier: ModelTier | undefined;\n preferenceScore: number | undefined;\n preferenceTier: 'strong' | 'weak' | undefined;\n topsisScore: number | undefined;\n ucbScore: number | undefined;\n taskProfile: TaskProfile;\n}\n\n/**\n * Builds the routing decision fields (excluding adapter which requires Map lookup).\n */\nexport function buildDecisionFields(ctx: BuildDecisionContext): {\n confidence: number;\n reason: string;\n alternatives: CliName[];\n} {\n const confidence = calculateConfidence(ctx.topsisScore, ctx.ucbScore, ctx.candidates.length);\n const reason = buildReason({\n selectedCli: ctx.selectedCli,\n stages: ctx.stagesExecuted,\n ...(ctx.topsisScore !== undefined ? { topsisScore: ctx.topsisScore } : {}),\n ...(ctx.ucbScore !== undefined ? { ucbScore: ctx.ucbScore } : {}),\n ...(ctx.preferenceScore !== undefined ? { preferenceScore: ctx.preferenceScore } : {}),\n ...(ctx.difficultyTier !== undefined ? { difficultyTier: ctx.difficultyTier } : {}),\n ...(ctx.difficultyEstimate?.aggregateScore !== undefined\n ? { difficultyScore: ctx.difficultyEstimate.aggregateScore }\n : {}),\n });\n const alternatives = ctx.topsisRanking.filter((c) => c !== ctx.selectedCli);\n return { confidence, reason, alternatives };\n}\n\n/**\n * Builds preference stats for CompositeRouter stats output.\n */\nexport function buildPreferenceStats(\n enablePreferenceRouting: boolean,\n preferenceRouter:\n | {\n getStats: () => { totalDataPoints: number; strongModelPreferenceRate: number };\n hasMinimumData: () => boolean;\n }\n | undefined\n):\n | {\n enabled: boolean;\n hasSufficientData: boolean;\n dataPointCount: number;\n strongModelPreferenceRate: number;\n }\n | undefined {\n if (!enablePreferenceRouting || preferenceRouter === undefined) {\n return undefined;\n }\n const stats = preferenceRouter.getStats();\n return {\n enabled: true,\n hasSufficientData: preferenceRouter.hasMinimumData(),\n dataPointCount: stats.totalDataPoints,\n strongModelPreferenceRate: stats.strongModelPreferenceRate,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Capacity-Aware Load Balancing (Issue #807)\n// ---------------------------------------------------------------------------\n\nimport type { CapacityStatus, ICliAdapter } from './types.js';\n\n/**\n * Fetches capacity status from all adapters.\n * Returns a map of CLI name to capacity status.\n */\nexport async function fetchCapacityData(\n adapters: Map<CliName, ICliAdapter>\n): Promise<Map<CliName, CapacityStatus>> {\n const result = new Map<CliName, CapacityStatus>();\n const entries = [...adapters];\n const settled = await Promise.allSettled(entries.map(([, a]) => a.getCapacity()));\n for (const [idx, entry] of entries.entries()) {\n const outcome = settled[idx];\n if (outcome?.status === 'fulfilled') {\n result.set(entry[0], outcome.value);\n }\n }\n return result;\n}\n","/**\n * Type definitions for the Weather Report MCP tool.\n *\n * Surfaces observed model performance as a living \"weather report\"\n * and computes adaptive routing bonuses from outcome data.\n *\n * @module mcp/tools/weather-report-types\n * (Source: Issue #865 — Weather report with adaptive routing)\n */\n\nimport { z } from 'zod';\nimport type { TaskCategory } from '../../config/task-specialization-types.js';\nimport type { GroupStats } from '../../orchestration/outcomes/outcome-types.js';\nimport { CLI_NAMES, type CliNameLiteral } from '../../config/model-capabilities-types.js';\n\n// ============================================================================\n// Input Schema\n// ============================================================================\n\nexport const WeatherReportInputSchema = z.object({\n /** Filter by CLI name. */\n cli: z.enum(CLI_NAMES).optional().describe('Filter by CLI'),\n /** Filter by task category. */\n category: z\n .enum([\n 'architecture',\n 'code_generation',\n 'code_review',\n 'research',\n 'security_review',\n 'planning',\n 'documentation',\n 'testing',\n 'devops',\n 'exploration',\n ])\n .optional()\n .describe('Filter by task category'),\n /** Include adaptive routing bonus data. */\n includeAdaptive: z\n .boolean()\n .optional()\n .default(true)\n .describe('Include adaptive routing bonuses (default: true)'),\n});\n\n/** Validated MCP input (includeAdaptive is always populated after Zod parse). */\nexport type WeatherReportInput = z.infer<typeof WeatherReportInputSchema>;\n\n/** Options for generateWeatherReport (all fields optional). */\nexport interface WeatherReportOptions {\n readonly cli?: CliNameLiteral;\n readonly category?: string;\n readonly includeAdaptive?: boolean;\n}\n\n// ============================================================================\n// Output Types\n// ============================================================================\n\n/** Adapter attempt stats separating infra failures from model-quality failures (#1982). */\nexport interface AdapterAttemptStats {\n /**\n * Success rate excluding adapter_unavailable failures. Represents model-quality\n * success when the adapter could actually attempt the task. Rounded to 3 decimals.\n */\n readonly adapterAttemptSuccessRate: number;\n /** Count of adapter_unavailable failures in the sample. */\n readonly adapterUnavailableCount: number;\n /**\n * Fraction of total attempts that failed due to adapter_unavailable. Rounded\n * to 3 decimals. Useful for comparing infra availability across CLIs/categories.\n */\n readonly adapterUnavailableRate: number;\n}\n\n/** Per-CLI performance stats in the weather report. */\nexport interface CliWeather extends AdapterAttemptStats {\n readonly cli: string;\n readonly totalTasks: number;\n readonly successRate: number;\n readonly avgDurationMs: number;\n readonly byCategory: ReadonlyMap<string, GroupStats>;\n}\n\n/** Adaptive bonus for a CLI+category pair. */\nexport interface AdaptiveBonus {\n readonly cli: string;\n readonly category: TaskCategory;\n readonly staticBonus: number;\n readonly adaptiveBonus: number;\n readonly sampleCount: number;\n readonly sufficient: boolean;\n}\n\n/** Tier recommendation surfaced in the weather report (#895). */\nexport interface TierRecommendationEntry {\n readonly category: string;\n readonly direction: 'promote' | 'demote';\n readonly currentTier: number;\n readonly recommendedTier: number;\n readonly successRate: number;\n readonly sampleCount: number;\n readonly reason: string;\n}\n\n/** Learning insight for a CLI+category pair (Issue #901, Phase 4). */\nexport interface LearningInsight {\n readonly cli: string;\n readonly category: TaskCategory;\n readonly trend: 'improving' | 'declining' | 'stable';\n readonly confidence: number;\n readonly adjustedBaseline: number;\n readonly sampleCount: number;\n}\n\n/** Recommended CLI→category mapping for LinUCB cold-start (Epic #952, Phase 6). */\nexport interface RecommendedMapping {\n readonly category: TaskCategory;\n readonly recommendedCli: string;\n readonly successRate: number;\n readonly sampleCount: number;\n readonly confidence: 'high' | 'medium' | 'low';\n}\n\n/** Rate limit stats per provider (Issue #996). */\nexport interface RateLimitReport {\n readonly provider: string;\n readonly totalHits: number;\n readonly lastHitAt: number;\n readonly avgRetryAfterMs: number | undefined;\n}\n\n/** Per-tool performance stats (Issue #1022). */\nexport interface ToolPerformanceEntry {\n readonly toolName: string;\n readonly totalCalls: number;\n readonly successRate: number;\n readonly avgDurationMs: number;\n readonly errorCount: number;\n}\n\n/** Failure breakdown entry for the weather report (Issue #1025). */\nexport interface FailureBreakdownEntry {\n readonly category: string;\n readonly count: number;\n readonly percentage: number;\n}\n\n/** Per-expert-role performance stats from worker dispatch outcomes (Issue #1324, #1427). */\nexport interface ExpertPerformanceEntry {\n readonly role: string;\n readonly totalTasks: number;\n readonly successRate: number;\n readonly avgDurationMs: number;\n readonly dominantErrorPattern?: string;\n /** Number of consecutive failures at tail of outcome history (Issue #1427). */\n readonly consecutiveFailures: number;\n /** ISO timestamp of last successful outcome (Issue #1427). */\n readonly lastSuccessAt?: string;\n /** True when successRate < 0.5 — signals operator attention needed (Issue #1427). */\n readonly degraded: boolean;\n}\n\n/** Agent health summary from heartbeat monitor (Issue #1032). */\nexport interface AgentHealthSummary {\n readonly activeSessions: number;\n readonly stalledSessions: number;\n readonly sessions: readonly AgentSessionEntry[];\n}\n\n/** Single agent session health entry. */\nexport interface AgentSessionEntry {\n readonly sessionId: string;\n readonly expertId: string;\n readonly health: 'alive' | 'slow' | 'stalled';\n readonly elapsedMs: number;\n readonly timeSinceHeartbeatMs: number;\n readonly heartbeatCount: number;\n}\n\n/** Swarm health metrics dashboard (Issue #1403, Phase 6.2). */\nexport interface SwarmHealthMetrics {\n /** % of dispatched expert roles that produced at least one success. Target: 70-90%. */\n readonly agentUtilization: number;\n /** Successful tasks / total worker dispatches. Target: > 0.1. */\n readonly collaborationEfficiency: number;\n /** % of tasks routed to the empirically best CLI for their category. Target: > 80%. */\n readonly routingAccuracy: number;\n /** Avg gap between actual success rate and best-possible rate per category. Target: decreasing. */\n readonly weeklyRegret: number;\n /** Avg samples to reach 'high' confidence per category. Target: < 50. */\n readonly adaptationSpeed: number;\n /** Number of observed categories with sufficient data. */\n readonly observedCategories: number;\n /** Number of expert roles observed. */\n readonly observedRoles: number;\n}\n\n/** Worker failure triage statistics (#1506). */\nexport interface TriageStats {\n /** Total outcomes that were retried via triage. */\n readonly totalRetried: number;\n /** Retry success rate (retried + success / total retried). */\n readonly retrySuccessRate: number;\n /** Breakdown by triage action. */\n readonly actionBreakdown: readonly { readonly action: string; readonly count: number }[];\n}\n\n/** Full weather report response. */\nexport interface WeatherReportResponse {\n readonly overall: AdapterAttemptStats & {\n readonly totalTasks: number;\n readonly successRate: number;\n readonly avgDurationMs: number;\n };\n readonly cliWeather: readonly CliWeather[];\n readonly adaptiveBonuses: readonly AdaptiveBonus[];\n /** Outcome-driven tier change recommendations (#895). */\n readonly tierRecommendations: readonly TierRecommendationEntry[];\n /** Adaptive learning insights per CLI+category (#901). */\n readonly learningInsights?: readonly LearningInsight[];\n /** Recommended CLI mappings per category for LinUCB priors (Epic #952). */\n readonly recommendedMappings?: readonly RecommendedMapping[];\n /** Rate limit utilization per provider (Issue #996). */\n readonly rateLimits?: readonly RateLimitReport[];\n /** Per-tool invocation metrics (Issue #1022). */\n readonly toolPerformance?: readonly ToolPerformanceEntry[];\n /** Failure breakdown by category (Issue #1025). */\n readonly failureBreakdown?: readonly FailureBreakdownEntry[];\n /** Agent health from heartbeat monitor (Issue #1032). */\n readonly agentHealth?: AgentHealthSummary;\n /** Per-expert-role performance from worker dispatch outcomes (Issue #1324). */\n readonly expertPerformance?: readonly ExpertPerformanceEntry[];\n /** Swarm health metrics dashboard (Issue #1403). */\n readonly swarmHealth?: SwarmHealthMetrics;\n /** Worker failure triage statistics (#1506). */\n readonly triageStats?: TriageStats;\n /** Recent performance within the lookback window (#1401). */\n readonly recentWindow?: {\n readonly windowMs: number;\n readonly totalTasks: number;\n readonly successRate: number;\n readonly avgDurationMs: number;\n };\n readonly explorationRate: number;\n readonly coldStartThreshold: number;\n readonly collectedAt: string;\n}\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\n/** Default lookback window: 7 days in milliseconds. */\nexport const DEFAULT_OUTCOME_LOOKBACK_MS = 7 * 24 * 60 * 60 * 1000;\n\nexport const WeatherReportConfigSchema = z.object({\n /** Minimum observations before adjusting bonuses (lowered for faster activation). */\n coldStartThreshold: z.number().int().min(1).max(1000).default(3),\n /** Exploration rate: fraction of random routing (0.0-1.0). */\n explorationRate: z.number().min(0).max(1).default(0.1),\n /** Max adaptive bonus adjustment (+/-). */\n maxBonusAdjustment: z.number().min(0).max(20).default(10),\n /**\n * Lookback window for outcome queries (ms). Only outcomes within this\n * window are used for adaptive bonuses. Falls back to all history if\n * the window has fewer samples than coldStartThreshold. Default: 7 days.\n */\n outcomeLookbackMs: z.number().int().min(0).default(DEFAULT_OUTCOME_LOOKBACK_MS),\n});\n\nexport type WeatherReportConfig = z.infer<typeof WeatherReportConfigSchema>;\n\n/** Creates default configuration. */\nexport function createDefaultWeatherConfig(): WeatherReportConfig {\n return WeatherReportConfigSchema.parse({});\n}\n","/**\n * Gateway Keyword Constants\n *\n * Single source of truth for security and architecture keywords used by\n * both the tier classifier and governance enforcer. Extracted to prevent\n * divergence between the two modules (DRY).\n *\n * @module mcp/gateway/gateway-keywords\n */\n\n/** Keywords that indicate security-related work (case-insensitive substring match). */\nexport const SECURITY_KEYWORDS = [\n 'security',\n 'vulnerabilit',\n 'cve-',\n 'exploit',\n 'injection',\n 'xss',\n 'csrf',\n 'auth',\n 'penetration',\n 'threat',\n 'malware',\n 'credentials',\n 'secrets',\n 'encryption',\n 'certificate',\n] as const;\n\n/** Keywords that indicate architecture-related work (case-insensitive substring match). */\nexport const ARCHITECTURE_KEYWORDS = [\n 'architecture',\n 'breaking change',\n 'breaking api',\n 'api change',\n 'migration',\n 'refactor.*system',\n 'redesign',\n 'microservice',\n 'monolith',\n 'deprecation',\n 'schema change',\n 'database',\n 'infrastructure',\n] as const;\n\n/** Roles that always trigger promotion to Tier 3. */\nexport const PROMOTED_ROLES = new Set(['security_expert', 'architecture_expert']);\n","/**\n * Request Tier Classifier\n *\n * Pure function that classifies incoming MCP tool requests into tiers\n * for the orchestration gateway. No side effects, no I/O.\n *\n * Tier 1 (DIRECT): Read-only tools — direct dispatch + logging\n * Tier 2 (ANALYZED): Model-selection tools — task analysis first\n * Tier 3 (ORCHESTRATED): Complex/risky tools — full orchestration pipeline\n *\n * Security and architecture-related requests are always promoted to Tier 3.\n *\n * @module mcp/gateway/tier-classifier\n * (Source: Issue #892, Epic #888)\n */\n\nimport { SECURITY_KEYWORDS, ARCHITECTURE_KEYWORDS, PROMOTED_ROLES } from './gateway-keywords.js';\n\n/** Request processing tier. Higher = more orchestration overhead. */\nexport enum RequestTier {\n /** Direct dispatch with structured logging. */\n DIRECT = 1,\n /** Task analysis + model selection via delegate_to_model. */\n ANALYZED = 2,\n /** Full orchestration + decomposition + voting. */\n ORCHESTRATED = 3,\n}\n\n/** Per-tool tier override map (from nexus-agents.yaml). */\nexport type TierOverrides = Record<string, RequestTier>;\n\n/**\n * Default tier assignment for all 20 registered MCP tools.\n * Tier 1: read-only, no model invocation needed.\n * Tier 2: requires model selection or expert creation.\n * Tier 3: requires full orchestration, decomposition, or consensus.\n */\nexport const TOOL_TIER_MAP: Readonly<Record<string, RequestTier>> = {\n // Tier 1 — Read-only\n list_experts: RequestTier.DIRECT,\n list_workflows: RequestTier.DIRECT,\n memory_query: RequestTier.DIRECT,\n memory_stats: RequestTier.DIRECT,\n weather_report: RequestTier.DIRECT,\n research_analyze: RequestTier.DIRECT,\n research_catalog_review: RequestTier.DIRECT,\n\n // Tier 2 — Model selection\n delegate_to_model: RequestTier.ANALYZED,\n create_expert: RequestTier.ANALYZED,\n execute_expert: RequestTier.ANALYZED,\n research_add: RequestTier.ANALYZED,\n registry_import: RequestTier.ANALYZED,\n\n // Tier 3 — Full orchestration\n orchestrate: RequestTier.ORCHESTRATED,\n consensus_vote: RequestTier.ORCHESTRATED,\n execute_spec: RequestTier.ORCHESTRATED,\n run_workflow: RequestTier.ORCHESTRATED,\n run_graph_workflow: RequestTier.ORCHESTRATED,\n issue_triage: RequestTier.ORCHESTRATED,\n research_query: RequestTier.ORCHESTRATED,\n research_discover: RequestTier.ORCHESTRATED,\n};\n\n/**\n * Classifies an MCP tool request into a processing tier.\n *\n * @param toolName - The MCP tool being invoked\n * @param params - The tool's input parameters\n * @param overrides - Optional per-tool tier overrides\n * @returns The appropriate RequestTier for this request\n */\nexport function classifyRequestTier(\n toolName: string,\n params: Record<string, unknown>,\n overrides?: TierOverrides\n): RequestTier {\n const defaultTier = TOOL_TIER_MAP[toolName] ?? RequestTier.ANALYZED;\n const effectiveTier = overrides?.[toolName] ?? defaultTier;\n\n // Tier 1 tools (from canonical map, not overridden) skip promotion checks\n if (defaultTier === RequestTier.DIRECT && effectiveTier === RequestTier.DIRECT) {\n return RequestTier.DIRECT;\n }\n\n // Security/architecture promotion always wins — overrides cannot suppress it\n if (effectiveTier < RequestTier.ORCHESTRATED && shouldPromote(params)) {\n return RequestTier.ORCHESTRATED;\n }\n\n return effectiveTier;\n}\n\n/**\n * Checks if request params contain security or architecture keywords\n * that warrant promotion to Tier 3.\n */\nfunction shouldPromote(params: Record<string, unknown>): boolean {\n // Check role-based promotion\n const role = params['role'];\n if (typeof role === 'string' && PROMOTED_ROLES.has(role)) {\n return true;\n }\n\n // Check text content for keyword matches\n const textFields = ['task', 'proposal', 'prompt'];\n for (const field of textFields) {\n const value = params[field];\n if (typeof value === 'string' && containsPromotionKeyword(value)) {\n return true;\n }\n }\n\n return false;\n}\n\n/** Map from config string tier names to RequestTier enum values. */\nconst TIER_NAME_TO_ENUM: Readonly<Record<string, RequestTier>> = {\n DIRECT: RequestTier.DIRECT,\n ANALYZED: RequestTier.ANALYZED,\n ORCHESTRATED: RequestTier.ORCHESTRATED,\n};\n\n/**\n * Converts string tier override map (from config schema) to RequestTier enum map.\n * Ignores entries with invalid tier names.\n *\n * @param overrides - String-keyed tier names from GatewayConfigSchema\n * @returns Enum-valued TierOverrides, or undefined if empty/undefined\n */\nexport function parseTierOverrides(\n overrides: Record<string, string> | undefined\n): TierOverrides | undefined {\n if (overrides === undefined) return undefined;\n const result: TierOverrides = {};\n for (const [tool, tierName] of Object.entries(overrides)) {\n const tier = TIER_NAME_TO_ENUM[tierName];\n if (tier !== undefined) {\n result[tool] = tier;\n }\n }\n return Object.keys(result).length > 0 ? result : undefined;\n}\n\n/** Checks if text contains any security or architecture promotion keyword. */\nfunction containsPromotionKeyword(text: string): boolean {\n const lower = text.toLowerCase();\n for (const kw of SECURITY_KEYWORDS) {\n if (lower.includes(kw)) return true;\n }\n for (const kw of ARCHITECTURE_KEYWORDS) {\n if (new RegExp(kw, 'i').test(text)) return true;\n }\n return false;\n}\n","/**\n * Outcome-Driven Tier Promotion Recommender\n *\n * Analyzes task outcome data to recommend tier changes for MCP tools.\n * Recommendations are advisory only — humans approve changes via config.\n *\n * Thresholds (from Issue #895):\n * - Promote: >30% failure rate at current tier → recommend next tier\n * - Demote: >95% success rate over 50+ executions → eligible for demotion\n * - Minimum sample: 20 executions before any recommendation\n *\n * @module mcp/gateway/tier-recommender\n * (Source: Issue #895, Epic #888)\n */\n\nimport type { PerformanceSummary, GroupStats } from '../../orchestration/outcomes/outcome-types.js';\nimport { RequestTier, TOOL_TIER_MAP } from './tier-classifier.js';\n\n/** Recommendation direction. */\nexport type TierDirection = 'promote' | 'demote';\n\n/** A single tier change recommendation. */\nexport interface TierRecommendation {\n /** Category that triggered this recommendation. */\n category: string;\n /** Current tier for tools in this category. */\n currentTier: RequestTier;\n /** Recommended tier. */\n recommendedTier: RequestTier;\n /** Direction of the recommendation. */\n direction: TierDirection;\n /** Observed success rate (0-1). */\n successRate: number;\n /** Number of observations. */\n sampleCount: number;\n /** Human-readable reason. */\n reason: string;\n}\n\n/** Configuration for tier recommendation thresholds. */\nexport interface TierRecommenderConfig {\n /** Minimum executions before making any recommendation. */\n readonly minSamples: number;\n /** Failure rate threshold for promotion (0-1). */\n readonly promoteFailureRate: number;\n /** Success rate threshold for demotion (0-1). */\n readonly demoteSuccessRate: number;\n /** Minimum executions for demotion eligibility. */\n readonly demoteMinSamples: number;\n}\n\n/** Default configuration per issue spec. */\nconst DEFAULT_CONFIG: TierRecommenderConfig = {\n minSamples: 20,\n promoteFailureRate: 0.3,\n demoteSuccessRate: 0.95,\n demoteMinSamples: 50,\n};\n\n/** Maps categories to their typical tool tier (best effort). */\nfunction getCategoryTier(category: string): RequestTier {\n // Tools that tend to be used for each category\n const categoryToolMap: Record<string, string> = {\n research: 'research_query',\n exploration: 'research_discover',\n code_generation: 'delegate_to_model',\n code_review: 'run_workflow',\n architecture: 'orchestrate',\n security_review: 'orchestrate',\n planning: 'orchestrate',\n documentation: 'run_workflow',\n testing: 'execute_expert',\n devops: 'delegate_to_model',\n };\n\n const tool = categoryToolMap[category];\n if (tool !== undefined) {\n return TOOL_TIER_MAP[tool] ?? RequestTier.ANALYZED;\n }\n return RequestTier.ANALYZED;\n}\n\n/**\n * Generates tier recommendations from outcome data.\n *\n * @param summary - Performance summary from OutcomeStore.summarize()\n * @param config - Optional threshold overrides\n * @returns Array of tier change recommendations (may be empty)\n */\nexport function generateTierRecommendations(\n summary: PerformanceSummary,\n config?: Partial<TierRecommenderConfig>\n): TierRecommendation[] {\n const cfg = { ...DEFAULT_CONFIG, ...config };\n const recommendations: TierRecommendation[] = [];\n\n for (const [category, stats] of summary.byCategory) {\n const rec = evaluateCategory(category, stats, cfg);\n if (rec !== null) recommendations.push(rec);\n }\n\n return recommendations;\n}\n\n/** Evaluates a single category for promotion or demotion. */\nfunction evaluateCategory(\n category: string,\n stats: GroupStats,\n cfg: TierRecommenderConfig\n): TierRecommendation | null {\n if (stats.count < cfg.minSamples) return null;\n\n const currentTier = getCategoryTier(category);\n const failureRate = 1 - stats.successRate;\n\n // Check for promotion (too many failures at current tier)\n if (failureRate > cfg.promoteFailureRate && currentTier < RequestTier.ORCHESTRATED) {\n const recommendedTier = currentTier + 1;\n return {\n category,\n currentTier,\n recommendedTier,\n direction: 'promote',\n successRate: stats.successRate,\n sampleCount: stats.count,\n reason: `${category}: ${(failureRate * 100).toFixed(0)}% failure rate over ${String(stats.count)} tasks — recommend promoting to Tier ${String(recommendedTier)}`,\n };\n }\n\n // Check for demotion (consistently successful at current tier)\n if (\n stats.successRate > cfg.demoteSuccessRate &&\n stats.count >= cfg.demoteMinSamples &&\n currentTier > RequestTier.DIRECT\n ) {\n const recommendedTier = currentTier - 1;\n return {\n category,\n currentTier,\n recommendedTier,\n direction: 'demote',\n successRate: stats.successRate,\n sampleCount: stats.count,\n reason: `${category}: ${(stats.successRate * 100).toFixed(0)}% success rate over ${String(stats.count)} tasks — eligible for demotion to Tier ${String(recommendedTier)}`,\n };\n }\n\n return null;\n}\n","/**\n * Adaptive Thresholds — Learning Loop (Issue #901, Phase 4)\n *\n * Pure function-based module that computes dynamic thresholds from\n * observed task outcomes. Replaces hardcoded baseline/maxBonus/coldStart\n * values with data-driven adjustments.\n *\n * @module orchestration/outcomes/adaptive-thresholds\n */\n\nimport type { TaskOutcome } from './outcome-types.js';\nimport type { OutcomeStore } from './outcome-store.js';\nimport type { TaskCategory } from '../../config/task-specialization-types.js';\nimport type { CliNameLiteral } from '../../config/model-capabilities-types.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Direction of performance change over time. */\nexport type Trend = 'improving' | 'declining' | 'stable';\n\n/** Result of computing adaptive thresholds for a CLI+category pair. */\nexport interface AdaptiveThresholdResult {\n /** Adjusted baseline success rate (default: 0.7). */\n readonly baseline: number;\n /** Adjusted max bonus cap (default: 10). */\n readonly maxBonus: number;\n /** Minimum samples before adjustment (always 10). */\n readonly coldStart: number;\n /** Detected performance trend. */\n readonly trend: Trend;\n /** Confidence in the result (0-1), based on sample size. */\n readonly confidence: number;\n /** Number of outcomes used for computation. */\n readonly sampleCount: number;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_BASELINE = 0.7;\nconst DEFAULT_MAX_BONUS = 10;\n// Reduced from 10→5→3 per E2E findings (#1047, #1134): real interactive sessions\n// generate too few outcomes per CLI×category pair for higher thresholds.\nconst COLD_START_THRESHOLD = 3;\nconst DEFAULT_WINDOW_SIZE = 25;\nconst FULL_CONFIDENCE_SAMPLES = 50;\nconst TREND_DELTA_THRESHOLD = 0.05;\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Computes adaptive thresholds for a CLI+category pair from outcome data.\n *\n * Below cold start threshold: returns defaults with zero confidence.\n * Above threshold: adjusts baseline toward observed rate, scales max\n * bonus by confidence, and detects trend.\n */\nexport function computeAdaptiveThresholds(\n store: OutcomeStore,\n cli: CliNameLiteral,\n category: TaskCategory\n): AdaptiveThresholdResult {\n const outcomes = store.query({ cli, category });\n const sampleCount = outcomes.length;\n\n if (sampleCount < COLD_START_THRESHOLD) {\n return {\n baseline: DEFAULT_BASELINE,\n maxBonus: DEFAULT_MAX_BONUS,\n coldStart: COLD_START_THRESHOLD,\n trend: 'stable',\n confidence: 0,\n sampleCount,\n };\n }\n\n const confidence = computeConfidence(sampleCount);\n const overallRate = successRate(outcomes);\n const trend = detectTrend(outcomes);\n\n // Weighted blend: move baseline toward observed rate proportional to confidence\n const baseline = DEFAULT_BASELINE * (1 - confidence) + overallRate * confidence;\n\n // Scale max bonus with confidence — low confidence → smaller swings\n const maxBonus = DEFAULT_MAX_BONUS * confidence;\n\n return {\n baseline: round(baseline),\n maxBonus: round(maxBonus),\n coldStart: COLD_START_THRESHOLD,\n trend,\n confidence: round(confidence),\n sampleCount,\n };\n}\n\n/**\n * Detects performance trend by comparing recent vs historical success rates.\n *\n * Splits outcomes into two windows of `windowSize` (default 25).\n * If fewer than 2 * windowSize outcomes, uses half-split.\n */\nexport function detectTrend(\n outcomes: readonly TaskOutcome[],\n windowSize: number = DEFAULT_WINDOW_SIZE\n): Trend {\n if (outcomes.length < 2) return 'stable';\n\n const midpoint = Math.max(1, Math.floor(outcomes.length / 2));\n const effectiveWindow = Math.min(windowSize, midpoint);\n\n const historical = outcomes.slice(Math.max(0, midpoint - effectiveWindow), midpoint);\n const recent = outcomes.slice(outcomes.length - effectiveWindow);\n\n const historicalRate = successRate(historical);\n const recentRate = successRate(recent);\n const delta = recentRate - historicalRate;\n\n if (delta > TREND_DELTA_THRESHOLD) return 'improving';\n if (delta < -TREND_DELTA_THRESHOLD) return 'declining';\n return 'stable';\n}\n\n// ============================================================================\n// Internal Helpers\n// ============================================================================\n\nfunction successRate(outcomes: readonly TaskOutcome[]): number {\n if (outcomes.length === 0) return 0;\n return outcomes.filter((o) => o.success).length / outcomes.length;\n}\n\nfunction computeConfidence(sampleCount: number): number {\n return Math.min(1, sampleCount / FULL_CONFIDENCE_SAMPLES);\n}\n\nfunction round(value: number): number {\n return Math.round(value * 1000) / 1000;\n}\n","/**\n * Rate Limit Detection and Tracking\n *\n * Detects rate limit errors from model adapter responses and tracks\n * rate limit events for weather report metrics.\n *\n * @module adapters/rate-limit-detector\n * (Source: Issue #996 — Rate limit error surfacing)\n */\n\nimport { RateLimitError, getErrorMessage } from '../core/index.js';\n\n// ============================================================================\n// Detection\n// ============================================================================\n\n/**\n * Canonical rate-limit detection patterns.\n * Shared by API adapters and CLI subprocess adapters. (Issue #1596)\n */\nexport const RATE_LIMIT_PATTERNS = [\n 'rate limit',\n 'rate_limit',\n 'too many requests',\n '429',\n 'quota exceeded',\n 'throttl',\n 'usage limit',\n 'requests per minute',\n 'tokens per minute',\n] as const;\n\n/**\n * Checks whether a text string contains rate-limit indicators.\n * Used by CLI subprocess adapters for stdout/stderr classification. (Issue #1596)\n */\nexport function isRateLimitText(text: string): boolean {\n const lower = text.toLowerCase();\n return RATE_LIMIT_PATTERNS.some((p) => lower.includes(p));\n}\n\n/**\n * Detects whether an error is a rate limit error.\n * Pattern-matches against common provider error messages.\n */\nexport function isRateLimitLikeError(error: unknown): boolean {\n return isRateLimitText(getErrorMessage(error));\n}\n\n/**\n * Parses retry-after metadata from an error message.\n * Providers often include timing hints in error messages.\n */\nexport function parseRetryAfterMs(errorMessage: string): number | undefined {\n const lower = errorMessage.toLowerCase();\n\n // Match \"retry after X seconds\" or \"retry-after: X\"\n const secondsMatch = /retry[- ]?after[:\\s]+(\\d+(?:\\.\\d+)?)\\s*(?:s|sec)/i.exec(lower);\n if (secondsMatch !== null) {\n const parsed = parseFloat(secondsMatch[1] ?? '0');\n return Math.ceil(parsed * 1000);\n }\n\n // Match \"retry after X ms\" or \"wait X milliseconds\"\n const msMatch = /(?:retry[- ]?after|wait)[:\\s]+(\\d+)\\s*(?:ms|millisecond)/i.exec(lower);\n if (msMatch !== null) {\n return parseInt(msMatch[1] ?? '0', 10);\n }\n\n // Match \"try again in X seconds\"\n const againMatch = /try again in (\\d+(?:\\.\\d+)?)\\s*(?:s|sec)/i.exec(lower);\n if (againMatch !== null) {\n const parsed = parseFloat(againMatch[1] ?? '0');\n return Math.ceil(parsed * 1000);\n }\n\n return undefined;\n}\n\n/**\n * Wraps a generic error as a RateLimitError with parsed metadata.\n */\nexport function toRateLimitError(error: unknown, provider?: string): RateLimitError {\n const message = getErrorMessage(error);\n const retryAfterMs = parseRetryAfterMs(message);\n return new RateLimitError(message, {\n ...(retryAfterMs !== undefined ? { retryAfterMs } : {}),\n ...(provider !== undefined ? { provider } : {}),\n ...(error instanceof Error ? { cause: error } : {}),\n });\n}\n\n// ============================================================================\n// Tracking\n// ============================================================================\n\n/** A single rate limit event record. */\nexport interface RateLimitEvent {\n readonly provider: string;\n readonly timestamp: number;\n readonly retryAfterMs: number | undefined;\n}\n\n/** Aggregate stats for rate limit events per provider. */\nexport interface RateLimitStats {\n readonly provider: string;\n readonly totalHits: number;\n readonly lastHitAt: number;\n readonly avgRetryAfterMs: number | undefined;\n}\n\nconst MAX_EVENTS = 200;\nconst events: RateLimitEvent[] = [];\n\n/** Records a rate limit event for tracking. */\nexport function recordRateLimitEvent(event: RateLimitEvent): void {\n events.push(event);\n if (events.length > MAX_EVENTS) {\n events.splice(0, events.length - MAX_EVENTS);\n }\n}\n\n/** Gets rate limit stats grouped by provider. */\nexport function getRateLimitStats(): readonly RateLimitStats[] {\n const grouped = new Map<string, RateLimitEvent[]>();\n for (const event of events) {\n const existing = grouped.get(event.provider);\n if (existing !== undefined) {\n existing.push(event);\n } else {\n grouped.set(event.provider, [event]);\n }\n }\n\n const stats: RateLimitStats[] = [];\n for (const [provider, providerEvents] of grouped) {\n const retryValues = providerEvents\n .map((e) => e.retryAfterMs)\n .filter((v): v is number => v !== undefined);\n const avgRetry =\n retryValues.length > 0\n ? retryValues.reduce((a, b) => a + b, 0) / retryValues.length\n : undefined;\n const lastEvent = providerEvents[providerEvents.length - 1];\n\n stats.push({\n provider,\n totalHits: providerEvents.length,\n lastHitAt: lastEvent?.timestamp ?? 0,\n ...(avgRetry !== undefined\n ? { avgRetryAfterMs: Math.round(avgRetry) }\n : { avgRetryAfterMs: undefined }),\n });\n }\n\n return stats;\n}\n\n/** Clears all tracked rate limit events. Useful for testing. */\nexport function clearRateLimitEvents(): void {\n events.length = 0;\n}\n","/**\n * Tool usage metrics recorder (Issue #1022)\n *\n * Lightweight, bounded, in-memory store for MCP tool invocation metrics.\n * Records tool name, duration, and success/failure for every tool call.\n * Used by the weather report to surface per-tool analytics.\n *\n * @module mcp/middleware/tool-metrics\n */\n\nimport { getTimeProvider } from '../../core/index.js';\nimport type { Middleware, ToolResult } from './middleware-chain.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** A single recorded tool invocation metric. */\nexport interface ToolMetric {\n readonly toolName: string;\n readonly durationMs: number;\n readonly success: boolean;\n readonly timestamp: string;\n}\n\n/** Aggregated stats for a single tool. */\nexport interface ToolStats {\n readonly toolName: string;\n readonly totalCalls: number;\n readonly successRate: number;\n readonly avgDurationMs: number;\n readonly errorCount: number;\n}\n\n// ============================================================================\n// Store\n// ============================================================================\n\nconst MAX_ENTRIES = 5_000;\nconst metrics: ToolMetric[] = [];\n\n/** Record a tool invocation metric. */\nexport function recordToolMetric(metric: ToolMetric): void {\n metrics.push(metric);\n if (metrics.length > MAX_ENTRIES) {\n metrics.splice(0, metrics.length - MAX_ENTRIES);\n }\n}\n\n/** Get all recorded tool metrics (read-only snapshot). */\nexport function getToolMetrics(): readonly ToolMetric[] {\n return [...metrics];\n}\n\n/** Aggregate metrics into per-tool stats. */\nexport function getToolStats(): readonly ToolStats[] {\n const groups = new Map<string, ToolMetric[]>();\n\n for (const m of metrics) {\n const list = groups.get(m.toolName);\n if (list !== undefined) {\n list.push(m);\n } else {\n groups.set(m.toolName, [m]);\n }\n }\n\n const stats: ToolStats[] = [];\n for (const [toolName, list] of groups) {\n const sc = list.filter((m) => m.success).length;\n const td = list.reduce((s, m) => s + m.durationMs, 0);\n stats.push({\n toolName,\n totalCalls: list.length,\n successRate: sc / list.length,\n avgDurationMs: td / list.length,\n errorCount: list.length - sc,\n });\n }\n\n return stats.sort((a, b) => b.totalCalls - a.totalCalls);\n}\n\n/** Clear all recorded metrics (for testing). */\nexport function clearToolMetrics(): void {\n metrics.length = 0;\n}\n\n// ============================================================================\n// Middleware\n// ============================================================================\n\n/**\n * Creates a middleware that records tool invocation metrics.\n * Should be placed as the outermost middleware (before audit)\n * to capture the full request lifecycle including middleware overhead.\n */\nexport function createMetricsMiddleware(): Middleware {\n return async (args, ctx, next): Promise<ToolResult> => {\n const startTime = getTimeProvider().now();\n\n try {\n const result = await next(args, ctx);\n const durationMs = getTimeProvider().now() - startTime;\n\n recordToolMetric({\n toolName: ctx.requestContext.toolName,\n durationMs,\n success: result.isError !== true,\n timestamp: new Date().toISOString(),\n });\n\n return result;\n } catch (error) {\n const durationMs = getTimeProvider().now() - startTime;\n\n recordToolMetric({\n toolName: ctx.requestContext.toolName,\n durationMs,\n success: false,\n timestamp: new Date().toISOString(),\n });\n\n throw error;\n }\n };\n}\n","/**\n * Heartbeat-based liveness monitor for expert agent sessions.\n *\n * Tracks active expert executions with periodic heartbeats.\n * Detects stalled sessions that stop making progress, enabling\n * faster detection than wall-clock timeouts alone.\n *\n * @module agents/heartbeat-monitor\n * (Source: Issue #1032 — Agent heartbeat health monitor)\n */\n\nimport { randomBytes } from 'node:crypto';\nimport { getTimeProvider } from '../core/index.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Health status of an expert session. */\nexport type SessionHealth = 'alive' | 'slow' | 'stalled';\n\n/** Snapshot of a single expert session. */\nexport interface ExpertSessionSnapshot {\n readonly sessionId: string;\n readonly expertId: string;\n readonly startedAt: number;\n readonly lastHeartbeat: number;\n readonly heartbeatCount: number;\n readonly health: SessionHealth;\n readonly elapsedMs: number;\n readonly timeSinceHeartbeatMs: number;\n}\n\n/** Aggregate health report for all active sessions. */\nexport interface AgentHealthReport {\n readonly activeSessions: number;\n readonly stalledSessions: number;\n readonly sessions: readonly ExpertSessionSnapshot[];\n}\n\n/** Configuration for the heartbeat monitor. */\nexport interface HeartbeatConfig {\n /** Time without heartbeat before marking 'slow' (ms). */\n readonly slowThresholdMs: number;\n /** Time without heartbeat before marking 'stalled' (ms). */\n readonly stalledThresholdMs: number;\n /** Absolute max lifetime for any session (ms). Safety cap. */\n readonly absoluteMaxMs: number;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n// Canonical source: config/timeouts.ts (Issue #1046)\nimport { HEARTBEAT_TIMEOUTS } from '../config/timeouts.js';\n\nconst DEFAULT_SLOW_THRESHOLD_MS = HEARTBEAT_TIMEOUTS.slowThresholdMs;\nconst DEFAULT_STALLED_THRESHOLD_MS = HEARTBEAT_TIMEOUTS.stalledThresholdMs;\nconst DEFAULT_ABSOLUTE_MAX_MS = HEARTBEAT_TIMEOUTS.absoluteMaxMs;\n\n// ============================================================================\n// Internal Session State\n// ============================================================================\n\ninterface SessionEntry {\n readonly expertId: string;\n readonly startedAt: number;\n lastHeartbeat: number;\n heartbeatCount: number;\n /** Previous health state for transition detection (Issue #1088 Phase 4). */\n previousHealth: SessionHealth;\n}\n\n/** Health transition info returned by getSessionHealth(). */\nexport interface HealthTransition {\n readonly sessionId: string;\n readonly agentId: string;\n readonly health: SessionHealth;\n readonly previousHealth: SessionHealth;\n readonly changed: boolean;\n readonly elapsedMs: number;\n readonly heartbeatCount: number;\n}\n\n// ============================================================================\n// HeartbeatMonitor\n// ============================================================================\n\n/**\n * Tracks expert session liveness via heartbeats.\n *\n * - `startSession()` begins tracking a new expert execution\n * - `heartbeat()` resets the liveness timer for a session\n * - `endSession()` stops tracking\n * - `getHealth()` returns aggregate health report\n * - `isStalled()` checks if a specific session is stalled\n */\nexport class HeartbeatMonitor {\n private readonly config: HeartbeatConfig;\n private readonly sessions = new Map<string, SessionEntry>();\n\n constructor(config?: Partial<HeartbeatConfig>) {\n this.config = {\n slowThresholdMs: config?.slowThresholdMs ?? DEFAULT_SLOW_THRESHOLD_MS,\n stalledThresholdMs: config?.stalledThresholdMs ?? DEFAULT_STALLED_THRESHOLD_MS,\n absoluteMaxMs: config?.absoluteMaxMs ?? DEFAULT_ABSOLUTE_MAX_MS,\n };\n }\n\n /** Start tracking a new expert session. Returns session ID. */\n startSession(expertId: string): string {\n const sessionId = `hb-${expertId}-${randomBytes(6).toString('hex')}`;\n const now = getTimeProvider().now();\n this.sessions.set(sessionId, {\n expertId,\n startedAt: now,\n lastHeartbeat: now,\n heartbeatCount: 0,\n previousHealth: 'alive',\n });\n return sessionId;\n }\n\n /** Record a heartbeat for an active session. */\n heartbeat(sessionId: string): void {\n const entry = this.sessions.get(sessionId);\n if (entry === undefined) return;\n entry.lastHeartbeat = getTimeProvider().now();\n entry.heartbeatCount++;\n }\n\n /** Stop tracking a session. */\n endSession(sessionId: string): void {\n this.sessions.delete(sessionId);\n }\n\n /** Check if a session has exceeded the stalled threshold. */\n isStalled(sessionId: string): boolean {\n const entry = this.sessions.get(sessionId);\n if (entry === undefined) return false;\n const elapsed = getTimeProvider().now() - entry.lastHeartbeat;\n return elapsed >= this.config.stalledThresholdMs;\n }\n\n /** Check if a session has exceeded the absolute max lifetime. */\n isExpired(sessionId: string): boolean {\n const entry = this.sessions.get(sessionId);\n if (entry === undefined) return false;\n return getTimeProvider().now() - entry.startedAt >= this.config.absoluteMaxMs;\n }\n\n /** Get aggregate health report for all active sessions. */\n getHealth(): AgentHealthReport {\n const now = getTimeProvider().now();\n const sessions: ExpertSessionSnapshot[] = [];\n let stalledCount = 0;\n\n for (const [sessionId, entry] of this.sessions) {\n const timeSince = now - entry.lastHeartbeat;\n const health = this.classifyHealth(timeSince);\n if (health === 'stalled') stalledCount++;\n\n sessions.push({\n sessionId,\n expertId: entry.expertId,\n startedAt: entry.startedAt,\n lastHeartbeat: entry.lastHeartbeat,\n heartbeatCount: entry.heartbeatCount,\n health,\n elapsedMs: now - entry.startedAt,\n timeSinceHeartbeatMs: timeSince,\n });\n }\n\n return {\n activeSessions: this.sessions.size,\n stalledSessions: stalledCount,\n sessions,\n };\n }\n\n /**\n * Get health state with transition detection for a session.\n * Updates previousHealth on each call to track transitions.\n * (Issue #1088 Phase 4 — observability)\n */\n getSessionHealth(sessionId: string): HealthTransition | undefined {\n const entry = this.sessions.get(sessionId);\n if (entry === undefined) return undefined;\n const now = getTimeProvider().now();\n const timeSince = now - entry.lastHeartbeat;\n const health = this.classifyHealth(timeSince);\n const changed = health !== entry.previousHealth;\n const result: HealthTransition = {\n sessionId,\n agentId: entry.expertId,\n health,\n previousHealth: entry.previousHealth,\n changed,\n elapsedMs: now - entry.startedAt,\n heartbeatCount: entry.heartbeatCount,\n };\n entry.previousHealth = health;\n return result;\n }\n\n /** Number of currently tracked sessions. */\n get activeCount(): number {\n return this.sessions.size;\n }\n\n private classifyHealth(timeSinceMs: number): SessionHealth {\n if (timeSinceMs >= this.config.stalledThresholdMs) return 'stalled';\n if (timeSinceMs >= this.config.slowThresholdMs) return 'slow';\n return 'alive';\n }\n}\n\n// ============================================================================\n// Singleton\n// ============================================================================\n\nlet globalMonitor: HeartbeatMonitor | undefined;\n\n/** Get or create the global heartbeat monitor singleton. */\nexport function getHeartbeatMonitor(): HeartbeatMonitor {\n globalMonitor ??= new HeartbeatMonitor();\n return globalMonitor;\n}\n\n/** Reset global monitor (for testing). */\nexport function resetHeartbeatMonitor(): void {\n globalMonitor = undefined;\n}\n","/**\n * Type definitions for configuration defaults.\n *\n * Provides type safety for the centralized defaults system.\n * Includes Zod schemas for runtime validation at config boundaries.\n *\n * @module config/defaults-types\n */\n\nimport { z } from 'zod';\nimport type { CliNameLiteral } from './model-capabilities-types.js';\n\n// ============================================================================\n// CLI Timeout Types\n// ============================================================================\n\n/**\n * Task complexity levels for CLI timeout selection.\n */\nexport type TaskComplexity = 'simple' | 'standard' | 'complex';\n\n/**\n * Timeout profile structure for CLI tools.\n */\nexport interface TimeoutProfile {\n /** Timeout for simple tasks (single function, quick analysis) in ms */\n readonly simple: number;\n /** Timeout for standard tasks (multi-file changes, moderate analysis) in ms */\n readonly standard: number;\n /** Timeout for complex tasks (codebase-wide changes, deep analysis) in ms */\n readonly complex: number;\n}\n\n/**\n * Known CLI names for timeout profiles.\n * Extends CliNameLiteral with 'default' for fallback timeout profiles.\n */\nexport type KnownCliName = CliNameLiteral | 'default';\n\n// ============================================================================\n// Defaults Type Definitions\n// ============================================================================\n\n/**\n * Mutable type for timeout defaults (for functions returning overridden values).\n */\nexport interface TimeoutDefaults {\n cliMs: number;\n cliSimpleMs: number;\n cliComplexMs: number;\n apiMs: number;\n apiMaxMs: number;\n workflowMs: number;\n workflowMaxMs: number;\n stepMs: number;\n mcpMs: number;\n mcpMaxMs: number;\n healthCheckMs: number;\n testGlobalMs: number;\n testTaskMs: number;\n circuitBreakerResetMs: number;\n}\n\n/**\n * Mutable type for rate limit defaults.\n */\nexport interface RateLimitDefaults {\n requestsPerMinute: number;\n enabled: boolean;\n maxConcurrent: number;\n capacity: number;\n refillRate: number;\n refillIntervalMs: number;\n}\n\n/**\n * Type for tool rate limit configuration.\n */\nexport interface ToolRateLimitConfig {\n readonly capacity: number;\n readonly refillRate: number;\n readonly refillIntervalMs: number;\n}\n\n/**\n * Mutable type for retry defaults.\n */\nexport interface RetryDefaults {\n maxRetries: number;\n baseDelayMs: number;\n maxDelayMs: number;\n jitterFactor: number;\n}\n\n/**\n * Mutable type for worker defaults.\n */\nexport interface WorkerDefaults {\n maxWorkers: number;\n poolSize: number;\n idleTimeoutMs: number;\n workflowMaxParallel: number;\n testParallelism: number;\n evaluationMaxWorkers: number;\n eventBusMaxHistory: number;\n swarmObserverMaxEvents: number;\n}\n\n/**\n * Mutable type for circuit breaker defaults.\n */\nexport interface CircuitBreakerDefaults {\n failureThreshold: number;\n resetTimeoutMs: number;\n halfOpenSuccessThreshold: number;\n countTimeoutsAsFailures: boolean;\n countAuthFailuresAsFailures: boolean;\n countRateLimitsAsFailures: boolean;\n halfOpenMaxRequests: number;\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Type guard for task complexity.\n */\nexport function isTaskComplexity(value: unknown): value is TaskComplexity {\n return value === 'simple' || value === 'standard' || value === 'complex';\n}\n\n/**\n * Type guard for known CLI names.\n */\nexport function isKnownCliName(cli: string): cli is KnownCliName {\n return (\n cli === 'claude' ||\n cli === 'gemini' ||\n cli === 'codex' ||\n cli === 'opencode' ||\n cli === 'default'\n );\n}\n\n// ============================================================================\n// Zod Schemas for Runtime Validation\n// ============================================================================\n\n/**\n * Positive integer validator.\n */\nconst positiveInt = z.number().int().positive();\n\n/**\n * Non-negative integer validator.\n */\nconst nonNegativeInt = z.number().int().nonnegative();\n\n/**\n * Positive duration in milliseconds validator.\n */\nconst durationMs = z.number().int().positive().describe('Duration in milliseconds');\n\n/**\n * Schema for TimeoutProfile.\n */\nexport const TimeoutProfileSchema = z.object({\n simple: durationMs.describe('Timeout for simple tasks'),\n standard: durationMs.describe('Timeout for standard tasks'),\n complex: durationMs.describe('Timeout for complex tasks'),\n});\n\n/**\n * Schema for RetryDefaults.\n */\nexport const RetryDefaultsSchema = z.object({\n maxRetries: nonNegativeInt.max(10).describe('Maximum retry attempts'),\n baseDelayMs: durationMs.describe('Base delay between retries'),\n maxDelayMs: durationMs.describe('Maximum delay between retries'),\n jitterFactor: z.number().min(0).max(1).describe('Jitter factor (0-1)'),\n});\n\n/**\n * Schema for RateLimitDefaults.\n */\nexport const RateLimitDefaultsSchema = z.object({\n requestsPerMinute: positiveInt.max(1000).describe('Max requests per minute'),\n enabled: z.boolean().describe('Whether rate limiting is enabled'),\n maxConcurrent: positiveInt.max(100).describe('Max concurrent requests'),\n capacity: positiveInt.describe('Token bucket capacity'),\n refillRate: positiveInt.describe('Token refill rate'),\n refillIntervalMs: durationMs.describe('Token refill interval'),\n});\n\n/**\n * Schema for CircuitBreakerDefaults.\n */\nexport const CircuitBreakerDefaultsSchema = z.object({\n failureThreshold: z.number().int().min(1).max(100).describe('Failures before opening'),\n resetTimeoutMs: durationMs.describe('Time before attempting reset'),\n halfOpenSuccessThreshold: z.number().int().min(1).max(10).describe('Successes to close'),\n countTimeoutsAsFailures: z.boolean().describe('Count timeouts as failures'),\n countAuthFailuresAsFailures: z.boolean().describe('Count auth failures as failures'),\n countRateLimitsAsFailures: z.boolean().describe('Count rate limit errors as failures'),\n halfOpenMaxRequests: positiveInt.describe('Max requests in half-open state'),\n});\n\n/**\n * Schema for ToolRateLimitConfig.\n */\nexport const ToolRateLimitConfigSchema = z.object({\n capacity: positiveInt.describe('Token bucket capacity'),\n refillRate: positiveInt.describe('Token refill rate'),\n refillIntervalMs: durationMs.describe('Token refill interval'),\n});\n\n/**\n * Schema for WorkerDefaults.\n */\nexport const WorkerDefaultsSchema = z.object({\n maxWorkers: positiveInt.max(32).describe('Maximum worker threads'),\n poolSize: positiveInt.max(32).describe('Worker pool size'),\n idleTimeoutMs: durationMs.describe('Worker idle timeout'),\n workflowMaxParallel: positiveInt.max(10).describe('Max parallel workflow tasks'),\n testParallelism: positiveInt.max(16).describe('Test parallelism'),\n evaluationMaxWorkers: positiveInt.max(16).describe('Evaluation worker count'),\n eventBusMaxHistory: nonNegativeInt.max(10000).describe('Event bus history limit'),\n swarmObserverMaxEvents: nonNegativeInt.max(10000).describe('Swarm observer event limit'),\n});\n\n/**\n * Schema for TimeoutDefaults.\n */\nexport const TimeoutDefaultsSchema = z.object({\n cliMs: durationMs.describe('Default CLI timeout'),\n cliSimpleMs: durationMs.describe('Simple CLI task timeout'),\n cliComplexMs: durationMs.describe('Complex CLI task timeout'),\n apiMs: durationMs.describe('Default API timeout'),\n apiMaxMs: durationMs.describe('Maximum API timeout'),\n workflowMs: durationMs.describe('Default workflow timeout'),\n workflowMaxMs: durationMs.describe('Maximum workflow timeout'),\n stepMs: durationMs.describe('Default step timeout'),\n mcpMs: durationMs.describe('Default MCP timeout'),\n mcpMaxMs: durationMs.describe('Maximum MCP timeout'),\n healthCheckMs: durationMs.describe('Health check timeout'),\n testGlobalMs: durationMs.describe('Global test timeout'),\n testTaskMs: durationMs.describe('Task test timeout'),\n circuitBreakerResetMs: durationMs.describe('Circuit breaker reset timeout'),\n});\n","/**\n * Centralized Timeout Configuration\n *\n * Single source of truth for ALL timeout values in nexus-agents.\n * Every timeout-related constant should be defined here and imported\n * by consumers — never hardcoded elsewhere.\n *\n * Taxonomy:\n * - **CLI**: Per-CLI subprocess execution timeouts by task complexity\n * - **Vote**: Consensus voting round timeouts\n * - **MCP**: MCP tool handler timeouts (default + per-tool overrides)\n * - **Workflow**: Workflow step and overall execution timeouts\n * - **Graph**: Graph workflow execution timeouts\n * - **API**: External API request timeouts\n * - **Internal**: Health checks, circuit breakers, wave scheduling\n *\n * Environment variable overrides: use `resolveTimeout()` for categories\n * that support runtime configuration.\n *\n * @module config/timeouts\n * (Source: Issue #984 — Centralize timeout configuration)\n */\n\nimport type { TaskComplexity, KnownCliName, TimeoutProfile } from './defaults-types.js';\nimport { isKnownCliName } from './defaults-types.js';\nimport { detectTaskCategory } from './task-specialization.js';\n\n// Re-export types that consumers need\nexport type { TaskComplexity, KnownCliName, TimeoutProfile };\nexport { isKnownCliName };\n\n// ============================================================================\n// Central Timeout Constants\n// ============================================================================\n\n/**\n * Per-CLI timeout profiles by task complexity.\n *\n * Values based on real-world performance testing (Issues #357, #366, #983):\n * - Claude: Consistent 30-120s across complexity levels\n * - Gemini: 30-180s — complex tasks need extra buffer for large context\n * - Codex: 10-90s — optimized for code generation, increased per #983\n *\n * When both defaults-timeout-profiles.ts and cli-timeout-profiles.ts\n * had conflicting values, the Issue #366 values (from observed failures)\n * take precedence.\n */\nexport const CLI_TIMEOUTS = {\n claude: { simple: 30_000, standard: 120_000, complex: 600_000 },\n gemini: { simple: 30_000, standard: 180_000, complex: 600_000 },\n codex: { simple: 10_000, standard: 60_000, complex: 300_000 },\n opencode: { simple: 30_000, standard: 120_000, complex: 600_000 },\n default: { simple: 30_000, standard: 120_000, complex: 600_000 },\n} as const satisfies Record<KnownCliName, TimeoutProfile>;\n\n/**\n * Consensus voting timeouts.\n * Increased from 90s to 120s per Issue #983 for slower CLIs.\n */\nexport const VOTE_TIMEOUTS = {\n /** Default per-agent vote timeout.\n * Increased from 180s to 300s per Issue #1640 — architecture/security\n * experts regularly exceed 180s on complex proposals (avg 315s observed). */\n defaultMs: 300_000,\n /** Minimum allowed vote timeout (floor for env override). */\n minMs: 30_000,\n /** Maximum allowed vote timeout (cap for env override). */\n maxMs: 600_000,\n /** Default max retries per agent. */\n maxRetries: 2,\n} as const;\n\n/**\n * MCP tool handler timeouts.\n * Used by the tool middleware wrapper (CVE-2026-0621 mitigation).\n */\nexport const MCP_TIMEOUTS = {\n /** Default timeout for MCP tool handlers. */\n defaultMs: 60_000,\n /** Maximum allowed MCP tool timeout. */\n maxMs: 900_000,\n /**\n * Safety buffer between an internal wall-clock deadline (e.g. the consensus\n * overall deadline) and when the outer `wrapToolWithTimeout` middleware\n * would fire. Tools that race their own partial-result deadline MUST clamp\n * that deadline to `perTool[toolName] - perToolSafetyBufferMs` so the\n * internal timeout always fires first; otherwise the middleware kills the\n * promise chain before the tool can serialise its partial response and the\n * client sees a naked `Operation '<tool>' timed out after Nms` error.\n * (Source: Issue #2104 — MCP wrapper aborts before internal deadline)\n */\n perToolSafetyBufferMs: 10_000,\n /** Per-tool timeout overrides for long-running tools. */\n perTool: {\n orchestrate: 900_000, // 15 min — multi-step agent orchestration\n consensus_vote: 600_000, // 10 min — 5-6 agents voting in parallel via Promise.all\n execute_expert: 900_000, // 15 min — complex expert reasoning tasks\n run_workflow: 900_000, // 15 min — multi-step workflow execution\n } as Readonly<Record<string, number>>,\n} as const;\n\n/**\n * Clamps a computed internal wall-clock deadline so it always fires before\n * the outer MCP tool-wrapper timeout. Returns the smaller of:\n * - the caller's computed deadline,\n * - `perTool[toolName] - perToolSafetyBufferMs`.\n *\n * Floored at `defaultMs / 2` so the tool remains minimally useful even if a\n * future change lowers the MCP cap far below what the tool's formula expects.\n *\n * @param computedMs - The tool's own wall-clock deadline (e.g. sum of per-vote\n * budgets plus stagger + response buffer).\n * @param toolName - Key into `MCP_TIMEOUTS.perTool`; falls back to `defaultMs`\n * for unknown tools.\n * @returns Clamped deadline in milliseconds.\n * (Source: Issue #2105 — consensus_vote overallDeadlineMs > MCP wrapper)\n */\nexport function getMcpSafeDeadlineMs(computedMs: number, toolName: string): number {\n const perToolCap = MCP_TIMEOUTS.perTool[toolName] ?? MCP_TIMEOUTS.defaultMs;\n const safeCap = perToolCap - MCP_TIMEOUTS.perToolSafetyBufferMs;\n const floor = Math.floor(MCP_TIMEOUTS.defaultMs / 2);\n // Never return less than the floor (keeps tools usable under tight caps).\n const capped = Math.min(computedMs, safeCap);\n return Math.max(capped, floor);\n}\n\n/**\n * Workflow execution timeouts.\n */\nexport const WORKFLOW_TIMEOUTS = {\n /** Per-step timeout. */\n stepMs: 300_000,\n /** Overall workflow timeout. */\n workflowMs: 300_000,\n /** Maximum workflow timeout. */\n workflowMaxMs: 1_800_000,\n /** Maximum retry delay between steps. */\n maxRetryDelayMs: 30_000,\n} as const;\n\n/**\n * Graph workflow execution timeouts.\n */\nexport const GRAPH_TIMEOUTS = {\n /** Default graph execution timeout. */\n defaultMs: 120_000,\n /** Maximum graph steps before abort. */\n maxSteps: 100,\n} as const;\n\n/**\n * Per-CLI task dispatch timeouts (consensus plans, triangulated review).\n * Used when dispatching tasks to multiple CLIs in parallel.\n */\nexport const PER_CLI_TASK_TIMEOUTS = {\n /** Default per-CLI timeout for parallel dispatch. */\n defaultMs: 300_000,\n /** Minimum per-CLI timeout. */\n minMs: 1_000,\n /** Maximum per-CLI timeout. */\n maxMs: 600_000,\n /** Parallel exploration per-CLI timeout (raised from 120s for reliability, Issue #1403). */\n explorationMs: 180_000,\n} as const;\n\n/**\n * External API request timeouts.\n */\nexport const API_TIMEOUTS = {\n /** Default API request timeout. */\n defaultMs: 30_000,\n /** Maximum API request timeout. */\n maxMs: 300_000,\n /** arXiv API timeout. */\n arxivMs: 30_000,\n /** Source discovery API timeout. */\n sourceMs: 30_000,\n /** V2 delegate pipeline timeout. */\n v2DelegateMs: 30_000,\n /** Provider API call timeout. */\n providerMs: 30_000,\n /** GitHub API request timeout. */\n githubApiMs: 10_000,\n} as const;\n\n/**\n * Worker dispatch timeouts (AOrchestra multi-worker execution).\n * (Source: Issue #1313 — Worker dispatch resilience)\n */\nexport const WORKER_TIMEOUTS = {\n /** Default per-worker execution timeout. */\n defaultMs: 60_000,\n /** Minimum allowed worker timeout (aligned with dispatcher floor, #1490). */\n minMs: 30_000,\n /** Maximum allowed worker timeout (aligned with dispatcher ceiling, #1490). */\n maxMs: 900_000,\n} as const;\n\n/**\n * Internal system timeouts (health checks, circuit breakers, etc.).\n */\nexport const INTERNAL_TIMEOUTS = {\n /** Health check timeout. */\n healthCheckMs: 5_000,\n /** Circuit breaker reset timeout. */\n circuitBreakerResetMs: 30_000,\n /** Self-evaluation command timeout. */\n selfEvalMs: 120_000,\n /** Wave scheduler per-task timeout. */\n waveTaskMs: 60_000,\n /** Puppeteer orchestration timeout. */\n puppeteerMs: 300_000,\n} as const;\n\n/**\n * Expert execution timeouts by inferred task complexity.\n * Complex reasoning tasks (architecture, security, planning) need longer\n * timeouts than standard code generation or documentation tasks.\n * (Source: Issue #1028 — Dynamic expert timeout)\n * (Updated: Issue #1045 — E2E testing revealed 180s insufficient for\n * architecture design tasks; consensus_vote proves 94s is normal for\n * complex deliberation, so 300s gives adequate headroom)\n * (Updated: RCA — real model API calls take 30-60s/turn; even standard\n * expert tasks need 2-3 turns minimum, so 90s caused universal timeouts)\n */\nexport const EXPERT_TIMEOUTS = {\n /** Complex reasoning tasks: architecture, security_review, planning. */\n complexMs: 600_000,\n /** Standard tasks: code_generation, testing, code_review, etc. */\n standardMs: 300_000,\n /** Minimum allowed expert timeout. */\n minMs: 30_000,\n /** Maximum allowed expert timeout. */\n maxMs: 900_000,\n /** Categories considered complex (longer timeout).\n * Updated: Issue #1675 — devops (avg 54s) and documentation (avg 64s on gemini)\n * regularly exceed the 120s standard CLI timeout. */\n complexCategories: [\n 'architecture',\n 'security_review',\n 'planning',\n 'research',\n 'devops',\n 'documentation',\n ] as readonly string[],\n} as const;\n\n/**\n * Agent heartbeat monitoring thresholds.\n * (Source: Issue #1046 — Centralize scattered timeouts)\n */\nexport const HEARTBEAT_TIMEOUTS = {\n /** Agent is considered slow after this duration without heartbeat. */\n slowThresholdMs: 60_000,\n /** Agent is considered stalled (no heartbeat) after this duration. */\n stalledThresholdMs: 120_000,\n /** Absolute maximum agent execution time (safety cap). */\n absoluteMaxMs: 900_000,\n /** Periodic heartbeat emission interval (Issue #1087). */\n heartbeatIntervalMs: 15_000,\n} as const;\n\n/**\n * MCP middleware timeout guard defaults.\n * (Source: Issue #1046 — Centralize scattered timeouts)\n */\nexport const TIMEOUT_GUARD = {\n /** Default operation timeout for the guard middleware. */\n defaultMs: 60_000,\n /** Maximum allowed timeout for any guarded operation. */\n maxMs: 900_000,\n /** Fraction of timeout at which to emit near-timeout warning. */\n nearTimeoutThreshold: 0.8,\n} as const;\n\n/**\n * Reflective memory retriever timeouts and cache settings.\n * (Source: Issue #1046 — Centralize scattered timeouts)\n */\nexport const REFLECTIVE_TIMEOUTS = {\n /** Timeout for reflection LLM call (aggressive — keeps retrieval fast). */\n reflectionMs: 2_000,\n /** Cache TTL in milliseconds. */\n cacheTtlMs: 300_000,\n} as const;\n\n/**\n * Workflow step executor defaults.\n * (Source: Issue #1046 — Centralize scattered timeouts)\n */\nexport const STEP_EXECUTOR_TIMEOUTS = {\n /** Default step timeout. */\n defaultMs: 300_000,\n /** Default retry delay between step attempts. */\n retryDelayMs: 1_000,\n} as const;\n\n/**\n * Cache TTL and rate limiter intervals.\n * (Source: Issue #1046 — Centralize scattered timeouts)\n */\nexport const CACHE_TIMEOUTS = {\n /** Reputation model cache TTL. */\n reputationTtlMs: 300_000,\n /** Rate limiter token refill interval. */\n rateLimitRefillMs: 1_000,\n} as const;\n\n/**\n * CLI subprocess spawn and command timeouts.\n * Used when spawning external processes (gh, docker, CLI adapters).\n * (Source: Timeout audit — centralize scattered hardcoded values)\n */\nexport const CLI_SUBPROCESS_TIMEOUTS = {\n /** CLI adapter spawn timeout (detect/startup). */\n spawnMs: 10_000,\n /** Docker version check timeout. */\n dockerCheckMs: 5_000,\n /** gh CLI command timeout. */\n ghCommandMs: 30_000,\n /** CLI status probe timeout. */\n statusProbeMs: 5_000,\n /** Environment setup timeout. */\n envSetupMs: 3_000,\n /** Release validation (long-running). */\n releaseValidateMs: 120_000,\n /** Release build (longest-running). */\n releaseBuildMs: 180_000,\n /** Graph workflow execution timeout. */\n graphWorkflowMs: 60_000,\n /** Self-development plan phase duration. */\n selfDevPlanMs: 300_000,\n /** Self-development refine phase duration. */\n selfDevRefineMs: 180_000,\n /** Self-development vote phase duration. */\n selfDevVoteMs: 120_000,\n /** Collaboration protocol session timeout. */\n collaborationMs: 60_000,\n /** Maximum wait time for CI checks (auto-merge). */\n ciWaitMaxMs: 300_000,\n /** CI check polling interval (auto-merge). */\n ciPollIntervalMs: 15_000,\n} as const;\n\n/**\n * Exponential backoff configuration for CLI adapter retries.\n * (Source: Issue #1220 — Centralize hardcoded values)\n */\nexport const BACKOFF_CONFIG = {\n /** Base delay multiplier in milliseconds. */\n baseDelayMs: 1_000,\n /** Exponent base for exponential backoff (delay = base^attempt * baseDelayMs). */\n exponentBase: 2,\n} as const;\n\n/**\n * Agent message router timeouts.\n * (Source: Issue #1220 — Centralize hardcoded values)\n */\nexport const AGENT_ROUTER_TIMEOUTS = {\n /** Default router timeout per message. */\n defaultMs: 30_000,\n /** Default max retries for message routing. */\n maxRetries: 3,\n /** Default delay between retries. */\n retryDelayMs: 1_000,\n} as const;\n\n/**\n * Codex MCP adapter execution defaults.\n * (Source: Issue #1220 — Centralize hardcoded values)\n */\nexport const CODEX_MCP_TIMEOUTS = {\n /** Default execution timeout. */\n defaultMs: 120_000,\n /** Default max retries. */\n maxRetries: 2,\n} as const;\n\n/**\n * Test framework timeouts (not for production code).\n */\nexport const TEST_TIMEOUTS = {\n /** Global test run timeout. */\n globalMs: 600_000,\n /** Per-task test timeout. */\n taskMs: 120_000,\n} as const;\n\n// ============================================================================\n// Accessor Functions\n// ============================================================================\n\n/**\n * Gets the timeout profile for a specific CLI.\n *\n * @param cli - CLI name (claude, gemini, codex)\n * @returns TimeoutProfile for the CLI (or default for unknown CLIs)\n */\nexport function getCliTimeoutProfile(cli: string): TimeoutProfile {\n if (isKnownCliName(cli)) {\n return CLI_TIMEOUTS[cli];\n }\n return CLI_TIMEOUTS.default;\n}\n\n/**\n * Gets timeout for a task based on CLI and complexity.\n *\n * @param cli - CLI name\n * @param complexity - Task complexity level\n * @returns Timeout in milliseconds\n */\nexport function getCliTimeout(cli: string, complexity: TaskComplexity): number {\n return getCliTimeoutProfile(cli)[complexity];\n}\n\n/**\n * Gets the timeout for an expert task based on task description complexity.\n *\n * Uses `detectTaskCategory()` to infer category, then maps to timeout tier.\n * Supports `NEXUS_EXPERT_TIMEOUT_MS` env override.\n *\n * @param taskDescription - Task text to analyze for complexity\n * @returns Timeout in milliseconds\n * (Source: Issue #1028 — Dynamic expert timeout)\n */\nexport function getExpertTaskTimeout(taskDescription: string): number {\n const envOverride = resolveEnvTimeout(\n 'NEXUS_EXPERT_TIMEOUT_MS',\n 0,\n EXPERT_TIMEOUTS.minMs,\n EXPERT_TIMEOUTS.maxMs\n );\n if (envOverride > 0) return envOverride;\n\n const match = detectTaskCategory(taskDescription);\n const category = match?.category ?? 'exploration';\n const isComplex = EXPERT_TIMEOUTS.complexCategories.includes(category);\n return isComplex ? EXPERT_TIMEOUTS.complexMs : EXPERT_TIMEOUTS.standardMs;\n}\n\n// ============================================================================\n// Environment Variable Resolution\n// ============================================================================\n\n/** Environment variable names for timeout overrides. */\nexport const TIMEOUT_ENV_VARS = {\n vote: 'NEXUS_VOTE_TIMEOUT_MS',\n mcp: 'NEXUS_MCP_TIMEOUT_MS',\n workflow: 'NEXUS_WORKFLOW_TIMEOUT_MS',\n graph: 'NEXUS_GRAPH_TIMEOUT_MS',\n expert: 'NEXUS_EXPERT_TIMEOUT_MS',\n worker: 'NEXUS_WORKER_TIMEOUT_MS',\n} as const;\n\n/**\n * Resolves vote timeout with environment variable override.\n * Clamps to [VOTE_TIMEOUTS.minMs, VOTE_TIMEOUTS.maxMs].\n *\n * @returns Resolved vote timeout in milliseconds\n */\nexport function resolveVoteTimeout(): number {\n return resolveEnvTimeout(\n TIMEOUT_ENV_VARS.vote,\n VOTE_TIMEOUTS.defaultMs,\n VOTE_TIMEOUTS.minMs,\n VOTE_TIMEOUTS.maxMs\n );\n}\n\n/**\n * Resolves worker dispatch timeout with environment variable override.\n * Clamps to [WORKER_TIMEOUTS.minMs, WORKER_TIMEOUTS.maxMs].\n *\n * @returns Resolved worker timeout in milliseconds\n * (Source: Issue #1313 — Worker dispatch resilience)\n */\nexport function resolveWorkerTimeout(): number {\n return resolveEnvTimeout(\n TIMEOUT_ENV_VARS.worker,\n WORKER_TIMEOUTS.defaultMs,\n WORKER_TIMEOUTS.minMs,\n WORKER_TIMEOUTS.maxMs\n );\n}\n\n/**\n * Resolves a timeout from an environment variable with min/max clamping.\n *\n * @param envVar - Environment variable name\n * @param defaultMs - Default timeout if env var is not set\n * @param minMs - Minimum allowed value (floor)\n * @param maxMs - Maximum allowed value (cap)\n * @returns Resolved timeout in milliseconds\n */\nexport function resolveEnvTimeout(\n envVar: string,\n defaultMs: number,\n minMs: number,\n maxMs: number\n): number {\n const envVal = process.env[envVar];\n if (envVal !== undefined) {\n const parsed = Number(envVal);\n if (!Number.isNaN(parsed) && parsed > 0) {\n return Math.min(Math.max(parsed, minMs), maxMs);\n }\n }\n return defaultMs;\n}\n\n/**\n * Validates and clamps a requested timeout to safe bounds.\n *\n * @param requestedMs - Requested timeout in milliseconds\n * @param minMs - Minimum allowed (default: VOTE_TIMEOUTS.minMs)\n * @param maxMs - Maximum allowed (default: VOTE_TIMEOUTS.maxMs)\n * @returns Object with clamped value and whether it was modified\n */\nexport function validateTimeout(\n requestedMs: number,\n minMs: number = VOTE_TIMEOUTS.minMs,\n maxMs: number = VOTE_TIMEOUTS.maxMs\n): { value: number; clamped: boolean } {\n const clamped = Math.min(Math.max(requestedMs, minMs), maxMs);\n return { value: clamped, clamped: clamped !== requestedMs };\n}\n","/* eslint-disable max-lines */\n/**\n * nexus-agents/mcp - Weather Report\n *\n * Computes a living performance dashboard from task outcome data\n * and calculates adaptive routing bonuses using epsilon-greedy\n * exploration/exploitation tradeoff.\n *\n * @module mcp/tools/weather-report\n * (Source: Issue #865 — Weather report with adaptive routing)\n */\n\nimport type {\n PerformanceSummary,\n GroupStats,\n TaskOutcome,\n} from '../../orchestration/outcomes/outcome-types.js';\nimport { getOutcomeStore, type OutcomeStore } from '../../orchestration/outcomes/outcome-store.js';\nimport { categorizeOutcomeErrorMessage } from '../../orchestration/outcomes/outcome-types.js';\nimport type { TaskCategory } from '../../config/task-specialization-types.js';\nimport { TASK_CATEGORIES } from '../../config/task-specialization-types.js';\nimport { getSpecialization } from '../../config/task-specialization.js';\nimport type { CliNameLiteral } from '../../config/model-capabilities-types.js';\nimport type {\n WeatherReportOptions,\n WeatherReportResponse,\n CliWeather,\n AdaptiveBonus,\n AdapterAttemptStats,\n WeatherReportConfig,\n TierRecommendationEntry,\n LearningInsight,\n RecommendedMapping,\n ToolPerformanceEntry,\n FailureBreakdownEntry,\n ExpertPerformanceEntry,\n SwarmHealthMetrics,\n} from './weather-report-types.js';\nimport type { RateLimitReport, TriageStats } from './weather-report-types.js';\nimport { createDefaultWeatherConfig } from './weather-report-types.js';\nimport { generateTierRecommendations } from '../gateway/tier-recommender.js';\nimport { computeAdaptiveThresholds } from '../../orchestration/outcomes/adaptive-thresholds.js';\nimport { getRateLimitStats } from '../../adapters/rate-limit-detector.js';\nimport { getToolStats } from '../middleware/tool-metrics.js';\nimport { getHeartbeatMonitor } from '../../agents/heartbeat-monitor.js';\nimport type { AgentHealthSummary } from './weather-report-types.js';\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nconst CLI_NAMES = ['claude', 'gemini', 'codex', 'opencode'] as const;\n\n/** Collect non-empty optional sections into a spread-friendly object. */\nfunction collectOptionalSections(sections: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(sections)) {\n if (value === undefined || value === null) continue;\n if (Array.isArray(value) && value.length === 0) continue;\n result[key] = value;\n }\n return result;\n}\n\n/**\n * Generates the weather report from current outcome data.\n */\n/** Builds all optional report sections, filtering out empty ones. */\nfunction buildOptionalSections(\n input: WeatherReportOptions,\n cfg: WeatherReportConfig\n): Record<string, unknown> {\n const expertPerformance = buildExpertPerformance();\n return collectOptionalSections({\n rateLimits: buildRateLimitReport(),\n toolPerformance: buildToolPerformance(),\n failureBreakdown: buildFailureBreakdown(input),\n agentHealth: buildAgentHealth(),\n expertPerformance,\n swarmHealth: buildSwarmHealth(expertPerformance),\n triageStats: buildTriageStats(input),\n recentWindow: buildRecentWindow(cfg),\n });\n}\n\n/**\n * Generates the weather report from current outcome data.\n */\nexport function generateWeatherReport(\n input: WeatherReportOptions,\n config?: Partial<WeatherReportConfig>\n): WeatherReportResponse {\n const cfg = { ...createDefaultWeatherConfig(), ...config };\n const store = getOutcomeStore();\n const includeAdaptive = input.includeAdaptive ?? true;\n const summary = store.summarize(buildQuery(input.cli, input.category));\n const overallOutcomes = store.query(buildQuery(input.cli, input.category));\n\n const base = {\n overall: {\n totalTasks: summary.totalTasks,\n successRate: summary.successRate,\n avgDurationMs: summary.avgDurationMs,\n ...computeAdapterAttemptStats(overallOutcomes),\n },\n cliWeather: buildCliWeather(summary, input),\n adaptiveBonuses: includeAdaptive ? computeAdaptiveBonuses(cfg) : [],\n tierRecommendations: buildTierRecommendations(summary),\n ...buildOptionalSections(input, cfg),\n explorationRate: cfg.explorationRate,\n coldStartThreshold: cfg.coldStartThreshold,\n collectedAt: new Date().toISOString(),\n };\n\n if (includeAdaptive) {\n return {\n ...base,\n learningInsights: buildLearningInsights(),\n recommendedMappings: buildRecommendedMappings(),\n };\n }\n\n return base;\n}\n\n/** Builds agent health from heartbeat monitor (Issue #1032). */\nfunction buildAgentHealth(): AgentHealthSummary | undefined {\n const monitor = getHeartbeatMonitor();\n if (monitor.activeCount === 0) return undefined;\n const health = monitor.getHealth();\n return {\n activeSessions: health.activeSessions,\n stalledSessions: health.stalledSessions,\n sessions: health.sessions.map((s) => ({\n sessionId: s.sessionId,\n expertId: s.expertId,\n health: s.health,\n elapsedMs: s.elapsedMs,\n timeSinceHeartbeatMs: s.timeSinceHeartbeatMs,\n heartbeatCount: s.heartbeatCount,\n })),\n };\n}\n\n/** Builds recent-window performance stats within the lookback period (#1401). */\nfunction buildRecentWindow(cfg: WeatherReportConfig): WeatherReportResponse['recentWindow'] {\n if (cfg.outcomeLookbackMs <= 0) return undefined;\n const store = getOutcomeStore();\n const since = new Date(Date.now() - cfg.outcomeLookbackMs).toISOString();\n const recent = store.query({ since });\n if (recent.length === 0) return undefined;\n\n const successes = recent.filter((o) => o.success).length;\n const totalDuration = recent.reduce((s, o) => s + o.durationMs, 0);\n return {\n windowMs: cfg.outcomeLookbackMs,\n totalTasks: recent.length,\n successRate: round3(successes / recent.length),\n avgDurationMs: Math.round(totalDuration / recent.length),\n };\n}\n\n/** Builds rate limit report from tracked events (Issue #996). */\nfunction buildRateLimitReport(): readonly RateLimitReport[] {\n return getRateLimitStats().map((s) => ({\n provider: s.provider,\n totalHits: s.totalHits,\n lastHitAt: s.lastHitAt,\n avgRetryAfterMs: s.avgRetryAfterMs,\n }));\n}\n\n/**\n * Queries outcomes with a lookback window, falling back to all history\n * if the window has fewer samples than coldStartThreshold. (#1401)\n */\nexport function queryWithLookback(\n store: OutcomeStore,\n cli: CliNameLiteral,\n category: TaskCategory,\n cfg: WeatherReportConfig\n): readonly TaskOutcome[] {\n // Exclude e2e-eval outcomes — they measure the eval harness, not CLI reliability (#1680)\n const exclude = ['e2e-eval'];\n if (cfg.outcomeLookbackMs > 0) {\n const since = new Date(Date.now() - cfg.outcomeLookbackMs).toISOString();\n const recent = store.query({ cli, category, since, excludeQualitySignals: exclude });\n if (recent.length >= cfg.coldStartThreshold) return recent;\n }\n // Fall back to all history if lookback window has insufficient data\n return store.query({ cli, category, excludeQualitySignals: exclude });\n}\n\n/**\n * Calculates adaptive specialization bonus for a given CLI+category.\n * Returns the adjustment on top of the static bonus.\n *\n * - Below cold-start threshold: returns 0 (no adjustment)\n * - Above threshold: scales bonus by observed success rate vs baseline\n * - Clamped to [-maxBonusAdjustment, +maxBonusAdjustment]\n */\nexport function getAdaptiveBonus(\n cli: string,\n category: TaskCategory,\n config?: Partial<WeatherReportConfig>\n): number {\n const cfg = { ...createDefaultWeatherConfig(), ...config };\n const store = getOutcomeStore();\n const cliName = cli as CliNameLiteral;\n\n // Use lookback window for recent-weighted adaptive bonuses (#1401)\n const outcomes = queryWithLookback(store, cliName, category, cfg);\n if (outcomes.length < cfg.coldStartThreshold) return 0;\n\n const successRate = outcomes.filter((o) => o.success).length / outcomes.length;\n // Compare against fixed baseline (0.7), not adaptive baseline (#1483).\n // The adaptive baseline self-adjusts to match observed rate, zeroing delta.\n const FIXED_BASELINE = 0.7;\n const delta = successRate - FIXED_BASELINE;\n\n // Compute confidence from windowed outcomes (not all-time) to prevent\n // stale historical data from inflating bonus magnitude (#1676).\n const FULL_CONFIDENCE_SAMPLES = 50;\n const windowedConfidence = Math.min(1, outcomes.length / FULL_CONFIDENCE_SAMPLES);\n const maxBonus = Math.min(cfg.maxBonusAdjustment * windowedConfidence, cfg.maxBonusAdjustment);\n\n // Scale: +30% above baseline → +maxBonus; config caps adaptive value\n const scaled = (delta / 0.3) * maxBonus;\n return clamp(scaled, -maxBonus, maxBonus);\n}\n\n/**\n * Determines if exploration should override normal routing.\n * Uses epsilon-greedy: returns true with probability = explorationRate.\n */\nexport function shouldExplore(config?: Partial<WeatherReportConfig>): boolean {\n const cfg = { ...createDefaultWeatherConfig(), ...config };\n return Math.random() < cfg.explorationRate;\n}\n\n// ============================================================================\n// Internal Helpers\n// ============================================================================\n\nfunction buildQuery(\n cli?: string,\n category?: string\n): { cli?: CliNameLiteral; category?: TaskCategory } {\n const query: { cli?: CliNameLiteral; category?: TaskCategory } = {};\n if (cli !== undefined) query.cli = cli as CliNameLiteral;\n if (category !== undefined) query.category = category as TaskCategory;\n return query;\n}\n\n/**\n * Computes adapter attempt stats from a set of outcomes, separating infrastructure\n * failures (adapter_unavailable) from model-quality failures. Returns an empty\n * stats object (zeros) when the input is empty. (#1982)\n */\nfunction computeAdapterAttemptStats(outcomes: readonly TaskOutcome[]): AdapterAttemptStats {\n if (outcomes.length === 0) {\n return { adapterAttemptSuccessRate: 0, adapterUnavailableCount: 0, adapterUnavailableRate: 0 };\n }\n const adapterUnavailable = outcomes.filter((o) => {\n if (o.success) return false;\n const cat =\n o.failureCategory ??\n (typeof o.errorMessage === 'string' && o.errorMessage.length > 0\n ? categorizeOutcomeErrorMessage(o.errorMessage)\n : undefined);\n return cat === 'adapter_unavailable';\n }).length;\n const attempted = outcomes.length - adapterUnavailable;\n const successes = outcomes.filter((o) => o.success).length;\n const attemptSuccessRate = attempted > 0 ? successes / attempted : 0;\n return {\n adapterAttemptSuccessRate: round3(attemptSuccessRate),\n adapterUnavailableCount: adapterUnavailable,\n adapterUnavailableRate: round3(adapterUnavailable / outcomes.length),\n };\n}\n\nfunction buildCliWeather(\n summary: PerformanceSummary,\n input: WeatherReportOptions\n): readonly CliWeather[] {\n const clis = input.cli !== undefined ? [input.cli] : [...CLI_NAMES];\n\n return clis.map((cli) => {\n const stats = summary.byCli.get(cli);\n const store = getOutcomeStore();\n const cliOutcomes = store.query({ cli: cli });\n\n // Build per-category breakdown for this CLI\n const byCategory = new Map<string, GroupStats>();\n for (const cat of TASK_CATEGORIES) {\n const catOutcomes = cliOutcomes.filter((o) => o.category === cat);\n if (catOutcomes.length > 0) {\n const sc = catOutcomes.filter((o) => o.success).length;\n const td = catOutcomes.reduce((s, o) => s + o.durationMs, 0);\n byCategory.set(cat, {\n count: catOutcomes.length,\n successRate: sc / catOutcomes.length,\n avgDurationMs: td / catOutcomes.length,\n });\n }\n }\n\n return {\n cli,\n totalTasks: stats?.count ?? 0,\n successRate: stats?.successRate ?? 0,\n avgDurationMs: stats?.avgDurationMs ?? 0,\n byCategory,\n ...computeAdapterAttemptStats(cliOutcomes),\n };\n });\n}\n\nfunction computeAdaptiveBonuses(cfg: WeatherReportConfig): readonly AdaptiveBonus[] {\n const bonuses: AdaptiveBonus[] = [];\n\n for (const cli of CLI_NAMES) {\n for (const category of TASK_CATEGORIES) {\n const spec = getSpecialization(category);\n const staticBonus = getStaticBonusForCli(cli, spec);\n const store = getOutcomeStore();\n const outcomes = queryWithLookback(store, cli, category, cfg);\n const sampleCount = outcomes.length;\n const sufficient = sampleCount >= cfg.coldStartThreshold;\n const adaptiveAdj = sufficient ? getAdaptiveBonus(cli, category, cfg) : 0;\n\n // Only include entries with actual data or non-zero bonuses\n if (sampleCount > 0 || staticBonus > 0 || adaptiveAdj !== 0) {\n bonuses.push({\n cli,\n category,\n staticBonus,\n adaptiveBonus: Math.round(adaptiveAdj * 10) / 10,\n sampleCount,\n sufficient,\n });\n }\n }\n }\n\n return bonuses;\n}\n\n/** Gets the static specialization bonus for a CLI in a given spec. */\nfunction getStaticBonusForCli(\n cli: string,\n spec: { primaryCli: string; secondaryCli: string; bonus: number }\n): number {\n if (cli === spec.primaryCli) return spec.bonus;\n if (cli === spec.secondaryCli) return Math.floor(spec.bonus / 2);\n return 0;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\n/** Builds learning insights from adaptive thresholds (#901). */\nfunction buildLearningInsights(): readonly LearningInsight[] {\n const store = getOutcomeStore();\n const insights: LearningInsight[] = [];\n\n for (const cli of CLI_NAMES) {\n for (const category of TASK_CATEGORIES) {\n const thresholds = computeAdaptiveThresholds(store, cli, category);\n if (thresholds.sampleCount > 0) {\n insights.push({\n cli,\n category,\n trend: thresholds.trend,\n confidence: thresholds.confidence,\n adjustedBaseline: thresholds.baseline,\n sampleCount: thresholds.sampleCount,\n });\n }\n }\n }\n\n return insights;\n}\n\n/** Builds recommended CLI mappings per category for LinUCB cold-start (#952). */\nfunction buildRecommendedMappings(): readonly RecommendedMapping[] {\n const store = getOutcomeStore();\n const mappings: RecommendedMapping[] = [];\n\n for (const category of TASK_CATEGORIES) {\n let bestCli = '';\n let bestRate = -1;\n let bestCount = 0;\n\n for (const cli of CLI_NAMES) {\n const outcomes = store.query({ cli, category });\n if (outcomes.length === 0) continue;\n const rate = outcomes.filter((o) => o.success).length / outcomes.length;\n if (rate > bestRate || (rate === bestRate && outcomes.length > bestCount)) {\n bestCli = cli;\n bestRate = rate;\n bestCount = outcomes.length;\n }\n }\n\n if (bestCli !== '') {\n const confidence = bestCount >= 20 ? 'high' : bestCount >= 10 ? 'medium' : 'low';\n mappings.push({\n category,\n recommendedCli: bestCli,\n successRate: bestRate,\n sampleCount: bestCount,\n confidence: confidence,\n });\n }\n }\n\n return mappings;\n}\n\n/** Minimum observations per category to count toward routing accuracy (#1442). */\nconst ROUTING_MIN_SAMPLES = 5;\n\n/** Confidence threshold for adaptation speed measurement. */\nconst ADAPTATION_CONFIDENCE_THRESHOLD = 0.7;\n\n/** Per-category routing analysis result. */\ninterface CategoryRoutingStats {\n readonly accurateCount: number;\n readonly totalRouted: number;\n readonly regret: number;\n}\n\n/** Tolerance band for routing accuracy — CLIs within this % of best are \"good\" (#1442, #1488).\n * Widened from 10% to 25%: a CLI achieving ≥75% of the best rate is acceptable routing. */\nconst ROUTING_ACCURACY_TOLERANCE = 0.25;\n\n/** Analyzes routing accuracy and regret for a single category. */\nfunction analyzeCategoryRouting(\n catOutcomes: ReadonlyArray<{ cli: string; success: boolean }>\n): CategoryRoutingStats | null {\n let bestRate = 0;\n const cliRates = new Map<string, number>();\n for (const cli of CLI_NAMES) {\n const cliCat = catOutcomes.filter((o) => o.cli === cli);\n if (cliCat.length === 0) continue;\n const rate = cliCat.filter((o) => o.success).length / cliCat.length;\n cliRates.set(cli, rate);\n if (rate > bestRate) bestRate = rate;\n }\n if (cliRates.size === 0) return null;\n\n // Count tasks routed to any \"good\" CLI (within tolerance band of best)\n const threshold = bestRate * (1 - ROUTING_ACCURACY_TOLERANCE);\n const goodClis = new Set<string>();\n for (const [cli, rate] of cliRates) {\n if (rate >= threshold) goodClis.add(cli);\n }\n\n const routed = catOutcomes.filter((o) => goodClis.has(o.cli)).length;\n const actualRate = catOutcomes.filter((o) => o.success).length / catOutcomes.length;\n return { accurateCount: routed, totalRouted: catOutcomes.length, regret: bestRate - actualRate };\n}\n\n/** Computes avg samples for the best CLI per category to reach high confidence. */\nfunction computeAdaptationSpeed(): number {\n const store = getOutcomeStore();\n let speedSum = 0;\n let speedCount = 0;\n for (const category of TASK_CATEGORIES) {\n // Find the best CLI for this category (fewest samples to reach confidence)\n let bestSamples = Infinity;\n let found = false;\n for (const cli of CLI_NAMES) {\n const thresholds = computeAdaptiveThresholds(store, cli, category);\n if (thresholds.confidence >= ADAPTATION_CONFIDENCE_THRESHOLD && thresholds.sampleCount > 0) {\n if (thresholds.sampleCount < bestSamples) {\n bestSamples = thresholds.sampleCount;\n found = true;\n }\n }\n }\n if (found) {\n speedSum += bestSamples;\n speedCount++;\n }\n }\n return speedCount > 0 ? speedSum / speedCount : 0;\n}\n\n/** Builds swarm health metrics from outcome + expert data (Issue #1403). */\nfunction buildSwarmHealth(\n expertPerf: readonly ExpertPerformanceEntry[]\n): SwarmHealthMetrics | undefined {\n const allOutcomes = getOutcomeStore().query();\n if (allOutcomes.length === 0) return undefined;\n\n const activeRoles = expertPerf.filter((e) => e.successRate > 0).length;\n const agentUtilization = expertPerf.length > 0 ? activeRoles / expertPerf.length : 0;\n\n const delegateOutcomes = allOutcomes.filter((o) => o.source === 'delegate');\n const delegateSuccesses = delegateOutcomes.filter((o) => o.success).length;\n const collaborationEfficiency =\n delegateOutcomes.length > 0 ? delegateSuccesses / delegateOutcomes.length : 0;\n\n let accurateCount = 0;\n let totalRouted = 0;\n let regretSum = 0;\n let observedCategories = 0;\n\n for (const category of TASK_CATEGORIES) {\n const catOutcomes = allOutcomes.filter((o) => o.category === category);\n if (catOutcomes.length < ROUTING_MIN_SAMPLES) continue;\n observedCategories++;\n const stats = analyzeCategoryRouting(catOutcomes);\n if (stats === null) continue;\n accurateCount += stats.accurateCount;\n totalRouted += stats.totalRouted;\n regretSum += stats.regret;\n }\n\n const regretCategories = totalRouted > 0 ? observedCategories : 0;\n return {\n agentUtilization: round3(agentUtilization),\n collaborationEfficiency: round3(collaborationEfficiency),\n routingAccuracy: round3(totalRouted > 0 ? accurateCount / totalRouted : 0),\n weeklyRegret: round3(regretCategories > 0 ? regretSum / regretCategories : 0),\n adaptationSpeed: Math.round(computeAdaptationSpeed()),\n observedCategories,\n observedRoles: expertPerf.length,\n };\n}\n\n/** Round to 3 decimal places. */\nfunction round3(n: number): number {\n return Math.round(n * 1000) / 1000;\n}\n\n/** Worker model prefix used by recordWorkerOutcomes (Issue #1323). */\nconst WORKER_MODEL_PREFIX = 'worker-';\n\n/** Finds the most common failure category among failed outcomes. */\nfunction findDominantError(\n failed: ReadonlyArray<{ failureCategory?: string | undefined }>\n): string | undefined {\n if (failed.length === 0) return undefined;\n const counts = new Map<string, number>();\n for (const f of failed) {\n const cat = f.failureCategory ?? 'execution';\n counts.set(cat, (counts.get(cat) ?? 0) + 1);\n }\n let maxCount = 0;\n let dominant: string | undefined;\n for (const [cat, count] of counts) {\n if (count > maxCount) {\n maxCount = count;\n dominant = cat;\n }\n }\n return dominant;\n}\n\n/** Count consecutive failures from the tail of an outcome list (Issue #1427). */\nfunction countTrailingFailures(outcomes: ReadonlyArray<{ success: boolean }>): number {\n let count = 0;\n for (let i = outcomes.length - 1; i >= 0; i--) {\n if (outcomes[i]?.success === false) {\n count++;\n } else {\n break;\n }\n }\n return count;\n}\n\n/** Builds per-expert-role performance from worker dispatch outcomes (Issue #1324, #1427). */\nfunction buildExpertPerformance(): readonly ExpertPerformanceEntry[] {\n const store = getOutcomeStore();\n const allOutcomes = store.query();\n const workerOutcomes = allOutcomes.filter((o) => o.model.startsWith(WORKER_MODEL_PREFIX));\n if (workerOutcomes.length === 0) return [];\n\n const byRole = new Map<string, typeof workerOutcomes>();\n for (const o of workerOutcomes) {\n const role = o.model.slice(WORKER_MODEL_PREFIX.length);\n const existing = byRole.get(role) ?? [];\n existing.push(o);\n byRole.set(role, existing);\n }\n\n const entries: ExpertPerformanceEntry[] = [];\n for (const [role, outcomes] of byRole) {\n const successes = outcomes.filter((o) => o.success).length;\n const totalDuration = outcomes.reduce((s, o) => s + o.durationMs, 0);\n const dominantErrorPattern = findDominantError(outcomes.filter((o) => !o.success));\n const successRate = successes / outcomes.length;\n\n // Count consecutive failures from the tail of history (Issue #1427)\n const consecutiveFailures = countTrailingFailures(outcomes);\n\n // Find last success timestamp\n const lastSuccess = [...outcomes].reverse().find((o) => o.success);\n const lastSuccessAt =\n lastSuccess !== undefined ? new Date(lastSuccess.timestamp).toISOString() : undefined;\n\n entries.push({\n role,\n totalTasks: outcomes.length,\n successRate,\n avgDurationMs: Math.round(totalDuration / outcomes.length),\n consecutiveFailures,\n degraded: successRate < 0.5,\n ...(dominantErrorPattern !== undefined ? { dominantErrorPattern } : {}),\n ...(lastSuccessAt !== undefined ? { lastSuccessAt } : {}),\n });\n }\n\n // Sort by reliability (worst first) per Issue #1427\n return entries.sort((a, b) => a.successRate - b.successRate);\n}\n\n/** Builds failure breakdown from failed outcomes (Issue #1025). */\nfunction buildFailureBreakdown(input: WeatherReportOptions): readonly FailureBreakdownEntry[] {\n const store = getOutcomeStore();\n const outcomes = store.query(buildQuery(input.cli, input.category));\n const failed = outcomes.filter((o) => !o.success);\n if (failed.length === 0) return [];\n\n const counts = new Map<string, number>();\n for (const o of failed) {\n // Retroactive reclassification for pre-#1441 entries missing failureCategory\n const cat =\n o.failureCategory ??\n (typeof o.errorMessage === 'string' && o.errorMessage.length > 0\n ? categorizeOutcomeErrorMessage(o.errorMessage)\n : 'execution');\n counts.set(cat, (counts.get(cat) ?? 0) + 1);\n }\n\n const entries: FailureBreakdownEntry[] = [];\n for (const [category, count] of counts) {\n entries.push({\n category,\n count,\n percentage: Math.round((count / failed.length) * 1000) / 10,\n });\n }\n return entries.sort((a, b) => b.count - a.count);\n}\n\n/** Builds triage statistics from outcome data (#1506). */\nfunction buildTriageStats(input: WeatherReportOptions): TriageStats | undefined {\n const store = getOutcomeStore();\n const outcomes = store.query(buildQuery(input.cli, input.category));\n\n const retriedOutcomes = outcomes.filter(\n (o) => (o as Record<string, unknown>)['wasRetried'] === true\n );\n if (retriedOutcomes.length === 0) return undefined;\n\n const retrySuccesses = retriedOutcomes.filter((o) => o.success).length;\n const actionCounts = new Map<string, number>();\n for (const o of outcomes) {\n const action = (o as Record<string, unknown>)['triageAction'];\n if (typeof action === 'string') {\n actionCounts.set(action, (actionCounts.get(action) ?? 0) + 1);\n }\n }\n\n return {\n totalRetried: retriedOutcomes.length,\n retrySuccessRate: Math.round((retrySuccesses / retriedOutcomes.length) * 1000) / 1000,\n actionBreakdown: Array.from(actionCounts.entries())\n .map(([action, count]) => ({ action, count }))\n .sort((a, b) => b.count - a.count),\n };\n}\n\n/** Builds per-tool performance stats from recorded metrics (#1022). */\nfunction buildToolPerformance(): readonly ToolPerformanceEntry[] {\n return getToolStats().map((s) => ({\n toolName: s.toolName,\n totalCalls: s.totalCalls,\n successRate: Math.round(s.successRate * 1000) / 1000,\n avgDurationMs: Math.round(s.avgDurationMs),\n errorCount: s.errorCount,\n }));\n}\n\n/** Generates tier recommendations from outcome summary (#895). */\nfunction buildTierRecommendations(summary: PerformanceSummary): readonly TierRecommendationEntry[] {\n return generateTierRecommendations(summary).map((r) => ({\n category: r.category,\n direction: r.direction,\n currentTier: r.currentTier,\n recommendedTier: r.recommendedTier,\n successRate: r.successRate,\n sampleCount: r.sampleCount,\n reason: r.reason,\n }));\n}\n","/**\n * Weather Report Bonus Stage — converts adaptive bonuses into routing scores.\n *\n * Closes Gap 1 from Issue #1389: weather report recommendations now feed\n * back into the routing pipeline as stage score adjustments.\n *\n * @module cli-adapters/weather-bonus-stage\n * (Source: Issue #1389, Epic: close feedback loops)\n */\n\nimport type { CliName } from './types.js';\nimport type { TaskCategory } from '../config/task-specialization-types.js';\nimport { generateWeatherReport } from '../mcp/tools/weather-report.js';\nimport type { AdaptiveBonus } from '../mcp/tools/weather-report-types.js';\nimport { createLogger } from '../core/index.js';\n\nconst logger = createLogger({ component: 'weather-bonus-stage' });\n\n/** Minimum sample count before a bonus is considered reliable. */\nconst MIN_SAMPLE_COUNT = 5;\n\n/**\n * Convert weather report adaptive bonuses for a task category\n * into a routing stage score map.\n *\n * Returns a Map<CliName, number> suitable for merging with other stage scores.\n * Best-effort: returns empty map on any error.\n *\n * @param taskCategory - The detected task category\n * @returns Score map with adaptive bonus per CLI\n */\nexport function getWeatherBonusScores(taskCategory: TaskCategory): Map<CliName, number> {\n try {\n const report = generateWeatherReport({ includeAdaptive: true });\n return convertBonusesToScoreMap(report.adaptiveBonuses, taskCategory);\n } catch {\n logger.debug('Weather bonus stage skipped (best-effort)');\n return new Map();\n }\n}\n\n/**\n * Pure function: convert adaptive bonuses into a CLI score map.\n * Exported for testing.\n */\nexport function convertBonusesToScoreMap(\n bonuses: readonly AdaptiveBonus[],\n taskCategory: TaskCategory\n): Map<CliName, number> {\n const scores = new Map<CliName, number>();\n for (const bonus of bonuses) {\n if (bonus.category !== taskCategory) continue;\n if (bonus.sampleCount < MIN_SAMPLE_COUNT) continue;\n if (bonus.adaptiveBonus === 0) continue;\n scores.set(bonus.cli as CliName, bonus.adaptiveBonus);\n }\n if (scores.size > 0) {\n logger.debug('Weather bonus scores applied', {\n category: taskCategory,\n clis: [...scores.keys()],\n });\n }\n return scores;\n}\n","/* eslint-disable max-lines */\n/**\n * CompositeRouter pipeline stage execution functions.\n * @module cli-adapters/composite-router-stages\n */\nimport type { Result } from '../core/index.js';\nimport { ok, err } from '../core/index.js';\nimport type { ILogger } from '../core/index.js';\nimport {\n createSharedTaskAnalyzer,\n taskAnalysisResultToTaskProfile,\n type TaskProfile,\n} from '../core/index.js';\nimport type { CliName, CliTask } from './types.js';\nimport type { BudgetRouter } from './budget-router.js';\nimport type { TopsisRouter } from './topsis-router.js';\nimport type { LinUCBBandit } from './linucb-bandit.js';\nimport type { PreferenceRouter } from './preference-router.js';\nimport type { ZeroRouter } from './zero-router.js';\nimport type { LatencyTracker } from './latency-tracker.js';\nimport type { IRoutingMemory } from '../context/routing-memory.js';\nimport {\n CompositeRoutingError,\n type CompositeRouterConfigWithPreference,\n type PipelineResult,\n} from './composite-router-types.js';\nimport {\n ConfidenceCascadeStage,\n CapabilityMatchStage,\n QualityConstraintStage,\n ResourceStrategyStage,\n DistilledRuleStage,\n KnnRoutingStage,\n} from './routing/stages/index.js';\nimport { createRoutingContext, getRemainingCandidates } from './routing/router-stage.js';\nimport {\n cliTaskToTask,\n taskProfileToBanditContext,\n filterByPreferenceTier,\n applyBudgetFilter,\n applyTopsisRanking,\n applyZeroRouterFilter,\n defaultPreferenceStageResult,\n defaultZeroRouterStageResult,\n type PreferenceStageResult,\n type ZeroRouterStageResult,\n type PerformanceFloorEntry,\n} from './composite-router-helpers.js';\nimport { getWeatherBonusScores } from './weather-bonus-stage.js';\nimport { detectTaskCategory } from '../config/task-specialization.js';\nimport { getOutcomeStore } from '../orchestration/outcomes/outcome-store.js';\n\n/** Module-level singleton — SharedTaskAnalyzer is stateless, no need to re-instantiate per call. */\nconst sharedAnalyzer = createSharedTaskAnalyzer();\n\n/** Dependencies required for pipeline stage execution. */\nexport interface StageDependencies {\n config: CompositeRouterConfigWithPreference;\n logger: ILogger;\n cliNames: CliName[];\n budgetRouter: BudgetRouter | undefined;\n zeroRouter: ZeroRouter | undefined;\n preferenceRouter: PreferenceRouter | undefined;\n topsisRouter: TopsisRouter | undefined;\n linucbBandit: LinUCBBandit | undefined;\n latencyTracker: LatencyTracker | undefined;\n routingMemory: IRoutingMemory | undefined;\n /** Confidence cascade stage instance (Issue #755) */\n confidenceCascadeStage: ConfidenceCascadeStage | undefined;\n /** Capability match stage instance (Issue #755) */\n capabilityMatchStage: CapabilityMatchStage | undefined;\n /** Quality constraint stage instance (Issue #755) */\n qualityConstraintStage: QualityConstraintStage | undefined;\n /** Resource strategy stage instance (Issue #998) */\n resourceStrategyStage: ResourceStrategyStage | undefined;\n /** Distilled rule stage instance (Issue #999) */\n distilledRuleStage: DistilledRuleStage | undefined;\n /** KNN routing stage instance (arXiv:2507.05370) */\n knnRoutingStage: KnnRoutingStage | undefined;\n}\n\n/** Result from budget stage including rejection tracking. */\nexport interface BudgetStageResult {\n candidates: CliName[];\n withinBudget: boolean | undefined;\n rejected: boolean;\n}\n\n/** Analyzes task and returns profile, updating stages array. */\nexport function analyzeTaskProfile(task: CliTask, stagesExecuted: string[]): TaskProfile {\n const internalTask = cliTaskToTask(task);\n const analysis = sharedAnalyzer.analyze(internalTask);\n stagesExecuted.push('task-analysis');\n return taskAnalysisResultToTaskProfile(analysis);\n}\n\n/** Runs budget filtering stage. */\nexport function runBudgetStage(\n task: CliTask,\n candidates: CliName[],\n stagesExecuted: string[],\n deps: StageDependencies\n): Result<{ candidates: CliName[]; withinBudget: boolean | undefined }, CompositeRoutingError> {\n if (!deps.config.enableBudgetFilter || deps.budgetRouter === undefined) {\n return ok({ candidates, withinBudget: undefined });\n }\n const result = applyBudgetFilter(task, candidates, deps.budgetRouter, deps.config);\n stagesExecuted.push('budget-filter');\n if (result.eligible.length === 0) {\n return err(new CompositeRoutingError('No CLIs within budget', 'budget-filter'));\n }\n return ok({ candidates: result.eligible, withinBudget: result.withinBudget });\n}\n\n/** Default complexity when no signal is available. */\nconst DEFAULT_COMPLEXITY: ConfidenceCascadeStageResult['complexity'] = 'moderate';\n\n/** Extract complexity level from confidence cascade signals. */\nfunction extractComplexityFromSignals(\n signals: readonly string[]\n): 'simple' | 'moderate' | 'complex' {\n for (const s of signals) {\n if (s === 'confidence:complexity-simple') return 'simple';\n if (s === 'confidence:complexity-complex') return 'complex';\n if (s === 'confidence:complexity-moderate') return 'moderate';\n }\n return DEFAULT_COMPLEXITY;\n}\n\n/** Extract task type from capability match signals. */\nfunction extractTaskTypeFromSignals(signals: readonly string[]): string {\n for (const s of signals) {\n if (s.startsWith('capability:task-')) return s.slice('capability:task-'.length);\n }\n return 'general';\n}\n\n/** Extract best CLI from signals with a given prefix. */\nfunction extractBestCliFromSignals(\n signals: readonly string[],\n prefix: string\n): CliName | undefined {\n for (const s of signals) {\n if (s.startsWith(prefix)) return s.slice(prefix.length) as CliName;\n }\n return undefined;\n}\n\n/** Extract resource tier from signals. */\nfunction extractTierFromSignals(signals: readonly string[]): string {\n for (const s of signals) {\n if (s.startsWith('resource-strategy:tier=')) return s.slice('resource-strategy:tier='.length);\n }\n return 'balanced';\n}\n\n/** Count applied rules from distilled-rule signals. */\nfunction countAppliedRulesFromSignals(signals: readonly string[]): number {\n let count = 0;\n for (const s of signals) {\n if (s.startsWith('distilled-rule:applied=')) count++;\n }\n return count;\n}\n\n/** Confidence cascade stage result. (Issue #755) */\nexport interface ConfidenceCascadeStageResult {\n scores: Map<CliName, number>;\n complexity: 'simple' | 'moderate' | 'complex';\n shouldEscalate: boolean;\n}\n\n/** Default confidence cascade result. */\nconst DEFAULT_CASCADE_RESULT: ConfidenceCascadeStageResult = {\n scores: new Map(),\n complexity: DEFAULT_COMPLEXITY,\n shouldEscalate: false,\n};\n\n/** Runs confidence cascade stage. (Issue #755, #1350) */\nexport async function runConfidenceCascadeStage(\n task: CliTask,\n candidates: CliName[],\n stagesExecuted: string[],\n deps: StageDependencies\n): Promise<ConfidenceCascadeStageResult> {\n if (!deps.config.enableConfidenceCascade || deps.confidenceCascadeStage === undefined) {\n return DEFAULT_CASCADE_RESULT;\n }\n\n const ctx = createRoutingContext(task.content, candidates);\n const result = await deps.confidenceCascadeStage.route(ctx);\n stagesExecuted.push('confidence-cascade');\n\n if (!result.ok) {\n deps.logger.debug('Confidence cascade stage failed', { error: result.error.message });\n return DEFAULT_CASCADE_RESULT;\n }\n\n const { signals, scores } = result.value.context;\n const complexity = extractComplexityFromSignals(signals);\n const shouldEscalate = signals.includes('confidence:should-escalate');\n\n deps.logger.debug('Confidence cascade completed', {\n complexity,\n shouldEscalate,\n scoreCount: scores.size,\n });\n\n return { scores: new Map(scores), complexity, shouldEscalate };\n}\n\n/** Capability match stage result. (Issue #755) */\nexport interface CapabilityMatchStageResult {\n scores: Map<CliName, number>;\n taskType: string;\n bestCli: CliName | undefined;\n}\n\n/** Default capability match result. */\nconst DEFAULT_CAPABILITY_RESULT: CapabilityMatchStageResult = {\n scores: new Map(),\n taskType: 'general',\n bestCli: undefined,\n};\n\n/** Runs capability match stage. (Issue #755, #1350) */\nexport async function runCapabilityMatchStage(\n task: CliTask,\n candidates: CliName[],\n stagesExecuted: string[],\n deps: StageDependencies\n): Promise<CapabilityMatchStageResult> {\n if (!deps.config.enableCapabilityMatch || deps.capabilityMatchStage === undefined) {\n return DEFAULT_CAPABILITY_RESULT;\n }\n\n const ctx = createRoutingContext(task.content, candidates);\n const result = await deps.capabilityMatchStage.route(ctx);\n stagesExecuted.push('capability-match');\n\n if (!result.ok) {\n deps.logger.debug('Capability match stage failed', { error: result.error.message });\n return DEFAULT_CAPABILITY_RESULT;\n }\n\n const { signals, scores } = result.value.context;\n const taskType = extractTaskTypeFromSignals(signals);\n const bestCli = extractBestCliFromSignals(signals, 'capability:best-');\n\n deps.logger.debug('Capability match completed', {\n taskType,\n bestCli,\n scoreCount: scores.size,\n });\n\n return { scores: new Map(scores), taskType, bestCli };\n}\n\n/** Quality constraint stage result. (Issue #755) */\nexport interface QualityConstraintStageResult {\n eligible: CliName[];\n filtered: Map<CliName, string>;\n usedFallback: boolean;\n}\n\n/** Runs quality constraint stage. (Issue #755, #1350) */\nexport async function runQualityConstraintStage(\n candidates: CliName[],\n stagesExecuted: string[],\n deps: StageDependencies\n): Promise<QualityConstraintStageResult> {\n if (!deps.config.enableQualityConstraint || deps.qualityConstraintStage === undefined) {\n return { eligible: candidates, filtered: new Map(), usedFallback: false };\n }\n\n const ctx = createRoutingContext('', candidates);\n const result = await deps.qualityConstraintStage.route(ctx);\n stagesExecuted.push('quality-constraint');\n\n if (!result.ok) {\n deps.logger.debug('Quality constraint stage failed', { error: result.error.message });\n return { eligible: candidates, filtered: new Map(), usedFallback: false };\n }\n\n const remaining = getRemainingCandidates(result.value.context);\n const filtered = new Map(result.value.context.filtered);\n const usedFallback = result.value.context.signals.includes('quality:used-fallback');\n\n deps.logger.debug('Quality constraint completed', {\n eligible: remaining.length,\n filtered: filtered.size,\n usedFallback,\n });\n\n // If all candidates filtered, fall back to original set\n const eligible = remaining.length > 0 ? remaining : candidates;\n return { eligible, filtered, usedFallback: remaining.length === 0 || usedFallback };\n}\n\n/** Resource strategy stage result. (Issue #998) */\nexport interface ResourceStrategyStageResult {\n scores: Map<CliName, number>;\n tier: string;\n resourceLevel: number | undefined;\n}\n\n/** Default resource strategy result. */\nconst DEFAULT_RESOURCE_RESULT: ResourceStrategyStageResult = {\n scores: new Map(),\n tier: 'balanced',\n resourceLevel: undefined,\n};\n\n/** Runs resource strategy stage. (Issue #998, #1350) */\nexport async function runResourceStrategyStage(\n task: CliTask,\n candidates: CliName[],\n stagesExecuted: string[],\n deps: StageDependencies\n): Promise<ResourceStrategyStageResult> {\n if (!deps.config.enableResourceStrategy || deps.resourceStrategyStage === undefined) {\n return DEFAULT_RESOURCE_RESULT;\n }\n\n const ctx = createRoutingContext(task.content, candidates);\n const result = await deps.resourceStrategyStage.route(ctx);\n stagesExecuted.push('resource-strategy');\n\n if (!result.ok) {\n deps.logger.debug('Resource strategy stage failed', { error: result.error.message });\n return DEFAULT_RESOURCE_RESULT;\n }\n\n const { signals, scores } = result.value.context;\n const tier = extractTierFromSignals(signals);\n\n deps.logger.debug('Resource strategy completed', { tier, scoreCount: scores.size });\n\n return { scores: new Map(scores), tier, resourceLevel: undefined };\n}\n\n/** Distilled rule stage result. (Issue #999) */\nexport interface DistilledRuleStageResult {\n scores: Map<CliName, number>;\n rulesApplied: number;\n}\n\n/** Runs distilled rule stage. (Issue #999, #1350) */\nexport async function runDistilledRuleStage(\n task: CliTask,\n candidates: CliName[],\n stagesExecuted: string[],\n deps: StageDependencies\n): Promise<DistilledRuleStageResult> {\n if (!deps.config.enableStrategyDistillation || deps.distilledRuleStage === undefined) {\n return { scores: new Map(), rulesApplied: 0 };\n }\n\n const ctx = createRoutingContext(task.content, candidates);\n const result = await deps.distilledRuleStage.route(ctx);\n stagesExecuted.push('distilled-rule');\n\n if (!result.ok) {\n deps.logger.debug('Distilled rule stage failed', { error: result.error.message });\n return { scores: new Map(), rulesApplied: 0 };\n }\n\n const { signals, scores } = result.value.context;\n const rulesApplied = countAppliedRulesFromSignals(signals);\n\n deps.logger.debug('Distilled rule stage completed', { rulesApplied, scoreCount: scores.size });\n\n return { scores: new Map(scores), rulesApplied };\n}\n\n/** KNN routing stage result. (arXiv:2507.05370) */\nexport interface KnnRoutingStageResult {\n scores: Map<CliName, number>;\n hasExperience: boolean;\n}\n\n/** Runs KNN experience-based routing stage. (arXiv:2507.05370) */\nexport async function runKnnRoutingStage(\n task: CliTask,\n candidates: CliName[],\n stagesExecuted: string[],\n deps: StageDependencies\n): Promise<KnnRoutingStageResult> {\n if (!deps.config.enableKnnRouting || deps.knnRoutingStage === undefined) {\n return { scores: new Map(), hasExperience: false };\n }\n\n const ctx = createRoutingContext(task.content, candidates);\n const result = await deps.knnRoutingStage.route(ctx);\n stagesExecuted.push('knn-routing');\n\n if (!result.ok) {\n deps.logger.debug('KNN routing stage failed', { error: result.error.message });\n return { scores: new Map(), hasExperience: false };\n }\n\n const { signals, scores } = result.value.context;\n const hasExperience = signals.includes('knn:experience-matched');\n\n deps.logger.debug('KNN routing completed', { hasExperience, scoreCount: scores.size });\n\n return { scores: new Map(scores), hasExperience };\n}\n\n/** Runs ZeroRouter difficulty estimation stage. */\nexport function runZeroRouterStage(\n task: CliTask,\n candidates: CliName[],\n stagesExecuted: string[],\n deps: StageDependencies\n): ZeroRouterStageResult {\n if (!deps.config.enableZeroRouter || deps.zeroRouter === undefined) {\n return defaultZeroRouterStageResult(candidates);\n }\n\n const result = applyZeroRouterFilter(task, candidates, deps.zeroRouter);\n stagesExecuted.push('zero-router');\n\n deps.logger.debug('ZeroRouter applied', {\n level: result.difficultyEstimate?.level,\n tier: result.difficultyTier,\n score: result.difficultyEstimate?.aggregateScore.toFixed(3),\n candidatesAfter: result.filteredCandidates.length,\n });\n\n return result;\n}\n\n/** Builds per-CLI performance data for the given task category from the outcome store.\n * Returns empty map if category is unknown or store is empty. (#1401) */\nfunction getPerformanceDataForCategory(taskContent: string): Map<CliName, PerformanceFloorEntry> {\n try {\n const match = detectTaskCategory(taskContent);\n if (match === null) return new Map();\n const summary = getOutcomeStore().summarize({ category: match.category });\n const result = new Map<CliName, PerformanceFloorEntry>();\n for (const [cli, stats] of summary.byCli) {\n result.set(cli as CliName, {\n successRate: stats.successRate,\n sampleCount: stats.count,\n });\n }\n return result;\n } catch {\n return new Map();\n }\n}\n\n/** Runs TOPSIS ranking stage. Uses plan billing criteria when billingMode is 'plan'.\n * When stageScores are provided, adjusts quality profiles before evaluation. (#1354)\n * When performance floor data is available, penalizes underperforming CLIs. (#1401) */\nexport function runTopsisStage(\n taskProfile: TaskProfile,\n candidates: CliName[],\n stagesExecuted: string[],\n deps: StageDependencies,\n options?: {\n stageScores?: ReadonlyMap<CliName, number>;\n performanceData?: ReadonlyMap<CliName, PerformanceFloorEntry>;\n }\n): { ranking: CliName[]; score: number | undefined } {\n if (!deps.config.enableTopsisRanking || deps.topsisRouter === undefined) {\n return { ranking: candidates, score: undefined };\n }\n const topsisOptions: Parameters<typeof applyTopsisRanking>[3] = {\n billingMode: deps.config.billingMode,\n };\n if (options?.stageScores !== undefined) topsisOptions.stageScores = options.stageScores;\n if (options?.performanceData !== undefined)\n topsisOptions.performanceData = options.performanceData;\n const result = applyTopsisRanking(taskProfile, candidates, deps.topsisRouter, topsisOptions);\n stagesExecuted.push('topsis-ranking');\n return { ranking: result.ranking, score: result.topScore };\n}\n\n/** Runs LinUCB bandit selection stage. */\nexport function runLinUCBStage(\n taskProfile: TaskProfile,\n topsisRanking: CliName[],\n stagesExecuted: string[],\n deps: StageDependencies\n): { selectedCli: CliName | undefined; ucbScore: number | undefined } {\n if (!deps.config.enableLinUCBSelection || deps.linucbBandit === undefined) {\n return { selectedCli: topsisRanking[0], ucbScore: undefined };\n }\n const banditContext = taskProfileToBanditContext(taskProfile);\n const selection = deps.linucbBandit.select(banditContext);\n stagesExecuted.push('linucb-selection');\n return { selectedCli: selection.armName as CliName, ucbScore: selection.ucbScore };\n}\n\n/** Runs preference routing stage. */\nexport function runPreferenceStage(\n task: CliTask,\n candidates: CliName[],\n stagesExecuted: string[],\n deps: StageDependencies\n): PreferenceStageResult {\n if (!deps.config.enablePreferenceRouting || deps.preferenceRouter === undefined) {\n return defaultPreferenceStageResult(candidates);\n }\n if (!deps.preferenceRouter.hasMinimumData()) {\n deps.logger.debug('Preference routing skipped: insufficient data');\n return defaultPreferenceStageResult(candidates);\n }\n\n const decision = deps.preferenceRouter.route(task.content);\n stagesExecuted.push('preference-routing');\n const preferredCandidates = filterByPreferenceTier(candidates, decision.selectedTier);\n\n deps.logger.debug('Preference routing applied', {\n tier: decision.selectedTier,\n probability: decision.prediction.strongModelProbability,\n candidatesAfter: preferredCandidates.length,\n });\n\n return {\n preferenceScore: decision.prediction.strongModelProbability,\n preferenceTier: decision.selectedTier,\n preferredCandidates: preferredCandidates.length > 0 ? preferredCandidates : candidates,\n };\n}\n\n/** Latency scoring stage result. (Issue #361) */\nexport interface LatencyStageResult {\n latencyScore: number | undefined;\n latencyAdjustedRanking: CliName[];\n}\n\n/** Runs latency scoring stage. (Issue #361) */\nexport function runLatencyStage(\n candidates: CliName[],\n stagesExecuted: string[],\n deps: StageDependencies\n): LatencyStageResult {\n if (!deps.config.enableLatencyTracking || deps.latencyTracker === undefined) {\n return { latencyScore: undefined, latencyAdjustedRanking: candidates };\n }\n\n const scores = deps.latencyTracker.getScores(candidates);\n stagesExecuted.push('latency-scoring');\n\n // Sort candidates by latency score (higher is better/faster)\n const sortedCandidates = [...candidates].sort((a, b) => {\n const scoreA = scores.find((s) => s.cli === a)?.score ?? 0;\n const scoreB = scores.find((s) => s.cli === b)?.score ?? 0;\n return scoreB - scoreA;\n });\n\n const topScore = scores.find((s) => s.cli === sortedCandidates[0])?.score;\n\n deps.logger.debug('Latency scoring applied', {\n scores: scores.map((s) => ({\n cli: s.cli,\n score: s.score.toFixed(3),\n reliable: s.hasReliableData,\n })),\n topCandidate: sortedCandidates[0],\n });\n\n return {\n latencyScore: topScore,\n latencyAdjustedRanking: sortedCandidates,\n };\n}\n\n/** Routing memory stage result. (Issue #489) */\nexport interface RoutingMemoryStageResult {\n recommendation: CliName | undefined;\n memoryConfidence: number | undefined;\n}\n\n/** Runs routing memory stage to get learned recommendation. (Issue #489) */\nexport function runRoutingMemoryStage(\n task: CliTask,\n candidates: CliName[],\n stagesExecuted: string[],\n deps: StageDependencies\n): RoutingMemoryStageResult {\n if (!deps.config.enableRoutingMemory || deps.routingMemory === undefined) {\n return { recommendation: undefined, memoryConfidence: undefined };\n }\n\n const taskType = inferTaskTypeFromContent(task.content);\n const recommendation = deps.routingMemory.getRecommendation(taskType);\n stagesExecuted.push('routing-memory');\n\n if (recommendation !== undefined && candidates.includes(recommendation)) {\n deps.logger.debug('Routing memory recommendation', {\n taskType,\n recommended: recommendation,\n inCandidates: true,\n });\n return { recommendation, memoryConfidence: 0.8 };\n }\n\n deps.logger.debug('Routing memory: no recommendation or not in candidates', {\n taskType,\n recommended: recommendation,\n candidateCount: candidates.length,\n });\n return { recommendation: undefined, memoryConfidence: undefined };\n}\n\n/** Task type keywords mapping for routing memory. */\nconst TASK_TYPE_KEYWORDS: ReadonlyArray<readonly [string, ReadonlyArray<string>]> = [\n ['coding', ['code', 'implement']],\n ['review', ['review', 'audit']],\n ['testing', ['test', 'spec']],\n ['documentation', ['document', 'explain']],\n ['refactoring', ['refactor']],\n ['debugging', ['debug', 'fix']],\n];\n\n/** Infer task type from content for routing memory lookup. */\nfunction inferTaskTypeFromContent(content: string): string {\n const lower = content.toLowerCase();\n for (const [taskType, keywords] of TASK_TYPE_KEYWORDS) {\n if (keywords.some((kw) => lower.includes(kw))) return taskType;\n }\n return 'general';\n}\n\n/** Merge multiple score maps into a single aggregated map. */\nfunction mergeScoreMaps(\n ...maps: ReadonlyArray<ReadonlyMap<CliName, number>>\n): Map<CliName, number> {\n const merged = new Map<CliName, number>();\n for (const m of maps) {\n for (const [cli, score] of m) {\n merged.set(cli, (merged.get(cli) ?? 0) + score);\n }\n }\n return merged;\n}\n\n/** Runs scoring stages (priorities 10-55) and returns intermediate results. */\nasync function runScoringStages(\n task: CliTask,\n candidates: CliName[],\n stagesExecuted: string[],\n deps: StageDependencies\n): Promise<{\n cascadeResult: ConfidenceCascadeStageResult;\n memoryResult: RoutingMemoryStageResult;\n capResult: CapabilityMatchStageResult;\n knnResult: KnnRoutingStageResult;\n zeroResult: ZeroRouterStageResult;\n distilledResult: DistilledRuleStageResult;\n prefResult: PreferenceStageResult;\n resourceResult: ResourceStrategyStageResult;\n candidates: CliName[];\n}> {\n const cascadeResult = await runConfidenceCascadeStage(task, candidates, stagesExecuted, deps);\n const memoryResult = runRoutingMemoryStage(task, candidates, stagesExecuted, deps);\n const capResult = await runCapabilityMatchStage(task, candidates, stagesExecuted, deps);\n const knnResult = await runKnnRoutingStage(task, candidates, stagesExecuted, deps);\n const zeroResult = runZeroRouterStage(task, candidates, stagesExecuted, deps);\n let filtered = zeroResult.filteredCandidates;\n const distilledResult = await runDistilledRuleStage(task, filtered, stagesExecuted, deps);\n const prefResult = runPreferenceStage(task, filtered, stagesExecuted, deps);\n filtered = prefResult.preferredCandidates;\n const resourceResult = await runResourceStrategyStage(task, filtered, stagesExecuted, deps);\n return {\n cascadeResult,\n memoryResult,\n capResult,\n knnResult,\n zeroResult,\n distilledResult,\n prefResult,\n resourceResult,\n candidates: filtered,\n };\n}\n\n/** Aggregates scores from scoring stages + weather bonuses for TOPSIS. (#1354, #1389) */\nfunction aggregateStageScores(\n scoring: Awaited<ReturnType<typeof runScoringStages>>,\n taskContent: string\n): Map<CliName, number> {\n const weatherScores = getWeatherBonusForTask(taskContent);\n return mergeScoreMaps(\n scoring.cascadeResult.scores,\n scoring.capResult.scores,\n scoring.knnResult.scores,\n scoring.distilledResult.scores,\n scoring.resourceResult.scores,\n weatherScores\n );\n}\n\n/** Best-effort weather bonus lookup for a task. */\nfunction getWeatherBonusForTask(taskContent: string): Map<CliName, number> {\n try {\n const match = detectTaskCategory(taskContent);\n if (match === null) return new Map();\n return getWeatherBonusScores(match.category);\n } catch {\n return new Map();\n }\n}\n\n/** Apply quality constraints and return filtered candidates or error (#1686). */\nasync function applyQualityConstraints(\n candidates: CliName[],\n stagesExecuted: string[],\n deps: StageDependencies\n): Promise<\n Result<\n { candidates: CliName[]; qualityResult: QualityConstraintStageResult },\n CompositeRoutingError\n >\n> {\n const qualityResult = await runQualityConstraintStage(candidates, stagesExecuted, deps);\n if (qualityResult.eligible.length === 0) {\n return err(\n new CompositeRoutingError('All candidates rejected by quality constraints', 'selection')\n );\n }\n return ok({ candidates: qualityResult.eligible, qualityResult });\n}\n\n/** Override LinUCB selection if the chosen CLI is below performance floor (#1790). */\nfunction applyLinUCBFloorOverride(\n linucbCli: CliName,\n topsisRanking: CliName[],\n opts: {\n perfData?: ReadonlyMap<CliName, PerformanceFloorEntry> | undefined;\n taskType: string;\n stagesExecuted: string[];\n }\n): CliName {\n if (opts.perfData === undefined) return linucbCli;\n const cliPerf = opts.perfData.get(linucbCli);\n if (cliPerf === undefined || cliPerf.sampleCount < 20 || cliPerf.successRate >= 0.5) {\n return linucbCli;\n }\n const topsisTop = topsisRanking[0];\n if (topsisTop === undefined || topsisTop === linucbCli) return linucbCli;\n opts.stagesExecuted.push('perf-floor-override');\n return topsisTop;\n}\n\n/** Executes full pipeline and returns result. (Made async in Issue #1350) */\n// eslint-disable-next-line max-lines-per-function -- routing pipeline is a cohesive sequence\nexport async function runPipeline(\n task: CliTask,\n taskProfile: TaskProfile,\n stagesExecuted: string[],\n cliNames: CliName[],\n deps: StageDependencies\n): Promise<Result<PipelineResult, CompositeRoutingError>> {\n let candidates: CliName[] = [...cliNames];\n if (candidates.length === 0) {\n return err(new CompositeRoutingError('No CLI adapters available', 'initialization'));\n }\n\n const budgetResult = runBudgetStage(task, candidates, stagesExecuted, deps);\n if (!budgetResult.ok) return budgetResult;\n candidates = budgetResult.value.candidates;\n const withinBudget = budgetResult.value.withinBudget;\n\n const scoring = await runScoringStages(task, candidates, stagesExecuted, deps);\n candidates = scoring.candidates;\n\n // Constraint-first: quality constraints filter BEFORE TOPSIS/LinUCB (#1686)\n const constrained = await applyQualityConstraints(candidates, stagesExecuted, deps);\n if (!constrained.ok) return constrained;\n candidates = constrained.value.candidates;\n const stageScores = aggregateStageScores(scoring, task.content);\n const topsisOpts: Parameters<typeof runTopsisStage>[4] = {\n performanceData: getPerformanceDataForCategory(task.content),\n };\n if (stageScores.size > 0) topsisOpts.stageScores = stageScores;\n const topsisResult = runTopsisStage(taskProfile, candidates, stagesExecuted, deps, topsisOpts);\n\n const linucbResult = runLinUCBStage(taskProfile, topsisResult.ranking, stagesExecuted, deps);\n if (linucbResult.selectedCli === undefined) {\n return err(new CompositeRoutingError('No candidates available', 'selection'));\n }\n\n // Performance floor override: reject LinUCB selection if CLI is below floor (#1790)\n const effectiveSelection = applyLinUCBFloorOverride(\n linucbResult.selectedCli,\n topsisResult.ranking,\n {\n perfData: topsisOpts.performanceData,\n taskType: taskProfile.taskType,\n stagesExecuted,\n }\n );\n\n const latencyResult = runLatencyStage(candidates, stagesExecuted, deps);\n const selectedCli = selectWithMemoryInfluence(effectiveSelection, scoring.memoryResult, deps);\n\n return ok(\n buildPipelineResult({\n ...scoring,\n qualityResult: constrained.value.qualityResult,\n topsisResult,\n linucbResult: { ucbScore: linucbResult.ucbScore },\n latencyResult,\n withinBudget,\n selectedCli,\n })\n );\n}\n\n/** Intermediate params for pipeline result construction. */\ninterface PipelineResultParams {\n cascadeResult: ConfidenceCascadeStageResult;\n capResult: CapabilityMatchStageResult;\n knnResult: KnnRoutingStageResult;\n distilledResult: DistilledRuleStageResult;\n resourceResult: ResourceStrategyStageResult;\n qualityResult: QualityConstraintStageResult;\n zeroResult: ZeroRouterStageResult;\n prefResult: PreferenceStageResult;\n topsisResult: { ranking: CliName[]; score: number | undefined };\n linucbResult: { ucbScore: number | undefined };\n latencyResult: LatencyStageResult;\n memoryResult: RoutingMemoryStageResult;\n withinBudget: boolean | undefined;\n selectedCli: CliName;\n}\n\n/** Assemble PipelineResult from stage outputs, including async stage scores. */\nfunction buildPipelineResult(p: PipelineResultParams): PipelineResult {\n const stageScores = mergeScoreMaps(\n p.cascadeResult.scores,\n p.capResult.scores,\n p.knnResult.scores,\n p.distilledResult.scores,\n p.resourceResult.scores\n );\n\n return {\n candidates: p.qualityResult.eligible,\n withinBudget: p.withinBudget,\n difficultyEstimate: p.zeroResult.difficultyEstimate,\n difficultyTier: p.zeroResult.difficultyTier,\n preferenceScore: p.prefResult.preferenceScore,\n preferenceTier: p.prefResult.preferenceTier,\n topsisRanking: p.topsisResult.ranking,\n topsisScore: p.topsisResult.score,\n selectedCli: p.selectedCli,\n ucbScore: p.linucbResult.ucbScore,\n latencyScore: p.latencyResult.latencyScore,\n memoryRecommendation: p.memoryResult.recommendation,\n memoryConfidence: p.memoryResult.memoryConfidence,\n ...(stageScores.size > 0 ? { stageScores } : {}),\n ...(p.cascadeResult.complexity !== DEFAULT_COMPLEXITY\n ? { cascadeComplexity: p.cascadeResult.complexity }\n : {}),\n ...(p.capResult.taskType !== 'general' ? { capabilityTaskType: p.capResult.taskType } : {}),\n ...(p.qualityResult.filtered.size > 0 ? { qualityFiltered: p.qualityResult.filtered } : {}),\n ...(p.resourceResult.tier !== 'balanced' ? { resourceTier: p.resourceResult.tier } : {}),\n ...(p.distilledResult.rulesApplied > 0\n ? { distilledRulesApplied: p.distilledResult.rulesApplied }\n : {}),\n };\n}\n\n/** Select CLI with optional memory influence. (Issue #489) */\nfunction selectWithMemoryInfluence(\n linucbSelection: CliName,\n memoryResult: RoutingMemoryStageResult,\n deps: StageDependencies\n): CliName {\n // If routing memory has a high-confidence recommendation, use it.\n // Threshold must exceed the default memoryConfidence (0.8) to prevent\n // routing memory from always overriding LinUCB learning. (#1171)\n if (memoryResult.recommendation !== undefined && memoryResult.memoryConfidence !== undefined) {\n const confidenceThreshold = 0.85;\n if (memoryResult.memoryConfidence >= confidenceThreshold) {\n deps.logger.debug('Using routing memory recommendation', {\n memoryChoice: memoryResult.recommendation,\n linucbChoice: linucbSelection,\n confidence: memoryResult.memoryConfidence,\n });\n return memoryResult.recommendation;\n }\n }\n return linucbSelection;\n}\n","/**\n * CompositeRouter outcome recording functions.\n * @module cli-adapters/composite-router-outcome\n */\nimport {\n getErrorMessage,\n type ILogger,\n createLogger,\n createSharedTaskAnalyzer,\n taskAnalysisResultToBanditContext,\n} from '../core/index.js';\nimport type { CliName, CliTask } from './types.js';\nimport type { LinUCBBandit } from './linucb-bandit.js';\nimport type { PreferenceRouter } from './preference-router.js';\nimport type { IZeroRouter } from './zero-router.js';\nimport { cliTaskToTask, buildDifficultyOutcome } from './composite-router-helpers.js';\nimport { getOutcomeStore } from '../orchestration/outcomes/outcome-store.js';\nimport { clamp01 } from '../utils/math-utils.js';\n\n/** Module-level singleton — SharedTaskAnalyzer is stateless. */\nconst sharedAnalyzer = createSharedTaskAnalyzer();\n\n/** Last routed task info for difficulty outcome recording. */\nexport interface LastRoutedTaskInfo {\n task: CliTask;\n selectedCli: CliName;\n difficulty: number;\n}\n\n/** Dependencies required for outcome recording. */\nexport interface OutcomeDependencies {\n logger: ILogger;\n cliNames: CliName[];\n linucbBandit: LinUCBBandit | undefined;\n preferenceRouter: PreferenceRouter | undefined;\n zeroRouter: IZeroRouter | undefined;\n lastRoutedTask: LastRoutedTaskInfo | undefined;\n}\n\n/** Records a bandit outcome for the given CLI. */\nexport function recordBanditOutcome(\n cliName: CliName,\n task: CliTask,\n reward: number,\n deps: OutcomeDependencies\n): void {\n if (deps.linucbBandit === undefined) return;\n const armIndex = deps.cliNames.indexOf(cliName);\n if (armIndex === -1) {\n deps.logger.warn('Unknown CLI for outcome recording', { cliName });\n return;\n }\n const internalTask = cliTaskToTask(task);\n const analysis = sharedAnalyzer.analyze(internalTask);\n const context = taskAnalysisResultToBanditContext(analysis);\n deps.linucbBandit.update(armIndex, context, reward);\n deps.logger.debug('Recorded outcome', { cliName, reward });\n}\n\n/** Records a preference signal for the preference router. */\nexport function recordPreferenceSignal(\n query: string,\n strongModelPreferred: boolean,\n quality: { strong?: number; weak?: number } | undefined,\n deps: OutcomeDependencies\n): void {\n if (deps.preferenceRouter === undefined) {\n deps.logger.warn('Preference routing not enabled, cannot record preference');\n return;\n }\n deps.preferenceRouter.recordPreference(\n query,\n strongModelPreferred,\n quality?.strong,\n quality?.weak\n );\n deps.logger.debug('Recorded preference', { strongModelPreferred });\n}\n\n/** Gets difficulty info for a task, using cached value if available. */\nexport function getDifficultyInfo(\n task: CliTask,\n deps: OutcomeDependencies\n): { difficulty: number; selectedCli: CliName } {\n if (deps.lastRoutedTask?.task.content === task.content) {\n return {\n difficulty: deps.lastRoutedTask.difficulty,\n selectedCli: deps.lastRoutedTask.selectedCli,\n };\n }\n if (deps.zeroRouter === undefined) {\n return { difficulty: 0.5, selectedCli: 'claude' };\n }\n const estimate = deps.zeroRouter.estimateDifficulty(task);\n return { difficulty: estimate.aggregateScore, selectedCli: 'claude' };\n}\n\n/** Records a difficulty outcome for ZeroRouter calibration. */\nexport function recordZeroRouterOutcome(\n task: CliTask,\n success: boolean,\n qualityScore: number | undefined,\n deps: OutcomeDependencies\n): void {\n if (deps.zeroRouter === undefined) {\n deps.logger.debug('ZeroRouter not enabled, skipping difficulty outcome');\n return;\n }\n const { difficulty, selectedCli } = getDifficultyInfo(task, deps);\n const outcome = buildDifficultyOutcome(\n task.content,\n difficulty,\n selectedCli,\n success,\n qualityScore\n );\n deps.zeroRouter.calibrate(outcome);\n deps.logger.debug('Recorded difficulty outcome', {\n difficulty: difficulty.toFixed(3),\n success,\n qualityScore,\n });\n}\n\n/** Checks if preference router has minimum data for routing. */\nexport function hasMinimumPreferenceData(deps: OutcomeDependencies): boolean {\n if (deps.preferenceRouter === undefined) return false;\n return deps.preferenceRouter.hasMinimumData();\n}\n\n// ============================================================================\n// Quality-Enriched Rewards (Issue #929)\n// ============================================================================\n\n/** Number of recent outcomes to consider for quality calculation. */\nconst QUALITY_HISTORY_LIMIT = 20;\n\n/** Maximum latency (ms) for normalization in reward calculation. */\nconst MAX_LATENCY_MS = 30_000;\n\n/**\n * Computes a quality-enriched reward using OutcomeStore history.\n *\n * Instead of binary 1/0 rewards, produces continuous rewards (0.1-0.8)\n * that incorporate historical success rate and latency. This enables\n * LinUCB to learn more nuanced model preferences.\n *\n * @param cli - CLI that executed the task\n * @param success - Whether the task succeeded\n * @param durationMs - Task execution duration in ms\n * @returns Reward value in [0, 1] range\n */\nexport function computeQualityReward(cli: CliName, success: boolean, durationMs: number): number {\n if (!success) return 0.1;\n\n let reward = 0.5;\n\n try {\n const recent = getOutcomeStore().query({ cli, limit: QUALITY_HISTORY_LIMIT });\n if (recent.length > 0) {\n const rate = recent.filter((o) => o.success).length / recent.length;\n reward += rate * 0.3;\n }\n } catch (error: unknown) {\n createLogger({ component: 'composite-router' }).warn(\n 'Failed to query outcome store for quality reward',\n {\n error: getErrorMessage(error),\n cli,\n }\n );\n }\n\n const latencyPenalty = Math.min(0.2, (durationMs / MAX_LATENCY_MS) * 0.2);\n reward -= latencyPenalty;\n\n return clamp01(reward);\n}\n","/**\n * CompositeRouter Metrics Helpers\n *\n * Helper functions for recording routing metrics.\n * Extracted from composite-router.ts to reduce file size.\n *\n * @module cli-adapters/composite-router-metrics\n * (Source: Issue #559 - Wire RoutingMetricsCollector to CompositeRouter)\n */\n\nimport type { ILogger } from '../core/index.js';\nimport { getTimeProvider, getRandomProvider } from '../core/index.js';\nimport type { CliName } from './types.js';\nimport type {\n CompositeRoutingDecision,\n IRoutingMetricsCollector,\n} from './composite-router-types.js';\n\n/**\n * Options for recording a routing outcome.\n */\nexport interface RecordOutcomeOptions {\n readonly traceId: string;\n readonly cliName: CliName;\n readonly success: boolean;\n readonly reward: number;\n readonly qualityScore?: number;\n readonly latencyMs?: number;\n}\n\n/**\n * Dependencies for metrics recording functions.\n */\nexport interface MetricsRecordingDeps {\n readonly metricsCollector: IRoutingMetricsCollector | undefined;\n readonly logger: ILogger;\n}\n\n/**\n * Records a routing decision to the metrics collector.\n *\n * @param decision - The routing decision to record\n * @param traceId - Unique trace ID for correlation\n * @param deps - Dependencies (metrics collector and logger)\n */\nexport function recordDecisionToMetrics(\n decision: CompositeRoutingDecision,\n traceId: string,\n deps: MetricsRecordingDeps\n): void {\n if (deps.metricsCollector === undefined) return;\n\n deps.metricsCollector.recordDecision({\n timestamp: getTimeProvider().nowIso(),\n traceId,\n selectedModel: decision.cliName,\n alternativeModels: decision.alternatives,\n isExploration: decision.ucbScore !== undefined && decision.ucbScore > 0.5,\n taskType: decision.taskProfile.taskType,\n contextTokens: decision.taskProfile.contextRequired,\n routingLatencyMs: decision.decisionTimeMs,\n });\n\n deps.logger.debug('Recorded routing decision to metrics', {\n traceId,\n selectedModel: decision.cliName,\n });\n}\n\n/**\n * Records an outcome to the metrics collector.\n *\n * @param opts - Outcome options\n * @param deps - Dependencies (metrics collector and logger)\n */\nexport function recordOutcomeToMetrics(\n opts: RecordOutcomeOptions,\n deps: MetricsRecordingDeps\n): void {\n if (deps.metricsCollector === undefined) return;\n\n // Build record inline with conditional spread for readonly interface\n deps.metricsCollector.recordOutcome({\n timestamp: getTimeProvider().nowIso(),\n traceId: opts.traceId,\n model: opts.cliName,\n success: opts.success,\n reward: opts.reward,\n ...(opts.qualityScore !== undefined && { qualityScore: opts.qualityScore }),\n ...(opts.latencyMs !== undefined && { latencyMs: opts.latencyMs }),\n });\n\n deps.logger.debug('Recorded outcome to metrics', {\n traceId: opts.traceId,\n model: opts.cliName,\n success: opts.success,\n reward: opts.reward,\n });\n}\n\n/**\n * Generates a unique trace ID for metrics correlation.\n *\n * @returns A unique trace ID string\n */\nexport function generateTraceId(): string {\n return `rt-${String(getTimeProvider().now())}-${getRandomProvider().random().toString(36).slice(2, 8)}`;\n}\n","/* eslint-disable max-lines */\n/**\n * CompositeRouter: Chains Budget -> ZeroRouter -> Preference -> TOPSIS -> LinUCB.\n * @module cli-adapters/composite-router\n * (Source: Issue #166, Epic #164, Issue #347, arXiv:2509.07571)\n */\nimport type { Result } from '../core/index.js';\nimport {\n getErrorMessage,\n ok,\n err,\n createLogger,\n getTimeProvider,\n getRandomProvider,\n} from '../core/index.js';\n\nimport type { ILogger } from '../core/index.js';\nimport type { ICliAdapter, CliName, CliTask, CliResponse, CliError } from './types.js';\nimport type {\n IOrchestrationObserver,\n RoutingDecision,\n} from '../agents/observability/orchestration-observer-types.js';\nimport { BudgetRouter } from './budget-router.js';\nimport { TopsisRouter } from './topsis-router.js';\nimport { LinUCBBandit } from './linucb-bandit.js';\nimport { PreferenceRouter } from './preference-router.js';\nimport type { PreferenceRouterConfig } from './preference-router-types.js';\nimport { ZeroRouter, type IZeroRouter } from './zero-router.js';\nimport type { ZeroRouterConfig } from './zero-router-types.js';\nimport { LatencyTracker, type ILatencyTracker } from './latency-tracker.js';\nimport type { LatencyTrackerConfig } from './latency-tracker-types.js';\nimport {\n RoutingMemory,\n type IRoutingMemory,\n type RoutingMemoryConfig,\n type ModelPerformance,\n} from '../context/routing-memory.js';\nimport {\n ConfidenceCascadeStage,\n CapabilityMatchStage,\n QualityConstraintStage,\n ResourceStrategyStage,\n DistilledRuleStage,\n KnnRoutingStage,\n type ConfidenceCascadeConfig,\n type CapabilityMatchConfig,\n type QualityConstraintConfig,\n type ResourceStrategyConfig,\n type DistilledRuleStageConfig,\n} from './routing/stages/index.js';\nimport {\n StrategyDistiller,\n createPersistentDistillerOrFallback,\n} from '../learning/strategy-distiller.js';\nimport { getOutcomeStore } from '../orchestration/outcomes/outcome-store.js';\nimport { isPersistenceEnabled } from '../config/learning-persistence.js';\nimport { getPipelineEventBus } from '../pipeline/event-bus.js';\nimport { generateSyntheticPriors, runWarmUp } from '../cli/warm-up.js';\nimport {\n CompositeRouterConfigSchema,\n CompositeRoutingError,\n type CompositeRouterConfig,\n type CompositeRouterConfigWithPreference,\n type CompositeRoutingDecision,\n type CompositeRouterStats,\n type BuildDecisionParams,\n type PipelineResult,\n type IRoutingMetricsCollector,\n} from './composite-router-types.js';\nimport {\n buildDecisionFields,\n buildPreferenceStats,\n fetchCapacityData,\n} from './composite-router-helpers.js';\nimport {\n analyzeTaskProfile,\n runPipeline,\n type StageDependencies,\n} from './composite-router-stages.js';\nimport {\n recordBanditOutcome,\n recordPreferenceSignal,\n recordZeroRouterOutcome,\n hasMinimumPreferenceData,\n computeQualityReward,\n type LastRoutedTaskInfo,\n type OutcomeDependencies,\n} from './composite-router-outcome.js';\nimport {\n recordDecisionToMetrics,\n recordOutcomeToMetrics,\n generateTraceId,\n} from './composite-router-metrics.js';\n\n// Re-export types for consumers\nexport {\n CompositeRouterConfigSchema,\n DEFAULT_COMPOSITE_CONFIG,\n CompositeRoutingError,\n type CompositeRouterConfig,\n type CompositeRouterConfigWithPreference,\n type CompositeRoutingDecision,\n type CompositeRouterStats,\n type IRoutingMetricsCollector,\n} from './composite-router-types.js';\n\n/** Quality score assigned to failed routing decisions for memory recording. */\nconst FAILURE_QUALITY_SCORE = 0.3;\n\n/** Default token count estimate when task.maxTokens is not specified. */\nconst DEFAULT_TOKEN_ESTIMATE = 1000;\n\n/** Composite router interface for dependency injection. */\nexport interface ICompositeRouter {\n route(task: CliTask): Promise<Result<CompositeRoutingDecision, CompositeRoutingError>>;\n executeTask(task: CliTask): Promise<Result<CliResponse, CliError | CompositeRoutingError>>;\n recordOutcome(cliName: CliName, task: CliTask, reward: number): void;\n recordPreference(\n query: string,\n strongPreferred: boolean,\n quality?: { strong?: number; weak?: number }\n ): void;\n recordDifficultyOutcome(task: CliTask, success: boolean, qualityScore?: number): void;\n getStats(): CompositeRouterStats;\n hasMinimumPreferenceData(): boolean;\n getZeroRouter(): IZeroRouter | undefined;\n getLatencyTracker(): ILatencyTracker | undefined;\n getRoutingMemory(): IRoutingMemory | undefined;\n /** Get the metrics collector (if configured) (Issue #559) */\n getMetricsCollector(): IRoutingMetricsCollector | undefined;\n /** Get the orchestration observer (if configured) (Issue #587) */\n getOrchestrationObserver(): IOrchestrationObserver | undefined;\n /** Get capacity status for all registered CLIs (Issue #807) */\n getCapacityDashboard(): Promise<Map<CliName, import('./types.js').CapacityStatus>>;\n}\n\n/** CompositeRouter implementation. */\nexport class CompositeRouter implements ICompositeRouter {\n private readonly config: CompositeRouterConfig;\n private readonly logger: ILogger;\n private readonly adapters: Map<CliName, ICliAdapter>;\n private budgetRouter?: BudgetRouter;\n private zeroRouter?: ZeroRouter;\n private preferenceRouter?: PreferenceRouter;\n private topsisRouter?: TopsisRouter;\n private linucbBandit?: LinUCBBandit;\n private latencyTracker?: LatencyTracker;\n private routingMemory?: RoutingMemory;\n /** Metrics collector for routing observability (Issue #559) */\n private metricsCollector?: IRoutingMetricsCollector;\n /** Orchestration observer for routing decision tracking (Issue #587) */\n private orchestrationObserver?: IOrchestrationObserver;\n /** Confidence cascade stage instance (Issue #755) */\n private confidenceCascadeStage?: ConfidenceCascadeStage;\n /** Capability match stage instance (Issue #755) */\n private capabilityMatchStage?: CapabilityMatchStage;\n /** Quality constraint stage instance (Issue #755) */\n private qualityConstraintStage?: QualityConstraintStage;\n /** Resource strategy stage instance (Issue #998) */\n private resourceStrategyStage?: ResourceStrategyStage;\n /** Distilled rule stage instance (Issue #999) */\n private distilledRuleStage?: DistilledRuleStage;\n /** KNN routing stage instance (arXiv:2507.05370) */\n private knnRoutingStage?: KnnRoutingStage;\n /** Strategy distiller instance (Issue #999) */\n private strategyDistiller?: StrategyDistiller;\n private readonly cliNames: CliName[];\n\n // Statistics tracking\n private totalDecisions = 0;\n private decisionsPerCli: Record<CliName, number> = {\n claude: 0,\n gemini: 0,\n codex: 0,\n opencode: 0,\n };\n private totalDecisionTimeMs = 0;\n private budgetRejections = 0;\n\n // Track last routing for difficulty outcome recording\n private lastRoutedTask?: LastRoutedTaskInfo;\n\n // Track last traceId for metrics correlation (Issue #559)\n private lastTraceId?: string;\n\n constructor(\n adapters: Map<CliName, ICliAdapter>,\n config?: Partial<CompositeRouterConfigWithPreference>,\n logger?: ILogger\n ) {\n const {\n preferenceRouterConfig,\n zeroRouterConfig,\n latencyTrackerConfig,\n routingMemoryConfig,\n confidenceCascadeConfig,\n capabilityMatchConfig,\n qualityConstraintConfig,\n resourceStrategyConfig,\n distilledRuleStageConfig,\n metricsCollector,\n orchestrationObserver,\n ...baseConfig\n } = config ?? {};\n this.config = CompositeRouterConfigSchema.parse(baseConfig);\n this.logger = logger ?? createLogger({ component: 'CompositeRouter' });\n this.adapters = adapters;\n this.cliNames = Array.from(adapters.keys());\n // Only assign metricsCollector if provided (Issue #559)\n if (metricsCollector !== undefined) {\n this.metricsCollector = metricsCollector;\n }\n // Only assign orchestrationObserver if provided (Issue #587)\n if (orchestrationObserver !== undefined) {\n this.orchestrationObserver = orchestrationObserver;\n this.logger.debug('OrchestrationObserver wired to CompositeRouter');\n }\n this.initializeCoreRouters(\n adapters,\n preferenceRouterConfig,\n zeroRouterConfig,\n latencyTrackerConfig\n );\n this.initializeMemoryAndStages(routingMemoryConfig, {\n confidenceCascade: confidenceCascadeConfig,\n capabilityMatch: capabilityMatchConfig,\n qualityConstraint: qualityConstraintConfig,\n resourceStrategy: resourceStrategyConfig,\n distilledRule: distilledRuleStageConfig,\n });\n this.logInitialization(adapters.size);\n }\n\n private initializeCoreRouters(\n adapters: Map<CliName, ICliAdapter>,\n preferenceConfig?: Partial<PreferenceRouterConfig>,\n zeroConfig?: Partial<ZeroRouterConfig>,\n latencyConfig?: Partial<LatencyTrackerConfig>\n ): void {\n if (this.config.enableBudgetFilter && adapters.size > 0) {\n this.budgetRouter = new BudgetRouter(adapters);\n }\n if (this.config.enableZeroRouter) this.zeroRouter = new ZeroRouter(zeroConfig, this.logger);\n if (this.config.enablePreferenceRouting)\n this.preferenceRouter = new PreferenceRouter(preferenceConfig);\n if (this.config.enableTopsisRanking) this.topsisRouter = new TopsisRouter();\n if (this.config.enableLinUCBSelection && this.cliNames.length > 0) {\n this.linucbBandit = new LinUCBBandit(this.cliNames, { alpha: this.config.linucbAlpha });\n this.warmStartBandit();\n }\n if (this.config.enableLatencyTracking) this.latencyTracker = new LatencyTracker(latencyConfig);\n }\n\n private initializeMemoryAndStages(\n routingMemoryConfig?: Partial<RoutingMemoryConfig>,\n stageConfigs?: {\n confidenceCascade?: Partial<ConfidenceCascadeConfig> | undefined;\n capabilityMatch?: Partial<CapabilityMatchConfig> | undefined;\n qualityConstraint?: Partial<QualityConstraintConfig> | undefined;\n resourceStrategy?: Partial<ResourceStrategyConfig> | undefined;\n distilledRule?: Partial<DistilledRuleStageConfig> | undefined;\n }\n ): void {\n if (this.config.enableRoutingMemory) {\n this.routingMemory = new RoutingMemory(routingMemoryConfig);\n this.logger.info('RoutingMemory enabled for learned routing', {\n minObservations: this.routingMemory.getStats().totalPreferences,\n });\n }\n if (this.config.enableKnnRouting && this.routingMemory !== undefined) {\n this.knnRoutingStage = new KnnRoutingStage(this.routingMemory);\n }\n this.initializeOptionalStages(stageConfigs);\n }\n\n private initializeOptionalStages(\n stageConfigs: {\n confidenceCascade?: Partial<ConfidenceCascadeConfig> | undefined;\n capabilityMatch?: Partial<CapabilityMatchConfig> | undefined;\n qualityConstraint?: Partial<QualityConstraintConfig> | undefined;\n resourceStrategy?: Partial<ResourceStrategyConfig> | undefined;\n distilledRule?: Partial<DistilledRuleStageConfig> | undefined;\n } = {}\n ): void {\n if (this.config.enableConfidenceCascade) {\n this.confidenceCascadeStage = new ConfidenceCascadeStage(stageConfigs.confidenceCascade);\n }\n if (this.config.enableCapabilityMatch) {\n this.capabilityMatchStage = new CapabilityMatchStage(stageConfigs.capabilityMatch);\n }\n if (this.config.enableQualityConstraint) {\n this.qualityConstraintStage = new QualityConstraintStage(stageConfigs.qualityConstraint);\n }\n if (this.config.enableResourceStrategy) {\n this.resourceStrategyStage = new ResourceStrategyStage(stageConfigs.resourceStrategy);\n }\n if (this.config.enableStrategyDistillation) {\n this.strategyDistiller = isPersistenceEnabled()\n ? createPersistentDistillerOrFallback(getOutcomeStore(), this.logger)\n : new StrategyDistiller(getOutcomeStore(), this.logger);\n this.distilledRuleStage = new DistilledRuleStage(\n this.strategyDistiller,\n stageConfigs.distilledRule\n );\n }\n }\n\n /** Emit routing.decision event to pipeline event bus (#1687). */\n private emitRoutingDecision(decision: CompositeRoutingDecision, taskDescription: string): void {\n getPipelineEventBus().emit({\n type: 'routing.decision',\n timestamp: getTimeProvider().now(),\n taskId: taskDescription.slice(0, 100),\n selectedModel: decision.cliName,\n reasoning: decision.reason,\n decisionPath: decision.stagesExecuted,\n });\n }\n\n /** Warm-start LinUCB bandit from persisted outcomes (Issue #1015).\n * Uses a 30-day lookback window so stale outcomes don't override\n * routing changes like primaryCli specialization (#1667). */\n private warmStartBandit(): void {\n if (this.linucbBandit === undefined) return;\n try {\n let replayed = 0;\n if (isPersistenceEnabled()) {\n // Use 30-day lookback — stale all-time data was overriding\n // specialization matrix changes (e.g., architecture claude→gemini) (#1667)\n const WARM_START_LOOKBACK_MS = 30 * 24 * 60 * 60 * 1000;\n const since = new Date(getTimeProvider().now() - WARM_START_LOOKBACK_MS).toISOString();\n const outcomes = getOutcomeStore().query({\n since,\n excludeQualitySignals: ['e2e-eval'],\n });\n if (outcomes.length > 0) {\n replayed = this.linucbBandit.warmStart(outcomes);\n this.logger.info('LinUCB warm-started from recent outcomes', {\n outcomesAvailable: outcomes.length,\n outcomesReplayed: replayed,\n lookbackDays: 30,\n });\n }\n }\n // Always seed specialization priors — not just cold-start (#1667).\n // This ensures primaryCli preferences from TASK_SPECIALIZATION_MATRIX\n // always influence LinUCB, even when warm-start data disagrees.\n const priors = generateSyntheticPriors();\n this.linucbBandit.seedPriors(priors, replayed === 0 ? 3 : 1);\n if (replayed === 0) {\n const result = runWarmUp(this.logger);\n if (!result.skipped) {\n const outcomes = getOutcomeStore().query();\n this.linucbBandit.warmStart(outcomes);\n }\n this.logger.info('LinUCB cold-start seeded from specialization matrix', {\n syntheticOutcomes: result.seeded,\n });\n }\n } catch (error: unknown) {\n this.logger.warn('LinUCB warm-start failed, starting cold', {\n error: getErrorMessage(error),\n });\n }\n }\n\n private logInitialization(adapterCount: number): void {\n this.logger.info('CompositeRouter initialized', {\n adapterCount,\n enableBudget: this.config.enableBudgetFilter,\n enableZeroRouter: this.config.enableZeroRouter,\n enablePreference: this.config.enablePreferenceRouting,\n enableTopsis: this.config.enableTopsisRanking,\n enableLinUCB: this.config.enableLinUCBSelection,\n enableLatencyTracking: this.config.enableLatencyTracking,\n enableConfidenceCascade: this.config.enableConfidenceCascade,\n enableCapabilityMatch: this.config.enableCapabilityMatch,\n enableQualityConstraint: this.config.enableQualityConstraint,\n enableResourceStrategy: this.config.enableResourceStrategy,\n enableStrategyDistillation: this.config.enableStrategyDistillation,\n });\n }\n\n async route(task: CliTask): Promise<Result<CompositeRoutingDecision, CompositeRoutingError>> {\n const result = await this.executeRouting(task, getTimeProvider().now());\n // Emit routing.decision to pipeline event bus for trace persistence (#1687)\n if (result.ok) {\n this.emitRoutingDecision(result.value, task.content);\n }\n return result;\n }\n\n /**\n * Unified method that routes, executes, and auto-records feedback.\n * Use this for most cases; use route() when you need decision details without execution.\n *\n * @param task - Task to execute\n * @returns Result with CLI response or error\n */\n async executeTask(task: CliTask): Promise<Result<CliResponse, CliError | CompositeRoutingError>> {\n const routeResult = await this.route(task);\n if (!routeResult.ok) {\n return err(routeResult.error);\n }\n\n const decision = routeResult.value;\n const startTime = getTimeProvider().now();\n\n // Generate traceId for metrics correlation (Issue #559)\n const traceId = generateTraceId();\n this.lastTraceId = traceId;\n recordDecisionToMetrics(decision, traceId, {\n metricsCollector: this.metricsCollector,\n logger: this.logger,\n });\n\n // Record routing decision to orchestration observer (Issue #587)\n this.recordToOrchestrationObserver(decision, task);\n\n const executeResult = await decision.adapter.execute(task);\n\n const durationMs = getTimeProvider().now() - startTime;\n const success = executeResult.ok;\n\n // Auto-record feedback for learning systems\n this.autoRecordFeedback(decision, task, success, durationMs);\n\n return executeResult;\n }\n\n private autoRecordFeedback(\n decision: CompositeRoutingDecision,\n task: CliTask,\n success: boolean,\n durationMs: number\n ): void {\n // Record bandit outcome with quality-enriched reward (Issue #929)\n const reward = computeQualityReward(decision.cliName, success, durationMs);\n this.recordOutcome(decision.cliName, task, reward);\n\n // Record difficulty outcome for ZeroRouter learning\n this.recordDifficultyOutcome(task, success);\n\n // Record latency for latency-based routing (Issue #361)\n if (this.latencyTracker !== undefined) {\n this.latencyTracker.record(decision.cliName, durationMs, success);\n }\n\n // Record performance in routing memory for learned routing (Issue #463)\n if (this.routingMemory !== undefined) {\n const taskType = this.inferTaskType(task);\n const performance: ModelPerformance = {\n avgQuality: success ? decision.confidence : FAILURE_QUALITY_SCORE,\n successRate: success ? 1.0 : 0.0,\n avgLatencyMs: durationMs,\n avgTokens: task.maxTokens ?? DEFAULT_TOKEN_ESTIMATE,\n observations: 1,\n };\n this.routingMemory.storePreference(decision.cliName, taskType, performance);\n }\n\n // Record outcome to metrics collector (Issue #559)\n if (this.lastTraceId !== undefined) {\n recordOutcomeToMetrics(\n {\n traceId: this.lastTraceId,\n cliName: decision.cliName,\n success,\n reward,\n qualityScore: success ? decision.confidence : FAILURE_QUALITY_SCORE,\n latencyMs: durationMs,\n },\n { metricsCollector: this.metricsCollector, logger: this.logger }\n );\n }\n\n this.logger.debug('Auto-recorded feedback', {\n cli: decision.cliName,\n success,\n durationMs,\n reward,\n });\n }\n\n /** Task type inference keywords. */\n private static readonly TASK_TYPE_KEYWORDS: ReadonlyArray<\n readonly [string, ReadonlyArray<string>]\n > = [\n ['coding', ['code', 'implement']],\n ['review', ['review', 'audit']],\n ['testing', ['test', 'spec']],\n ['documentation', ['document', 'explain']],\n ['refactoring', ['refactor']],\n ['debugging', ['debug', 'fix']],\n ];\n\n /**\n * Infer task type from task content for routing memory.\n */\n private inferTaskType(task: CliTask): string {\n const content = task.content.toLowerCase();\n for (const [taskType, keywords] of CompositeRouter.TASK_TYPE_KEYWORDS) {\n if (keywords.some((kw) => content.includes(kw))) return taskType;\n }\n return 'general';\n }\n\n private async executeRouting(\n task: CliTask,\n startTime: number\n ): Promise<Result<CompositeRoutingDecision, CompositeRoutingError>> {\n const stagesExecuted: string[] = [];\n try {\n const taskProfile = analyzeTaskProfile(task, stagesExecuted);\n const deps = this.getStageDependencies();\n const pipelineResult = await runPipeline(\n task,\n taskProfile,\n stagesExecuted,\n this.cliNames,\n deps\n );\n if (!pipelineResult.ok) {\n if (pipelineResult.error.stage === 'budget-filter') this.budgetRejections++;\n return pipelineResult;\n }\n\n this.trackLastRoutedTask(task, pipelineResult.value);\n\n return this.buildRoutingDecision({\n ...pipelineResult.value,\n taskProfile,\n stagesExecuted,\n startTime,\n });\n } catch (error: unknown) {\n return this.handleRoutingError(error, stagesExecuted);\n }\n }\n\n private getStageDependencies(): StageDependencies {\n return {\n config: this.config,\n logger: this.logger,\n cliNames: this.cliNames,\n budgetRouter: this.budgetRouter,\n zeroRouter: this.zeroRouter,\n preferenceRouter: this.preferenceRouter,\n topsisRouter: this.topsisRouter,\n linucbBandit: this.linucbBandit,\n latencyTracker: this.latencyTracker,\n routingMemory: this.routingMemory,\n // Issue #755 replacement stages\n confidenceCascadeStage: this.confidenceCascadeStage,\n capabilityMatchStage: this.capabilityMatchStage,\n qualityConstraintStage: this.qualityConstraintStage,\n // Issue #998 resource strategy\n resourceStrategyStage: this.resourceStrategyStage,\n // Issue #999 distilled rule stage\n distilledRuleStage: this.distilledRuleStage,\n // arXiv:2507.05370 KNN routing\n knnRoutingStage: this.knnRoutingStage,\n };\n }\n\n private trackLastRoutedTask(task: CliTask, result: PipelineResult): void {\n if (result.difficultyEstimate !== undefined) {\n this.lastRoutedTask = {\n task,\n selectedCli: result.selectedCli,\n difficulty: result.difficultyEstimate.aggregateScore,\n };\n }\n }\n\n private buildRoutingDecision(\n params: BuildDecisionParams & PipelineResult\n ): Result<CompositeRoutingDecision, CompositeRoutingError> {\n const selectedAdapter = this.adapters.get(params.selectedCli);\n if (selectedAdapter === undefined) {\n return err(\n new CompositeRoutingError('Adapter not found: ' + params.selectedCli, 'selection')\n );\n }\n\n const decisionTimeMs = getTimeProvider().now() - params.startTime;\n this.updateStats(params.selectedCli, decisionTimeMs);\n const { confidence, reason, alternatives } = buildDecisionFields({ ...params, decisionTimeMs });\n\n return ok({\n adapter: selectedAdapter,\n cliName: params.selectedCli,\n confidence,\n reason,\n stagesExecuted: params.stagesExecuted,\n decisionTimeMs,\n withinBudget: params.withinBudget,\n difficultyEstimate: params.difficultyEstimate,\n difficultyTier: params.difficultyTier,\n preferenceScore: params.preferenceScore,\n preferenceTier: params.preferenceTier,\n topsisScore: params.topsisScore,\n ucbScore: params.ucbScore,\n latencyScore: params.latencyScore,\n alternatives,\n taskProfile: params.taskProfile,\n });\n }\n\n private updateStats(selectedCli: CliName, decisionTimeMs: number): void {\n this.totalDecisions++;\n this.decisionsPerCli[selectedCli]++;\n this.totalDecisionTimeMs += decisionTimeMs;\n }\n\n /**\n * Record a routing decision to the orchestration observer (Issue #587).\n */\n private recordToOrchestrationObserver(decision: CompositeRoutingDecision, task: CliTask): void {\n if (this.orchestrationObserver === undefined) {\n return;\n }\n\n // Convert CompositeRoutingDecision to RoutingDecision for observer\n const routingDecision: RoutingDecision = {\n timestamp: new Date().toISOString(),\n taskId: `task-${getRandomProvider().uuid()}`,\n taskDescription:\n task.content.length > 100 ? task.content.substring(0, 100) + '...' : task.content,\n selectedCli: decision.cliName,\n confidence: decision.confidence,\n reason: decision.reason,\n alternatives: decision.alternatives,\n stagesExecuted: decision.stagesExecuted,\n decisionTimeMs: decision.decisionTimeMs,\n withinBudget: decision.withinBudget,\n topsisScore: decision.topsisScore,\n ucbScore: decision.ucbScore,\n };\n\n this.orchestrationObserver.recordRoutingDecision(routingDecision);\n this.logger.debug('Recorded routing decision to OrchestrationObserver', {\n cli: decision.cliName,\n confidence: decision.confidence,\n });\n }\n\n private handleRoutingError(\n error: unknown,\n stagesExecuted: string[]\n ): Result<CompositeRoutingDecision, CompositeRoutingError> {\n const stage = stagesExecuted[stagesExecuted.length - 1] ?? 'unknown';\n const msg = 'Routing failed: ' + getErrorMessage(error);\n return err(new CompositeRoutingError(msg, stage, error instanceof Error ? error : undefined));\n }\n\n recordOutcome(cliName: CliName, task: CliTask, reward: number): void {\n recordBanditOutcome(cliName, task, reward, this.getOutcomeDependencies());\n }\n\n recordPreference(\n query: string,\n strongModelPreferred: boolean,\n quality?: { strong?: number; weak?: number }\n ): void {\n recordPreferenceSignal(query, strongModelPreferred, quality, this.getOutcomeDependencies());\n }\n\n recordDifficultyOutcome(task: CliTask, success: boolean, qualityScore?: number): void {\n recordZeroRouterOutcome(task, success, qualityScore, this.getOutcomeDependencies());\n }\n\n hasMinimumPreferenceData(): boolean {\n return hasMinimumPreferenceData(this.getOutcomeDependencies());\n }\n\n private getOutcomeDependencies(): OutcomeDependencies {\n return {\n logger: this.logger,\n cliNames: this.cliNames,\n linucbBandit: this.linucbBandit,\n preferenceRouter: this.preferenceRouter,\n zeroRouter: this.zeroRouter,\n lastRoutedTask: this.lastRoutedTask,\n };\n }\n\n getZeroRouter(): IZeroRouter | undefined {\n return this.zeroRouter;\n }\n\n getLatencyTracker(): ILatencyTracker | undefined {\n return this.latencyTracker;\n }\n\n /**\n * Get the metrics collector (if configured).\n * (Source: Issue #559 - Wire RoutingMetricsCollector to CompositeRouter)\n */\n getMetricsCollector(): IRoutingMetricsCollector | undefined {\n return this.metricsCollector;\n }\n\n /**\n * Get the orchestration observer (if configured).\n * (Source: Issue #587 - Wire OrchestrationObserver to CompositeRouter)\n */\n getOrchestrationObserver(): IOrchestrationObserver | undefined {\n return this.orchestrationObserver;\n }\n\n /**\n * Get capacity status for all registered CLIs (Issue #807).\n */\n async getCapacityDashboard(): Promise<Map<CliName, import('./types.js').CapacityStatus>> {\n return fetchCapacityData(this.adapters);\n }\n\n getStats(): CompositeRouterStats {\n const preferenceStats = buildPreferenceStats(\n this.config.enablePreferenceRouting,\n this.preferenceRouter\n );\n const latencyStats = this.latencyTracker?.getTrackerStats();\n const routingMemoryStats = this.routingMemory?.getStats();\n const baseStats = {\n totalDecisions: this.totalDecisions,\n decisionsPerCli: { ...this.decisionsPerCli },\n avgDecisionTimeMs:\n this.totalDecisions > 0 ? this.totalDecisionTimeMs / this.totalDecisions : 0,\n budgetRejectionRate:\n this.totalDecisions > 0 ? this.budgetRejections / this.totalDecisions : 0,\n banditStats: this.linucbBandit?.getStats() ?? [],\n latencyStats,\n routingMemoryStats,\n };\n\n if (preferenceStats !== undefined) {\n return { ...baseStats, preferenceStats };\n }\n return baseStats;\n }\n\n /** Get the routing memory instance (if enabled). */\n getRoutingMemory(): IRoutingMemory | undefined {\n return this.routingMemory;\n }\n}\n\n/** Creates a CompositeRouter instance. */\nexport function createCompositeRouter(\n adapters: Map<CliName, ICliAdapter>,\n config?: Partial<CompositeRouterConfig>,\n logger?: ILogger\n): ICompositeRouter {\n return new CompositeRouter(adapters, config, logger);\n}\n","/**\n * nexus-agents/core - Model Adapter Types\n *\n * Unified interface for all model adapters (Claude, OpenAI, Gemini, Ollama).\n */\n\nimport type { Result } from '../result.js';\nimport type { ConfigError, ModelError } from '../errors.js';\n\n/**\n * Model capabilities supported by adapters.\n */\nexport const ModelCapability = {\n COMPLETION: 'completion',\n STREAMING: 'streaming',\n TOOL_USE: 'tool_use',\n VISION: 'vision',\n EXTENDED_THINKING: 'extended_thinking',\n} as const;\n\nexport type ModelCapability = (typeof ModelCapability)[keyof typeof ModelCapability];\n\n/**\n * Message role in a conversation.\n */\nexport type MessageRole = 'user' | 'assistant' | 'system';\n\n/**\n * Content block types in messages and responses.\n */\nexport type ContentBlock =\n | { type: 'text'; text: string }\n | { type: 'tool_use'; id: string; name: string; input: unknown }\n | { type: 'tool_result'; tool_use_id: string; content: string; is_error?: boolean }\n | { type: 'image'; source: { type: 'base64'; media_type: string; data: string } };\n\n/**\n * Message in a conversation.\n */\nexport interface Message {\n role: MessageRole;\n content: string | ContentBlock[];\n}\n\n/**\n * Tool definition for function calling.\n */\nexport interface ToolDefinition {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n}\n\n/**\n * Response format specification.\n *\n * @remarks\n * Adapter support (Issue #470):\n * - **OpenAI**: Full support for `json_object` and `json_schema`\n * - **Ollama**: Supports `json_object` and `json_schema` (passes schema directly)\n * - **Claude**: NOT SUPPORTED - Anthropic API lacks native JSON mode\n * - **Gemini**: NOT SUPPORTED - Google API lacks JSON format constraints\n *\n * For Claude/Gemini, use tool use or prompt engineering for structured output.\n */\nexport type ResponseFormat =\n | { type: 'text' }\n | { type: 'json_object' }\n | { type: 'json_schema'; schema: Record<string, unknown> };\n\n/**\n * Request to complete a conversation.\n */\nexport interface CompletionRequest {\n /** Conversation messages */\n messages: Message[];\n /** System prompt (if not included in messages) */\n systemPrompt?: string;\n /** Sampling temperature (0.0 - 1.0) */\n temperature?: number;\n /** Maximum tokens to generate */\n maxTokens?: number;\n /** Tools available for the model */\n tools?: ToolDefinition[];\n /**\n * Expected response format.\n *\n * @remarks\n * Only supported by OpenAI and Ollama adapters. Claude and Gemini\n * adapters will ignore this field. See {@link ResponseFormat} for details.\n */\n responseFormat?: ResponseFormat;\n /** Stop sequences */\n stop?: string[];\n}\n\n/**\n * Token usage statistics.\n */\nexport interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n}\n\n/**\n * Reason the model stopped generating.\n */\nexport type StopReason = 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use';\n\n/**\n * Response from a completion request.\n */\nexport interface CompletionResponse {\n /** Response content blocks */\n content: ContentBlock[];\n /** Token usage statistics */\n usage: TokenUsage;\n /** Reason generation stopped */\n stopReason: StopReason;\n /** Model that generated the response */\n model: string;\n}\n\n/**\n * Chunk from a streaming response.\n */\nexport type StreamChunk =\n | { type: 'content_block_start'; index: number; contentBlock: ContentBlock }\n | { type: 'content_block_delta'; index: number; delta: { type: 'text_delta'; text: string } }\n | { type: 'content_block_stop'; index: number }\n | { type: 'message_start'; message: { model: string } }\n | { type: 'message_delta'; delta: { stop_reason: StopReason }; usage: TokenUsage }\n | { type: 'message_stop' };\n\n/**\n * Unified interface for all model adapters.\n */\nexport interface IModelAdapter {\n /** Provider identifier (e.g., 'anthropic', 'openai') */\n readonly providerId: string;\n\n /** Model identifier (e.g., 'claude-sonnet-4', 'gpt-4o') */\n readonly modelId: string;\n\n /** Capabilities this model supports */\n readonly capabilities: readonly ModelCapability[];\n\n /**\n * Send a completion request.\n * @param request - The completion request\n * @returns Result with response or ModelError\n */\n complete(request: CompletionRequest): Promise<Result<CompletionResponse, ModelError>>;\n\n /**\n * Stream a completion request.\n * @param request - The completion request\n * @yields StreamChunk objects as they arrive\n */\n stream(request: CompletionRequest): AsyncIterable<StreamChunk>;\n\n /**\n * Count tokens in text.\n * @param text - Text to count tokens for\n * @returns Approximate token count\n */\n countTokens(text: string): Promise<number>;\n\n /**\n * Validate adapter configuration.\n * @returns Ok if valid, ConfigError if invalid\n */\n validateConfig(): Result<void, ConfigError>;\n}\n","/**\n * nexus-agents/core - Agent Types\n *\n * Base interface for all agents (TechLead, Experts, dynamic agents).\n */\n\nimport type { Result } from '../result.js';\nimport type { AgentError } from '../errors.js';\n\n/**\n * Agent state in the lifecycle.\n */\nexport type AgentState = 'idle' | 'thinking' | 'acting' | 'waiting' | 'error';\n\n/**\n * Predefined agent roles.\n *\n * @remarks\n * 'orchestrator' is the preferred name for the coordination agent (Issue #759).\n * 'tech_lead' is retained for backward compatibility but will be deprecated in v3.0.\n */\nexport type AgentRole =\n | 'orchestrator' // Preferred: Coordinates multi-agent workflows (Issue #759)\n | 'tech_lead' // @deprecated Use 'orchestrator' instead. Retained for backward compatibility.\n | 'code_expert'\n | 'architecture_expert'\n | 'security_expert'\n | 'documentation_expert'\n | 'testing_expert'\n | 'devops_expert'\n | 'research_expert'\n | 'pm_expert' // Product manager: requirements, user stories, acceptance criteria (Issue #902)\n | 'ux_expert' // UX designer: interaction design, usability, user journeys (Issue #902)\n | 'infrastructure_expert' // Physical server, bare metal, OOB management (Issue #1082)\n | 'qa_expert' // Quality assurance: code review, standards compliance, regression (#1684)\n | 'data_visualization_expert' // Data analysis, chart design, interactive visualizations\n | 'thinker' // TRINITY: High-level reasoning (arXiv:2512.04695)\n | 'worker' // TRINITY: Task execution\n | 'verifier' // TRINITY: Output validation\n | 'custom';\n\n/**\n * Role type for the orchestration/coordination agent.\n * Includes both 'orchestrator' (preferred) and 'tech_lead' (deprecated).\n */\nexport type OrchestratorRole = Extract<AgentRole, 'orchestrator' | 'tech_lead'>;\n\n/**\n * Agent capabilities.\n */\nexport const AgentCapability = {\n TASK_EXECUTION: 'task_execution',\n DELEGATION: 'delegation',\n COLLABORATION: 'collaboration',\n TOOL_USE: 'tool_use',\n CODE_GENERATION: 'code_generation',\n CODE_REVIEW: 'code_review',\n RESEARCH: 'research',\n} as const;\n\nexport type AgentCapability = (typeof AgentCapability)[keyof typeof AgentCapability];\n\n/**\n * Task context and constraints.\n */\nexport interface TaskContext {\n /** Working directory or scope */\n workingDirectory?: string;\n /** Relevant files */\n files?: string[];\n /** Previous messages in conversation */\n history?: TaskHistoryItem[];\n /** Additional metadata */\n metadata?: Record<string, unknown>;\n}\n\nexport interface TaskHistoryItem {\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: string;\n}\n\n/**\n * Constraints on task execution.\n *\n * @remarks\n * Enforcement status of each field (Issue #469):\n * - `maxDuration`: ENFORCED - Task times out after this duration\n * - `maxTokens`: INFORMATIONAL - Included in task context for agent awareness, not enforced\n * - `outputFormat`: DEPRECATED - Not enforced, will be removed in v3.0\n * - `allowedTools`: DEPRECATED - Not enforced, will be removed in v3.0\n */\nexport interface TaskConstraints {\n /** Maximum execution time in ms. ENFORCED via timeout mechanism. */\n maxDuration?: number;\n /**\n * Maximum tokens to use. INFORMATIONAL only - agents can see this but it's not enforced.\n * Use model adapter budgets for actual token enforcement.\n */\n maxTokens?: number;\n /**\n * Required output format.\n * @deprecated Not enforced. Will be removed in v3.0.\n * Use structured output patterns at the prompt level instead.\n */\n outputFormat?: 'text' | 'json' | 'markdown';\n /**\n * Allowed tools for this task.\n * @deprecated Not enforced. Will be removed in v3.0.\n * Use policy firewall rules for tool restrictions instead.\n */\n allowedTools?: string[];\n}\n\n/**\n * Task to be executed by an agent.\n */\nexport interface Task {\n /** Unique task identifier */\n id: string;\n /** Task description */\n description: string;\n /** Task context */\n context: TaskContext;\n /** Optional constraints. See {@link TaskConstraints} for enforcement status. */\n constraints?: TaskConstraints;\n /**\n * Priority (higher = more urgent).\n * INFORMATIONAL - Logged but not used for scheduling or execution order.\n */\n priority?: number;\n}\n\n/**\n * Metadata about task execution.\n */\nexport interface ResultMetadata {\n /** Execution duration in ms */\n durationMs: number;\n /** Tokens used */\n tokensUsed: number;\n /** Tools invoked */\n toolsUsed: string[];\n /** Model used */\n model: string;\n}\n\n/**\n * Result of task execution.\n */\nexport interface TaskResult {\n /** Task that was executed */\n taskId: string;\n /** Result output */\n output: unknown;\n /** Execution metadata */\n metadata: ResultMetadata;\n}\n\n/**\n * Inter-agent message types.\n */\nexport type AgentMessageType = 'task' | 'result' | 'query' | 'feedback' | 'status';\n\n/**\n * Message between agents.\n */\nexport interface AgentMessage {\n /** Unique message identifier */\n id: string;\n /** Sender agent ID */\n from: string;\n /** Recipient agent ID */\n to: string;\n /** Message type */\n type: AgentMessageType;\n /** Message payload */\n payload: unknown;\n /** Timestamp */\n timestamp: string;\n}\n\n/**\n * Response to an agent message.\n */\nexport interface AgentResponse {\n /** Original message ID */\n messageId: string;\n /** Response status */\n status: 'accepted' | 'rejected' | 'completed' | 'failed';\n /** Response data */\n data?: unknown;\n /** Error message if failed */\n error?: string;\n}\n\n/**\n * Context provided during agent initialization.\n */\nexport interface AgentContext {\n /** Agent configuration */\n config: AgentConfig;\n /** Available tools */\n tools?: string[];\n /** Shared memory/state */\n sharedState?: Record<string, unknown>;\n}\n\n/**\n * Agent configuration.\n */\nexport interface AgentConfig {\n /** Model to use */\n modelId: string;\n /** Temperature for generation */\n temperature?: number;\n /** System prompt */\n systemPrompt?: string;\n /** Maximum context tokens */\n maxContextTokens?: number;\n}\n\n/**\n * Base interface for all agents.\n */\nexport interface IAgent {\n /** Unique agent identifier */\n readonly id: string;\n\n /** Agent role */\n readonly role: AgentRole;\n\n /** Current state */\n readonly state: AgentState;\n\n /** Agent capabilities */\n readonly capabilities: readonly AgentCapability[];\n\n /**\n * Execute a task.\n * @param task - Task to execute\n * @returns Result with TaskResult or AgentError\n */\n execute(task: Task): Promise<Result<TaskResult, AgentError>>;\n\n /**\n * Handle an inter-agent message.\n * @param msg - Message to handle\n * @returns Result with AgentResponse or AgentError\n */\n handleMessage(msg: AgentMessage): Promise<Result<AgentResponse, AgentError>>;\n\n /**\n * Initialize the agent with context.\n * @param ctx - Agent context\n * @returns Result with void or AgentError\n */\n initialize(ctx: AgentContext): Promise<Result<void, AgentError>>;\n\n /**\n * Cleanup agent resources.\n */\n cleanup(): Promise<void>;\n}\n","/**\n * nexus-agents/core - Workflow Types\n *\n * Interface for workflow execution engine.\n */\n\nimport type { Result } from '../result.js';\nimport type { WorkflowError } from '../errors.js';\nimport type { AgentRole } from './agent.js';\n\n/**\n * Budget allocation for context categories.\n */\nexport interface ContextBudget {\n /** System instructions and project context (default: 15%) */\n system: number;\n /** Current task description and requirements (default: 20%) */\n task: number;\n /** Active working content (default: 50%) */\n active: number;\n /** Reserved for response generation (default: 15%) */\n reserved: number;\n}\n\n/**\n * Partial context budget for step-level overrides.\n */\nexport type PartialContextBudget = Partial<ContextBudget>;\n\n/**\n * Workflow input definition.\n */\nexport interface InputDefinition {\n /** Input name */\n name: string;\n /** Input type */\n type: 'string' | 'number' | 'boolean' | 'object' | 'array';\n /** Description */\n description?: string;\n /** Whether required */\n required?: boolean;\n /** Default value */\n default?: unknown;\n}\n\n/**\n * Single step in a workflow.\n */\nexport interface WorkflowStep {\n /** Unique step identifier */\n id: string;\n /** Agent role to execute this step */\n agent: AgentRole;\n /** Action to perform */\n action: string;\n /** Inputs for the step */\n inputs: Record<string, unknown>;\n /** Step dependencies (wait for these to complete) */\n dependsOn?: string[];\n /** Execute in parallel with dependencies */\n parallel?: boolean;\n /** Number of retry attempts */\n retries?: number;\n /** Timeout in ms */\n timeout?: number;\n /** Condition for execution */\n condition?: string;\n /** Step-specific context budget override (merges with workflow default) */\n contextBudget?: PartialContextBudget;\n}\n\n/**\n * Workflow definition (loaded from template).\n */\nexport interface WorkflowDefinition {\n /** Workflow name */\n name: string;\n /** Version */\n version: string;\n /** Description */\n description?: string;\n /** Input definitions */\n inputs: InputDefinition[];\n /** Workflow steps */\n steps: WorkflowStep[];\n /** Global timeout in ms */\n timeout?: number;\n /** Default context budget for workflow steps (individual steps can override) */\n defaultBudget?: ContextBudget;\n}\n\n/**\n * Result of step execution.\n */\nexport interface StepResult {\n /** Step ID */\n stepId: string;\n /** Step output */\n output: unknown;\n /** Duration in ms */\n durationMs: number;\n /** Status */\n status: 'success' | 'failed' | 'skipped';\n /** Error message if failed */\n error?: string;\n}\n\n/**\n * Result of workflow execution.\n */\nexport interface WorkflowResult {\n /** Execution ID */\n executionId: string;\n /** Workflow name */\n workflowName: string;\n /** Step results */\n stepResults: StepResult[];\n /** Final output */\n output: unknown;\n /** Total duration in ms */\n totalDurationMs: number;\n}\n\n/**\n * Workflow execution status.\n */\nexport type ExecutionStatus =\n | { state: 'pending' }\n | { state: 'running'; currentStep: string; progress: number }\n | { state: 'completed'; result: WorkflowResult }\n | { state: 'failed'; error: string; failedStep?: string }\n | { state: 'cancelled'; cancelledAt: string };\n\n/**\n * Workflow template metadata.\n */\nexport interface WorkflowTemplate {\n /** Template name */\n name: string;\n /** Version */\n version: string;\n /** Description */\n description?: string;\n /** File path */\n path: string;\n /** Category */\n category?: string;\n}\n\n/**\n * Parse error for workflow templates.\n */\nexport class ParseError extends Error {\n readonly line: number | undefined;\n readonly column: number | undefined;\n\n constructor(message: string, options?: { line?: number; column?: number }) {\n super(message);\n this.name = 'ParseError';\n this.line = options?.line;\n this.column = options?.column;\n }\n}\n\n/**\n * Workflow engine interface.\n */\nexport interface IWorkflowEngine {\n /**\n * Load workflow template from file.\n * @param path - Path to template file\n * @returns Result with WorkflowDefinition or ParseError\n */\n loadTemplate(path: string): Promise<Result<WorkflowDefinition, ParseError>>;\n\n /**\n * Execute a workflow with inputs.\n * @param workflow - Workflow definition\n * @param inputs - Input values\n * @returns Result with WorkflowResult or WorkflowError\n */\n execute(\n workflow: WorkflowDefinition,\n inputs: Record<string, unknown>\n ): Promise<Result<WorkflowResult, WorkflowError>>;\n\n /**\n * Get execution status.\n * @param executionId - Execution ID to check\n * @returns Current execution status\n */\n getStatus(executionId: string): ExecutionStatus;\n\n /**\n * Cancel a running workflow.\n * @param executionId - Execution ID to cancel\n * @returns Result with void or WorkflowError\n */\n cancel(executionId: string): Promise<Result<void, WorkflowError>>;\n\n /**\n * List available workflow templates.\n * @returns Array of available templates\n */\n listTemplates(): Promise<WorkflowTemplate[]>;\n\n /**\n * Get a built-in or registered template definition by name.\n * @param name - Template name (e.g., 'code-review')\n * @returns The workflow definition, or undefined if not found\n */\n getTemplateByName(name: string): Promise<WorkflowDefinition | undefined>;\n}\n","/**\n * nexus-agents/core - Orchestrator Types\n *\n * Unified interface for orchestration strategies.\n * Per System Mandate Loop I - Single canonical path for orchestration.\n *\n * Implementations:\n * - TechLead: LLM-based task decomposition and expert selection\n * - PuppeteerOrchestrator: Policy-based step execution with learning\n * - WorkflowEngine: Static template-based workflow execution\n *\n * @see docs/adr/0002-orchestrator-interface.md for decision rationale\n */\n\nimport type { Result } from '../result.js';\nimport type { IAgent, Task, AgentRole } from './agent.js';\nimport type { ExecutionStatus } from './workflow.js';\n\n/**\n * Orchestration strategy type.\n */\nexport type OrchestratorType = 'tech_lead' | 'puppeteer' | 'workflow' | 'custom';\n\n/**\n * Orchestrator execution options.\n */\nexport interface OrchestratorExecuteOptions {\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n /** Maximum execution time in ms */\n timeout?: number;\n /** Maximum number of steps/iterations */\n maxSteps?: number;\n /** Token budget for LLM calls */\n tokenBudget?: number;\n /** Callback for progress updates */\n onProgress?: (status: ExecutionStatus) => void;\n /** Additional metadata passed to orchestrator */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Orchestrator definition - the input that defines what to orchestrate.\n * This is a discriminated union to support different orchestration styles.\n */\nexport type OrchestratorDefinition =\n | { type: 'task'; task: Task }\n | { type: 'workflow'; templatePath: string }\n | { type: 'policy'; policyId: string; initialState: Record<string, unknown> };\n\n/**\n * Step in an orchestration execution.\n */\nexport interface OrchestratorStep {\n /** Step identifier */\n id: string;\n /** Agent that executed the step */\n agentId: string;\n /** Agent role */\n role: AgentRole;\n /** Step action/description */\n action: string;\n /** Step output */\n output: unknown;\n /** Duration in ms */\n durationMs: number;\n /** Tokens used in this step */\n tokensUsed: number;\n /** Status */\n status: 'success' | 'failed' | 'skipped';\n /** Error if failed */\n error: string | undefined;\n}\n\n/**\n * Result of orchestration execution.\n */\nexport interface OrchestratorResult {\n /** Unique execution ID */\n executionId: string;\n /** Orchestrator type that executed */\n orchestratorType: OrchestratorType;\n /** Steps executed */\n steps: OrchestratorStep[];\n /** Final aggregated output */\n output: unknown;\n /** Total execution time in ms */\n totalDurationMs: number;\n /** Total tokens consumed */\n totalTokensUsed: number;\n /** Agents involved */\n agentsUsed: string[];\n}\n\n/**\n * Orchestrator error with context.\n */\nexport class OrchestratorError extends Error {\n override readonly name = 'OrchestratorError' as const;\n readonly code: OrchestratorErrorCode;\n readonly step: string | undefined;\n override readonly cause: Error | undefined;\n\n constructor(\n message: string,\n code: OrchestratorErrorCode,\n options?: { step?: string; cause?: Error }\n ) {\n super(message);\n this.code = code;\n this.step = options?.step;\n this.cause = options?.cause;\n }\n}\n\n/**\n * Error codes for orchestrator failures.\n */\nexport type OrchestratorErrorCode =\n | 'TIMEOUT'\n | 'CANCELLED'\n | 'STEP_FAILED'\n | 'AGENT_ERROR'\n | 'BUDGET_EXCEEDED'\n | 'INVALID_DEFINITION'\n | 'NO_AGENTS_AVAILABLE'\n | 'POLICY_VIOLATION';\n\n/**\n * Unified orchestrator interface.\n *\n * This interface provides a canonical path for all orchestration\n * in the system, regardless of the underlying strategy.\n *\n * @example\n * ```typescript\n * const orchestrator: IOrchestrator = factory.create('tech_lead');\n *\n * const result = await orchestrator.execute(\n * { type: 'task', task: myTask },\n * { timeout: 30000 }\n * );\n *\n * if (result.ok) {\n * console.log('Output:', result.value.output);\n * }\n * ```\n */\nexport interface IOrchestrator {\n /** Unique orchestrator instance ID */\n readonly id: string;\n\n /** Orchestrator type */\n readonly type: OrchestratorType;\n\n /**\n * Execute an orchestration.\n *\n * @param definition - What to orchestrate (task, workflow, or policy)\n * @param inputs - Input values for the orchestration\n * @param options - Execution options (timeout, budget, callbacks)\n * @returns Result with OrchestratorResult or OrchestratorError\n */\n execute(\n definition: OrchestratorDefinition,\n inputs: Record<string, unknown>,\n options?: OrchestratorExecuteOptions\n ): Promise<Result<OrchestratorResult, OrchestratorError>>;\n\n /**\n * Get status of an execution.\n *\n * @param executionId - Execution ID to check\n * @returns Current execution status\n */\n getStatus(executionId: string): ExecutionStatus;\n\n /**\n * Cancel a running execution.\n *\n * @param executionId - Execution ID to cancel\n * @param reason - Optional cancellation reason\n * @returns Result with void or OrchestratorError\n */\n cancel(executionId: string, reason?: string): Promise<Result<void, OrchestratorError>>;\n\n /**\n * Register an agent with this orchestrator.\n * Optional - not all orchestrators manage agent pools.\n *\n * @param agent - Agent to register\n */\n registerAgent?(agent: IAgent): void;\n\n /**\n * Unregister an agent.\n * Optional - not all orchestrators manage agent pools.\n *\n * @param agentId - Agent ID to unregister\n */\n unregisterAgent?(agentId: string): void;\n\n /**\n * List registered agents.\n * Optional - not all orchestrators manage agent pools.\n *\n * @returns Array of registered agent IDs and roles\n */\n listAgents?(): Array<{ id: string; role: AgentRole }>;\n\n /**\n * Get execution history.\n * Optional - for orchestrators that track history.\n *\n * @param limit - Maximum number of executions to return\n * @returns Array of past execution results\n */\n getHistory?(limit?: number): OrchestratorResult[];\n}\n\n/**\n * Factory for creating orchestrators.\n */\nexport interface IOrchestratorFactory {\n /**\n * Create an orchestrator instance.\n *\n * @param type - Orchestrator type\n * @param config - Optional configuration\n * @returns New orchestrator instance\n */\n create(type: OrchestratorType, config?: Record<string, unknown>): IOrchestrator;\n\n /**\n * List available orchestrator types.\n */\n listTypes(): OrchestratorType[];\n}\n","/**\n * nexus-agents/context - MobiMEM Implementation Helpers\n *\n * Pure helper functions for MobiMEM implementation.\n * Extracted to keep main implementation under 400 lines.\n *\n * @module context/mobimem-impl-helpers\n * (Source: Issue #149, arXiv:2512.15784)\n */\n\nimport { createHash } from 'node:crypto';\nimport type { ActionStep } from './mobimem-types.js';\n\n/**\n * Calculate confidence score based on observation count.\n * Uses logarithmic scaling: confidence = min(1, log10(count + 1) / 2)\n *\n * @param observationCount - Number of observations\n * @returns Confidence score between 0 and 1\n */\nexport function calculateConfidence(observationCount: number): number {\n return Math.min(1, Math.log10(observationCount + 1) / 2);\n}\n\n/**\n * Generate a unique pattern key from task type, action sequence, and context.\n * Uses SHA-256 hash of the action sequence for consistent keying.\n *\n * @param taskType - The type of task\n * @param actionSequence - Sequence of action steps\n * @param contextSignature - Context signature string\n * @returns Unique pattern key string\n */\nexport function generatePatternKey(\n taskType: string,\n actionSequence: readonly ActionStep[],\n contextSignature: string\n): string {\n const sequenceHash = createHash('sha256')\n .update(\n JSON.stringify(actionSequence.map((a) => ({ type: a.actionType, params: a.parameters })))\n )\n .digest('hex')\n .slice(0, 16);\n return `${taskType}:${contextSignature}:${sequenceHash}`;\n}\n\n/**\n * Hash an input value for cache key generation.\n * Uses SHA-256 hash of JSON-stringified input.\n *\n * @param input - Input value to hash\n * @returns SHA-256 hex hash of the input\n */\nexport function hashInput(input: unknown): string {\n return createHash('sha256').update(JSON.stringify(input)).digest('hex');\n}\n\n/**\n * Calculate pattern score for ranking.\n * Score = successRate * contextMatch * log10(attemptCount + 1)\n *\n * @param successRate - Pattern success rate (0-1)\n * @param contextMatches - Whether context signature matches exactly\n * @param attemptCount - Number of attempts\n * @returns Calculated score for ranking\n */\nexport function calculatePatternScore(\n successRate: number,\n contextMatches: boolean,\n attemptCount: number\n): number {\n const contextMatch = contextMatches ? 1 : 0.5;\n return successRate * contextMatch * Math.log10(attemptCount + 1);\n}\n\n/**\n * Compute success rate from success count and attempt count.\n *\n * @param successCount - Number of successes\n * @param attemptCount - Total attempts\n * @returns Success rate (0-1)\n */\nexport function computeSuccessRate(successCount: number, attemptCount: number): number {\n return attemptCount > 0 ? successCount / attemptCount : 0;\n}\n\n/**\n * Compute updated metrics for experience entries.\n *\n * @param prevSuccess - Previous success count\n * @param prevAttempts - Previous attempt count\n * @param success - Whether current attempt succeeded\n * @returns Updated metrics\n */\nexport function computeUpdatedMetrics(\n prevSuccess: number,\n prevAttempts: number,\n success: boolean\n): { successCount: number; attemptCount: number; successRate: number } {\n const successCount = prevSuccess + (success ? 1 : 0);\n const attemptCount = prevAttempts + 1;\n return {\n successCount,\n attemptCount,\n successRate: computeSuccessRate(successCount, attemptCount),\n };\n}\n\n/**\n * Count unique values from an iterable by extracting a key.\n *\n * @param values - Iterable of values\n * @param keyFn - Function to extract the unique key\n * @returns Count of unique keys\n */\nexport function countUnique<T>(values: Iterable<T>, keyFn: (v: T) => string): number {\n const seen = new Set<string>();\n for (const v of values) {\n seen.add(keyFn(v));\n }\n return seen.size;\n}\n\n/**\n * Compute average of a numeric property from an iterable.\n *\n * @param values - Iterable of values\n * @param valueFn - Function to extract numeric value\n * @returns Average value, or 0 if empty\n */\nexport function computeAverage<T>(values: Iterable<T>, valueFn: (v: T) => number): number {\n let total = 0;\n let count = 0;\n for (const v of values) {\n total += valueFn(v);\n count++;\n }\n return count > 0 ? total / count : 0;\n}\n","/**\n * nexus-agents/context - MobiMEM Implementation\n *\n * Implements MobiMEM post-deployment evolution memory system with\n * Profile, Experience, and Action memory modules.\n *\n * Key features:\n * - Profile Memory: Agent/user preferences and behavioral patterns\n * - Experience Memory: Workflow execution patterns with success tracking\n * - Action Cache: Fast retrieval of successful interaction results\n *\n * @module context/mobimem\n * (Source: Issue #149, arXiv:2512.15784)\n */\n\nimport { createLogger } from '../core/logger.js';\nimport type { IMobiMem, MobiMemConfig, MobiMemStats } from './mobimem-types.js';\nimport { DEFAULT_MOBIMEM_CONFIG, MobiMemConfigSchema } from './mobimem-types.js';\nimport { ProfileMemoryImpl, ExperienceMemoryImpl, ActionCacheImpl } from './mobimem-impl.js';\n\n// Re-export types\nexport type {\n IMobiMem,\n IProfileMemory,\n IExperienceMemory,\n IActionCache,\n MobiMemConfig,\n MobiMemStats,\n ProfileEntry,\n ExperienceEntry,\n ActionCacheEntry,\n ActionStep,\n ExecutionOutcome,\n} from './mobimem-types.js';\nexport { DEFAULT_MOBIMEM_CONFIG } from './mobimem-types.js';\n\nconst logger = createLogger({ component: 'MobiMem' });\n\n/**\n * MobiMEM main implementation.\n * Combines Profile, Experience, and Action memory modules.\n */\nexport class MobiMem implements IMobiMem {\n readonly profile: ProfileMemoryImpl;\n readonly experience: ExperienceMemoryImpl;\n readonly action: ActionCacheImpl;\n private readonly config: MobiMemConfig;\n\n constructor(config: Partial<MobiMemConfig> = {}) {\n const validated = MobiMemConfigSchema.parse({ ...DEFAULT_MOBIMEM_CONFIG, ...config });\n this.config = validated;\n this.profile = new ProfileMemoryImpl(this.config);\n this.experience = new ExperienceMemoryImpl(this.config);\n this.action = new ActionCacheImpl(this.config);\n logger.info('MobiMem initialized', {\n maxProfileEntries: this.config.maxProfileEntries,\n maxExperiencePatterns: this.config.maxExperiencePatterns,\n maxActionCacheEntries: this.config.maxActionCacheEntries,\n });\n }\n\n getStats(): MobiMemStats {\n const actionStats = this.action.getStats();\n\n return {\n profile: {\n totalEntries: this.profile.getEntryCount(),\n uniqueEntities: this.profile.getUniqueEntities(),\n avgConfidence: this.profile.getAverageConfidence(),\n },\n experience: {\n totalPatterns: this.experience.getPatternCount(),\n uniqueTaskTypes: this.experience.getUniqueTaskTypes(),\n avgSuccessRate: this.experience.getAverageSuccessRate(),\n },\n action: {\n totalEntries: actionStats.entries,\n totalHits: actionStats.hits,\n hitRate: actionStats.hitRate,\n timeSavedMs: actionStats.timeSavedMs,\n },\n };\n }\n\n runMaintenance(): void {\n if (this.config.autoEviction) {\n const evicted = this.action.evictExpired();\n if (evicted > 0) {\n logger.debug('Evicted expired action cache entries', { count: evicted });\n }\n }\n }\n\n close(): void {\n logger.info('MobiMem closed');\n }\n\n /** Export MobiMem state for disk persistence (#1782). */\n exportData(): MobiMemSnapshot {\n return {\n stats: this.getStats(),\n exportedAt: new Date().toISOString(),\n };\n }\n\n /** Save MobiMem state to disk (#1782). */\n async save(filePath: string): Promise<void> {\n try {\n const fs = await import('node:fs/promises');\n const path = await import('node:path');\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n const data = JSON.stringify(this.exportData(), null, 2);\n await fs.writeFile(filePath, data, 'utf-8');\n logger.debug('MobiMem state saved', { path: filePath });\n } catch (error) {\n logger.warn('Failed to save MobiMem state', { error: String(error) });\n }\n }\n}\n\n/** Snapshot of MobiMem state for persistence (#1782). */\nexport interface MobiMemSnapshot {\n readonly stats: MobiMemStats;\n readonly exportedAt: string;\n}\n\n/**\n * Create a MobiMem instance.\n */\nexport function createMobiMem(config?: Partial<MobiMemConfig>): MobiMem {\n return new MobiMem(config);\n}\n"],"mappings":"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","names":["color","err","fs","randomUUID","err","durationMs","logger","z","z","metrics","durationMs","metrics","randomUUID","z","z","path","logger","randomBytes","estimateTokens","logger","estimateTokens","durationMs","map","estimateCost","logger","estimateCost","z","z","randomUUID","z","logger","randomUUID","z","REASONING_KEYWORDS","CREATIVITY_KEYWORDS","logger","z","percentile","durationMs","performance","metrics","durationMs","z","z","durationMs","logger","durationMs","z","z","DEFAULT_CONFIG","logger","durationMs","DEFAULT_CONFIG","logger","durationMs","DEFAULT_CONFIG","logger","elapsed","updated","DEFAULT_CONFIG","logger","elapsed","updated","DEFAULT_CONFIG","dotProduct","logger","durationMs","map","successRate","logger","performance","z","logger","z","logger","CLI_NAMES","logger","z","z","z","DEFAULT_CONFIG","RATE_LIMIT_PATTERNS","durationMs","randomBytes","z","z","randomBytes","CLI_NAMES","successRate","FULL_CONFIDENCE_SAMPLES","clamp","logger","sharedAnalyzer","TASK_TYPE_KEYWORDS","sharedAnalyzer","durationMs","generateTraceId","logger","generateTraceId","durationMs","performance","createHash","calculateConfidence","successRate","calculateConfidence","randomUUID","metrics","durationMs","logger","fs","path"]}