claude-flow 3.10.4 → 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.
- package/package.json +1 -1
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-agent-planning.smoke.d.ts +18 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-agent-planning.smoke.js +253 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-agent.d.ts +198 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-agent.js +651 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-causal-memory.d.ts +133 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-causal-memory.js +281 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-causal-memory.smoke.d.ts +22 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-causal-memory.smoke.js +300 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-convergence.d.ts +138 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-convergence.js +260 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-convergence.smoke.d.ts +19 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-convergence.smoke.js +246 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-critic.d.ts +123 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-critic.js +312 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-critic.smoke.d.ts +21 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-critic.smoke.js +327 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-decomposer.d.ts +125 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-decomposer.js +350 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-decomposer.smoke.d.ts +21 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-decomposer.smoke.js +228 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-e2e-smoke.d.ts +27 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-e2e-smoke.js +136 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-extract.smoke.d.ts +45 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-extract.smoke.js +242 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-hardness/features.d.ts +46 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-hardness/features.js +170 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-hardness/predictor.d.ts +105 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-hardness/predictor.js +260 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-hardness/predictor.smoke.d.ts +20 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-hardness/predictor.smoke.js +235 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-hardness/train-data-loader.d.ts +51 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-hardness/train-data-loader.js +179 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-judge.d.ts +88 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-judge.js +437 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-loader.d.ts +87 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-loader.js +326 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-tools/file_read.d.ts +35 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-tools/file_read.js +403 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-tools/grounded_query.d.ts +126 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-tools/grounded_query.js +225 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-tools/index.d.ts +32 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-tools/index.js +36 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-tools/types.d.ts +62 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-tools/types.js +12 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-tools/web_search.d.ts +30 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-tools/web_search.js +210 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-voting.d.ts +88 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-voting.js +297 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-voting.smoke.d.ts +20 -0
- package/v3/@claude-flow/cli/dist/src/benchmarks/gaia-voting.smoke.js +332 -0
- package/v3/@claude-flow/cli/dist/src/commands/gaia-bench.d.ts +40 -0
- package/v3/@claude-flow/cli/dist/src/commands/gaia-bench.js +597 -0
- package/v3/@claude-flow/cli/dist/src/commands/index.js +2 -0
- package/v3/@claude-flow/cli/dist/src/commands/init.js +41 -4
- package/v3/@claude-flow/cli/dist/src/init/executor.js +25 -6
- package/v3/@claude-flow/cli/dist/src/init/mcp-generator.js +9 -4
- package/v3/@claude-flow/cli/package.json +1 -1
|
@@ -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,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
|