@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,235 @@
1
+ /**
2
+ * Smoke tests for gaia-hardness predictor — ADR-136 Track Q
3
+ *
4
+ * All tests are mock-based (no live API calls, no HF token, $0 cost).
5
+ *
6
+ * Test matrix:
7
+ * 1. Feature extraction: math question fires requiresMath + qword_calc
8
+ * 2. Feature extraction: simple factual question has low complexity signal
9
+ * 3. Feature extraction: question with file attachment fires has_file_attachment
10
+ * 4. Feature extraction: multi-hop question fires multi_hop_signal
11
+ * 5. Cold-start fallback: untrained predictor returns medium with confidence=0.5
12
+ * 6. Train on mock data: predictor becomes trained after ≥ 10 examples
13
+ * 7. Trained predictor: math-heavy question predicts harder than trivial question
14
+ * 8. Export/import: weights round-trip through JSON without loss
15
+ *
16
+ * Refs: ADR-136, #2156
17
+ */
18
+ import assert from 'node:assert/strict';
19
+ import { extractFeatures, FEATURE_LABELS } from './features.js';
20
+ import { HardnessPredictor } from './predictor.js';
21
+ // ---------------------------------------------------------------------------
22
+ // Fixture helpers
23
+ // ---------------------------------------------------------------------------
24
+ function makeQuestion(text, overrides = {}) {
25
+ return {
26
+ task_id: 'smoke-test',
27
+ level: 1,
28
+ question: text,
29
+ final_answer: 'X',
30
+ file_name: null,
31
+ file_path: null,
32
+ ...overrides,
33
+ };
34
+ }
35
+ function labelIndex(label) {
36
+ return FEATURE_LABELS.indexOf(label);
37
+ }
38
+ // ---------------------------------------------------------------------------
39
+ // Test 1: Math question fires expected features
40
+ // ---------------------------------------------------------------------------
41
+ function testMathQuestionFeatures() {
42
+ const q = makeQuestion('What is 15 multiplied by 4? Calculate the exact product.');
43
+ const fv = extractFeatures(q);
44
+ const calcIdx = labelIndex('qword_calc_compute');
45
+ const mathIdx = labelIndex('requires_math');
46
+ const numIdx = labelIndex('has_numeric');
47
+ assert.ok(calcIdx >= 0, 'qword_calc_compute feature not found');
48
+ assert.ok(mathIdx >= 0, 'requires_math feature not found');
49
+ assert.ok(numIdx >= 0, 'has_numeric feature not found');
50
+ assert.equal(fv.values[numIdx], 1, 'has_numeric should be 1 for "15 multiplied by 4"');
51
+ // "Calculate" or "what" triggers calc compute or requires_math
52
+ const eitherMath = fv.values[calcIdx] === 1 || fv.values[mathIdx] === 1;
53
+ assert.ok(eitherMath, 'math question should fire qword_calc_compute or requires_math');
54
+ console.log(' [PASS] Test 1: math question fires expected features');
55
+ }
56
+ // ---------------------------------------------------------------------------
57
+ // Test 2: Simple factual question has low complexity
58
+ // ---------------------------------------------------------------------------
59
+ function testSimpleFactualQuestion() {
60
+ const q = makeQuestion('What is the capital of France?');
61
+ const fv = extractFeatures(q);
62
+ assert.equal(fv.values.length, 17, 'feature vector should have 17 dims');
63
+ const multiHopIdx = labelIndex('multi_hop_signal');
64
+ const toolIdx = labelIndex('tool_implication_norm');
65
+ const fileIdx = labelIndex('has_file_attachment');
66
+ assert.equal(fv.values[multiHopIdx], 0, 'simple question should have no multi-hop signal');
67
+ assert.equal(fv.values[toolIdx], 0, 'simple question should have no tool implication');
68
+ assert.equal(fv.values[fileIdx], 0, 'simple question should have no file attachment');
69
+ // Word count should be normalised well below 1
70
+ const wordNormIdx = labelIndex('len_words_norm');
71
+ assert.ok(fv.values[wordNormIdx] < 0.3, 'short question should have normalised word count < 0.3');
72
+ console.log(' [PASS] Test 2: simple factual question has low complexity signal');
73
+ }
74
+ // ---------------------------------------------------------------------------
75
+ // Test 3: File attachment fires has_file_attachment
76
+ // ---------------------------------------------------------------------------
77
+ function testFileAttachmentFeature() {
78
+ const q = makeQuestion('Analyse the attached PDF document and extract the table.', {
79
+ file_name: 'document.pdf',
80
+ file_path: '/tmp/document.pdf',
81
+ });
82
+ const fv = extractFeatures(q);
83
+ const fileIdx = labelIndex('has_file_attachment');
84
+ const toolIdx = labelIndex('tool_implication_norm');
85
+ assert.equal(fv.values[fileIdx], 1, 'question with file_name should have has_file_attachment=1');
86
+ assert.ok(fv.values[toolIdx] > 0, 'PDF question should have tool_implication > 0');
87
+ console.log(' [PASS] Test 3: file attachment fires has_file_attachment');
88
+ }
89
+ // ---------------------------------------------------------------------------
90
+ // Test 4: Multi-hop question fires multi_hop_signal
91
+ // ---------------------------------------------------------------------------
92
+ function testMultiHopFeature() {
93
+ const q = makeQuestion('Who was the president of the country that won the most gold medals at the Olympics that was held in the city that hosted the 1936 Games?');
94
+ const fv = extractFeatures(q);
95
+ const multiHopIdx = labelIndex('multi_hop_signal');
96
+ assert.equal(fv.values[multiHopIdx], 1, 'multi-hop question should fire multi_hop_signal');
97
+ console.log(' [PASS] Test 4: multi-hop question fires multi_hop_signal');
98
+ }
99
+ // ---------------------------------------------------------------------------
100
+ // Test 5: Cold-start fallback returns medium with confidence=0.5
101
+ // ---------------------------------------------------------------------------
102
+ function testColdStartFallback() {
103
+ const predictor = new HardnessPredictor();
104
+ assert.equal(predictor.isTrained, false, 'new predictor should not be trained');
105
+ const q = makeQuestion('What is the capital of France?');
106
+ const result = predictor.predict(q);
107
+ assert.equal(result.difficulty, 'medium', 'cold-start should return medium');
108
+ assert.equal(result.confidence, 0.5, 'cold-start should return confidence=0.5');
109
+ assert.equal(result.budget.model, 'sonnet', 'medium budget should use sonnet');
110
+ assert.equal(result.budget.maxTurns, 8, 'medium budget should have maxTurns=8');
111
+ assert.equal(result.budget.votingAttempts, 1, 'medium budget should have votingAttempts=1');
112
+ console.log(' [PASS] Test 5: cold-start fallback returns medium with confidence=0.5');
113
+ }
114
+ // ---------------------------------------------------------------------------
115
+ // Test 6: Becomes trained after ≥ 10 labelled examples
116
+ // ---------------------------------------------------------------------------
117
+ function testBecomesTrainedWith10Examples() {
118
+ const predictor = new HardnessPredictor();
119
+ // Generate 15 mock examples (mix of correct/incorrect)
120
+ const examples = [];
121
+ for (let i = 0; i < 15; i++) {
122
+ examples.push({
123
+ question: makeQuestion(`Mock question number ${i} about topic ${i % 3}`),
124
+ wasCorrect: i % 3 !== 0,
125
+ turns: 3 + (i % 6),
126
+ });
127
+ }
128
+ assert.equal(predictor.isTrained, false, 'should not be trained before training');
129
+ predictor.train(examples);
130
+ assert.equal(predictor.isTrained, true, 'should be trained after ≥10 examples');
131
+ console.log(' [PASS] Test 6: predictor becomes trained after ≥ 10 examples');
132
+ }
133
+ // ---------------------------------------------------------------------------
134
+ // Test 7: Trained predictor scores math question harder than trivial question
135
+ // ---------------------------------------------------------------------------
136
+ function testTrainedRelativeHardness() {
137
+ const predictor = new HardnessPredictor({ conservativeMode: false });
138
+ // Train on 20 examples with clear pattern:
139
+ // - Short simple questions → correct (easy)
140
+ // - Long multi-step questions → incorrect (hard)
141
+ const examples = [];
142
+ for (let i = 0; i < 10; i++) {
143
+ examples.push({
144
+ question: makeQuestion(`What is the capital of country ${i}?`),
145
+ wasCorrect: true,
146
+ turns: 2,
147
+ });
148
+ examples.push({
149
+ question: makeQuestion(`Calculate the exact percentage difference between ${i * 100} and ${i * 100 + 50}, ` +
150
+ `then multiply by the number of years between 1990 and 2023. ` +
151
+ `Express as a decimal rounded to 3 places.`),
152
+ wasCorrect: false,
153
+ turns: 12,
154
+ });
155
+ }
156
+ predictor.train(examples);
157
+ const trivialQ = makeQuestion('What is the capital of France?');
158
+ const mathQ = makeQuestion('Calculate the exact percentage difference between 750 and 1250, ' +
159
+ 'then multiply by the number of years between 1990 and 2023. ' +
160
+ 'Express as a decimal rounded to 3 places.');
161
+ const trivialResult = predictor.predict(trivialQ);
162
+ const mathResult = predictor.predict(mathQ);
163
+ // The difficulty ordering should not put math as easier than trivial.
164
+ const ORDER = { easy: 0, medium: 1, hard: 2 };
165
+ assert.ok(ORDER[mathResult.difficulty] >= ORDER[trivialResult.difficulty], `math question (${mathResult.difficulty}) should be ≥ trivial (${trivialResult.difficulty})`);
166
+ console.log(` [PASS] Test 7: math="${mathResult.difficulty}" (conf=${mathResult.confidence.toFixed(2)}) ≥ trivial="${trivialResult.difficulty}" (conf=${trivialResult.confidence.toFixed(2)})`);
167
+ }
168
+ // ---------------------------------------------------------------------------
169
+ // Test 8: Weights round-trip through JSON export/import
170
+ // ---------------------------------------------------------------------------
171
+ function testWeightRoundTrip() {
172
+ const predictor = new HardnessPredictor();
173
+ const examples = [];
174
+ for (let i = 0; i < 12; i++) {
175
+ examples.push({
176
+ question: makeQuestion(`Question ${i}`),
177
+ wasCorrect: i % 2 === 0,
178
+ turns: 4 + i,
179
+ });
180
+ }
181
+ predictor.train(examples);
182
+ const exported = predictor.export();
183
+ assert.ok(exported !== null, 'exported state should not be null after training');
184
+ const predictor2 = new HardnessPredictor();
185
+ predictor2.import(exported);
186
+ assert.equal(predictor2.isTrained, true, 'imported predictor should be trained');
187
+ // Both predictors should give the same result for the same question.
188
+ const q = makeQuestion('How many sides does a hexagon have?');
189
+ const r1 = predictor.predict(q);
190
+ const r2 = predictor2.predict(q);
191
+ assert.equal(r1.difficulty, r2.difficulty, 'exported/imported predictor should give same difficulty');
192
+ assert.ok(Math.abs(r1.confidence - r2.confidence) < 0.001, 'exported/imported predictor should give same confidence');
193
+ console.log(' [PASS] Test 8: weights round-trip through export/import without loss');
194
+ }
195
+ // ---------------------------------------------------------------------------
196
+ // Runner
197
+ // ---------------------------------------------------------------------------
198
+ async function runSmoke() {
199
+ console.log('\n=== gaia-hardness predictor.smoke.ts — ADR-136 Track Q ===');
200
+ console.log('(mock-based, no live API, $0 cost)\n');
201
+ let passed = 0;
202
+ let total = 0;
203
+ function run(name, fn) {
204
+ total++;
205
+ try {
206
+ fn();
207
+ passed++;
208
+ }
209
+ catch (err) {
210
+ console.error(` [FAIL] ${name}: ${err instanceof Error ? err.message : String(err)}`);
211
+ }
212
+ }
213
+ run('Feature extraction: math question', testMathQuestionFeatures);
214
+ run('Feature extraction: simple factual', testSimpleFactualQuestion);
215
+ run('Feature extraction: file attachment', testFileAttachmentFeature);
216
+ run('Feature extraction: multi-hop signal', testMultiHopFeature);
217
+ run('Cold-start fallback: medium + confidence=0.5', testColdStartFallback);
218
+ run('Train: becomes trained with ≥10 examples', testBecomesTrainedWith10Examples);
219
+ run('Trained: math harder than trivial', testTrainedRelativeHardness);
220
+ run('Export/import: weights round-trip', testWeightRoundTrip);
221
+ console.log(`\n=== Summary: ${passed}/${total} tests passed ===`);
222
+ if (passed < total) {
223
+ process.exit(1);
224
+ }
225
+ }
226
+ // Run when invoked directly.
227
+ if (process.argv[1]?.endsWith('predictor.smoke.js') ||
228
+ process.argv[1]?.endsWith('predictor.smoke.ts')) {
229
+ runSmoke().catch((err) => {
230
+ console.error('Smoke crashed:', err);
231
+ process.exit(2);
232
+ });
233
+ }
234
+ export { runSmoke };
235
+ //# sourceMappingURL=predictor.smoke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"predictor.smoke.js","sourceRoot":"","sources":["../../../../src/benchmarks/gaia-hardness/predictor.smoke.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * GAIA Hardness Predictor — Training Data Loader (ADR-136 Track Q)
3
+ *
4
+ * Loads labelled training examples from prior bench-run result JSONs
5
+ * (iter-15, iter-23, iter-28 outputs) and converts them into the
6
+ * `LabeledExample[]` format consumed by `HardnessPredictor.train()`.
7
+ *
8
+ * Expected result JSON schema (matches gaia-bench --output json):
9
+ * {
10
+ * level: number,
11
+ * model: string,
12
+ * summary: { total, passed, passRate, estCostUsd, meanTurns, meanWallMs },
13
+ * results: [
14
+ * {
15
+ * task_id: string, question: string, model: string, correct: boolean,
16
+ * answer: string | null, expected_output: string, error?: string,
17
+ * turns?: number, wallMs?: number, inputTokens?: number, outputTokens?: number
18
+ * }
19
+ * ]
20
+ * }
21
+ *
22
+ * The file may contain either:
23
+ * (a) a single JSON object (one model run), or
24
+ * (b) a JSON array of objects (multi-model run from --models a,b,c), or
25
+ * (c) a text preamble followed by JSON (raw output from gaia-bench text mode
26
+ * — we scan for the first '[' or '{' and parse from there).
27
+ *
28
+ * Missing files are silently skipped (returns empty array).
29
+ * Malformed files emit a warning to stderr and are skipped.
30
+ *
31
+ * Default search paths (tried in order, first found wins per iter):
32
+ * /tmp/gaia-l1-full.json
33
+ * /tmp/gaia-l1-haiku.json
34
+ * /tmp/gaia-all-p1b.json
35
+ * /tmp/gaia-all-p2.json
36
+ * <custom paths passed by caller>
37
+ *
38
+ * Refs: ADR-136, #2156
39
+ */
40
+ import type { LabeledExample } from './predictor.js';
41
+ /** Default candidate paths for historical bench-run result JSONs. */
42
+ export declare const DEFAULT_RESULT_PATHS: readonly string[];
43
+ /**
44
+ * Load labelled training examples from historical bench-run result JSONs.
45
+ *
46
+ * @param additionalPaths - Extra file paths to scan beyond the defaults.
47
+ * @param verbose - If true, log loaded example counts to stderr.
48
+ * @returns Deduplicated array of LabeledExample (dedup by task_id, last write wins).
49
+ */
50
+ export declare function loadTrainingData(additionalPaths?: string[], verbose?: boolean): LabeledExample[];
51
+ //# sourceMappingURL=train-data-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"train-data-loader.d.ts","sourceRoot":"","sources":["../../../../src/benchmarks/gaia-hardness/train-data-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAMrD,qEAAqE;AACrE,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAMxC,CAAC;AAqIX;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,eAAe,GAAE,MAAM,EAAO,EAC9B,OAAO,UAAQ,GACd,cAAc,EAAE,CAoClB"}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * GAIA Hardness Predictor — Training Data Loader (ADR-136 Track Q)
3
+ *
4
+ * Loads labelled training examples from prior bench-run result JSONs
5
+ * (iter-15, iter-23, iter-28 outputs) and converts them into the
6
+ * `LabeledExample[]` format consumed by `HardnessPredictor.train()`.
7
+ *
8
+ * Expected result JSON schema (matches gaia-bench --output json):
9
+ * {
10
+ * level: number,
11
+ * model: string,
12
+ * summary: { total, passed, passRate, estCostUsd, meanTurns, meanWallMs },
13
+ * results: [
14
+ * {
15
+ * task_id: string, question: string, model: string, correct: boolean,
16
+ * answer: string | null, expected_output: string, error?: string,
17
+ * turns?: number, wallMs?: number, inputTokens?: number, outputTokens?: number
18
+ * }
19
+ * ]
20
+ * }
21
+ *
22
+ * The file may contain either:
23
+ * (a) a single JSON object (one model run), or
24
+ * (b) a JSON array of objects (multi-model run from --models a,b,c), or
25
+ * (c) a text preamble followed by JSON (raw output from gaia-bench text mode
26
+ * — we scan for the first '[' or '{' and parse from there).
27
+ *
28
+ * Missing files are silently skipped (returns empty array).
29
+ * Malformed files emit a warning to stderr and are skipped.
30
+ *
31
+ * Default search paths (tried in order, first found wins per iter):
32
+ * /tmp/gaia-l1-full.json
33
+ * /tmp/gaia-l1-haiku.json
34
+ * /tmp/gaia-all-p1b.json
35
+ * /tmp/gaia-all-p2.json
36
+ * <custom paths passed by caller>
37
+ *
38
+ * Refs: ADR-136, #2156
39
+ */
40
+ import * as fs from 'node:fs';
41
+ // ---------------------------------------------------------------------------
42
+ // Default result-file search paths
43
+ // ---------------------------------------------------------------------------
44
+ /** Default candidate paths for historical bench-run result JSONs. */
45
+ export const DEFAULT_RESULT_PATHS = [
46
+ '/tmp/gaia-l1-full.json',
47
+ '/tmp/gaia-l1-haiku.json',
48
+ '/tmp/gaia-all-p1b.json',
49
+ '/tmp/gaia-all-p2.json',
50
+ '/tmp/gaia-all-probe.json',
51
+ ];
52
+ // ---------------------------------------------------------------------------
53
+ // JSON extraction helper
54
+ // ---------------------------------------------------------------------------
55
+ /**
56
+ * Attempt to extract and parse a JSON value (object or array) from a string
57
+ * that may have a text preamble before the JSON.
58
+ *
59
+ * Strategy:
60
+ * 1. Find the first '[' — parse as array.
61
+ * 2. Find the first '{' — parse as object.
62
+ * 3. Return null on failure.
63
+ */
64
+ function extractJson(content) {
65
+ const bracketIdx = content.indexOf('[');
66
+ const braceIdx = content.indexOf('{');
67
+ // Prefer whichever appears first (handles both array and object formats).
68
+ const candidates = [];
69
+ if (bracketIdx >= 0)
70
+ candidates.push([bracketIdx, '[']);
71
+ if (braceIdx >= 0)
72
+ candidates.push([braceIdx, '{']);
73
+ candidates.sort((a, b) => a[0] - b[0]);
74
+ for (const [startIdx] of candidates) {
75
+ try {
76
+ return JSON.parse(content.slice(startIdx));
77
+ }
78
+ catch {
79
+ // Try next candidate.
80
+ }
81
+ }
82
+ return null;
83
+ }
84
+ // ---------------------------------------------------------------------------
85
+ // Parse a single file into RawBenchOutput[]
86
+ // ---------------------------------------------------------------------------
87
+ function parseBenchFile(filePath) {
88
+ let content;
89
+ try {
90
+ content = fs.readFileSync(filePath, 'utf-8');
91
+ }
92
+ catch {
93
+ return [];
94
+ }
95
+ const parsed = extractJson(content);
96
+ if (parsed === null) {
97
+ process.stderr.write(`[gaia-hardness] Warning: could not extract JSON from ${filePath}\n`);
98
+ return [];
99
+ }
100
+ // Normalise to array of RawBenchOutput.
101
+ const outputs = [];
102
+ if (Array.isArray(parsed)) {
103
+ for (const item of parsed) {
104
+ if (item && typeof item === 'object' && Array.isArray(item.results)) {
105
+ outputs.push(item);
106
+ }
107
+ }
108
+ }
109
+ else if (parsed !== null &&
110
+ typeof parsed === 'object' &&
111
+ Array.isArray(parsed.results)) {
112
+ outputs.push(parsed);
113
+ }
114
+ if (outputs.length === 0) {
115
+ process.stderr.write(`[gaia-hardness] Warning: no valid bench outputs found in ${filePath}\n`);
116
+ }
117
+ return outputs;
118
+ }
119
+ // ---------------------------------------------------------------------------
120
+ // Convert RawQuestionResult → LabeledExample
121
+ // ---------------------------------------------------------------------------
122
+ function toGaiaQuestion(r) {
123
+ return {
124
+ task_id: r.task_id,
125
+ level: 1, // level not stored in result JSON; default to 1
126
+ question: r.question,
127
+ final_answer: r.expected_output,
128
+ file_name: null,
129
+ file_path: null,
130
+ };
131
+ }
132
+ function toBenchLabeledExample(r) {
133
+ return {
134
+ question: toGaiaQuestion(r),
135
+ wasCorrect: Boolean(r.correct),
136
+ turns: r.turns,
137
+ };
138
+ }
139
+ // ---------------------------------------------------------------------------
140
+ // Public API
141
+ // ---------------------------------------------------------------------------
142
+ /**
143
+ * Load labelled training examples from historical bench-run result JSONs.
144
+ *
145
+ * @param additionalPaths - Extra file paths to scan beyond the defaults.
146
+ * @param verbose - If true, log loaded example counts to stderr.
147
+ * @returns Deduplicated array of LabeledExample (dedup by task_id, last write wins).
148
+ */
149
+ export function loadTrainingData(additionalPaths = [], verbose = false) {
150
+ const allPaths = [...DEFAULT_RESULT_PATHS, ...additionalPaths];
151
+ const seen = new Set();
152
+ const examples = [];
153
+ for (const filePath of allPaths) {
154
+ if (!fs.existsSync(filePath))
155
+ continue;
156
+ const outputs = parseBenchFile(filePath);
157
+ let fileCount = 0;
158
+ for (const output of outputs) {
159
+ for (const result of output.results) {
160
+ if (!result.task_id || typeof result.correct !== 'boolean')
161
+ continue;
162
+ const key = result.task_id;
163
+ if (seen.has(key))
164
+ continue; // first file wins (chronological order)
165
+ seen.add(key);
166
+ examples.push(toBenchLabeledExample(result));
167
+ fileCount++;
168
+ }
169
+ }
170
+ if (verbose && fileCount > 0) {
171
+ process.stderr.write(`[gaia-hardness] Loaded ${fileCount} examples from ${filePath}\n`);
172
+ }
173
+ }
174
+ if (verbose) {
175
+ process.stderr.write(`[gaia-hardness] Total training examples: ${examples.length}\n`);
176
+ }
177
+ return examples;
178
+ }
179
+ //# sourceMappingURL=train-data-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"train-data-loader.js","sourceRoot":"","sources":["../../../../src/benchmarks/gaia-hardness/train-data-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * GAIA Judge — ADR-133-PR6
3
+ *
4
+ * Two-stage answer scorer for the GAIA benchmark:
5
+ *
6
+ * Stage 1 — Fast path: normalized exact-match.
7
+ * Normalise = lowercase + strip surrounding whitespace + strip surrounding
8
+ * single/double quotes + collapse internal whitespace runs to one space.
9
+ * Roughly 30 % of GAIA Level-1 answers satisfy this; no API call required.
10
+ *
11
+ * Stage 2 — LLM-as-judge: when exact-match fails, ask Claude Sonnet whether
12
+ * the candidate answer is semantically equivalent to the ground truth.
13
+ * The prompt embeds GAIA's official evaluation guideline (see
14
+ * https://huggingface.co/datasets/gaia-benchmark/GAIA for full spec).
15
+ *
16
+ * Caching: judgment results are persisted under
17
+ * ~/.cache/ruflo/gaia/judgments/<hash>.json
18
+ * keyed on (question_id, candidate_answer, model_id, JUDGE_PROMPT_VERSION).
19
+ * Re-running the same pair hits the cache and returns instantly.
20
+ *
21
+ * API pattern: raw fetch() against https://api.anthropic.com/v1/messages —
22
+ * mirrors the pattern established in gaia-agent.ts (ADR-133-PR3).
23
+ *
24
+ * Refs: ADR-133, #2156
25
+ */
26
+ export interface JudgeResult {
27
+ questionId: string;
28
+ passed: boolean;
29
+ scoringPath: 'exact-match' | 'llm-judge' | 'cache';
30
+ candidateAnswer: string;
31
+ groundTruth: string;
32
+ judgeReason?: string;
33
+ judgeModel?: string;
34
+ judgeTokensIn?: number;
35
+ judgeTokensOut?: number;
36
+ judgeCostUsd?: number;
37
+ }
38
+ export interface JudgeOptions {
39
+ /** Default: 'claude-sonnet-4-6' */
40
+ judgeModel?: string;
41
+ /** Default: '~/.cache/ruflo/gaia/judgments/' */
42
+ cacheDir?: string;
43
+ skipCache?: boolean;
44
+ apiKey?: string;
45
+ }
46
+ /**
47
+ * GAIA normalisation as specified in the dataset paper:
48
+ * - strip surrounding whitespace
49
+ * - lowercase
50
+ * - strip a single pair of surrounding quotes (single or double)
51
+ * - collapse internal whitespace runs to one space
52
+ */
53
+ export declare function normaliseAnswer(raw: string | null | undefined): string;
54
+ /**
55
+ * Attempt to match a candidate numeric answer to an expected answer where the
56
+ * question implies a unit scale.
57
+ *
58
+ * Examples that this catches:
59
+ * candidate="17000", expected="17", question contains "thousand"
60
+ * → candidate / 1000 ≈ expected → MATCH
61
+ * candidate="17", expected="17000", question contains "thousand"
62
+ * → candidate × 1000 ≈ expected → MATCH (reverse direction)
63
+ *
64
+ * Returns true only when a numeric match is found under one of the scale
65
+ * multipliers mentioned in the question text. Returns false for non-numeric
66
+ * inputs or when no multiplier matches.
67
+ *
68
+ * @param candidate - The raw string from the model (may include commas/spaces).
69
+ * @param expected - The raw ground-truth string.
70
+ * @param questionText - The original question (used to detect multiplier words).
71
+ */
72
+ export declare function unitAwareNumberMatch(candidate: string, expected: string, questionText?: string): boolean;
73
+ /**
74
+ * Judge a single GAIA answer.
75
+ *
76
+ * @param question - Object with `id` (task_id), `expected` (ground truth),
77
+ * and optional `questionText` (the full question string,
78
+ * used for unit-aware numeric matching in Stage 1).
79
+ * @param candidateAnswer - The answer produced by the agent; `null` counts as a miss.
80
+ * @param options - Optional overrides (model, cache dir, API key, etc.).
81
+ * @returns - JudgeResult with pass/fail, scoring path, and cost metrics.
82
+ */
83
+ export declare function judgeAnswer(question: {
84
+ id: string;
85
+ expected: string;
86
+ questionText?: string;
87
+ }, candidateAnswer: string | null, options?: JudgeOptions): Promise<JudgeResult>;
88
+ //# sourceMappingURL=gaia-judge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gaia-judge.d.ts","sourceRoot":"","sources":["../../../src/benchmarks/gaia-judge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AA+BH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,aAAa,GAAG,WAAW,GAAG,OAAO,CAAC;IACnD,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAMD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAWtE;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAoCT;AAwMD;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,EACjE,eAAe,EAAE,MAAM,GAAG,IAAI,EAC9B,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,WAAW,CAAC,CAyFtB"}