@bradtaylorsf/alpha-loop 1.14.0 → 1.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +73 -1
  2. package/dist/cli.js +37 -2
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/eval.d.ts +22 -0
  5. package/dist/commands/eval.js +105 -1
  6. package/dist/commands/eval.js.map +1 -1
  7. package/dist/commands/evolve-routing.d.ts +24 -0
  8. package/dist/commands/evolve-routing.js +320 -0
  9. package/dist/commands/evolve-routing.js.map +1 -0
  10. package/dist/commands/history.d.ts +2 -0
  11. package/dist/commands/history.js +95 -1
  12. package/dist/commands/history.js.map +1 -1
  13. package/dist/commands/init.d.ts +6 -0
  14. package/dist/commands/init.js +26 -1
  15. package/dist/commands/init.js.map +1 -1
  16. package/dist/commands/report.d.ts +7 -0
  17. package/dist/commands/report.js +27 -0
  18. package/dist/commands/report.js.map +1 -0
  19. package/dist/commands/scan.d.ts +1 -1
  20. package/dist/commands/scan.js.map +1 -1
  21. package/dist/engine/agents.d.ts +30 -8
  22. package/dist/engine/agents.js +94 -10
  23. package/dist/engine/agents.js.map +1 -1
  24. package/dist/engine/prerequisites.d.ts +40 -2
  25. package/dist/engine/prerequisites.js +126 -2
  26. package/dist/engine/prerequisites.js.map +1 -1
  27. package/dist/lib/agent.d.ts +39 -2
  28. package/dist/lib/agent.js +106 -4
  29. package/dist/lib/agent.js.map +1 -1
  30. package/dist/lib/config.d.ts +73 -1
  31. package/dist/lib/config.js +214 -1
  32. package/dist/lib/config.js.map +1 -1
  33. package/dist/lib/escalation.d.ts +102 -0
  34. package/dist/lib/escalation.js +241 -0
  35. package/dist/lib/escalation.js.map +1 -0
  36. package/dist/lib/eval-matrix.d.ts +125 -0
  37. package/dist/lib/eval-matrix.js +317 -0
  38. package/dist/lib/eval-matrix.js.map +1 -0
  39. package/dist/lib/eval-report.d.ts +12 -0
  40. package/dist/lib/eval-report.js +132 -0
  41. package/dist/lib/eval-report.js.map +1 -0
  42. package/dist/lib/eval-secret-scan.d.ts +41 -0
  43. package/dist/lib/eval-secret-scan.js +163 -0
  44. package/dist/lib/eval-secret-scan.js.map +1 -0
  45. package/dist/lib/eval.js +7 -4
  46. package/dist/lib/eval.js.map +1 -1
  47. package/dist/lib/hardware.d.ts +9 -0
  48. package/dist/lib/hardware.js +32 -0
  49. package/dist/lib/hardware.js.map +1 -0
  50. package/dist/lib/pipeline.d.ts +5 -1
  51. package/dist/lib/pipeline.js +217 -16
  52. package/dist/lib/pipeline.js.map +1 -1
  53. package/dist/lib/prerequisites.js +11 -3
  54. package/dist/lib/prerequisites.js.map +1 -1
  55. package/dist/lib/routing-history.d.ts +43 -0
  56. package/dist/lib/routing-history.js +112 -0
  57. package/dist/lib/routing-history.js.map +1 -0
  58. package/dist/lib/routing-promotion.d.ts +95 -0
  59. package/dist/lib/routing-promotion.js +229 -0
  60. package/dist/lib/routing-promotion.js.map +1 -0
  61. package/dist/lib/session.js +13 -0
  62. package/dist/lib/session.js.map +1 -1
  63. package/dist/lib/telemetry.d.ts +147 -0
  64. package/dist/lib/telemetry.js +353 -0
  65. package/dist/lib/telemetry.js.map +1 -0
  66. package/package.json +1 -1
@@ -1,3 +1,10 @@
1
+ import type { RoutingEndpoint } from './config.js';
2
+ /**
3
+ * Supported agent CLI shapes. `lmstudio` piggy-backs on the `claude` CLI (since
4
+ * LM Studio exposes an Anthropic-compatible endpoint); `ollama` piggy-backs on
5
+ * the `codex` CLI (OpenAI-compatible).
6
+ */
7
+ export type AgentType = 'claude' | 'codex' | 'opencode' | 'lmstudio' | 'ollama';
1
8
  export type AgentResult = {
2
9
  exitCode: number;
3
10
  output: string;
@@ -10,9 +17,13 @@ export type AgentResult = {
10
17
  outputTokens?: number;
11
18
  /** Model used for the invocation. */
12
19
  model?: string;
20
+ /** Number of tool_use blocks emitted during the run. */
21
+ toolCalls?: number;
22
+ /** Number of tool_result blocks with is_error === true. */
23
+ toolErrors?: number;
13
24
  };
14
25
  export type AgentOptions = {
15
- agent: 'claude' | 'codex' | 'opencode';
26
+ agent: AgentType;
16
27
  model: string;
17
28
  prompt: string;
18
29
  cwd: string;
@@ -24,9 +35,19 @@ export type AgentOptions = {
24
35
  maxTurns?: number;
25
36
  /** Resume the most recent agent session in the CWD instead of starting fresh. */
26
37
  resume?: boolean;
38
+ /**
39
+ * Env-var overrides merged over `process.env` when spawning the child.
40
+ * Callers MUST compute this per stage (see `buildEndpointEnv`) so that a
41
+ * frontier stage does not inherit a local-endpoint env from a prior stage.
42
+ */
43
+ env?: Record<string, string>;
27
44
  };
28
45
  /**
29
46
  * Build CLI command and args for a given agent type.
47
+ *
48
+ * `lmstudio` delegates to the claude CLI shape (Anthropic-compatible); `ollama`
49
+ * delegates to the codex CLI shape (OpenAI-compatible). Endpoint selection is
50
+ * wired via env vars (see `buildEndpointEnv`), not CLI flags.
30
51
  */
31
52
  export declare function buildAgentArgs(options: AgentOptions): {
32
53
  command: string;
@@ -36,7 +57,23 @@ export declare function buildAgentArgs(options: AgentOptions): {
36
57
  * Build a shell command string for one-shot agent prompts (scan, vision).
37
58
  * Reads prompt from stdin. Returns the command to pipe into.
38
59
  */
39
- export declare function buildOneShotCommand(agent: 'claude' | 'codex' | 'opencode', model: string): string;
60
+ export declare function buildOneShotCommand(agent: AgentType, model: string): string;
61
+ /**
62
+ * Build the env-var overrides needed to point a child CLI at a specific
63
+ * routing endpoint. Anthropic-shaped endpoints set ANTHROPIC_BASE_URL /
64
+ * ANTHROPIC_MODEL; OpenAI-compatible endpoints set OPENAI_BASE_URL /
65
+ * OPENAI_MODEL.
66
+ *
67
+ * Callers MUST compute this per stage and not share envs across stages, so
68
+ * that a frontier stage does not inherit a local endpoint from a prior stage.
69
+ */
70
+ export declare function buildEndpointEnv(endpoint: RoutingEndpoint, model: string): Record<string, string>;
71
+ /**
72
+ * Default local-server base URLs for single-agent `lmstudio` / `ollama` mode.
73
+ * Exported so tests and callers can reference the same constants.
74
+ */
75
+ export declare const DEFAULT_LMSTUDIO_BASE_URL = "http://localhost:1234";
76
+ export declare const DEFAULT_OLLAMA_BASE_URL = "http://localhost:11434/v1";
40
77
  /**
41
78
  * Spawn an AI agent with a prompt.
42
79
  * Streams output to terminal in real-time while capturing it.
package/dist/lib/agent.js CHANGED
@@ -4,6 +4,7 @@
4
4
  import { spawn } from 'node:child_process';
5
5
  import { createWriteStream } from 'node:fs';
6
6
  import { log } from './logger.js';
7
+ import { classifyToolErrors } from './escalation.js';
7
8
  /**
8
9
  * Parse a Claude stream-json line into a human-readable log line.
9
10
  * Returns null for lines that shouldn't be logged.
@@ -69,10 +70,15 @@ function formatStreamJsonLine(line) {
69
70
  const DEFAULT_AGENT_TIMEOUT_MS = 30 * 60 * 1000;
70
71
  /**
71
72
  * Build CLI command and args for a given agent type.
73
+ *
74
+ * `lmstudio` delegates to the claude CLI shape (Anthropic-compatible); `ollama`
75
+ * delegates to the codex CLI shape (OpenAI-compatible). Endpoint selection is
76
+ * wired via env vars (see `buildEndpointEnv`), not CLI flags.
72
77
  */
73
78
  export function buildAgentArgs(options) {
74
79
  switch (options.agent) {
75
- case 'claude': {
80
+ case 'claude':
81
+ case 'lmstudio': {
76
82
  const args = [];
77
83
  if (options.resume)
78
84
  args.push('--continue');
@@ -85,7 +91,8 @@ export function buildAgentArgs(options) {
85
91
  }
86
92
  return { command: 'claude', args };
87
93
  }
88
- case 'codex': {
94
+ case 'codex':
95
+ case 'ollama': {
89
96
  const args = [];
90
97
  if (options.resume) {
91
98
  args.push('exec', 'resume', '--last');
@@ -114,14 +121,16 @@ export function buildAgentArgs(options) {
114
121
  */
115
122
  export function buildOneShotCommand(agent, model) {
116
123
  switch (agent) {
117
- case 'claude': {
124
+ case 'claude':
125
+ case 'lmstudio': {
118
126
  const parts = ['claude', '-p'];
119
127
  if (model)
120
128
  parts.push('--model', model);
121
129
  parts.push('--dangerously-skip-permissions', '--output-format', 'text');
122
130
  return parts.join(' ');
123
131
  }
124
- case 'codex': {
132
+ case 'codex':
133
+ case 'ollama': {
125
134
  const parts = ['codex', 'exec'];
126
135
  if (model)
127
136
  parts.push('--model', model);
@@ -138,6 +147,65 @@ export function buildOneShotCommand(agent, model) {
138
147
  throw new Error(`Unknown agent type: ${agent}`);
139
148
  }
140
149
  }
150
+ /**
151
+ * Build the env-var overrides needed to point a child CLI at a specific
152
+ * routing endpoint. Anthropic-shaped endpoints set ANTHROPIC_BASE_URL /
153
+ * ANTHROPIC_MODEL; OpenAI-compatible endpoints set OPENAI_BASE_URL /
154
+ * OPENAI_MODEL.
155
+ *
156
+ * Callers MUST compute this per stage and not share envs across stages, so
157
+ * that a frontier stage does not inherit a local endpoint from a prior stage.
158
+ */
159
+ export function buildEndpointEnv(endpoint, model) {
160
+ const env = {};
161
+ if (!endpoint || !endpoint.base_url)
162
+ return env;
163
+ switch (endpoint.type) {
164
+ case 'anthropic':
165
+ case 'anthropic_compat':
166
+ env.ANTHROPIC_BASE_URL = endpoint.base_url;
167
+ if (model)
168
+ env.ANTHROPIC_MODEL = model;
169
+ break;
170
+ case 'openai_compat':
171
+ env.OPENAI_BASE_URL = endpoint.base_url;
172
+ if (model)
173
+ env.OPENAI_MODEL = model;
174
+ break;
175
+ }
176
+ return env;
177
+ }
178
+ /**
179
+ * Default local-server base URLs for single-agent `lmstudio` / `ollama` mode.
180
+ * Exported so tests and callers can reference the same constants.
181
+ */
182
+ export const DEFAULT_LMSTUDIO_BASE_URL = 'http://localhost:1234';
183
+ export const DEFAULT_OLLAMA_BASE_URL = 'http://localhost:11434/v1';
184
+ /**
185
+ * Auto-injected env vars for single-agent `lmstudio` / `ollama` mode.
186
+ *
187
+ * Without this, `agent: lmstudio` would spawn the claude CLI with no base URL
188
+ * override and silently hit the real Anthropic API. We only inject defaults
189
+ * when the corresponding env var isn't already set in the parent process, so
190
+ * users who export `ANTHROPIC_BASE_URL` / `OPENAI_BASE_URL` to point at a
191
+ * non-default port keep full control.
192
+ */
193
+ function defaultLocalEnv(agent, model) {
194
+ const env = {};
195
+ if (agent === 'lmstudio') {
196
+ if (!process.env.ANTHROPIC_BASE_URL)
197
+ env.ANTHROPIC_BASE_URL = DEFAULT_LMSTUDIO_BASE_URL;
198
+ if (model && !process.env.ANTHROPIC_MODEL)
199
+ env.ANTHROPIC_MODEL = model;
200
+ }
201
+ else if (agent === 'ollama') {
202
+ if (!process.env.OPENAI_BASE_URL)
203
+ env.OPENAI_BASE_URL = DEFAULT_OLLAMA_BASE_URL;
204
+ if (model && !process.env.OPENAI_MODEL)
205
+ env.OPENAI_MODEL = model;
206
+ }
207
+ return env;
208
+ }
141
209
  /**
142
210
  * Spawn an AI agent with a prompt.
143
211
  * Streams output to terminal in real-time while capturing it.
@@ -156,10 +224,18 @@ export async function spawnAgent(options) {
156
224
  logStream = createWriteStream(options.logFile, { flags: 'w' });
157
225
  }
158
226
  const timeoutMs = options.timeout ?? DEFAULT_AGENT_TIMEOUT_MS;
227
+ // Compose env: caller overrides win > agent-default local base URLs > process.env
228
+ const localDefaults = defaultLocalEnv(options.agent, options.model);
229
+ const hasOverrides = options.env && Object.keys(options.env).length > 0;
230
+ const hasLocalDefaults = Object.keys(localDefaults).length > 0;
231
+ const spawnEnv = hasOverrides || hasLocalDefaults
232
+ ? { ...process.env, ...localDefaults, ...(options.env ?? {}) }
233
+ : process.env;
159
234
  return new Promise((resolve) => {
160
235
  const child = spawn(command, args, {
161
236
  cwd: options.cwd,
162
237
  stdio: ['pipe', 'pipe', 'pipe'],
238
+ env: spawnEnv,
163
239
  });
164
240
  let resolved = false;
165
241
  // For stream-json: accumulate partial lines, extract final result text
@@ -169,6 +245,9 @@ export async function spawnAgent(options) {
169
245
  let parsedCostUsd;
170
246
  let parsedInputTokens;
171
247
  let parsedOutputTokens;
248
+ // Tool-use telemetry (per-stage metrics aggregation).
249
+ let toolUseCount = 0;
250
+ let toolErrorCount = 0;
172
251
  // Pipe prompt via stdin (like: echo "$prompt" | claude -p)
173
252
  child.stdin.write(options.prompt);
174
253
  child.stdin.end();
@@ -228,6 +307,22 @@ export async function spawnAgent(options) {
228
307
  parsedOutputTokens = usage.output_tokens;
229
308
  }
230
309
  }
310
+ else if (obj.type === 'assistant') {
311
+ const msg = obj.message;
312
+ const content = (msg?.content ?? []);
313
+ for (const block of content) {
314
+ if (block.type === 'tool_use')
315
+ toolUseCount++;
316
+ }
317
+ }
318
+ else if (obj.type === 'user') {
319
+ const msg = obj.message;
320
+ const content = (msg?.content ?? []);
321
+ for (const block of content) {
322
+ if (block.type === 'tool_result' && block.is_error === true)
323
+ toolErrorCount++;
324
+ }
325
+ }
231
326
  }
232
327
  catch { /* not valid JSON, ignore */ }
233
328
  const formatted = formatStreamJsonLine(line);
@@ -264,6 +359,11 @@ export async function spawnAgent(options) {
264
359
  resolved = true;
265
360
  clearTimeout(timer);
266
361
  const duration = Date.now() - startTime;
362
+ // Fall back to output-string classification when we didn't see structured
363
+ // tool_result error blocks (e.g. non-stream-json agents like codex).
364
+ const toolErrorsFinal = toolErrorCount > 0
365
+ ? toolErrorCount
366
+ : classifyToolErrors(output).length;
267
367
  const result = {
268
368
  exitCode,
269
369
  output,
@@ -272,6 +372,8 @@ export async function spawnAgent(options) {
272
372
  costUsd: parsedCostUsd,
273
373
  inputTokens: parsedInputTokens,
274
374
  outputTokens: parsedOutputTokens,
375
+ toolCalls: toolUseCount,
376
+ toolErrors: toolErrorsFinal,
275
377
  };
276
378
  if (logStream) {
277
379
  logStream.end(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/lib/agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/lib/agent.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,52 @@ export type StepConfig = {
12
12
  };
13
13
  /** Per-step pipeline configuration. */
14
14
  export type PipelineConfig = Partial<Record<PipelineStepName, StepConfig>>;
15
+ /** The Loop stages that support per-stage routing (model + endpoint). */
16
+ export type RoutingStageName = 'plan' | 'build' | 'test_write' | 'test_exec' | 'review' | 'summary';
17
+ /** Per-stage routing configuration — targets a model on a named endpoint. */
18
+ export type RoutingStageConfig = {
19
+ model: string;
20
+ endpoint: string;
21
+ };
22
+ /** Endpoint protocol/API shape for a routing endpoint. */
23
+ export type RoutingEndpointType = 'anthropic' | 'anthropic_compat' | 'openai_compat';
24
+ /** A named endpoint that stages can route to. */
25
+ export type RoutingEndpoint = {
26
+ type: RoutingEndpointType;
27
+ base_url: string;
28
+ };
29
+ /** How the loop should behave when a routed stage errors out. */
30
+ export type RoutingFallbackMode = 'escalate' | 'retry' | 'fail';
31
+ /** Fallback behavior for routed stages. */
32
+ export type RoutingFallback = {
33
+ on_tool_error: RoutingFallbackMode;
34
+ escalate_to?: RoutingStageConfig;
35
+ /** Number of recent turns to track per stage for the rolling-error guardrail (default 10). */
36
+ escalation_window_issues?: number;
37
+ /** Rolling-error-rate threshold that triggers a stage revert (default 0.08 = 8%). */
38
+ escalation_error_threshold?: number;
39
+ /** How long a stage stays pinned to the fallback after the threshold fires (default 24h). */
40
+ escalation_revert_ms?: number;
41
+ };
42
+ /** Normalized fallback policy returned by getFallbackPolicy. */
43
+ export type FallbackPolicy = {
44
+ on_tool_error: RoutingFallbackMode;
45
+ escalate_to?: RoutingStageConfig;
46
+ escalation_window_issues: number;
47
+ escalation_error_threshold: number;
48
+ escalation_revert_ms: number;
49
+ };
50
+ /** Default guardrail values — 10-issue rolling window, 8% error threshold, 24-hour revert. */
51
+ export declare const DEFAULT_ESCALATION_WINDOW = 10;
52
+ export declare const DEFAULT_ESCALATION_ERROR_THRESHOLD = 0.08;
53
+ export declare const DEFAULT_ESCALATION_REVERT_MS: number;
54
+ /** Per-stage routing configuration for the Loop. */
55
+ export type RoutingConfig = {
56
+ profile?: string | string[];
57
+ stages?: Partial<Record<RoutingStageName, RoutingStageConfig>>;
58
+ endpoints?: Record<string, RoutingEndpoint>;
59
+ fallback?: RoutingFallback;
60
+ };
15
61
  /**
16
62
  * Estimate cost in USD from token counts and a pricing table.
17
63
  * Returns 0 if the model is not in the pricing table.
@@ -21,7 +67,7 @@ export type Config = {
21
67
  repo: string;
22
68
  repoOwner: string;
23
69
  project: number;
24
- agent: 'claude' | 'codex' | 'opencode';
70
+ agent: 'claude' | 'codex' | 'opencode' | 'lmstudio' | 'ollama';
25
71
  model: string;
26
72
  reviewModel: string;
27
73
  pollInterval: number;
@@ -71,6 +117,8 @@ export type Config = {
71
117
  pricing: Record<string, ModelPricing>;
72
118
  /** Per-step agent/model overrides. */
73
119
  pipeline: PipelineConfig;
120
+ /** Optional per-stage Loop routing (model + endpoint). Absent => no routing applied. */
121
+ routing?: RoutingConfig;
74
122
  /** Include repo-specific agent prompts during eval runs (default: true). */
75
123
  evalIncludeAgentPrompts: boolean;
76
124
  /** Include repo-specific skills during eval runs (default: true). */
@@ -94,3 +142,27 @@ export declare function resolveStepConfig(config: Config, step: PipelineStepName
94
142
  agent: string;
95
143
  model: string;
96
144
  };
145
+ /**
146
+ * Resolve the model and endpoint for a specific Loop routing stage.
147
+ *
148
+ * Returns undefined when `config.routing` is absent or the stage isn't
149
+ * configured — callers should fall back to the existing top-level
150
+ * `agent`/`model` behavior in that case.
151
+ */
152
+ export declare function resolveRoutingStage(config: Config, stage: RoutingStageName): {
153
+ model: string;
154
+ endpoint?: RoutingEndpoint;
155
+ } | undefined;
156
+ /**
157
+ * Return the normalized fallback policy for a config, or null when routing has
158
+ * no fallback configured. Fills guardrail fields with defaults.
159
+ */
160
+ export declare function getFallbackPolicy(config: Config): FallbackPolicy | null;
161
+ /**
162
+ * Deterministically pick a profile name when `routing.profile` is a list.
163
+ *
164
+ * Returns the string profile directly if `profile` is a single string, or a
165
+ * deterministic choice based on `issueId` when it's an array — so reruns of
166
+ * the same issue pick the same profile for reproducible A/B evaluation.
167
+ */
168
+ export declare function selectRoutingProfile(config: Config, issueId?: number): string | undefined;
@@ -1,6 +1,28 @@
1
1
  import { readFileSync, existsSync } from 'node:fs';
2
2
  import { execSync } from 'node:child_process';
3
3
  import { parse as parseYaml } from 'yaml';
4
+ /** Default guardrail values — 10-issue rolling window, 8% error threshold, 24-hour revert. */
5
+ export const DEFAULT_ESCALATION_WINDOW = 10;
6
+ export const DEFAULT_ESCALATION_ERROR_THRESHOLD = 0.08;
7
+ export const DEFAULT_ESCALATION_REVERT_MS = 24 * 60 * 60 * 1000;
8
+ const VALID_ROUTING_STAGES = [
9
+ 'plan',
10
+ 'build',
11
+ 'test_write',
12
+ 'test_exec',
13
+ 'review',
14
+ 'summary',
15
+ ];
16
+ const VALID_ENDPOINT_TYPES = [
17
+ 'anthropic',
18
+ 'anthropic_compat',
19
+ 'openai_compat',
20
+ ];
21
+ const VALID_FALLBACK_MODES = [
22
+ 'escalate',
23
+ 'retry',
24
+ 'fail',
25
+ ];
4
26
  /**
5
27
  * Estimate cost in USD from token counts and a pricing table.
6
28
  * Returns 0 if the model is not in the pricing table.
@@ -63,6 +85,9 @@ const DEFAULTS = {
63
85
  'gpt-4o-mini': { input: 0.15, output: 0.60 },
64
86
  'deepseek-v3': { input: 0.27, output: 1.10 },
65
87
  'gemini-2.5-flash': { input: 0.15, output: 0.60 },
88
+ 'qwen3-coder-30b-a3b': { input: 0, output: 0 },
89
+ 'gemma-4-31b': { input: 0, output: 0 },
90
+ 'glm-4.6': { input: 0, output: 0 },
66
91
  },
67
92
  pipeline: {},
68
93
  evalIncludeAgentPrompts: true,
@@ -195,6 +220,122 @@ export function detectRepo() {
195
220
  }
196
221
  return null;
197
222
  }
223
+ function parseRoutingStage(raw) {
224
+ if (!raw || typeof raw !== 'object')
225
+ return undefined;
226
+ const r = raw;
227
+ if (typeof r.model !== 'string' || typeof r.endpoint !== 'string')
228
+ return undefined;
229
+ return { model: r.model, endpoint: r.endpoint };
230
+ }
231
+ function parseRoutingConfig(raw) {
232
+ if (!raw || typeof raw !== 'object')
233
+ return undefined;
234
+ const r = raw;
235
+ const result = {};
236
+ let populated = false;
237
+ if (typeof r.profile === 'string') {
238
+ result.profile = r.profile;
239
+ populated = true;
240
+ }
241
+ else if (Array.isArray(r.profile) && r.profile.every((p) => typeof p === 'string')) {
242
+ result.profile = r.profile;
243
+ populated = true;
244
+ }
245
+ const endpoints = {};
246
+ if (r.endpoints && typeof r.endpoints === 'object') {
247
+ for (const [name, value] of Object.entries(r.endpoints)) {
248
+ if (!value || typeof value !== 'object')
249
+ continue;
250
+ const v = value;
251
+ if (typeof v.type !== 'string' || typeof v.base_url !== 'string') {
252
+ console.warn(`[config] routing.endpoints.${name}: expected { type, base_url }`);
253
+ continue;
254
+ }
255
+ if (!VALID_ENDPOINT_TYPES.includes(v.type)) {
256
+ console.warn(`[config] routing.endpoints.${name}: invalid type "${v.type}" (expected one of ${VALID_ENDPOINT_TYPES.join(', ')})`);
257
+ continue;
258
+ }
259
+ endpoints[name] = { type: v.type, base_url: v.base_url };
260
+ }
261
+ if (Object.keys(endpoints).length > 0) {
262
+ result.endpoints = endpoints;
263
+ populated = true;
264
+ }
265
+ }
266
+ const stages = {};
267
+ if (r.stages && typeof r.stages === 'object') {
268
+ const stagesRaw = r.stages;
269
+ for (const [key, value] of Object.entries(stagesRaw)) {
270
+ if (!VALID_ROUTING_STAGES.includes(key)) {
271
+ console.warn(`[config] routing.stages.${key}: unknown stage name (ignored)`);
272
+ continue;
273
+ }
274
+ const parsed = parseRoutingStage(value);
275
+ if (!parsed) {
276
+ console.warn(`[config] routing.stages.${key}: expected { model, endpoint }`);
277
+ continue;
278
+ }
279
+ if (result.endpoints && !(parsed.endpoint in result.endpoints)) {
280
+ console.warn(`[config] routing.stages.${key}: endpoint "${parsed.endpoint}" is not defined in routing.endpoints (ignored)`);
281
+ continue;
282
+ }
283
+ stages[key] = parsed;
284
+ }
285
+ if (Object.keys(stages).length > 0) {
286
+ result.stages = stages;
287
+ populated = true;
288
+ }
289
+ }
290
+ if (r.fallback && typeof r.fallback === 'object') {
291
+ const f = r.fallback;
292
+ if (typeof f.on_tool_error === 'string' && VALID_FALLBACK_MODES.includes(f.on_tool_error)) {
293
+ const fallback = { on_tool_error: f.on_tool_error };
294
+ const escalate = parseRoutingStage(f.escalate_to);
295
+ if (escalate) {
296
+ if (result.endpoints && !(escalate.endpoint in result.endpoints)) {
297
+ console.warn(`[config] routing.fallback.escalate_to: endpoint "${escalate.endpoint}" is not defined in routing.endpoints (ignored)`);
298
+ }
299
+ else {
300
+ fallback.escalate_to = escalate;
301
+ }
302
+ }
303
+ if (f.escalation_window_issues !== undefined) {
304
+ if (typeof f.escalation_window_issues === 'number' && Number.isFinite(f.escalation_window_issues) && f.escalation_window_issues > 0) {
305
+ fallback.escalation_window_issues = Math.floor(f.escalation_window_issues);
306
+ }
307
+ else {
308
+ console.warn(`[config] routing.fallback.escalation_window_issues: expected a positive number (got ${String(f.escalation_window_issues)})`);
309
+ }
310
+ }
311
+ if (f.escalation_error_threshold !== undefined) {
312
+ if (typeof f.escalation_error_threshold === 'number' &&
313
+ Number.isFinite(f.escalation_error_threshold) &&
314
+ f.escalation_error_threshold >= 0 &&
315
+ f.escalation_error_threshold <= 1) {
316
+ fallback.escalation_error_threshold = f.escalation_error_threshold;
317
+ }
318
+ else {
319
+ console.warn(`[config] routing.fallback.escalation_error_threshold: expected a number between 0 and 1 (got ${String(f.escalation_error_threshold)})`);
320
+ }
321
+ }
322
+ if (f.escalation_revert_ms !== undefined) {
323
+ if (typeof f.escalation_revert_ms === 'number' && Number.isFinite(f.escalation_revert_ms) && f.escalation_revert_ms > 0) {
324
+ fallback.escalation_revert_ms = Math.floor(f.escalation_revert_ms);
325
+ }
326
+ else {
327
+ console.warn(`[config] routing.fallback.escalation_revert_ms: expected a positive number of milliseconds (got ${String(f.escalation_revert_ms)})`);
328
+ }
329
+ }
330
+ result.fallback = fallback;
331
+ populated = true;
332
+ }
333
+ else if (f.on_tool_error !== undefined) {
334
+ console.warn(`[config] routing.fallback.on_tool_error: invalid value "${String(f.on_tool_error)}" (expected one of ${VALID_FALLBACK_MODES.join(', ')})`);
335
+ }
336
+ }
337
+ return populated ? result : undefined;
338
+ }
198
339
  function loadYamlConfig(configPath) {
199
340
  if (!existsSync(configPath))
200
341
  return {};
@@ -246,6 +387,13 @@ function loadYamlConfig(configPath) {
246
387
  if (ev.include_skills === false)
247
388
  result.evalIncludeSkills = false;
248
389
  }
390
+ // Handle routing nested config (per-stage model + endpoint)
391
+ if (parsed.routing !== undefined) {
392
+ const routing = parseRoutingConfig(parsed.routing);
393
+ if (routing) {
394
+ result.routing = routing;
395
+ }
396
+ }
249
397
  // Handle pricing table (nested object, not in YAML_KEY_MAP)
250
398
  if (parsed.pricing && typeof parsed.pricing === 'object') {
251
399
  const pricing = {};
@@ -299,6 +447,8 @@ export function loadConfig(overrides) {
299
447
  ...(overrides?.pipeline?.[step] ?? {}),
300
448
  };
301
449
  }
450
+ // Routing precedence is whole-object replacement (overrides > yaml > undefined).
451
+ const routing = overrides?.routing ?? yamlConfig.routing;
302
452
  const merged = {
303
453
  ...DEFAULTS,
304
454
  ...autoDetect,
@@ -307,9 +457,10 @@ export function loadConfig(overrides) {
307
457
  ...overrides,
308
458
  pricing: mergedPricing,
309
459
  pipeline: mergedPipeline,
460
+ routing,
310
461
  };
311
462
  // Validate agent is a known value
312
- const VALID_AGENTS = ['claude', 'codex', 'opencode'];
463
+ const VALID_AGENTS = ['claude', 'codex', 'opencode', 'lmstudio', 'ollama'];
313
464
  if (!VALID_AGENTS.includes(merged.agent)) {
314
465
  throw new Error(`Invalid agent: "${merged.agent}". Supported agents: ${VALID_AGENTS.join(', ')}`);
315
466
  }
@@ -333,4 +484,66 @@ export function resolveStepConfig(config, step) {
333
484
  const model = stepOverride?.model ?? fallbackModel;
334
485
  return { agent, model };
335
486
  }
487
+ // FNV-1a 32-bit hash of a string. Stable across runs so A/B profile selection
488
+ // is deterministic for a given issueId — needed for reproducible reruns.
489
+ function fnv1a32(input) {
490
+ let hash = 0x811c9dc5;
491
+ for (let i = 0; i < input.length; i++) {
492
+ hash ^= input.charCodeAt(i);
493
+ hash = (hash + ((hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24))) >>> 0;
494
+ }
495
+ return hash >>> 0;
496
+ }
497
+ /**
498
+ * Resolve the model and endpoint for a specific Loop routing stage.
499
+ *
500
+ * Returns undefined when `config.routing` is absent or the stage isn't
501
+ * configured — callers should fall back to the existing top-level
502
+ * `agent`/`model` behavior in that case.
503
+ */
504
+ export function resolveRoutingStage(config, stage) {
505
+ const routing = config.routing;
506
+ if (!routing)
507
+ return undefined;
508
+ const stageCfg = routing.stages?.[stage];
509
+ if (!stageCfg)
510
+ return undefined;
511
+ const endpoint = routing.endpoints?.[stageCfg.endpoint];
512
+ return { model: stageCfg.model, endpoint };
513
+ }
514
+ /**
515
+ * Return the normalized fallback policy for a config, or null when routing has
516
+ * no fallback configured. Fills guardrail fields with defaults.
517
+ */
518
+ export function getFallbackPolicy(config) {
519
+ const fallback = config.routing?.fallback;
520
+ if (!fallback)
521
+ return null;
522
+ return {
523
+ on_tool_error: fallback.on_tool_error,
524
+ escalate_to: fallback.escalate_to,
525
+ escalation_window_issues: fallback.escalation_window_issues ?? DEFAULT_ESCALATION_WINDOW,
526
+ escalation_error_threshold: fallback.escalation_error_threshold ?? DEFAULT_ESCALATION_ERROR_THRESHOLD,
527
+ escalation_revert_ms: fallback.escalation_revert_ms ?? DEFAULT_ESCALATION_REVERT_MS,
528
+ };
529
+ }
530
+ /**
531
+ * Deterministically pick a profile name when `routing.profile` is a list.
532
+ *
533
+ * Returns the string profile directly if `profile` is a single string, or a
534
+ * deterministic choice based on `issueId` when it's an array — so reruns of
535
+ * the same issue pick the same profile for reproducible A/B evaluation.
536
+ */
537
+ export function selectRoutingProfile(config, issueId) {
538
+ const profile = config.routing?.profile;
539
+ if (!profile)
540
+ return undefined;
541
+ if (typeof profile === 'string')
542
+ return profile;
543
+ if (profile.length === 0)
544
+ return undefined;
545
+ if (profile.length === 1 || issueId === undefined)
546
+ return profile[0];
547
+ return profile[fnv1a32(String(issueId)) % profile.length];
548
+ }
336
549
  //# sourceMappingURL=config.js.map