@claude-flow/cli 3.10.3 → 3.10.5

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 (121) hide show
  1. package/dist/src/benchmarks/gaia-agent-planning.smoke.d.ts +18 -0
  2. package/dist/src/benchmarks/gaia-agent-planning.smoke.d.ts.map +1 -0
  3. package/dist/src/benchmarks/gaia-agent-planning.smoke.js +253 -0
  4. package/dist/src/benchmarks/gaia-agent-planning.smoke.js.map +1 -0
  5. package/dist/src/benchmarks/gaia-agent.d.ts +198 -0
  6. package/dist/src/benchmarks/gaia-agent.d.ts.map +1 -0
  7. package/dist/src/benchmarks/gaia-agent.js +651 -0
  8. package/dist/src/benchmarks/gaia-agent.js.map +1 -0
  9. package/dist/src/benchmarks/gaia-causal-memory.d.ts +133 -0
  10. package/dist/src/benchmarks/gaia-causal-memory.d.ts.map +1 -0
  11. package/dist/src/benchmarks/gaia-causal-memory.js +281 -0
  12. package/dist/src/benchmarks/gaia-causal-memory.js.map +1 -0
  13. package/dist/src/benchmarks/gaia-causal-memory.smoke.d.ts +22 -0
  14. package/dist/src/benchmarks/gaia-causal-memory.smoke.d.ts.map +1 -0
  15. package/dist/src/benchmarks/gaia-causal-memory.smoke.js +300 -0
  16. package/dist/src/benchmarks/gaia-causal-memory.smoke.js.map +1 -0
  17. package/dist/src/benchmarks/gaia-convergence.d.ts +138 -0
  18. package/dist/src/benchmarks/gaia-convergence.d.ts.map +1 -0
  19. package/dist/src/benchmarks/gaia-convergence.js +260 -0
  20. package/dist/src/benchmarks/gaia-convergence.js.map +1 -0
  21. package/dist/src/benchmarks/gaia-convergence.smoke.d.ts +19 -0
  22. package/dist/src/benchmarks/gaia-convergence.smoke.d.ts.map +1 -0
  23. package/dist/src/benchmarks/gaia-convergence.smoke.js +246 -0
  24. package/dist/src/benchmarks/gaia-convergence.smoke.js.map +1 -0
  25. package/dist/src/benchmarks/gaia-critic.d.ts +123 -0
  26. package/dist/src/benchmarks/gaia-critic.d.ts.map +1 -0
  27. package/dist/src/benchmarks/gaia-critic.js +312 -0
  28. package/dist/src/benchmarks/gaia-critic.js.map +1 -0
  29. package/dist/src/benchmarks/gaia-critic.smoke.d.ts +21 -0
  30. package/dist/src/benchmarks/gaia-critic.smoke.d.ts.map +1 -0
  31. package/dist/src/benchmarks/gaia-critic.smoke.js +327 -0
  32. package/dist/src/benchmarks/gaia-critic.smoke.js.map +1 -0
  33. package/dist/src/benchmarks/gaia-decomposer.d.ts +125 -0
  34. package/dist/src/benchmarks/gaia-decomposer.d.ts.map +1 -0
  35. package/dist/src/benchmarks/gaia-decomposer.js +350 -0
  36. package/dist/src/benchmarks/gaia-decomposer.js.map +1 -0
  37. package/dist/src/benchmarks/gaia-decomposer.smoke.d.ts +21 -0
  38. package/dist/src/benchmarks/gaia-decomposer.smoke.d.ts.map +1 -0
  39. package/dist/src/benchmarks/gaia-decomposer.smoke.js +228 -0
  40. package/dist/src/benchmarks/gaia-decomposer.smoke.js.map +1 -0
  41. package/dist/src/benchmarks/gaia-e2e-smoke.d.ts +27 -0
  42. package/dist/src/benchmarks/gaia-e2e-smoke.d.ts.map +1 -0
  43. package/dist/src/benchmarks/gaia-e2e-smoke.js +136 -0
  44. package/dist/src/benchmarks/gaia-e2e-smoke.js.map +1 -0
  45. package/dist/src/benchmarks/gaia-extract.smoke.d.ts +45 -0
  46. package/dist/src/benchmarks/gaia-extract.smoke.d.ts.map +1 -0
  47. package/dist/src/benchmarks/gaia-extract.smoke.js +242 -0
  48. package/dist/src/benchmarks/gaia-extract.smoke.js.map +1 -0
  49. package/dist/src/benchmarks/gaia-hardness/features.d.ts +46 -0
  50. package/dist/src/benchmarks/gaia-hardness/features.d.ts.map +1 -0
  51. package/dist/src/benchmarks/gaia-hardness/features.js +170 -0
  52. package/dist/src/benchmarks/gaia-hardness/features.js.map +1 -0
  53. package/dist/src/benchmarks/gaia-hardness/predictor.d.ts +105 -0
  54. package/dist/src/benchmarks/gaia-hardness/predictor.d.ts.map +1 -0
  55. package/dist/src/benchmarks/gaia-hardness/predictor.js +260 -0
  56. package/dist/src/benchmarks/gaia-hardness/predictor.js.map +1 -0
  57. package/dist/src/benchmarks/gaia-hardness/predictor.smoke.d.ts +20 -0
  58. package/dist/src/benchmarks/gaia-hardness/predictor.smoke.d.ts.map +1 -0
  59. package/dist/src/benchmarks/gaia-hardness/predictor.smoke.js +235 -0
  60. package/dist/src/benchmarks/gaia-hardness/predictor.smoke.js.map +1 -0
  61. package/dist/src/benchmarks/gaia-hardness/train-data-loader.d.ts +51 -0
  62. package/dist/src/benchmarks/gaia-hardness/train-data-loader.d.ts.map +1 -0
  63. package/dist/src/benchmarks/gaia-hardness/train-data-loader.js +179 -0
  64. package/dist/src/benchmarks/gaia-hardness/train-data-loader.js.map +1 -0
  65. package/dist/src/benchmarks/gaia-judge.d.ts +88 -0
  66. package/dist/src/benchmarks/gaia-judge.d.ts.map +1 -0
  67. package/dist/src/benchmarks/gaia-judge.js +437 -0
  68. package/dist/src/benchmarks/gaia-judge.js.map +1 -0
  69. package/dist/src/benchmarks/gaia-loader.d.ts +87 -0
  70. package/dist/src/benchmarks/gaia-loader.d.ts.map +1 -0
  71. package/dist/src/benchmarks/gaia-loader.js +326 -0
  72. package/dist/src/benchmarks/gaia-loader.js.map +1 -0
  73. package/dist/src/benchmarks/gaia-tools/file_read.d.ts +35 -0
  74. package/dist/src/benchmarks/gaia-tools/file_read.d.ts.map +1 -0
  75. package/dist/src/benchmarks/gaia-tools/file_read.js +403 -0
  76. package/dist/src/benchmarks/gaia-tools/file_read.js.map +1 -0
  77. package/dist/src/benchmarks/gaia-tools/grounded_query.d.ts +126 -0
  78. package/dist/src/benchmarks/gaia-tools/grounded_query.d.ts.map +1 -0
  79. package/dist/src/benchmarks/gaia-tools/grounded_query.js +225 -0
  80. package/dist/src/benchmarks/gaia-tools/grounded_query.js.map +1 -0
  81. package/dist/src/benchmarks/gaia-tools/index.d.ts +32 -0
  82. package/dist/src/benchmarks/gaia-tools/index.d.ts.map +1 -0
  83. package/dist/src/benchmarks/gaia-tools/index.js +36 -0
  84. package/dist/src/benchmarks/gaia-tools/index.js.map +1 -0
  85. package/dist/src/benchmarks/gaia-tools/types.d.ts +62 -0
  86. package/dist/src/benchmarks/gaia-tools/types.d.ts.map +1 -0
  87. package/dist/src/benchmarks/gaia-tools/types.js +12 -0
  88. package/dist/src/benchmarks/gaia-tools/types.js.map +1 -0
  89. package/dist/src/benchmarks/gaia-tools/web_search.d.ts +30 -0
  90. package/dist/src/benchmarks/gaia-tools/web_search.d.ts.map +1 -0
  91. package/dist/src/benchmarks/gaia-tools/web_search.js +210 -0
  92. package/dist/src/benchmarks/gaia-tools/web_search.js.map +1 -0
  93. package/dist/src/benchmarks/gaia-voting.d.ts +88 -0
  94. package/dist/src/benchmarks/gaia-voting.d.ts.map +1 -0
  95. package/dist/src/benchmarks/gaia-voting.js +297 -0
  96. package/dist/src/benchmarks/gaia-voting.js.map +1 -0
  97. package/dist/src/benchmarks/gaia-voting.smoke.d.ts +20 -0
  98. package/dist/src/benchmarks/gaia-voting.smoke.d.ts.map +1 -0
  99. package/dist/src/benchmarks/gaia-voting.smoke.js +332 -0
  100. package/dist/src/benchmarks/gaia-voting.smoke.js.map +1 -0
  101. package/dist/src/commands/gaia-bench.d.ts +40 -0
  102. package/dist/src/commands/gaia-bench.d.ts.map +1 -0
  103. package/dist/src/commands/gaia-bench.js +597 -0
  104. package/dist/src/commands/gaia-bench.js.map +1 -0
  105. package/dist/src/commands/index.d.ts.map +1 -1
  106. package/dist/src/commands/index.js +2 -0
  107. package/dist/src/commands/index.js.map +1 -1
  108. package/dist/src/commands/init.d.ts.map +1 -1
  109. package/dist/src/commands/init.js +41 -4
  110. package/dist/src/commands/init.js.map +1 -1
  111. package/dist/src/init/executor.d.ts.map +1 -1
  112. package/dist/src/init/executor.js +25 -6
  113. package/dist/src/init/executor.js.map +1 -1
  114. package/dist/src/init/mcp-generator.d.ts.map +1 -1
  115. package/dist/src/init/mcp-generator.js +9 -4
  116. package/dist/src/init/mcp-generator.js.map +1 -1
  117. package/dist/src/init/statusline-generator.d.ts.map +1 -1
  118. package/dist/src/init/statusline-generator.js +287 -642
  119. package/dist/src/init/statusline-generator.js.map +1 -1
  120. package/dist/tsconfig.tsbuildinfo +1 -1
  121. package/package.json +1 -1
@@ -0,0 +1,327 @@
1
+ /**
2
+ * GAIA Critic Smoke Tests — ADR-135 Track D
3
+ *
4
+ * Tests for the adversarial critic agent in gaia-critic.ts.
5
+ * All tests use mocked responses — NO live API calls.
6
+ *
7
+ * Test coverage:
8
+ * 1. Critic returns "pass" → no retry, immediately returns candidate
9
+ * 2. Critic returns "fail" with suggestedRevision → triggers one retry
10
+ * 3. Critic returns "fail" twice → retries exhausted, returns last candidate
11
+ * 4. Critic returns "uncertain" → treated as "pass", no retry
12
+ * 5. API error in critic → graceful fallback, returns candidate as-is
13
+ * 6. Malformed JSON from critic → fallback parser extracts verdict
14
+ *
15
+ * Usage (no API key required):
16
+ * npx tsx src/benchmarks/gaia-critic.smoke.ts
17
+ *
18
+ * Refs: ADR-135, #2156
19
+ */
20
+ import { criticReview, runGaiaAgentWithCritic, } from './gaia-critic.js';
21
+ // ---------------------------------------------------------------------------
22
+ // Test helpers
23
+ // ---------------------------------------------------------------------------
24
+ let passed = 0;
25
+ let failed = 0;
26
+ function assert(condition, message) {
27
+ if (condition) {
28
+ console.log(` PASS ${message}`);
29
+ passed++;
30
+ }
31
+ else {
32
+ console.error(` FAIL ${message}`);
33
+ failed++;
34
+ }
35
+ }
36
+ function assertEqual(actual, expected, message) {
37
+ assert(actual === expected, `${message} (expected ${String(expected)}, got ${String(actual)})`);
38
+ }
39
+ /** A minimal GaiaQuestion fixture. */
40
+ const FIXTURE_QUESTION = {
41
+ task_id: 'smoke-001',
42
+ level: 1,
43
+ question: 'What is the capital of France?',
44
+ final_answer: 'Paris',
45
+ file_name: null,
46
+ file_path: null,
47
+ };
48
+ /** Minimal GaiaAgentResult with a given finalAnswer. */
49
+ function makeAgentResult(finalAnswer, turns = 2) {
50
+ return {
51
+ questionId: FIXTURE_QUESTION.task_id,
52
+ finalAnswer,
53
+ turns,
54
+ toolCallsByName: { web_search: 1 },
55
+ totalInputTokens: 100,
56
+ totalOutputTokens: 50,
57
+ wallMs: 1200,
58
+ };
59
+ }
60
+ function installFetchMock(responses) {
61
+ let callIndex = 0;
62
+ const original = globalThis.fetch;
63
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
+ globalThis.fetch = async (_url, _init) => {
65
+ const resp = responses[Math.min(callIndex, responses.length - 1)];
66
+ callIndex++;
67
+ if (!resp.ok) {
68
+ return {
69
+ ok: false,
70
+ status: resp.status ?? 500,
71
+ text: async () => resp.text ?? 'Internal error',
72
+ json: async () => { throw new Error('not ok'); },
73
+ };
74
+ }
75
+ return {
76
+ ok: true,
77
+ status: 200,
78
+ json: async () => resp.body ?? {},
79
+ text: async () => JSON.stringify(resp.body ?? {}),
80
+ };
81
+ };
82
+ return () => { globalThis.fetch = original; };
83
+ }
84
+ /**
85
+ * Build a mock Anthropic response body containing a critic verdict JSON.
86
+ */
87
+ function mockCriticResponse(verdict, reasoning, suggestedRevision = '') {
88
+ const content = JSON.stringify({ verdict, reasoning, suggestedRevision });
89
+ return {
90
+ content: [{ type: 'text', text: content }],
91
+ usage: { input_tokens: 200, output_tokens: 40 },
92
+ };
93
+ }
94
+ /**
95
+ * Mock for runGaiaAgent that immediately returns a fixed result.
96
+ * We monkey-patch the module-level import by wrapping runGaiaAgentWithCritic
97
+ * via its options.catalogue approach — but since gaia-agent's runGaiaAgent is
98
+ * imported directly, we mock at the fetch level instead (the agent also calls
99
+ * the Anthropic API, so we intercept there).
100
+ *
101
+ * For the smoke tests we only exercise criticReview directly in Tests 1-6, and
102
+ * use a simplified version of runGaiaAgentWithCritic that pre-supplies a
103
+ * mocked agent result rather than actually calling the API for the agent run.
104
+ *
105
+ * This avoids needing to rewrite the import mechanism just for smoke tests.
106
+ */
107
+ // ---------------------------------------------------------------------------
108
+ // Test 1: critic returns "pass" → no retry
109
+ // ---------------------------------------------------------------------------
110
+ async function test1_criticPass() {
111
+ console.log('\nTest 1: critic returns "pass" → no retry');
112
+ const restore = installFetchMock([
113
+ { ok: true, body: mockCriticResponse('pass', 'Answer is correct.') },
114
+ ]);
115
+ try {
116
+ const verdict = await criticReview(FIXTURE_QUESTION, 'Paris', { steps: [{ tool: 'web_search', result: 'Paris is the capital' }], turns: 2 }, { model: 'claude-sonnet-4-6', apiKey: 'test-key' });
117
+ assertEqual(verdict.verdict, 'pass', 'verdict is "pass"');
118
+ assert(verdict.reasoning.length > 0, 'reasoning is non-empty');
119
+ assert(verdict.costUsd >= 0, 'costUsd is non-negative');
120
+ assert(!verdict.error, 'no error flag');
121
+ }
122
+ finally {
123
+ restore();
124
+ }
125
+ }
126
+ // ---------------------------------------------------------------------------
127
+ // Test 2: critic returns "fail" with suggestedRevision
128
+ // ---------------------------------------------------------------------------
129
+ async function test2_criticFail() {
130
+ console.log('\nTest 2: critic returns "fail" with suggestedRevision');
131
+ const restore = installFetchMock([
132
+ {
133
+ ok: true,
134
+ body: mockCriticResponse('fail', 'The answer is the wrong city.', 'Paris'),
135
+ },
136
+ ]);
137
+ try {
138
+ const verdict = await criticReview(FIXTURE_QUESTION, 'Lyon', { steps: [{ tool: 'web_search', result: 'Lyon is in France' }], turns: 1 }, { model: 'claude-sonnet-4-6', apiKey: 'test-key' });
139
+ assertEqual(verdict.verdict, 'fail', 'verdict is "fail"');
140
+ assert((verdict.suggestedRevision ?? '').length > 0, 'suggestedRevision is non-empty');
141
+ assertEqual(verdict.suggestedRevision, 'Paris', 'suggestedRevision is "Paris"');
142
+ }
143
+ finally {
144
+ restore();
145
+ }
146
+ }
147
+ // ---------------------------------------------------------------------------
148
+ // Test 3: critic returns "fail" twice → retries exhausted
149
+ // ---------------------------------------------------------------------------
150
+ async function test3_retriesExhausted() {
151
+ console.log('\nTest 3: critic fails twice → retries exhausted, returns last candidate');
152
+ // We test this at the runGaiaAgentWithCritic level.
153
+ // We need to mock BOTH the critic fetch calls AND the agent API calls.
154
+ // Strategy: sequence the mock responses in the order they will be called.
155
+ //
156
+ // Call sequence (with enableCritic=true, maxRetries=1):
157
+ // 1. runGaiaAgent attempt 1 → agent Anthropic API call (returns answer "Lyon")
158
+ // 2. criticReview attempt 1 → critic API call (returns "fail")
159
+ // 3. runGaiaAgent attempt 2 → agent Anthropic API call (returns answer "Marseille")
160
+ // 4. criticReview attempt 2 → critic API call (returns "fail")
161
+ //
162
+ // For simplicity we make the agent calls also return valid Anthropic responses
163
+ // that produce a FINAL_ANSWER (the agent code parses stop_reason=end_turn).
164
+ const agentResponseLyon = {
165
+ id: 'msg_01',
166
+ type: 'message',
167
+ role: 'assistant',
168
+ stop_reason: 'end_turn',
169
+ content: [{ type: 'text', text: 'FINAL_ANSWER: Lyon' }],
170
+ usage: { input_tokens: 150, output_tokens: 20 },
171
+ model: 'claude-haiku-4-5',
172
+ };
173
+ const agentResponseMarseille = {
174
+ id: 'msg_02',
175
+ type: 'message',
176
+ role: 'assistant',
177
+ stop_reason: 'end_turn',
178
+ content: [{ type: 'text', text: 'FINAL_ANSWER: Marseille' }],
179
+ usage: { input_tokens: 150, output_tokens: 20 },
180
+ model: 'claude-haiku-4-5',
181
+ };
182
+ const restore = installFetchMock([
183
+ { ok: true, body: agentResponseLyon }, // agent call 1
184
+ { ok: true, body: mockCriticResponse('fail', 'Wrong city.', 'Paris') }, // critic 1
185
+ { ok: true, body: agentResponseMarseille }, // agent call 2 (retry)
186
+ { ok: true, body: mockCriticResponse('fail', 'Still wrong.', 'Paris') }, // critic 2
187
+ ]);
188
+ try {
189
+ const result = await runGaiaAgentWithCritic(FIXTURE_QUESTION, {
190
+ enableCritic: true,
191
+ apiKey: 'test-key',
192
+ criticOptions: { apiKey: 'test-key', maxRetries: 1 },
193
+ });
194
+ assertEqual(result.retriesAttempted, 1, 'retriesAttempted is 1');
195
+ assertEqual(result.criticVerdicts.length, 2, 'two critic verdicts collected');
196
+ assertEqual(result.criticVerdicts[0].verdict, 'fail', 'first verdict is fail');
197
+ assertEqual(result.criticVerdicts[1].verdict, 'fail', 'second verdict is fail');
198
+ // Last candidate is returned regardless.
199
+ assert(result.finalAnswer !== null, 'finalAnswer is non-null (last candidate returned)');
200
+ }
201
+ finally {
202
+ restore();
203
+ }
204
+ }
205
+ // ---------------------------------------------------------------------------
206
+ // Test 4: critic returns "uncertain" → treated as "pass", no retry
207
+ // ---------------------------------------------------------------------------
208
+ async function test4_uncertainAsPass() {
209
+ console.log('\nTest 4: critic returns "uncertain" → treated as pass, no retry');
210
+ const restore = installFetchMock([
211
+ {
212
+ ok: true,
213
+ body: mockCriticResponse('uncertain', 'Cannot verify without more context.'),
214
+ },
215
+ ]);
216
+ try {
217
+ const verdict = await criticReview(FIXTURE_QUESTION, 'Paris', { steps: [], turns: 1 }, { model: 'claude-sonnet-4-6', apiKey: 'test-key' });
218
+ assertEqual(verdict.verdict, 'uncertain', 'verdict is "uncertain"');
219
+ // Verify orchestrator treats uncertain as pass (no retry fired).
220
+ // We simulate by checking the logic directly: uncertain !== 'fail', so loop
221
+ // body is skipped. We test it via runGaiaAgentWithCritic with a minimal
222
+ // agent mock that returns a final answer.
223
+ const agentResponseParis = {
224
+ id: 'msg_03',
225
+ type: 'message',
226
+ role: 'assistant',
227
+ stop_reason: 'end_turn',
228
+ content: [{ type: 'text', text: 'FINAL_ANSWER: Paris' }],
229
+ usage: { input_tokens: 100, output_tokens: 15 },
230
+ model: 'claude-haiku-4-5',
231
+ };
232
+ const restore2 = installFetchMock([
233
+ { ok: true, body: agentResponseParis }, // agent call
234
+ { ok: true, body: mockCriticResponse('uncertain', 'Cannot verify.') }, // critic
235
+ ]);
236
+ try {
237
+ const result = await runGaiaAgentWithCritic(FIXTURE_QUESTION, {
238
+ enableCritic: true,
239
+ apiKey: 'test-key',
240
+ criticOptions: { apiKey: 'test-key', maxRetries: 1 },
241
+ });
242
+ assertEqual(result.retriesAttempted, 0, 'no retries for uncertain verdict');
243
+ assertEqual(result.criticVerdicts.length, 1, 'one critic verdict collected');
244
+ assertEqual(result.criticVerdicts[0].verdict, 'uncertain', 'verdict is uncertain');
245
+ }
246
+ finally {
247
+ restore2();
248
+ }
249
+ }
250
+ finally {
251
+ restore();
252
+ }
253
+ }
254
+ // ---------------------------------------------------------------------------
255
+ // Test 5: API error in critic → graceful fallback
256
+ // ---------------------------------------------------------------------------
257
+ async function test5_apiErrorFallback() {
258
+ console.log('\nTest 5: API error in critic → graceful fallback, original candidate returned');
259
+ const restore = installFetchMock([
260
+ { ok: false, status: 529, text: 'Overloaded' },
261
+ ]);
262
+ try {
263
+ const verdict = await criticReview(FIXTURE_QUESTION, 'Paris', { steps: [], turns: 1 }, { model: 'claude-sonnet-4-6', apiKey: 'test-key' });
264
+ // On API error, critic returns uncertain with error flag — does not throw.
265
+ assertEqual(verdict.verdict, 'uncertain', 'verdict is "uncertain" on API error');
266
+ assert(verdict.error === true, 'error flag is set');
267
+ assert(verdict.costUsd === 0, 'costUsd is 0 on error');
268
+ assert(verdict.reasoning.includes('failed'), 'reasoning mentions failure');
269
+ }
270
+ finally {
271
+ restore();
272
+ }
273
+ }
274
+ // ---------------------------------------------------------------------------
275
+ // Test 6: malformed JSON from critic → fallback parser
276
+ // ---------------------------------------------------------------------------
277
+ async function test6_malformedJson() {
278
+ console.log('\nTest 6: malformed JSON from critic → fallback parser extracts verdict');
279
+ // Simulate Sonnet returning prose with embedded JSON fragment.
280
+ const malformedBody = {
281
+ content: [{
282
+ type: 'text',
283
+ text: 'After careful review, I believe the answer is wrong. {"verdict":"fail","reasoning":"Incorrect city","suggestedRevision":"Paris"} The agent should try again.',
284
+ }],
285
+ usage: { input_tokens: 180, output_tokens: 60 },
286
+ };
287
+ const restore = installFetchMock([
288
+ { ok: true, body: malformedBody },
289
+ ]);
290
+ try {
291
+ const verdict = await criticReview(FIXTURE_QUESTION, 'Lyon', { steps: [], turns: 1 }, { model: 'claude-sonnet-4-6', apiKey: 'test-key' });
292
+ // Fallback parser should extract "fail" from the embedded JSON.
293
+ assertEqual(verdict.verdict, 'fail', 'fallback parser extracts "fail" verdict');
294
+ assert(!verdict.error, 'no error flag for recoverable parse');
295
+ }
296
+ finally {
297
+ restore();
298
+ }
299
+ }
300
+ // ---------------------------------------------------------------------------
301
+ // Run all tests
302
+ // ---------------------------------------------------------------------------
303
+ async function main() {
304
+ console.log('=== GAIA Critic Smoke Tests (ADR-135 Track D) ===');
305
+ console.log('All tests use mocked responses — no live API calls.\n');
306
+ try {
307
+ await test1_criticPass();
308
+ await test2_criticFail();
309
+ await test3_retriesExhausted();
310
+ await test4_uncertainAsPass();
311
+ await test5_apiErrorFallback();
312
+ await test6_malformedJson();
313
+ }
314
+ catch (err) {
315
+ console.error('\nUnexpected test runner error:', err);
316
+ process.exit(1);
317
+ }
318
+ console.log(`\n=== Results: ${passed} passed, ${failed} failed ===`);
319
+ if (failed > 0) {
320
+ process.exit(1);
321
+ }
322
+ }
323
+ main().catch(err => {
324
+ console.error(err);
325
+ process.exit(1);
326
+ });
327
+ //# sourceMappingURL=gaia-critic.smoke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gaia-critic.smoke.js","sourceRoot":"","sources":["../../../src/benchmarks/gaia-critic.smoke.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * GAIA Question Decomposer — ADR-135 Track E
3
+ *
4
+ * Decomposes complex GAIA benchmark questions into 1-5 ordered sub-questions
5
+ * that can each be answered with a single tool call, then synthesizes the
6
+ * sub-answers into a final response.
7
+ *
8
+ * Motivation (iter 29 finding): tool quality is the bottleneck on L1 (~20.8%).
9
+ * Bad tools that fail on complex queries may succeed on focused sub-queries.
10
+ * This mimics what humans do at 92% on GAIA (decompose-then-solve).
11
+ * Expected L1 lift: +5-10pp on multi-step questions (~30-40% of L1 set).
12
+ *
13
+ * Design:
14
+ * - NEW standalone file only; NOT wired into gaia-bench.ts to avoid merge
15
+ * conflicts with in-flight iter 29/31/34/35/36 branches.
16
+ * Wiring is a small follow-up PR.
17
+ * - `decomposeQuestion()` — Haiku-cheap classification + decomposition
18
+ * (~$0.0003 per question).
19
+ * - `synthesizeFromSubAnswers()` — Sonnet synthesis from sub-answers
20
+ * (the sub-answers are the hard work; synthesis is just combination).
21
+ * - Atomic questions are returned as-is — no overhead when not needed.
22
+ * - Graceful fallback to atomic on API errors or malformed JSON.
23
+ *
24
+ * Cost discipline:
25
+ * - Decomposition uses claude-haiku-4-5 (~$0.0003/question).
26
+ * - Synthesis uses claude-sonnet-4-6 (~$0.002/question).
27
+ * - Total overhead per question (when decomposed): ~$0.002-0.003.
28
+ *
29
+ * Plugin sync TODO (follow-up PR after gaia-bench wiring):
30
+ * - Update plugins/ruflo-workflows/commands/gaia-run.md with --decompose flag.
31
+ * - Update plugins/ruflo-workflows/skills/gaia-debugging/SKILL.md: add
32
+ * decomposition as a recommended strategy for multi-step failures.
33
+ *
34
+ * Refs: ADR-135, ADR-133, iter 29 finding, #2156
35
+ */
36
+ export interface DecomposedQuestion {
37
+ /** The original unmodified question text. */
38
+ originalQuestion: string;
39
+ /**
40
+ * Ordered sub-questions in dependency order (1-5).
41
+ * If decomposed=false, contains exactly one entry equal to originalQuestion.
42
+ */
43
+ subQuestions: string[];
44
+ /**
45
+ * Brief hint for how to combine sub-answers into the final answer.
46
+ * Example: "Multiply the two values found in sub-questions 1 and 2."
47
+ */
48
+ synthesisHint: string;
49
+ /**
50
+ * true if the question was split into multiple sub-questions;
51
+ * false if it was deemed atomic (single lookup / single computation).
52
+ */
53
+ decomposed: boolean;
54
+ /** USD spent on the decomposition API call (0 if fallback/atomic). */
55
+ cost: number;
56
+ }
57
+ export interface DecomposerOptions {
58
+ /**
59
+ * Model to use for decomposition classification.
60
+ * Default: 'claude-haiku-4-5' (cheap).
61
+ */
62
+ model?: string;
63
+ /**
64
+ * Maximum sub-questions to produce when decomposing.
65
+ * Default: 5.
66
+ */
67
+ maxSubQuestions?: number;
68
+ /** API key override. Falls back to ANTHROPIC_API_KEY env var. */
69
+ apiKey?: string;
70
+ }
71
+ export interface SynthesizerOptions {
72
+ /**
73
+ * Model to use for final-answer synthesis.
74
+ * Default: 'claude-sonnet-4-6'.
75
+ */
76
+ model?: string;
77
+ /** API key override. Falls back to ANTHROPIC_API_KEY env var. */
78
+ apiKey?: string;
79
+ }
80
+ export interface SynthesisResult {
81
+ /** The synthesized final answer string. */
82
+ finalAnswer: string;
83
+ /** Brief reasoning that led to the final answer. */
84
+ reasoning: string;
85
+ /** USD spent on the synthesis API call. */
86
+ cost: number;
87
+ }
88
+ /**
89
+ * Decomposes a complex question into 1-5 sub-questions in dependency order,
90
+ * OR returns the question as-is if it is already atomic.
91
+ *
92
+ * Uses `claude-haiku-4-5` by default for cheap classification + decomposition
93
+ * (~$0.0003 per question).
94
+ *
95
+ * Heuristics the model uses internally for "should decompose":
96
+ * - Question contains "and", "then", "after", "if X …"
97
+ * - Question contains multiple named entities that must each be looked up
98
+ * - Question asks for a derived/computed answer (X of Y where Y must be found)
99
+ *
100
+ * Graceful degradation: on API errors or malformed JSON, returns the question
101
+ * as atomic so the calling agent can still attempt a direct answer.
102
+ *
103
+ * @param questionText - The full GAIA question text.
104
+ * @param options - Optional overrides (model, maxSubQuestions, apiKey).
105
+ * @returns - DecomposedQuestion with subQuestions and synthesisHint.
106
+ */
107
+ export declare function decomposeQuestion(questionText: string, options?: DecomposerOptions): Promise<DecomposedQuestion>;
108
+ /**
109
+ * Given a decomposed question and answers to each sub-question, synthesizes
110
+ * a final concise answer.
111
+ *
112
+ * Uses `claude-sonnet-4-6` by default for higher reasoning quality — the
113
+ * sub-answers contain the hard-won information; synthesis is recombination.
114
+ *
115
+ * Graceful degradation: on API errors or malformed JSON, returns the last
116
+ * sub-answer concatenated with reasoning note.
117
+ *
118
+ * @param decomposed - The DecomposedQuestion from `decomposeQuestion()`.
119
+ * @param subAnswers - Array of string answers, one per sub-question.
120
+ * Must be the same length as decomposed.subQuestions.
121
+ * @param options - Optional overrides (model, apiKey).
122
+ * @returns - SynthesisResult with finalAnswer, reasoning, and cost.
123
+ */
124
+ export declare function synthesizeFromSubAnswers(decomposed: DecomposedQuestion, subAnswers: string[], options?: SynthesizerOptions): Promise<SynthesisResult>;
125
+ //# sourceMappingURL=gaia-decomposer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gaia-decomposer.d.ts","sourceRoot":"","sources":["../../../src/benchmarks/gaia-decomposer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAsCH,MAAM,WAAW,kBAAkB;IACjC,6CAA6C;IAC7C,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;CACd;AA8LD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,kBAAkB,CAAC,CA+D7B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,kBAAkB,EAC9B,UAAU,EAAE,MAAM,EAAE,EACpB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,eAAe,CAAC,CAkF1B"}