agentic-flow 2.0.13 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/README.md +376 -186
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/agent-booster/index.d.ts +14 -0
  5. package/dist/agent-booster/index.d.ts.map +1 -0
  6. package/dist/agent-booster/index.js +25 -0
  7. package/dist/agent-booster/index.js.map +1 -0
  8. package/dist/agents/directApiAgent.d.ts.map +1 -1
  9. package/dist/agents/directApiAgent.js +37 -19
  10. package/dist/agents/directApiAgent.js.map +1 -1
  11. package/dist/cli/commands/hooks.d.ts.map +1 -1
  12. package/dist/cli/commands/hooks.js +4 -1
  13. package/dist/cli/commands/hooks.js.map +1 -1
  14. package/dist/cli/mcp-manager.js +13 -6
  15. package/dist/cli/mcp-manager.js.map +1 -1
  16. package/dist/harness/provenance.d.ts +72 -0
  17. package/dist/harness/provenance.d.ts.map +1 -0
  18. package/dist/harness/provenance.js +92 -0
  19. package/dist/harness/provenance.js.map +1 -0
  20. package/dist/intelligence/EmbeddingService.js +3 -3
  21. package/dist/intelligence/EmbeddingService.js.map +1 -1
  22. package/dist/intelligence/agent-booster-enhanced.d.ts.map +1 -1
  23. package/dist/intelligence/agent-booster-enhanced.js +5 -3
  24. package/dist/intelligence/agent-booster-enhanced.js.map +1 -1
  25. package/dist/mcp/claudeFlowSdkServer.d.ts.map +1 -1
  26. package/dist/mcp/claudeFlowSdkServer.js +76 -29
  27. package/dist/mcp/claudeFlowSdkServer.js.map +1 -1
  28. package/dist/mcp/fastmcp/servers/claude-flow-sdk.js +27 -22
  29. package/dist/mcp/fastmcp/servers/claude-flow-sdk.js.map +1 -1
  30. package/dist/mcp/fastmcp/servers/http-sse.js +31 -20
  31. package/dist/mcp/fastmcp/servers/http-sse.js.map +1 -1
  32. package/dist/mcp/fastmcp/servers/http-streaming-updated.js +33 -32
  33. package/dist/mcp/fastmcp/servers/http-streaming-updated.js.map +1 -1
  34. package/dist/mcp/fastmcp/servers/poc-stdio.js +10 -11
  35. package/dist/mcp/fastmcp/servers/poc-stdio.js.map +1 -1
  36. package/dist/mcp/fastmcp/servers/stdio-full.js +33 -32
  37. package/dist/mcp/fastmcp/servers/stdio-full.js.map +1 -1
  38. package/dist/mcp/fastmcp/tools/agent/execute.d.ts.map +1 -1
  39. package/dist/mcp/fastmcp/tools/agent/execute.js +8 -5
  40. package/dist/mcp/fastmcp/tools/agent/execute.js.map +1 -1
  41. package/dist/mcp/fastmcp/tools/agent/list.d.ts.map +1 -1
  42. package/dist/mcp/fastmcp/tools/agent/list.js +4 -2
  43. package/dist/mcp/fastmcp/tools/agent/list.js.map +1 -1
  44. package/dist/mcp/fastmcp/tools/agent/parallel.d.ts.map +1 -1
  45. package/dist/mcp/fastmcp/tools/agent/parallel.js +4 -2
  46. package/dist/mcp/fastmcp/tools/agent/parallel.js.map +1 -1
  47. package/dist/mcp/fastmcp/tools/hooks/pretrain.d.ts.map +1 -1
  48. package/dist/mcp/fastmcp/tools/hooks/pretrain.js +11 -3
  49. package/dist/mcp/fastmcp/tools/hooks/pretrain.js.map +1 -1
  50. package/dist/mcp/fastmcp/tools/swarm/orchestrate.d.ts.map +1 -1
  51. package/dist/mcp/fastmcp/tools/swarm/orchestrate.js +9 -5
  52. package/dist/mcp/fastmcp/tools/swarm/orchestrate.js.map +1 -1
  53. package/dist/mcp/standalone-stdio.js +76 -57
  54. package/dist/mcp/standalone-stdio.js.map +1 -1
  55. package/dist/mcp/tools/harness-tools.d.ts +28 -0
  56. package/dist/mcp/tools/harness-tools.d.ts.map +1 -0
  57. package/dist/mcp/tools/harness-tools.js +90 -0
  58. package/dist/mcp/tools/harness-tools.js.map +1 -0
  59. package/dist/optimizations/configuration-tuning.d.ts +1 -1
  60. package/dist/reasoningbank/utils/embeddings.d.ts +0 -6
  61. package/dist/reasoningbank/utils/embeddings.d.ts.map +1 -1
  62. package/dist/reasoningbank/utils/embeddings.js +9 -43
  63. package/dist/reasoningbank/utils/embeddings.js.map +1 -1
  64. package/dist/repair/cli.d.ts +24 -0
  65. package/dist/repair/cli.d.ts.map +1 -0
  66. package/dist/repair/cli.js +69 -0
  67. package/dist/repair/cli.js.map +1 -0
  68. package/dist/repair/darwin-repair.d.ts +80 -0
  69. package/dist/repair/darwin-repair.d.ts.map +1 -0
  70. package/dist/repair/darwin-repair.js +81 -0
  71. package/dist/repair/darwin-repair.js.map +1 -0
  72. package/dist/router/cost-optimal-router.d.ts +89 -0
  73. package/dist/router/cost-optimal-router.d.ts.map +1 -0
  74. package/dist/router/cost-optimal-router.js +94 -0
  75. package/dist/router/cost-optimal-router.js.map +1 -0
  76. package/dist/router/providers/onnx-local-optimized.d.ts +1 -10
  77. package/dist/router/providers/onnx-local-optimized.d.ts.map +1 -1
  78. package/dist/router/providers/onnx-local-optimized.js +9 -10
  79. package/dist/router/providers/onnx-local-optimized.js.map +1 -1
  80. package/dist/router/providers/onnx-local.d.ts +0 -9
  81. package/dist/router/providers/onnx-local.d.ts.map +1 -1
  82. package/dist/router/providers/onnx-local.js +7 -22
  83. package/dist/router/providers/onnx-local.js.map +1 -1
  84. package/dist/router/router.d.ts +29 -0
  85. package/dist/router/router.d.ts.map +1 -1
  86. package/dist/router/router.js +83 -0
  87. package/dist/router/router.js.map +1 -1
  88. package/dist/router/types.d.ts +1 -1
  89. package/dist/router/types.d.ts.map +1 -1
  90. package/dist/router/types.js.map +1 -1
  91. package/dist/sdk/plugins.d.ts +6 -6
  92. package/dist/sdk/plugins.d.ts.map +1 -1
  93. package/dist/sdk/plugins.js +37 -0
  94. package/dist/sdk/plugins.js.map +1 -1
  95. package/dist/transport/index.d.ts +1 -0
  96. package/dist/transport/index.d.ts.map +1 -1
  97. package/dist/transport/index.js +1 -0
  98. package/dist/transport/index.js.map +1 -1
  99. package/dist/transport/quic-loader.d.ts +250 -0
  100. package/dist/transport/quic-loader.d.ts.map +1 -0
  101. package/dist/transport/quic-loader.js +507 -0
  102. package/dist/transport/quic-loader.js.map +1 -0
  103. package/dist/utils/agentBoosterPreprocessor.js +16 -22
  104. package/dist/utils/agentBoosterPreprocessor.js.map +1 -1
  105. package/package.json +21 -6
@@ -1 +1 @@
1
- {"version":3,"file":"embeddings.js","sourceRoot":"","sources":["../../../src/reasoningbank/utils/embeddings.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Embedding generation for semantic similarity\n * Uses local transformers.js - no API key required!\n *\n * `@xenova/transformers` is an OPTIONAL dependency. The module is loaded\n * dynamically inside `initializeEmbeddings()` so the rest of this file is\n * importable even when transformers.js is absent (e.g. when consumers\n * pass `npm install --omit=optional`). Code paths that don't call\n * `computeEmbedding()` continue to work without ever loading the module.\n */\n\nimport type { pipeline as Pipeline, env as Env, FeatureExtractionPipeline } from '@xenova/transformers';\nimport { loadConfig } from './config.js';\n\n// Cached references resolved at first call to initializeEmbeddings(). Types\n// are imported as `type-only` so TypeScript can typecheck the file without\n// requiring @xenova/transformers to be installed at build time — the actual\n// runtime import is dynamic below.\nlet pipeline: typeof Pipeline | null = null;\nlet env: typeof Env | null = null;\n\nlet embeddingPipeline: FeatureExtractionPipeline | null = null;\nlet initializationPromise: Promise<void> | null = null;\nconst embeddingCache = new Map<string, Float32Array>();\n// MEMORY LEAK FIX: Track TTL timers so they can be cleaned up\nconst embeddingTimers = new Map<string, NodeJS.Timeout>();\n\n/**\n * Initialize the embedding pipeline (lazy load)\n * RACE CONDITION FIX: Use promise-based initialization instead of busy-wait\n */\nasync function initializeEmbeddings(): Promise<void> {\n // Already initialized\n if (embeddingPipeline) return;\n\n // Initialization in progress - await existing promise\n if (initializationPromise) {\n return initializationPromise;\n }\n\n // Detect npx environment (known transformer initialization issues)\n const isNpxEnv = process.env.npm_lifecycle_event === 'npx' ||\n process.env.npm_execpath?.includes('npx') ||\n process.cwd().includes('/_npx/') ||\n process.cwd().includes('\\\\_npx\\\\');\n\n if (isNpxEnv && !process.env.FORCE_TRANSFORMERS) {\n console.log('[Embeddings] NPX environment detected - using hash-based embeddings');\n console.log('[Embeddings] For semantic search, install globally: npm install -g claude-flow');\n return;\n }\n\n // RACE CONDITION FIX: Create promise for concurrent callers to await\n initializationPromise = (async () => {\n // Optional-dep load: try to import @xenova/transformers. If absent,\n // emit a clear warning and let callers fall back to hash-based embeddings.\n if (!pipeline || !env) {\n try {\n const transformers = await import('@xenova/transformers');\n pipeline = transformers.pipeline;\n env = transformers.env;\n // Configure transformers.js to use WASM backend only (avoid ONNX runtime issues)\n // The native ONNX runtime causes \"DefaultLogger not registered\" errors in Node.js\n env.backends.onnx.wasm.proxy = false; // Disable ONNX runtime proxy\n env.backends.onnx.wasm.numThreads = 1; // Single thread for stability\n } catch (err: unknown) {\n console.warn('[Embeddings] @xenova/transformers not installed (optional dependency).');\n console.warn('[Embeddings] Install with: npm install @xenova/transformers');\n console.warn('[Embeddings] Falling back to hash-based embeddings');\n initializationPromise = null;\n return;\n }\n }\n\n console.log('[Embeddings] Initializing local embedding model (Xenova/all-MiniLM-L6-v2)...');\n console.log('[Embeddings] First run will download ~23MB model...');\n\n try {\n // `pipeline('feature-extraction', ...)` returns a union; narrow to\n // FeatureExtractionPipeline so call-sites can use .pooling / .normalize.\n embeddingPipeline = (await pipeline(\n 'feature-extraction',\n 'Xenova/all-MiniLM-L6-v2',\n { quantized: true } // Smaller, faster\n )) as FeatureExtractionPipeline;\n console.log('[Embeddings] Local model ready! (384 dimensions)');\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error('[Embeddings] Failed to initialize:', msg);\n console.warn('[Embeddings] Falling back to hash-based embeddings');\n // Reset promise so retry is possible\n initializationPromise = null;\n }\n })();\n\n return initializationPromise;\n}\n\n/**\n * Compute embedding for text using local model\n */\nexport async function computeEmbedding(text: string): Promise<Float32Array> {\n const config = loadConfig();\n\n // Check cache\n const cacheKey = `local:${text}`;\n if (embeddingCache.has(cacheKey)) {\n return embeddingCache.get(cacheKey)!;\n }\n\n let embedding: Float32Array;\n\n // Initialize if needed\n await initializeEmbeddings();\n\n if (embeddingPipeline) {\n try {\n // Use transformers.js for real embeddings\n const output = await embeddingPipeline(text, {\n pooling: 'mean',\n normalize: true\n });\n // output.data is a Tensor.data typed-array union; cast to a Float32-\n // compatible source. The model is feature-extraction with normalize:true\n // so the underlying buffer is always Float32 at runtime.\n embedding = new Float32Array(output.data as unknown as ArrayLike<number>);\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error('[Embeddings] Generation failed:', msg);\n embedding = hashEmbed(text, 384); // Fallback\n }\n } else {\n // Fallback to hash-based embeddings\n const dims = config?.embeddings?.dimensions || 384;\n embedding = hashEmbed(text, dims);\n }\n\n // MEMORY LEAK FIX: Clear existing timer if key exists\n const existingTimer = embeddingTimers.get(cacheKey);\n if (existingTimer) {\n clearTimeout(existingTimer);\n embeddingTimers.delete(cacheKey);\n }\n\n // Cache with LRU (limit 1000 entries)\n // PERFORMANCE FIX: Use proper LRU by tracking access order\n if (embeddingCache.size >= 1000) {\n // Find and remove oldest entry (first key in iteration order)\n const firstKey = embeddingCache.keys().next().value;\n if (firstKey) {\n embeddingCache.delete(firstKey);\n // Also clear its timer\n const timer = embeddingTimers.get(firstKey);\n if (timer) {\n clearTimeout(timer);\n embeddingTimers.delete(firstKey);\n }\n }\n }\n embeddingCache.set(cacheKey, embedding);\n\n // Set TTL for cache entry with tracked timer\n const ttl = config?.embeddings?.cache_ttl_seconds || 3600;\n const timerId = setTimeout(() => {\n embeddingCache.delete(cacheKey);\n embeddingTimers.delete(cacheKey);\n }, ttl * 1000);\n\n // MEMORY LEAK FIX: Track timer for cleanup\n embeddingTimers.set(cacheKey, timerId);\n\n return embedding;\n}\n\n/**\n * Batch compute embeddings (more efficient)\n */\nexport async function computeEmbeddingBatch(texts: string[]): Promise<Float32Array[]> {\n return Promise.all(texts.map(text => computeEmbedding(text)));\n}\n\n/**\n * Get embedding dimensions\n */\nexport function getEmbeddingDimensions(): number {\n return 384; // all-MiniLM-L6-v2 uses 384 dimensions\n}\n\n/**\n * Deterministic hash-based embedding (fallback)\n */\nfunction hashEmbed(text: string, dims: number): Float32Array {\n const hash = simpleHash(text);\n const vec = new Float32Array(dims);\n\n // Generate deterministic pseudo-random vector from hash\n for (let i = 0; i < dims; i++) {\n vec[i] = Math.sin(hash * (i + 1) * 0.01) + Math.cos(hash * i * 0.02);\n }\n\n return normalize(vec);\n}\n\n/**\n * Simple string hash function\n */\nfunction simpleHash(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) - hash) + str.charCodeAt(i);\n hash |= 0;\n }\n return Math.abs(hash);\n}\n\n/**\n * Normalize vector to unit length\n */\nfunction normalize(vec: Float32Array): Float32Array {\n let mag = 0;\n for (let i = 0; i < vec.length; i++) {\n mag += vec[i] * vec[i];\n }\n mag = Math.sqrt(mag);\n\n if (mag === 0) return vec;\n\n for (let i = 0; i < vec.length; i++) {\n vec[i] /= mag;\n }\n return vec;\n}\n\n/**\n * Clear embedding cache\n * MEMORY LEAK FIX: Also clear all TTL timers\n */\nexport function clearEmbeddingCache(): void {\n // Clear all timers first to prevent memory leaks\n for (const timer of embeddingTimers.values()) {\n clearTimeout(timer);\n }\n embeddingTimers.clear();\n embeddingCache.clear();\n}\n"]}
1
+ {"version":3,"file":"embeddings.js","sourceRoot":"","sources":["../../../src/reasoningbank/utils/embeddings.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Embedding generation for semantic similarity\n * Uses local transformers.js - no API key required!\n */\n\nimport { pipeline, env } from '@xenova/transformers';\nimport { loadConfig } from './config.js';\n\n// Configure transformers.js to use WASM backend only (avoid ONNX runtime issues)\n// The native ONNX runtime causes \"DefaultLogger not registered\" errors in Node.js\nenv.backends.onnx.wasm.proxy = false; // Disable ONNX runtime proxy\nenv.backends.onnx.wasm.numThreads = 1; // Single thread for stability\n\nlet embeddingPipeline: any = null;\nlet initializationPromise: Promise<void> | null = null;\nconst embeddingCache = new Map<string, Float32Array>();\n// MEMORY LEAK FIX: Track TTL timers so they can be cleaned up\nconst embeddingTimers = new Map<string, NodeJS.Timeout>();\n\n/**\n * Initialize the embedding pipeline (lazy load)\n * RACE CONDITION FIX: Use promise-based initialization instead of busy-wait\n */\nasync function initializeEmbeddings(): Promise<void> {\n // Already initialized\n if (embeddingPipeline) return;\n\n // Initialization in progress - await existing promise\n if (initializationPromise) {\n return initializationPromise;\n }\n\n // Detect npx environment (known transformer initialization issues)\n const isNpxEnv = process.env.npm_lifecycle_event === 'npx' ||\n process.env.npm_execpath?.includes('npx') ||\n process.cwd().includes('/_npx/') ||\n process.cwd().includes('\\\\_npx\\\\');\n\n if (isNpxEnv && !process.env.FORCE_TRANSFORMERS) {\n console.log('[Embeddings] NPX environment detected - using hash-based embeddings');\n console.log('[Embeddings] For semantic search, install globally: npm install -g claude-flow');\n return;\n }\n\n // RACE CONDITION FIX: Create promise for concurrent callers to await\n initializationPromise = (async () => {\n console.log('[Embeddings] Initializing local embedding model (Xenova/all-MiniLM-L6-v2)...');\n console.log('[Embeddings] First run will download ~23MB model...');\n\n try {\n embeddingPipeline = await pipeline(\n 'feature-extraction',\n 'Xenova/all-MiniLM-L6-v2',\n { quantized: true } // Smaller, faster\n );\n console.log('[Embeddings] Local model ready! (384 dimensions)');\n } catch (error: any) {\n console.error('[Embeddings] Failed to initialize:', error?.message || error);\n console.warn('[Embeddings] Falling back to hash-based embeddings');\n // Reset promise so retry is possible\n initializationPromise = null;\n }\n })();\n\n return initializationPromise;\n}\n\n/**\n * Compute embedding for text using local model\n */\nexport async function computeEmbedding(text: string): Promise<Float32Array> {\n const config = loadConfig();\n\n // Check cache\n const cacheKey = `local:${text}`;\n if (embeddingCache.has(cacheKey)) {\n return embeddingCache.get(cacheKey)!;\n }\n\n let embedding: Float32Array;\n\n // Initialize if needed\n await initializeEmbeddings();\n\n if (embeddingPipeline) {\n try {\n // Use transformers.js for real embeddings\n const output = await embeddingPipeline(text, {\n pooling: 'mean',\n normalize: true\n });\n embedding = new Float32Array(output.data);\n } catch (error: any) {\n console.error('[Embeddings] Generation failed:', error?.message || error);\n embedding = hashEmbed(text, 384); // Fallback\n }\n } else {\n // Fallback to hash-based embeddings\n const dims = config?.embeddings?.dimensions || 384;\n embedding = hashEmbed(text, dims);\n }\n\n // MEMORY LEAK FIX: Clear existing timer if key exists\n const existingTimer = embeddingTimers.get(cacheKey);\n if (existingTimer) {\n clearTimeout(existingTimer);\n embeddingTimers.delete(cacheKey);\n }\n\n // Cache with LRU (limit 1000 entries)\n // PERFORMANCE FIX: Use proper LRU by tracking access order\n if (embeddingCache.size >= 1000) {\n // Find and remove oldest entry (first key in iteration order)\n const firstKey = embeddingCache.keys().next().value;\n if (firstKey) {\n embeddingCache.delete(firstKey);\n // Also clear its timer\n const timer = embeddingTimers.get(firstKey);\n if (timer) {\n clearTimeout(timer);\n embeddingTimers.delete(firstKey);\n }\n }\n }\n embeddingCache.set(cacheKey, embedding);\n\n // Set TTL for cache entry with tracked timer\n const ttl = config?.embeddings?.cache_ttl_seconds || 3600;\n const timerId = setTimeout(() => {\n embeddingCache.delete(cacheKey);\n embeddingTimers.delete(cacheKey);\n }, ttl * 1000);\n\n // MEMORY LEAK FIX: Track timer for cleanup\n embeddingTimers.set(cacheKey, timerId);\n\n return embedding;\n}\n\n/**\n * Batch compute embeddings (more efficient)\n */\nexport async function computeEmbeddingBatch(texts: string[]): Promise<Float32Array[]> {\n return Promise.all(texts.map(text => computeEmbedding(text)));\n}\n\n/**\n * Get embedding dimensions\n */\nexport function getEmbeddingDimensions(): number {\n return 384; // all-MiniLM-L6-v2 uses 384 dimensions\n}\n\n/**\n * Deterministic hash-based embedding (fallback)\n */\nfunction hashEmbed(text: string, dims: number): Float32Array {\n const hash = simpleHash(text);\n const vec = new Float32Array(dims);\n\n // Generate deterministic pseudo-random vector from hash\n for (let i = 0; i < dims; i++) {\n vec[i] = Math.sin(hash * (i + 1) * 0.01) + Math.cos(hash * i * 0.02);\n }\n\n return normalize(vec);\n}\n\n/**\n * Simple string hash function\n */\nfunction simpleHash(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) - hash) + str.charCodeAt(i);\n hash |= 0;\n }\n return Math.abs(hash);\n}\n\n/**\n * Normalize vector to unit length\n */\nfunction normalize(vec: Float32Array): Float32Array {\n let mag = 0;\n for (let i = 0; i < vec.length; i++) {\n mag += vec[i] * vec[i];\n }\n mag = Math.sqrt(mag);\n\n if (mag === 0) return vec;\n\n for (let i = 0; i < vec.length; i++) {\n vec[i] /= mag;\n }\n return vec;\n}\n\n/**\n * Clear embedding cache\n * MEMORY LEAK FIX: Also clear all TTL timers\n */\nexport function clearEmbeddingCache(): void {\n // Clear all timers first to prevent memory leaks\n for (const timer of embeddingTimers.values()) {\n clearTimeout(timer);\n }\n embeddingTimers.clear();\n embeddingCache.clear();\n}\n"]}
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `agentic-flow-repair` — thin CLI over {@link repair} (ADR-074).
4
+ *
5
+ * Usage:
6
+ * node dist/repair/cli.js <repoRoot> [--generations N] [--children N]
7
+ * [--seed N] [--mock | --agent]
8
+ *
9
+ * Default substrate is 'real' (Test-Driven Repair): the repo's own test command
10
+ * gates every promotion. `--mock` is the deterministic, Docker-free smoke path.
11
+ * The full SWE-bench-Lite TDR product (issue checkout + Docker grading) is run
12
+ * via Darwin's own `metaharness-darwin` CLI — see ADR-074.
13
+ */
14
+ import { type SandboxMode } from './darwin-repair.js';
15
+ interface CliArgs {
16
+ repoRoot: string;
17
+ generations: number;
18
+ children: number;
19
+ seed: number;
20
+ sandboxMode: SandboxMode;
21
+ }
22
+ export declare function parseArgs(argv: string[]): CliArgs;
23
+ export {};
24
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/repair/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAE9D,UAAU,OAAO;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAoBjD"}
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `agentic-flow-repair` — thin CLI over {@link repair} (ADR-074).
4
+ *
5
+ * Usage:
6
+ * node dist/repair/cli.js <repoRoot> [--generations N] [--children N]
7
+ * [--seed N] [--mock | --agent]
8
+ *
9
+ * Default substrate is 'real' (Test-Driven Repair): the repo's own test command
10
+ * gates every promotion. `--mock` is the deterministic, Docker-free smoke path.
11
+ * The full SWE-bench-Lite TDR product (issue checkout + Docker grading) is run
12
+ * via Darwin's own `metaharness-darwin` CLI — see ADR-074.
13
+ */
14
+ import { repair } from './darwin-repair.js';
15
+ export function parseArgs(argv) {
16
+ const args = {
17
+ repoRoot: '.',
18
+ generations: 3,
19
+ children: 4,
20
+ seed: 0,
21
+ sandboxMode: 'real',
22
+ };
23
+ const positional = [];
24
+ for (let i = 0; i < argv.length; i++) {
25
+ const a = argv[i];
26
+ if (a === '--generations')
27
+ args.generations = Number(argv[++i]);
28
+ else if (a === '--children')
29
+ args.children = Number(argv[++i]);
30
+ else if (a === '--seed')
31
+ args.seed = Number(argv[++i]);
32
+ else if (a === '--mock')
33
+ args.sandboxMode = 'mock';
34
+ else if (a === '--agent')
35
+ args.sandboxMode = 'agent';
36
+ else if (!a.startsWith('-'))
37
+ positional.push(a);
38
+ }
39
+ if (positional[0])
40
+ args.repoRoot = positional[0];
41
+ return args;
42
+ }
43
+ async function main() {
44
+ const a = parseArgs(process.argv.slice(2));
45
+ const res = await repair({
46
+ repoRoot: a.repoRoot,
47
+ generations: a.generations,
48
+ childrenPerGeneration: a.children,
49
+ seed: a.seed,
50
+ sandboxMode: a.sandboxMode,
51
+ });
52
+ console.log(`\nDarwin Repair — ${a.repoRoot} (${a.sandboxMode})`);
53
+ console.log(` baseline finalScore : ${res.baselineScore.toFixed(3)}`);
54
+ if (res.winnerId) {
55
+ const sign = res.deltaOverBaseline >= 0 ? '+' : '';
56
+ console.log(` winner : ${res.winnerId} (Δ ${sign}${res.deltaOverBaseline.toFixed(3)})`);
57
+ }
58
+ console.log(` lineage : ${res.winnerLineage.join(' → ') || '(baseline only)'}`);
59
+ console.log(` variants evaluated : ${res.variantsEvaluated} over ${res.generations} generation(s)`);
60
+ console.log(res.improved ? ' ✅ improved over baseline\n' : ' — no promoted improvement over baseline\n');
61
+ }
62
+ // Run only when invoked directly (ESM-safe; no CommonJS require.main).
63
+ if (import.meta.url === `file://${process.argv[1]}`) {
64
+ main().catch((err) => {
65
+ console.error('repair failed:', err);
66
+ process.exit(1);
67
+ });
68
+ }
69
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/repair/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/**\n * `agentic-flow-repair` — thin CLI over {@link repair} (ADR-074).\n *\n * Usage:\n * node dist/repair/cli.js <repoRoot> [--generations N] [--children N]\n * [--seed N] [--mock | --agent]\n *\n * Default substrate is 'real' (Test-Driven Repair): the repo's own test command\n * gates every promotion. `--mock` is the deterministic, Docker-free smoke path.\n * The full SWE-bench-Lite TDR product (issue checkout + Docker grading) is run\n * via Darwin's own `metaharness-darwin` CLI — see ADR-074.\n */\n\nimport { repair, type SandboxMode } from './darwin-repair.js';\n\ninterface CliArgs {\n repoRoot: string;\n generations: number;\n children: number;\n seed: number;\n sandboxMode: SandboxMode;\n}\n\nexport function parseArgs(argv: string[]): CliArgs {\n const args: CliArgs = {\n repoRoot: '.',\n generations: 3,\n children: 4,\n seed: 0,\n sandboxMode: 'real',\n };\n const positional: string[] = [];\n for (let i = 0; i < argv.length; i++) {\n const a = argv[i];\n if (a === '--generations') args.generations = Number(argv[++i]);\n else if (a === '--children') args.children = Number(argv[++i]);\n else if (a === '--seed') args.seed = Number(argv[++i]);\n else if (a === '--mock') args.sandboxMode = 'mock';\n else if (a === '--agent') args.sandboxMode = 'agent';\n else if (!a.startsWith('-')) positional.push(a);\n }\n if (positional[0]) args.repoRoot = positional[0];\n return args;\n}\n\nasync function main(): Promise<void> {\n const a = parseArgs(process.argv.slice(2));\n const res = await repair({\n repoRoot: a.repoRoot,\n generations: a.generations,\n childrenPerGeneration: a.children,\n seed: a.seed,\n sandboxMode: a.sandboxMode,\n });\n\n console.log(`\\nDarwin Repair — ${a.repoRoot} (${a.sandboxMode})`);\n console.log(` baseline finalScore : ${res.baselineScore.toFixed(3)}`);\n if (res.winnerId) {\n const sign = res.deltaOverBaseline >= 0 ? '+' : '';\n console.log(` winner : ${res.winnerId} (Δ ${sign}${res.deltaOverBaseline.toFixed(3)})`);\n }\n console.log(` lineage : ${res.winnerLineage.join(' → ') || '(baseline only)'}`);\n console.log(` variants evaluated : ${res.variantsEvaluated} over ${res.generations} generation(s)`);\n console.log(res.improved ? ' ✅ improved over baseline\\n' : ' — no promoted improvement over baseline\\n');\n}\n\n// Run only when invoked directly (ESM-safe; no CommonJS require.main).\nif (import.meta.url === `file://${process.argv[1]}`) {\n main().catch((err) => {\n console.error('repair failed:', err);\n process.exit(1);\n });\n}\n"]}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Darwin Repair — autonomous harness evolution / Test-Driven Repair (ADR-074).
3
+ *
4
+ * A typed wrapper over `@metaharness/darwin`'s `evolve()`: freeze the model and
5
+ * evolve the harness around it (planner / context / reviewer / retry / tool /
6
+ * memory / score policy), keeping only variants that *measurably* improve under
7
+ * a frozen, reproducible scorer + safety gate.
8
+ *
9
+ * Modes (via `sandboxMode`):
10
+ * - 'real' (default) — Test-Driven Repair: the repo's own test command is the
11
+ * oracle, run in Darwin's shell-free, env-scrubbed sandbox.
12
+ * - 'mock' — deterministic, surface-driven loop. No repo test, no Docker,
13
+ * no network — used for hermetic smoke tests of the pipeline.
14
+ * - 'agent' — runs the variant's real surface code (Node ≥ 22).
15
+ *
16
+ * NOTE: the headline SWE-bench-Lite TDR *product* (≈68.3% with-test) additionally
17
+ * needs the official `swebench` Docker harness for issue checkout + grading — see
18
+ * ADR-074 for that deployment path. This wrapper exposes the runnable `evolve()`
19
+ * core that does not require Docker.
20
+ *
21
+ * @see docs/adr/ADR-074-metaharness-darwin-test-driven-repair.md
22
+ */
23
+ import { type EvolutionResult } from '@metaharness/darwin';
24
+ export type SandboxMode = 'real' | 'mock' | 'agent';
25
+ export interface RepairOptions {
26
+ /** Path to the repo to repair/evolve. */
27
+ repoRoot: string;
28
+ /** Work tree for Darwin artifacts. Default `<repoRoot>/.metaharness`. */
29
+ workRoot?: string;
30
+ /** Generations to run. Default 3. */
31
+ generations?: number;
32
+ /** Children produced per parent per generation. Default 4. */
33
+ childrenPerGeneration?: number;
34
+ /** Max variants evaluated concurrently. Default 4. */
35
+ concurrency?: number;
36
+ /** Minimum finalScore margin a child must beat its parent by. Default 0.05. */
37
+ promotionDelta?: number;
38
+ /** Deterministic seed. Default 0. */
39
+ seed?: number;
40
+ /** Fixed scoring tasks (the variant cannot edit these). Defaults to REPAIR_TASKS. */
41
+ tasks?: string[];
42
+ /** Evaluation substrate. Default 'real' (Test-Driven Repair). */
43
+ sandboxMode?: SandboxMode;
44
+ /** Per-variant test-command wall-clock budget (ms). Default Darwin's 120000. */
45
+ taskTimeoutMs?: number;
46
+ }
47
+ export interface RepairResult {
48
+ /** True iff a child beat the baseline and was promoted. */
49
+ improved: boolean;
50
+ /** Winner variant id (lineage tail), or null when nothing beat the baseline. */
51
+ winnerId: string | null;
52
+ /** baseline → … → winner ids. */
53
+ winnerLineage: string[];
54
+ /** Baseline finalScore (0 if unevaluated). */
55
+ baselineScore: number;
56
+ /** Winner finalScore, or null. */
57
+ winnerScore: number | null;
58
+ /** winnerScore − baselineScore. */
59
+ deltaOverBaseline: number;
60
+ generations: number;
61
+ /** Total variants in the archive (baseline + descendants). */
62
+ variantsEvaluated: number;
63
+ /** Full Darwin result for callers that need the archive/traces. */
64
+ raw: EvolutionResult;
65
+ }
66
+ /** Default scoring tasks for a repair run. */
67
+ export declare const REPAIR_TASKS: readonly string[];
68
+ /**
69
+ * Run an autonomous repair/evolution pass over a repo and return a friendly
70
+ * summary. Defaults to Test-Driven Repair ('real' sandbox): the repo's own
71
+ * tests gate every promotion.
72
+ */
73
+ export declare function repair(opts: RepairOptions): Promise<RepairResult>;
74
+ /** Reusable repair runner with bound defaults (e.g. a fixed sandbox mode). */
75
+ export declare class DarwinRepair {
76
+ private readonly defaults;
77
+ constructor(defaults?: Partial<RepairOptions>);
78
+ repair(opts: RepairOptions): Promise<RepairResult>;
79
+ }
80
+ //# sourceMappingURL=darwin-repair.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"darwin-repair.d.ts","sourceRoot":"","sources":["../../src/repair/darwin-repair.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EAAgC,KAAK,eAAe,EAAsB,MAAM,qBAAqB,CAAC;AAE7G,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qFAAqF;IACrF,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,iEAAiE;IACjE,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,gFAAgF;IAChF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,QAAQ,EAAE,OAAO,CAAC;IAClB,gFAAgF;IAChF,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,iCAAiC;IACjC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,8CAA8C;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,mCAAmC;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mEAAmE;IACnE,GAAG,EAAE,eAAe,CAAC;CACtB;AAED,8CAA8C;AAC9C,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAIzC,CAAC;AAMF;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAkCvE;AAED,8EAA8E;AAC9E,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,GAAE,OAAO,CAAC,aAAa,CAAM;IAElE,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;CAGnD"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Darwin Repair — autonomous harness evolution / Test-Driven Repair (ADR-074).
3
+ *
4
+ * A typed wrapper over `@metaharness/darwin`'s `evolve()`: freeze the model and
5
+ * evolve the harness around it (planner / context / reviewer / retry / tool /
6
+ * memory / score policy), keeping only variants that *measurably* improve under
7
+ * a frozen, reproducible scorer + safety gate.
8
+ *
9
+ * Modes (via `sandboxMode`):
10
+ * - 'real' (default) — Test-Driven Repair: the repo's own test command is the
11
+ * oracle, run in Darwin's shell-free, env-scrubbed sandbox.
12
+ * - 'mock' — deterministic, surface-driven loop. No repo test, no Docker,
13
+ * no network — used for hermetic smoke tests of the pipeline.
14
+ * - 'agent' — runs the variant's real surface code (Node ≥ 22).
15
+ *
16
+ * NOTE: the headline SWE-bench-Lite TDR *product* (≈68.3% with-test) additionally
17
+ * needs the official `swebench` Docker harness for issue checkout + grading — see
18
+ * ADR-074 for that deployment path. This wrapper exposes the runnable `evolve()`
19
+ * core that does not require Docker.
20
+ *
21
+ * @see docs/adr/ADR-074-metaharness-darwin-test-driven-repair.md
22
+ */
23
+ import { resolve } from 'node:path';
24
+ import { evolve } from '@metaharness/darwin';
25
+ /** Default scoring tasks for a repair run. */
26
+ export const REPAIR_TASKS = [
27
+ 'run repository test suite',
28
+ 'verify generated harness safety',
29
+ 'check trace quality',
30
+ ];
31
+ function finalScoreOf(record) {
32
+ return record?.score?.finalScore ?? null;
33
+ }
34
+ /**
35
+ * Run an autonomous repair/evolution pass over a repo and return a friendly
36
+ * summary. Defaults to Test-Driven Repair ('real' sandbox): the repo's own
37
+ * tests gate every promotion.
38
+ */
39
+ export async function repair(opts) {
40
+ const repoRoot = resolve(opts.repoRoot);
41
+ const config = {
42
+ repoRoot,
43
+ workRoot: opts.workRoot ? resolve(opts.workRoot) : resolve(repoRoot, '.metaharness'),
44
+ generations: opts.generations ?? 3,
45
+ childrenPerGeneration: opts.childrenPerGeneration ?? 4,
46
+ tasks: opts.tasks ? [...opts.tasks] : [...REPAIR_TASKS],
47
+ promotionDelta: opts.promotionDelta ?? 0.05,
48
+ concurrency: opts.concurrency ?? 4,
49
+ seed: opts.seed ?? 0,
50
+ sandboxMode: opts.sandboxMode ?? 'real',
51
+ ...(opts.taskTimeoutMs ? { taskTimeoutMs: opts.taskTimeoutMs } : {}),
52
+ };
53
+ const result = await evolve(config);
54
+ const baselineScore = finalScoreOf(result.baseline) ?? 0;
55
+ const winnerScore = finalScoreOf(result.winner);
56
+ const delta = (winnerScore ?? baselineScore) - baselineScore;
57
+ // winnerLineage is baseline → … → winner, so the tail is the winner id.
58
+ const winnerId = result.winner ? result.winnerLineage[result.winnerLineage.length - 1] ?? null : null;
59
+ return {
60
+ improved: result.winner != null && delta > 0,
61
+ winnerId,
62
+ winnerLineage: result.winnerLineage,
63
+ baselineScore,
64
+ winnerScore,
65
+ deltaOverBaseline: delta,
66
+ generations: result.generations,
67
+ variantsEvaluated: result.records.length,
68
+ raw: result,
69
+ };
70
+ }
71
+ /** Reusable repair runner with bound defaults (e.g. a fixed sandbox mode). */
72
+ export class DarwinRepair {
73
+ defaults;
74
+ constructor(defaults = {}) {
75
+ this.defaults = defaults;
76
+ }
77
+ repair(opts) {
78
+ return repair({ ...this.defaults, ...opts });
79
+ }
80
+ }
81
+ //# sourceMappingURL=darwin-repair.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"darwin-repair.js","sourceRoot":"","sources":["../../src/repair/darwin-repair.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAkE,MAAM,qBAAqB,CAAC;AA+C7G,8CAA8C;AAC9C,MAAM,CAAC,MAAM,YAAY,GAAsB;IAC7C,2BAA2B;IAC3B,iCAAiC;IACjC,qBAAqB;CACtB,CAAC;AAEF,SAAS,YAAY,CAAC,MAA4B;IAChD,OAAO,MAAM,EAAE,KAAK,EAAE,UAAU,IAAI,IAAI,CAAC;AAC3C,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAmB;IAC9C,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,MAAM,GAAoB;QAC9B,QAAQ;QACR,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,cAAc,CAAC;QACpF,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,CAAC;QAClC,qBAAqB,EAAE,IAAI,CAAC,qBAAqB,IAAI,CAAC;QACtD,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC;QACvD,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,IAAI;QAC3C,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,CAAC;QAClC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC;QACpB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,MAAM;QACvC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrE,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IAEpC,MAAM,aAAa,GAAG,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACzD,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,CAAC,WAAW,IAAI,aAAa,CAAC,GAAG,aAAa,CAAC;IAC7D,wEAAwE;IACxE,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAEtG,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,MAAM,IAAI,IAAI,IAAI,KAAK,GAAG,CAAC;QAC5C,QAAQ;QACR,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,aAAa;QACb,WAAW;QACX,iBAAiB,EAAE,KAAK;QACxB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,iBAAiB,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM;QACxC,GAAG,EAAE,MAAM;KACZ,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,MAAM,OAAO,YAAY;IACM;IAA7B,YAA6B,WAAmC,EAAE;QAArC,aAAQ,GAAR,QAAQ,CAA6B;IAAG,CAAC;IAEtE,MAAM,CAAC,IAAmB;QACxB,OAAO,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;CACF","sourcesContent":["/**\n * Darwin Repair — autonomous harness evolution / Test-Driven Repair (ADR-074).\n *\n * A typed wrapper over `@metaharness/darwin`'s `evolve()`: freeze the model and\n * evolve the harness around it (planner / context / reviewer / retry / tool /\n * memory / score policy), keeping only variants that *measurably* improve under\n * a frozen, reproducible scorer + safety gate.\n *\n * Modes (via `sandboxMode`):\n * - 'real' (default) — Test-Driven Repair: the repo's own test command is the\n * oracle, run in Darwin's shell-free, env-scrubbed sandbox.\n * - 'mock' — deterministic, surface-driven loop. No repo test, no Docker,\n * no network — used for hermetic smoke tests of the pipeline.\n * - 'agent' — runs the variant's real surface code (Node ≥ 22).\n *\n * NOTE: the headline SWE-bench-Lite TDR *product* (≈68.3% with-test) additionally\n * needs the official `swebench` Docker harness for issue checkout + grading — see\n * ADR-074 for that deployment path. This wrapper exposes the runnable `evolve()`\n * core that does not require Docker.\n *\n * @see docs/adr/ADR-074-metaharness-darwin-test-driven-repair.md\n */\n\nimport { resolve } from 'node:path';\nimport { evolve, type EvolutionConfig, type EvolutionResult, type ArchiveRecord } from '@metaharness/darwin';\n\nexport type SandboxMode = 'real' | 'mock' | 'agent';\n\nexport interface RepairOptions {\n /** Path to the repo to repair/evolve. */\n repoRoot: string;\n /** Work tree for Darwin artifacts. Default `<repoRoot>/.metaharness`. */\n workRoot?: string;\n /** Generations to run. Default 3. */\n generations?: number;\n /** Children produced per parent per generation. Default 4. */\n childrenPerGeneration?: number;\n /** Max variants evaluated concurrently. Default 4. */\n concurrency?: number;\n /** Minimum finalScore margin a child must beat its parent by. Default 0.05. */\n promotionDelta?: number;\n /** Deterministic seed. Default 0. */\n seed?: number;\n /** Fixed scoring tasks (the variant cannot edit these). Defaults to REPAIR_TASKS. */\n tasks?: string[];\n /** Evaluation substrate. Default 'real' (Test-Driven Repair). */\n sandboxMode?: SandboxMode;\n /** Per-variant test-command wall-clock budget (ms). Default Darwin's 120000. */\n taskTimeoutMs?: number;\n}\n\nexport interface RepairResult {\n /** True iff a child beat the baseline and was promoted. */\n improved: boolean;\n /** Winner variant id (lineage tail), or null when nothing beat the baseline. */\n winnerId: string | null;\n /** baseline → … → winner ids. */\n winnerLineage: string[];\n /** Baseline finalScore (0 if unevaluated). */\n baselineScore: number;\n /** Winner finalScore, or null. */\n winnerScore: number | null;\n /** winnerScore − baselineScore. */\n deltaOverBaseline: number;\n generations: number;\n /** Total variants in the archive (baseline + descendants). */\n variantsEvaluated: number;\n /** Full Darwin result for callers that need the archive/traces. */\n raw: EvolutionResult;\n}\n\n/** Default scoring tasks for a repair run. */\nexport const REPAIR_TASKS: readonly string[] = [\n 'run repository test suite',\n 'verify generated harness safety',\n 'check trace quality',\n];\n\nfunction finalScoreOf(record: ArchiveRecord | null): number | null {\n return record?.score?.finalScore ?? null;\n}\n\n/**\n * Run an autonomous repair/evolution pass over a repo and return a friendly\n * summary. Defaults to Test-Driven Repair ('real' sandbox): the repo's own\n * tests gate every promotion.\n */\nexport async function repair(opts: RepairOptions): Promise<RepairResult> {\n const repoRoot = resolve(opts.repoRoot);\n const config: EvolutionConfig = {\n repoRoot,\n workRoot: opts.workRoot ? resolve(opts.workRoot) : resolve(repoRoot, '.metaharness'),\n generations: opts.generations ?? 3,\n childrenPerGeneration: opts.childrenPerGeneration ?? 4,\n tasks: opts.tasks ? [...opts.tasks] : [...REPAIR_TASKS],\n promotionDelta: opts.promotionDelta ?? 0.05,\n concurrency: opts.concurrency ?? 4,\n seed: opts.seed ?? 0,\n sandboxMode: opts.sandboxMode ?? 'real',\n ...(opts.taskTimeoutMs ? { taskTimeoutMs: opts.taskTimeoutMs } : {}),\n };\n\n const result = await evolve(config);\n\n const baselineScore = finalScoreOf(result.baseline) ?? 0;\n const winnerScore = finalScoreOf(result.winner);\n const delta = (winnerScore ?? baselineScore) - baselineScore;\n // winnerLineage is baseline → … → winner, so the tail is the winner id.\n const winnerId = result.winner ? result.winnerLineage[result.winnerLineage.length - 1] ?? null : null;\n\n return {\n improved: result.winner != null && delta > 0,\n winnerId,\n winnerLineage: result.winnerLineage,\n baselineScore,\n winnerScore,\n deltaOverBaseline: delta,\n generations: result.generations,\n variantsEvaluated: result.records.length,\n raw: result,\n };\n}\n\n/** Reusable repair runner with bound defaults (e.g. a fixed sandbox mode). */\nexport class DarwinRepair {\n constructor(private readonly defaults: Partial<RepairOptions> = {}) {}\n\n repair(opts: RepairOptions): Promise<RepairResult> {\n return repair({ ...this.defaults, ...opts });\n }\n}\n"]}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Cost-Optimal Model Router (ADR-073)
3
+ *
4
+ * Routes each query to the *cheapest model predicted to clear a quality bar*,
5
+ * learned from eval logs — the productized DRACO Phase-2 finding. Wraps
6
+ * `@metaharness/router` (dependency-free k-NN / kernel-ridge, optional native
7
+ * FastGRNN via the already-present `@ruvector/tiny-dancer`).
8
+ *
9
+ * This is additive to `ModelRouter`'s existing config-rule routing: it selects
10
+ * a *model* by predicted cost-quality rather than a provider by static rule.
11
+ * It degrades gracefully — with no labelled examples it falls back to the
12
+ * best-predicted candidate (effectively the caller's prior behavior), so a
13
+ * cold start never breaks routing.
14
+ *
15
+ * @see docs/adr/ADR-073-metaharness-router-cost-optimal-model-routing.md
16
+ */
17
+ import { type RouteResult, type RouterCandidate } from '@metaharness/router';
18
+ import type { ProviderType } from './types.js';
19
+ /** One labelled observation: a query embedding and the quality a model achieved on it. */
20
+ export interface RoutingExample {
21
+ embedding: number[];
22
+ quality: number;
23
+ }
24
+ /** A flat training row: query embedding → quality each model achieved on that query. */
25
+ export interface RoutingDatasetRow {
26
+ embedding: number[];
27
+ scores: Record<string, number>;
28
+ }
29
+ /** Maps a router model id (e.g. "anthropic/claude-haiku-4.5") to a concrete provider + model. */
30
+ export interface ModelBinding {
31
+ provider: ProviderType;
32
+ model: string;
33
+ }
34
+ export interface CostOptimalRouterConfig {
35
+ /**
36
+ * Quality bar (0..1). When set, route() returns the CHEAPEST candidate
37
+ * predicted to clear it; when none clear it, the best-predicted; when unset,
38
+ * always the best-predicted.
39
+ */
40
+ qualityBar?: number;
41
+ /** k-NN neighbours used to predict quality on a new query (default 5). */
42
+ k?: number;
43
+ /**
44
+ * Optional explicit model id → provider/model bindings. When a routed id is
45
+ * absent here, it is parsed as `"<provider>/<model>"` (the OpenRouter-style
46
+ * convention), falling back to treating the whole id as the model name on the
47
+ * default provider.
48
+ */
49
+ modelMap?: Record<string, ModelBinding>;
50
+ /** Provider to assume when a model id has no `"<provider>/"` prefix. */
51
+ defaultProvider?: ProviderType;
52
+ }
53
+ /** A routing decision: the underlying RouteResult plus the resolved provider/model. */
54
+ export interface CostOptimalDecision extends RouteResult {
55
+ provider: ProviderType;
56
+ model: string;
57
+ }
58
+ /**
59
+ * Parse a router model id into a provider/model binding. `"anthropic/claude-..."`
60
+ * → `{ provider: 'anthropic', model: 'claude-...' }`. Ids without a known
61
+ * provider prefix bind to `defaultProvider` with the id as the model name.
62
+ */
63
+ export declare function parseModelId(id: string, modelMap: Record<string, ModelBinding> | undefined, defaultProvider: ProviderType): ModelBinding;
64
+ export declare class CostOptimalRouter {
65
+ private readonly router;
66
+ private readonly modelMap?;
67
+ private readonly defaultProvider;
68
+ private constructor();
69
+ /**
70
+ * Build from explicit candidates (each with its own labelled examples + price).
71
+ * Use when you already have per-model example sets.
72
+ */
73
+ static fromCandidates(candidates: RouterCandidate[], config?: CostOptimalRouterConfig): CostOptimalRouter;
74
+ /**
75
+ * Build from a flat routing dataset — rows of (query embedding → quality each
76
+ * model achieved) plus a per-model price table. This is the shape eval logs
77
+ * and the DRACO benchmark emit, and the same shape that seeds a native
78
+ * tiny-dancer trainer.
79
+ */
80
+ static fromDataset(rows: RoutingDatasetRow[], prices: Record<string, number>, config?: CostOptimalRouterConfig): CostOptimalRouter;
81
+ /** Route a pre-embedded query to the cost-optimal model + provider. */
82
+ route(queryEmbedding: number[]): CostOptimalDecision;
83
+ /**
84
+ * Route using an injected embedder (e.g. the ONNX/ruvector embedding service).
85
+ * Keeps this module decoupled from any specific embedding backend.
86
+ */
87
+ routeText(text: string, embed: (text: string) => Promise<number[]> | number[]): Promise<CostOptimalDecision>;
88
+ }
89
+ //# sourceMappingURL=cost-optimal-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-optimal-router.d.ts","sourceRoot":"","sources":["../../src/router/cost-optimal-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAU,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,0FAA0F;AAC1F,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wFAAwF;AACxF,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,iGAAiG;AACjG,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,CAAC,CAAC,EAAE,MAAM,CAAC;IACX;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACxC,wEAAwE;IACxE,eAAe,CAAC,EAAE,YAAY,CAAC;CAChC;AAED,uFAAuF;AACvF,MAAM,WAAW,mBAAoB,SAAQ,WAAW;IACtD,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,SAAS,EAClD,eAAe,EAAE,YAAY,GAC5B,YAAY,CAoBd;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAA+B;IACzD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAe;IAE/C,OAAO;IAMP;;;OAGG;IACH,MAAM,CAAC,cAAc,CACnB,UAAU,EAAE,eAAe,EAAE,EAC7B,MAAM,GAAE,uBAA4B,GACnC,iBAAiB;IASpB;;;;;OAKG;IACH,MAAM,CAAC,WAAW,CAChB,IAAI,EAAE,iBAAiB,EAAE,EACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,MAAM,GAAE,uBAA4B,GACnC,iBAAiB;IAQpB,uEAAuE;IACvE,KAAK,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,mBAAmB;IAMpD;;;OAGG;IACG,SAAS,CACb,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,GACpD,OAAO,CAAC,mBAAmB,CAAC;CAIhC"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Cost-Optimal Model Router (ADR-073)
3
+ *
4
+ * Routes each query to the *cheapest model predicted to clear a quality bar*,
5
+ * learned from eval logs — the productized DRACO Phase-2 finding. Wraps
6
+ * `@metaharness/router` (dependency-free k-NN / kernel-ridge, optional native
7
+ * FastGRNN via the already-present `@ruvector/tiny-dancer`).
8
+ *
9
+ * This is additive to `ModelRouter`'s existing config-rule routing: it selects
10
+ * a *model* by predicted cost-quality rather than a provider by static rule.
11
+ * It degrades gracefully — with no labelled examples it falls back to the
12
+ * best-predicted candidate (effectively the caller's prior behavior), so a
13
+ * cold start never breaks routing.
14
+ *
15
+ * @see docs/adr/ADR-073-metaharness-router-cost-optimal-model-routing.md
16
+ */
17
+ import { Router } from '@metaharness/router';
18
+ /**
19
+ * Parse a router model id into a provider/model binding. `"anthropic/claude-..."`
20
+ * → `{ provider: 'anthropic', model: 'claude-...' }`. Ids without a known
21
+ * provider prefix bind to `defaultProvider` with the id as the model name.
22
+ */
23
+ export function parseModelId(id, modelMap, defaultProvider) {
24
+ if (modelMap && modelMap[id])
25
+ return modelMap[id];
26
+ const slash = id.indexOf('/');
27
+ if (slash > 0) {
28
+ const maybeProvider = id.slice(0, slash);
29
+ const known = [
30
+ 'anthropic',
31
+ 'openai',
32
+ 'openrouter',
33
+ 'ollama',
34
+ 'litellm',
35
+ 'onnx',
36
+ 'gemini',
37
+ 'custom',
38
+ ];
39
+ if (known.includes(maybeProvider)) {
40
+ return { provider: maybeProvider, model: id.slice(slash + 1) };
41
+ }
42
+ }
43
+ return { provider: defaultProvider, model: id };
44
+ }
45
+ export class CostOptimalRouter {
46
+ router;
47
+ modelMap;
48
+ defaultProvider;
49
+ constructor(router, config) {
50
+ this.router = router;
51
+ this.modelMap = config.modelMap;
52
+ this.defaultProvider = config.defaultProvider ?? 'anthropic';
53
+ }
54
+ /**
55
+ * Build from explicit candidates (each with its own labelled examples + price).
56
+ * Use when you already have per-model example sets.
57
+ */
58
+ static fromCandidates(candidates, config = {}) {
59
+ const router = new Router({
60
+ candidates,
61
+ k: config.k,
62
+ qualityBar: config.qualityBar,
63
+ });
64
+ return new CostOptimalRouter(router, config);
65
+ }
66
+ /**
67
+ * Build from a flat routing dataset — rows of (query embedding → quality each
68
+ * model achieved) plus a per-model price table. This is the shape eval logs
69
+ * and the DRACO benchmark emit, and the same shape that seeds a native
70
+ * tiny-dancer trainer.
71
+ */
72
+ static fromDataset(rows, prices, config = {}) {
73
+ const router = Router.fromExamples(rows, prices, {
74
+ k: config.k,
75
+ qualityBar: config.qualityBar,
76
+ });
77
+ return new CostOptimalRouter(router, config);
78
+ }
79
+ /** Route a pre-embedded query to the cost-optimal model + provider. */
80
+ route(queryEmbedding) {
81
+ const result = this.router.route(queryEmbedding);
82
+ const { provider, model } = parseModelId(result.id, this.modelMap, this.defaultProvider);
83
+ return { ...result, provider, model };
84
+ }
85
+ /**
86
+ * Route using an injected embedder (e.g. the ONNX/ruvector embedding service).
87
+ * Keeps this module decoupled from any specific embedding backend.
88
+ */
89
+ async routeText(text, embed) {
90
+ const embedding = await embed(text);
91
+ return this.route(embedding);
92
+ }
93
+ }
94
+ //# sourceMappingURL=cost-optimal-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-optimal-router.js","sourceRoot":"","sources":["../../src/router/cost-optimal-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,MAAM,EAA0C,MAAM,qBAAqB,CAAC;AA+CrF;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAC1B,EAAU,EACV,QAAkD,EAClD,eAA6B;IAE7B,IAAI,QAAQ,IAAI,QAAQ,CAAC,EAAE,CAAC;QAAE,OAAO,QAAQ,CAAC,EAAE,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,MAAM,aAAa,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAiB,CAAC;QACzD,MAAM,KAAK,GAAmB;YAC5B,WAAW;YACX,QAAQ;YACR,YAAY;YACZ,QAAQ;YACR,SAAS;YACT,MAAM;YACN,QAAQ;YACR,QAAQ;SACT,CAAC;QACF,IAAI,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YAClC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;QACjE,CAAC;IACH,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,OAAO,iBAAiB;IACX,MAAM,CAAS;IACf,QAAQ,CAAgC;IACxC,eAAe,CAAe;IAE/C,YAAoB,MAAc,EAAE,MAA+B;QACjE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QAChC,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,IAAI,WAAW,CAAC;IAC/D,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,cAAc,CACnB,UAA6B,EAC7B,SAAkC,EAAE;QAEpC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;YACxB,UAAU;YACV,CAAC,EAAE,MAAM,CAAC,CAAC;YACX,UAAU,EAAE,MAAM,CAAC,UAAU;SAC9B,CAAC,CAAC;QACH,OAAO,IAAI,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,WAAW,CAChB,IAAyB,EACzB,MAA8B,EAC9B,SAAkC,EAAE;QAEpC,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE;YAC/C,CAAC,EAAE,MAAM,CAAC,CAAC;YACX,UAAU,EAAE,MAAM,CAAC,UAAU;SAC9B,CAAC,CAAC;QACH,OAAO,IAAI,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IAED,uEAAuE;IACvE,KAAK,CAAC,cAAwB;QAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QACjD,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QACzF,OAAO,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACxC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,SAAS,CACb,IAAY,EACZ,KAAqD;QAErD,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;CACF","sourcesContent":["/**\n * Cost-Optimal Model Router (ADR-073)\n *\n * Routes each query to the *cheapest model predicted to clear a quality bar*,\n * learned from eval logs — the productized DRACO Phase-2 finding. Wraps\n * `@metaharness/router` (dependency-free k-NN / kernel-ridge, optional native\n * FastGRNN via the already-present `@ruvector/tiny-dancer`).\n *\n * This is additive to `ModelRouter`'s existing config-rule routing: it selects\n * a *model* by predicted cost-quality rather than a provider by static rule.\n * It degrades gracefully — with no labelled examples it falls back to the\n * best-predicted candidate (effectively the caller's prior behavior), so a\n * cold start never breaks routing.\n *\n * @see docs/adr/ADR-073-metaharness-router-cost-optimal-model-routing.md\n */\n\nimport { Router, type RouteResult, type RouterCandidate } from '@metaharness/router';\nimport type { ProviderType } from './types.js';\n\n/** One labelled observation: a query embedding and the quality a model achieved on it. */\nexport interface RoutingExample {\n embedding: number[];\n quality: number; // 0..1\n}\n\n/** A flat training row: query embedding → quality each model achieved on that query. */\nexport interface RoutingDatasetRow {\n embedding: number[];\n scores: Record<string, number>; // modelId → quality (0..1)\n}\n\n/** Maps a router model id (e.g. \"anthropic/claude-haiku-4.5\") to a concrete provider + model. */\nexport interface ModelBinding {\n provider: ProviderType;\n model: string;\n}\n\nexport interface CostOptimalRouterConfig {\n /**\n * Quality bar (0..1). When set, route() returns the CHEAPEST candidate\n * predicted to clear it; when none clear it, the best-predicted; when unset,\n * always the best-predicted.\n */\n qualityBar?: number;\n /** k-NN neighbours used to predict quality on a new query (default 5). */\n k?: number;\n /**\n * Optional explicit model id → provider/model bindings. When a routed id is\n * absent here, it is parsed as `\"<provider>/<model>\"` (the OpenRouter-style\n * convention), falling back to treating the whole id as the model name on the\n * default provider.\n */\n modelMap?: Record<string, ModelBinding>;\n /** Provider to assume when a model id has no `\"<provider>/\"` prefix. */\n defaultProvider?: ProviderType;\n}\n\n/** A routing decision: the underlying RouteResult plus the resolved provider/model. */\nexport interface CostOptimalDecision extends RouteResult {\n provider: ProviderType;\n model: string;\n}\n\n/**\n * Parse a router model id into a provider/model binding. `\"anthropic/claude-...\"`\n * → `{ provider: 'anthropic', model: 'claude-...' }`. Ids without a known\n * provider prefix bind to `defaultProvider` with the id as the model name.\n */\nexport function parseModelId(\n id: string,\n modelMap: Record<string, ModelBinding> | undefined,\n defaultProvider: ProviderType,\n): ModelBinding {\n if (modelMap && modelMap[id]) return modelMap[id];\n const slash = id.indexOf('/');\n if (slash > 0) {\n const maybeProvider = id.slice(0, slash) as ProviderType;\n const known: ProviderType[] = [\n 'anthropic',\n 'openai',\n 'openrouter',\n 'ollama',\n 'litellm',\n 'onnx',\n 'gemini',\n 'custom',\n ];\n if (known.includes(maybeProvider)) {\n return { provider: maybeProvider, model: id.slice(slash + 1) };\n }\n }\n return { provider: defaultProvider, model: id };\n}\n\nexport class CostOptimalRouter {\n private readonly router: Router;\n private readonly modelMap?: Record<string, ModelBinding>;\n private readonly defaultProvider: ProviderType;\n\n private constructor(router: Router, config: CostOptimalRouterConfig) {\n this.router = router;\n this.modelMap = config.modelMap;\n this.defaultProvider = config.defaultProvider ?? 'anthropic';\n }\n\n /**\n * Build from explicit candidates (each with its own labelled examples + price).\n * Use when you already have per-model example sets.\n */\n static fromCandidates(\n candidates: RouterCandidate[],\n config: CostOptimalRouterConfig = {},\n ): CostOptimalRouter {\n const router = new Router({\n candidates,\n k: config.k,\n qualityBar: config.qualityBar,\n });\n return new CostOptimalRouter(router, config);\n }\n\n /**\n * Build from a flat routing dataset — rows of (query embedding → quality each\n * model achieved) plus a per-model price table. This is the shape eval logs\n * and the DRACO benchmark emit, and the same shape that seeds a native\n * tiny-dancer trainer.\n */\n static fromDataset(\n rows: RoutingDatasetRow[],\n prices: Record<string, number>,\n config: CostOptimalRouterConfig = {},\n ): CostOptimalRouter {\n const router = Router.fromExamples(rows, prices, {\n k: config.k,\n qualityBar: config.qualityBar,\n });\n return new CostOptimalRouter(router, config);\n }\n\n /** Route a pre-embedded query to the cost-optimal model + provider. */\n route(queryEmbedding: number[]): CostOptimalDecision {\n const result = this.router.route(queryEmbedding);\n const { provider, model } = parseModelId(result.id, this.modelMap, this.defaultProvider);\n return { ...result, provider, model };\n }\n\n /**\n * Route using an injected embedder (e.g. the ONNX/ruvector embedding service).\n * Keeps this module decoupled from any specific embedding backend.\n */\n async routeText(\n text: string,\n embed: (text: string) => Promise<number[]> | number[],\n ): Promise<CostOptimalDecision> {\n const embedding = await embed(text);\n return this.route(embedding);\n }\n}\n"]}
@@ -8,16 +8,7 @@
8
8
  * - Better generation parameters for code tasks
9
9
  * - System prompt caching
10
10
  *
11
- * Note: onnxruntime-node is optional - will error if not installed.
12
- *
13
- * NOTE (ruvnet/ruflo#2048): the previous top-level `await import('onnxruntime-node')`
14
- * fired the native-binding load (`onnxruntime_binding.node`) at module
15
- * import time. On Windows this crashes with "OS cannot run %1" — and the
16
- * crash propagated to any consumer that transitively imports this file
17
- * (e.g. `agentic-flow/reasoningbank` via `core/distill → router/router`).
18
- * This file does not use `ort` directly — the base `ONNXLocalProvider`
19
- * it extends does, and that file now lazy-loads ort on first session
20
- * init. So we just drop the eager top-level load here.
11
+ * Note: onnxruntime-node is optional - will error if not installed
21
12
  */
22
13
  import type { ChatParams, ChatResponse } from '../types.js';
23
14
  import { ONNXLocalProvider, ONNXLocalConfig } from './onnx-local.js';
@@ -1 +1 @@
1
- {"version":3,"file":"onnx-local-optimized.d.ts","sourceRoot":"","sources":["../../../src/router/providers/onnx-local-optimized.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EAIb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAErE,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,qBAAa,qBAAsB,SAAQ,iBAAiB;IAC1D,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,iBAAiB,CAAmE;gBAEhF,MAAM,GAAE,mBAAwB;IAkB5C;;OAEG;IACH,OAAO,CAAC,cAAc;IAKtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAmDvB;;OAEG;IACH,OAAO,CAAC,cAAc;IA8BtB;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC;IA+BrD;;OAEG;IACH,mBAAmB;;;;;;;;;;;;;;;;;;;;IAoBnB;;OAEG;IACH,WAAW;CAKZ"}
1
+ {"version":3,"file":"onnx-local-optimized.d.ts","sourceRoot":"","sources":["../../../src/router/providers/onnx-local-optimized.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAaH,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EAIb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAErE,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,qBAAa,qBAAsB,SAAQ,iBAAiB;IAC1D,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,iBAAiB,CAAmE;gBAEhF,MAAM,GAAE,mBAAwB;IAkB5C;;OAEG;IACH,OAAO,CAAC,cAAc;IAKtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAmDvB;;OAEG;IACH,OAAO,CAAC,cAAc;IA8BtB;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC;IA+BrD;;OAEG;IACH,mBAAmB;;;;;;;;;;;;;;;;;;;;IAoBnB;;OAEG;IACH,WAAW;CAKZ"}
@@ -8,17 +8,16 @@
8
8
  * - Better generation parameters for code tasks
9
9
  * - System prompt caching
10
10
  *
11
- * Note: onnxruntime-node is optional - will error if not installed.
12
- *
13
- * NOTE (ruvnet/ruflo#2048): the previous top-level `await import('onnxruntime-node')`
14
- * fired the native-binding load (`onnxruntime_binding.node`) at module
15
- * import time. On Windows this crashes with "OS cannot run %1" — and the
16
- * crash propagated to any consumer that transitively imports this file
17
- * (e.g. `agentic-flow/reasoningbank` via `core/distill → router/router`).
18
- * This file does not use `ort` directly — the base `ONNXLocalProvider`
19
- * it extends does, and that file now lazy-loads ort on first session
20
- * init. So we just drop the eager top-level load here.
11
+ * Note: onnxruntime-node is optional - will error if not installed
21
12
  */
13
+ let ort = null;
14
+ // Dynamic import for optional onnxruntime-node
15
+ try {
16
+ ort = await import('onnxruntime-node');
17
+ }
18
+ catch {
19
+ // Will be handled at runtime
20
+ }
22
21
  import { ONNXLocalProvider } from './onnx-local.js';
23
22
  export class OptimizedONNXProvider extends ONNXLocalProvider {
24
23
  optimizedConfig;