@claude-flow/cli 3.11.0 → 3.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/dist/src/commands/doctor.d.ts.map +1 -1
  2. package/dist/src/commands/doctor.js +175 -1
  3. package/dist/src/commands/doctor.js.map +1 -1
  4. package/dist/src/commands/eject.d.ts +33 -0
  5. package/dist/src/commands/eject.d.ts.map +1 -0
  6. package/dist/src/commands/eject.js +195 -0
  7. package/dist/src/commands/eject.js.map +1 -0
  8. package/dist/src/commands/hooks.d.ts.map +1 -1
  9. package/dist/src/commands/hooks.js +2 -1
  10. package/dist/src/commands/hooks.js.map +1 -1
  11. package/dist/src/commands/index.d.ts.map +1 -1
  12. package/dist/src/commands/index.js +4 -0
  13. package/dist/src/commands/index.js.map +1 -1
  14. package/dist/src/commands/init.d.ts.map +1 -1
  15. package/dist/src/commands/init.js +3 -0
  16. package/dist/src/commands/init.js.map +1 -1
  17. package/dist/src/commands/metaharness.d.ts +39 -0
  18. package/dist/src/commands/metaharness.d.ts.map +1 -0
  19. package/dist/src/commands/metaharness.js +194 -0
  20. package/dist/src/commands/metaharness.js.map +1 -0
  21. package/dist/src/mcp-client.d.ts.map +1 -1
  22. package/dist/src/mcp-client.js +4 -0
  23. package/dist/src/mcp-client.js.map +1 -1
  24. package/dist/src/mcp-tools/index.d.ts +1 -0
  25. package/dist/src/mcp-tools/index.d.ts.map +1 -1
  26. package/dist/src/mcp-tools/index.js +2 -0
  27. package/dist/src/mcp-tools/index.js.map +1 -1
  28. package/dist/src/mcp-tools/metaharness-tools.d.ts +31 -0
  29. package/dist/src/mcp-tools/metaharness-tools.d.ts.map +1 -0
  30. package/dist/src/mcp-tools/metaharness-tools.js +372 -0
  31. package/dist/src/mcp-tools/metaharness-tools.js.map +1 -0
  32. package/dist/src/plugins/store/discovery.d.ts.map +1 -1
  33. package/dist/src/plugins/store/discovery.js +3 -0
  34. package/dist/src/plugins/store/discovery.js.map +1 -1
  35. package/dist/src/plugins/store/types.d.ts +6 -1
  36. package/dist/src/plugins/store/types.d.ts.map +1 -1
  37. package/dist/src/ruvector/model-router.d.ts.map +1 -1
  38. package/dist/src/ruvector/model-router.js +37 -0
  39. package/dist/src/ruvector/model-router.js.map +1 -1
  40. package/dist/src/ruvector/router-parallel-recorder.d.ts +127 -0
  41. package/dist/src/ruvector/router-parallel-recorder.d.ts.map +1 -0
  42. package/dist/src/ruvector/router-parallel-recorder.js +183 -0
  43. package/dist/src/ruvector/router-parallel-recorder.js.map +1 -0
  44. package/dist/tsconfig.tsbuildinfo +1 -1
  45. package/package.json +11 -9
  46. package/dist/src/benchmarks/capability-tasks.d.ts +0 -126
  47. package/dist/src/benchmarks/capability-tasks.d.ts.map +0 -1
  48. package/dist/src/benchmarks/capability-tasks.js +0 -147
  49. package/dist/src/benchmarks/capability-tasks.js.map +0 -1
  50. package/dist/src/benchmarks/gaia-agent-contrastive.d.ts +0 -53
  51. package/dist/src/benchmarks/gaia-agent-contrastive.d.ts.map +0 -1
  52. package/dist/src/benchmarks/gaia-agent-contrastive.js +0 -177
  53. package/dist/src/benchmarks/gaia-agent-contrastive.js.map +0 -1
  54. package/dist/src/benchmarks/gaia-agent-gemini.d.ts +0 -51
  55. package/dist/src/benchmarks/gaia-agent-gemini.d.ts.map +0 -1
  56. package/dist/src/benchmarks/gaia-agent-gemini.js +0 -352
  57. package/dist/src/benchmarks/gaia-agent-gemini.js.map +0 -1
  58. package/dist/src/benchmarks/gaia-claude-p.d.ts +0 -105
  59. package/dist/src/benchmarks/gaia-claude-p.d.ts.map +0 -1
  60. package/dist/src/benchmarks/gaia-claude-p.js +0 -269
  61. package/dist/src/benchmarks/gaia-claude-p.js.map +0 -1
  62. package/dist/src/benchmarks/gaia-claude-p.smoke.d.ts +0 -20
  63. package/dist/src/benchmarks/gaia-claude-p.smoke.d.ts.map +0 -1
  64. package/dist/src/benchmarks/gaia-claude-p.smoke.js +0 -168
  65. package/dist/src/benchmarks/gaia-claude-p.smoke.js.map +0 -1
  66. package/dist/src/benchmarks/gaia-codeagent-runner.py +0 -556
  67. package/dist/src/benchmarks/gaia-codeagent.d.ts +0 -129
  68. package/dist/src/benchmarks/gaia-codeagent.d.ts.map +0 -1
  69. package/dist/src/benchmarks/gaia-codeagent.js +0 -590
  70. package/dist/src/benchmarks/gaia-codeagent.js.map +0 -1
  71. package/dist/src/benchmarks/gaia-codeagent.smoke.d.ts +0 -33
  72. package/dist/src/benchmarks/gaia-codeagent.smoke.d.ts.map +0 -1
  73. package/dist/src/benchmarks/gaia-codeagent.smoke.js +0 -241
  74. package/dist/src/benchmarks/gaia-codeagent.smoke.js.map +0 -1
  75. package/dist/src/benchmarks/gaia-dag-pilot.d.ts +0 -22
  76. package/dist/src/benchmarks/gaia-dag-pilot.d.ts.map +0 -1
  77. package/dist/src/benchmarks/gaia-dag-pilot.js +0 -158
  78. package/dist/src/benchmarks/gaia-dag-pilot.js.map +0 -1
  79. package/dist/src/benchmarks/gaia-dag.d.ts +0 -110
  80. package/dist/src/benchmarks/gaia-dag.d.ts.map +0 -1
  81. package/dist/src/benchmarks/gaia-dag.js +0 -658
  82. package/dist/src/benchmarks/gaia-dag.js.map +0 -1
  83. package/dist/src/benchmarks/gaia-dag.smoke.d.ts +0 -21
  84. package/dist/src/benchmarks/gaia-dag.smoke.d.ts.map +0 -1
  85. package/dist/src/benchmarks/gaia-dag.smoke.js +0 -290
  86. package/dist/src/benchmarks/gaia-dag.smoke.js.map +0 -1
  87. package/dist/src/benchmarks/gaia-ensemble-pilot.d.ts +0 -17
  88. package/dist/src/benchmarks/gaia-ensemble-pilot.d.ts.map +0 -1
  89. package/dist/src/benchmarks/gaia-ensemble-pilot.js +0 -106
  90. package/dist/src/benchmarks/gaia-ensemble-pilot.js.map +0 -1
  91. package/dist/src/benchmarks/gaia-ensemble.d.ts +0 -103
  92. package/dist/src/benchmarks/gaia-ensemble.d.ts.map +0 -1
  93. package/dist/src/benchmarks/gaia-ensemble.js +0 -462
  94. package/dist/src/benchmarks/gaia-ensemble.js.map +0 -1
  95. package/dist/src/benchmarks/gaia-gemini-pilot.d.ts +0 -17
  96. package/dist/src/benchmarks/gaia-gemini-pilot.d.ts.map +0 -1
  97. package/dist/src/benchmarks/gaia-gemini-pilot.js +0 -168
  98. package/dist/src/benchmarks/gaia-gemini-pilot.js.map +0 -1
  99. package/dist/src/benchmarks/gaia-mode-router.d.ts +0 -67
  100. package/dist/src/benchmarks/gaia-mode-router.d.ts.map +0 -1
  101. package/dist/src/benchmarks/gaia-mode-router.js +0 -126
  102. package/dist/src/benchmarks/gaia-mode-router.js.map +0 -1
  103. package/dist/src/benchmarks/gaia-mode-router.smoke.d.ts +0 -15
  104. package/dist/src/benchmarks/gaia-mode-router.smoke.d.ts.map +0 -1
  105. package/dist/src/benchmarks/gaia-mode-router.smoke.js +0 -131
  106. package/dist/src/benchmarks/gaia-mode-router.smoke.js.map +0 -1
  107. package/dist/src/benchmarks/gaia-tools/grounded_query.smoke.d.ts +0 -24
  108. package/dist/src/benchmarks/gaia-tools/grounded_query.smoke.d.ts.map +0 -1
  109. package/dist/src/benchmarks/gaia-tools/grounded_query.smoke.js +0 -276
  110. package/dist/src/benchmarks/gaia-tools/grounded_query.smoke.js.map +0 -1
  111. package/dist/src/benchmarks/gaia-tools/image_describe.d.ts +0 -45
  112. package/dist/src/benchmarks/gaia-tools/image_describe.d.ts.map +0 -1
  113. package/dist/src/benchmarks/gaia-tools/image_describe.js +0 -222
  114. package/dist/src/benchmarks/gaia-tools/image_describe.js.map +0 -1
  115. package/dist/src/benchmarks/gaia-tools/image_describe.smoke.d.ts +0 -24
  116. package/dist/src/benchmarks/gaia-tools/image_describe.smoke.d.ts.map +0 -1
  117. package/dist/src/benchmarks/gaia-tools/image_describe.smoke.js +0 -169
  118. package/dist/src/benchmarks/gaia-tools/image_describe.smoke.js.map +0 -1
  119. package/dist/src/benchmarks/gaia-tools/pdf_read.d.ts +0 -27
  120. package/dist/src/benchmarks/gaia-tools/pdf_read.d.ts.map +0 -1
  121. package/dist/src/benchmarks/gaia-tools/pdf_read.js +0 -226
  122. package/dist/src/benchmarks/gaia-tools/pdf_read.js.map +0 -1
  123. package/dist/src/benchmarks/gaia-tools/python_exec.d.ts +0 -31
  124. package/dist/src/benchmarks/gaia-tools/python_exec.d.ts.map +0 -1
  125. package/dist/src/benchmarks/gaia-tools/python_exec.js +0 -94
  126. package/dist/src/benchmarks/gaia-tools/python_exec.js.map +0 -1
  127. package/dist/src/benchmarks/gaia-tools/python_exec.smoke.d.ts +0 -13
  128. package/dist/src/benchmarks/gaia-tools/python_exec.smoke.d.ts.map +0 -1
  129. package/dist/src/benchmarks/gaia-tools/python_exec.smoke.js +0 -98
  130. package/dist/src/benchmarks/gaia-tools/python_exec.smoke.js.map +0 -1
  131. package/dist/src/benchmarks/gaia-tools/visit_webpage.d.ts +0 -52
  132. package/dist/src/benchmarks/gaia-tools/visit_webpage.d.ts.map +0 -1
  133. package/dist/src/benchmarks/gaia-tools/visit_webpage.js +0 -304
  134. package/dist/src/benchmarks/gaia-tools/visit_webpage.js.map +0 -1
  135. package/dist/src/benchmarks/gaia-tools/web_browse.d.ts +0 -61
  136. package/dist/src/benchmarks/gaia-tools/web_browse.d.ts.map +0 -1
  137. package/dist/src/benchmarks/gaia-tools/web_browse.js +0 -217
  138. package/dist/src/benchmarks/gaia-tools/web_browse.js.map +0 -1
  139. package/dist/src/benchmarks/gaia-tools/web_browse.smoke.d.ts +0 -26
  140. package/dist/src/benchmarks/gaia-tools/web_browse.smoke.d.ts.map +0 -1
  141. package/dist/src/benchmarks/gaia-tools/web_browse.smoke.js +0 -152
  142. package/dist/src/benchmarks/gaia-tools/web_browse.smoke.js.map +0 -1
  143. package/dist/src/benchmarks/gaia-tools/web_search.smoke.d.ts +0 -24
  144. package/dist/src/benchmarks/gaia-tools/web_search.smoke.d.ts.map +0 -1
  145. package/dist/src/benchmarks/gaia-tools/web_search.smoke.js +0 -311
  146. package/dist/src/benchmarks/gaia-tools/web_search.smoke.js.map +0 -1
  147. package/dist/src/benchmarks/gaia-visit-webpage.smoke.d.ts +0 -25
  148. package/dist/src/benchmarks/gaia-visit-webpage.smoke.d.ts.map +0 -1
  149. package/dist/src/benchmarks/gaia-visit-webpage.smoke.js +0 -304
  150. package/dist/src/benchmarks/gaia-visit-webpage.smoke.js.map +0 -1
  151. package/dist/src/commands/performance-capability.d.ts +0 -30
  152. package/dist/src/commands/performance-capability.d.ts.map +0 -1
  153. package/dist/src/commands/performance-capability.js +0 -349
  154. package/dist/src/commands/performance-capability.js.map +0 -1
@@ -1,169 +0,0 @@
1
- /**
2
- * Smoke tests for image_describe — ADR-133-PR5
3
- *
4
- * Run with:
5
- * cd v3/@claude-flow/cli
6
- * npx tsx src/benchmarks/gaia-tools/image_describe.smoke.ts
7
- *
8
- * Tests:
9
- * 1. URL image (Wikipedia logo PNG) — description contains 'wiki' or 'logo' or 'W'
10
- * 2. Missing API key — returns error string, does not crash
11
- * 3. Non-existent local file — returns error string, does not crash
12
- * 4. Invalid source (empty) — throws (caught by test harness)
13
- *
14
- * If ANTHROPIC_API_KEY is not set and gcloud is not available, Test 1 is
15
- * marked SKIP (not FAIL) — the tool's graceful error path is validated in
16
- * Test 2 instead.
17
- *
18
- * Cost estimate: ~$0.001 per live API call (Haiku vision, single small image).
19
- * Total smoke cost: ≤$0.001 (only Test 1 makes a live call).
20
- *
21
- * Refs: ADR-133, #2156
22
- */
23
- import { createImageDescribeTool } from './image_describe.js';
24
- async function runTest(name, fn) {
25
- try {
26
- await fn();
27
- return { name, status: 'PASS', message: 'OK' };
28
- }
29
- catch (e) {
30
- return { name, status: 'FAIL', message: String(e) };
31
- }
32
- }
33
- function assert(condition, msg) {
34
- if (!condition)
35
- throw new Error(`Assertion failed: ${msg}`);
36
- }
37
- // ---------------------------------------------------------------------------
38
- // Tests
39
- // ---------------------------------------------------------------------------
40
- // Test 1: Live API call — describe Wikipedia logo via URL.
41
- // SKIP if no API key is available (avoids failing in CI without credentials).
42
- async function testWikipediaLogo() {
43
- const hasApiKey = (process.env.ANTHROPIC_API_KEY ?? '').trim().length > 0;
44
- if (!hasApiKey) {
45
- // Try gcloud as a secondary check — if both are unavailable, skip.
46
- let gcpAvailable = false;
47
- try {
48
- const { execSync } = await import('node:child_process');
49
- const key = execSync('gcloud secrets versions access latest --secret=ANTHROPIC_API_KEY 2>/dev/null', { encoding: 'utf-8', timeout: 5_000 }).trim();
50
- gcpAvailable = key.length > 0;
51
- }
52
- catch {
53
- gcpAvailable = false;
54
- }
55
- if (!gcpAvailable) {
56
- // Signal SKIP by throwing a message the runner recognises.
57
- throw new Error('SKIP: ANTHROPIC_API_KEY not available — set env var to run live tests');
58
- }
59
- }
60
- const tool = createImageDescribeTool();
61
- const out = await tool.execute({
62
- // Small, stable public PNG — Wikipedia's logo.
63
- source: 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/80/Wikipedia-logo-v2.svg/200px-Wikipedia-logo-v2.svg.png',
64
- prompt: 'Describe the logo in one sentence.',
65
- });
66
- // Accept a graceful API error (e.g., rate limit) rather than failing the smoke.
67
- if (out.startsWith('[image_describe error]')) {
68
- // Surface as a warning but not a hard failure for CI without credentials.
69
- console.log(` [warn] API call returned error: ${out}`);
70
- return;
71
- }
72
- assert(out.includes('[image_describe:'), `Expected model tag in output, got:\n${out.slice(0, 300)}`);
73
- const lowerOut = out.toLowerCase();
74
- assert(lowerOut.includes('wiki') ||
75
- lowerOut.includes('logo') ||
76
- lowerOut.includes('globe') ||
77
- lowerOut.includes('puzzle') ||
78
- lowerOut.includes('encyclopedia'), `Expected description to mention logo/wiki/globe, got:\n${out.slice(0, 300)}`);
79
- }
80
- // Test 2: No API key supplied → returns error string without crashing.
81
- async function testMissingApiKey() {
82
- // Temporarily shadow the env var to simulate missing key.
83
- const savedKey = process.env.ANTHROPIC_API_KEY;
84
- delete process.env.ANTHROPIC_API_KEY;
85
- try {
86
- // Create tool with a dummy key that will be rejected by the API — but
87
- // the resolve step won't throw because we pass an explicit (invalid) key.
88
- // We want to confirm that a missing key returns an error string, not an
89
- // exception. To test the "no key at all" path we must clear env AND pass
90
- // no key.
91
- // Use a blank API key — resolveAnthropicApiKey should throw internally,
92
- // which execute() catches and returns as a string.
93
- const tool = createImageDescribeTool({ apiKey: '' });
94
- const out = await tool.execute({
95
- source: 'https://example.com/image.png',
96
- prompt: 'Describe.',
97
- });
98
- assert(typeof out === 'string', 'Expected string output when key is missing');
99
- // Either an error message or a valid description — both are acceptable.
100
- // The key assertion is that execute() did NOT throw.
101
- }
102
- finally {
103
- if (savedKey !== undefined)
104
- process.env.ANTHROPIC_API_KEY = savedKey;
105
- }
106
- }
107
- // Test 3: Non-existent local file → returns error string without crashing.
108
- async function testMissingLocalFile() {
109
- const tool = createImageDescribeTool();
110
- const out = await tool.execute({
111
- source: '/tmp/__gaia_nonexistent_image_abc123.png',
112
- });
113
- assert(typeof out === 'string', 'Expected string output for missing file');
114
- assert(out.startsWith('[image_describe error]'), `Expected error prefix for missing file, got:\n${out}`);
115
- assert(out.includes('not found') || out.includes('Cannot read'), `Expected "not found" or "Cannot read" in error, got:\n${out}`);
116
- }
117
- // Test 4: Empty source → throws (caller contract violation).
118
- async function testEmptySource() {
119
- const tool = createImageDescribeTool();
120
- let threw = false;
121
- try {
122
- await tool.execute({ source: '' });
123
- }
124
- catch {
125
- threw = true;
126
- }
127
- assert(threw, 'Expected execute() to throw for empty source');
128
- }
129
- // ---------------------------------------------------------------------------
130
- // Runner
131
- // ---------------------------------------------------------------------------
132
- async function main() {
133
- console.log('image_describe smoke tests — ADR-133-PR5\n');
134
- const tests = [
135
- runTest('Test 1: URL image — Wikipedia logo (live API)', testWikipediaLogo),
136
- runTest('Test 2: Missing API key — graceful error string', testMissingApiKey),
137
- runTest('Test 3: Non-existent local file — graceful error', testMissingLocalFile),
138
- runTest('Test 4: Empty source — throws', testEmptySource),
139
- ];
140
- const results = await Promise.all(tests);
141
- let passed = 0;
142
- let failed = 0;
143
- let skipped = 0;
144
- for (const r of results) {
145
- // Tests that throw 'SKIP:' are shown as skipped.
146
- const isSkip = r.status === 'FAIL' && r.message.startsWith('SKIP:');
147
- const displayStatus = isSkip ? 'SKIP' : r.status;
148
- console.log(`[${displayStatus}] ${r.name}`);
149
- if (displayStatus !== 'PASS') {
150
- console.log(` ${r.message.slice(0, 300)}`);
151
- }
152
- if (isSkip)
153
- skipped++;
154
- else if (r.status === 'PASS')
155
- passed++;
156
- else
157
- failed++;
158
- }
159
- console.log(`\nResults: ${passed} passed, ${failed} failed, ${skipped} skipped`);
160
- console.log(`Cost estimate: ≤$0.001 per run (single Haiku vision call for Test 1)`);
161
- if (failed > 0) {
162
- process.exit(1);
163
- }
164
- }
165
- main().catch((e) => {
166
- console.error('Fatal:', e);
167
- process.exit(1);
168
- });
169
- //# sourceMappingURL=image_describe.smoke.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"image_describe.smoke.js","sourceRoot":"","sources":["../../../../src/benchmarks/gaia-tools/image_describe.smoke.ts"],"names":[],"mappings":"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"}
@@ -1,27 +0,0 @@
1
- /**
2
- * GAIA Tool: pdf_read — ADR-138 iter 54
3
- *
4
- * Extracts text content from a PDF file using a Python subprocess.
5
- * GAIA L1 has ~20-30% of questions with PDF attachments; without this,
6
- * ruflo is functionally blind on those questions.
7
- *
8
- * Extraction chain (tries in order, returns first success):
9
- * 1. pdfminer.six — best quality, handles most text PDFs
10
- * 2. pdfplumber — good alternative, especially for tables
11
- * 3. PyPDF2/pypdf — fallback, lower quality but widely available
12
- * 4. pdftotext — CLI tool (poppler-utils), if installed
13
- * 5. Stub — returns a note that extraction failed
14
- *
15
- * For image-only (scanned) PDFs, all text extractors return empty.
16
- * In that case we return a note so the agent can try describe_image.
17
- *
18
- * Refs: ADR-138, #2156, iter 54
19
- */
20
- import { GaiaTool, ToolDefinition } from './types.js';
21
- export declare class PdfReadTool implements GaiaTool {
22
- readonly name = "pdf_read";
23
- readonly definition: ToolDefinition;
24
- execute(input: Record<string, unknown>): Promise<string>;
25
- }
26
- export declare function createPdfReadTool(): PdfReadTool;
27
- //# sourceMappingURL=pdf_read.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pdf_read.d.ts","sourceRoot":"","sources":["../../../../src/benchmarks/gaia-tools/pdf_read.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAwJtD,qBAAa,WAAY,YAAW,QAAQ;IAC1C,QAAQ,CAAC,IAAI,cAAc;IAE3B,QAAQ,CAAC,UAAU,EAAE,cAAc,CAkBjC;IAEI,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;CAsC/D;AAMD,wBAAgB,iBAAiB,IAAI,WAAW,CAE/C"}
@@ -1,226 +0,0 @@
1
- /**
2
- * GAIA Tool: pdf_read — ADR-138 iter 54
3
- *
4
- * Extracts text content from a PDF file using a Python subprocess.
5
- * GAIA L1 has ~20-30% of questions with PDF attachments; without this,
6
- * ruflo is functionally blind on those questions.
7
- *
8
- * Extraction chain (tries in order, returns first success):
9
- * 1. pdfminer.six — best quality, handles most text PDFs
10
- * 2. pdfplumber — good alternative, especially for tables
11
- * 3. PyPDF2/pypdf — fallback, lower quality but widely available
12
- * 4. pdftotext — CLI tool (poppler-utils), if installed
13
- * 5. Stub — returns a note that extraction failed
14
- *
15
- * For image-only (scanned) PDFs, all text extractors return empty.
16
- * In that case we return a note so the agent can try describe_image.
17
- *
18
- * Refs: ADR-138, #2156, iter 54
19
- */
20
- import { execFileSync } from 'node:child_process';
21
- import * as path from 'node:path';
22
- import * as fs from 'node:fs';
23
- // ---------------------------------------------------------------------------
24
- // Constants
25
- // ---------------------------------------------------------------------------
26
- const EXEC_TIMEOUT_MS = 30_000;
27
- const MAX_OUTPUT_CHARS = 8_000;
28
- // ---------------------------------------------------------------------------
29
- // Extraction helpers
30
- // ---------------------------------------------------------------------------
31
- /**
32
- * Try to extract PDF text using Python pdfminer.six (best quality).
33
- */
34
- function extractViaPdfminer(filePath) {
35
- const script = `
36
- import sys
37
- try:
38
- from pdfminer.high_level import extract_text
39
- text = extract_text(sys.argv[1])
40
- print(text[:12000] if text else '')
41
- except ImportError:
42
- print('[pdfminer_not_installed]')
43
- except Exception as e:
44
- print('[pdfminer_error:' + str(e) + ']')
45
- `.trim();
46
- try {
47
- const out = execFileSync('python3', ['-', filePath], {
48
- input: script,
49
- encoding: 'utf-8',
50
- timeout: EXEC_TIMEOUT_MS,
51
- }).trim();
52
- if (out && !out.startsWith('[pdfminer_not_installed]') && !out.startsWith('[pdfminer_error:')) {
53
- return out;
54
- }
55
- }
56
- catch { /* fall through */ }
57
- return '';
58
- }
59
- /**
60
- * Try to extract PDF text using pdfplumber (good for tables).
61
- */
62
- function extractViaPdfplumber(filePath) {
63
- const script = `
64
- import sys
65
- try:
66
- import pdfplumber
67
- with pdfplumber.open(sys.argv[1]) as pdf:
68
- texts = []
69
- for page in pdf.pages:
70
- t = page.extract_text()
71
- if t:
72
- texts.append(t)
73
- print('\\n\\n'.join(texts)[:12000])
74
- except ImportError:
75
- print('[pdfplumber_not_installed]')
76
- except Exception as e:
77
- print('[pdfplumber_error:' + str(e) + ']')
78
- `.trim();
79
- try {
80
- const out = execFileSync('python3', ['-', filePath], {
81
- input: script,
82
- encoding: 'utf-8',
83
- timeout: EXEC_TIMEOUT_MS,
84
- }).trim();
85
- if (out && !out.startsWith('[pdfplumber_not_installed]') && !out.startsWith('[pdfplumber_error:')) {
86
- return out;
87
- }
88
- }
89
- catch { /* fall through */ }
90
- return '';
91
- }
92
- /**
93
- * Try to extract PDF text using pypdf (widely available, lower quality).
94
- */
95
- function extractViaPypdf(filePath) {
96
- const script = `
97
- import sys
98
- try:
99
- try:
100
- import pypdf as pdf_lib
101
- except ImportError:
102
- import PyPDF2 as pdf_lib
103
- with open(sys.argv[1], 'rb') as f:
104
- reader = pdf_lib.PdfReader(f)
105
- texts = []
106
- for page in reader.pages:
107
- t = page.extract_text()
108
- if t:
109
- texts.append(t)
110
- print('\\n\\n'.join(texts)[:12000])
111
- except ImportError:
112
- print('[pypdf_not_installed]')
113
- except Exception as e:
114
- print('[pypdf_error:' + str(e) + ']')
115
- `.trim();
116
- try {
117
- const out = execFileSync('python3', ['-', filePath], {
118
- input: script,
119
- encoding: 'utf-8',
120
- timeout: EXEC_TIMEOUT_MS,
121
- }).trim();
122
- if (out && !out.startsWith('[pypdf_not_installed]') && !out.startsWith('[pypdf_error:')) {
123
- return out;
124
- }
125
- }
126
- catch { /* fall through */ }
127
- return '';
128
- }
129
- /**
130
- * Try to extract PDF text using the `pdftotext` CLI tool (poppler-utils).
131
- */
132
- function extractViaPdftotext(filePath) {
133
- try {
134
- const out = execFileSync('pdftotext', [filePath, '-'], {
135
- encoding: 'utf-8',
136
- timeout: EXEC_TIMEOUT_MS,
137
- }).trim();
138
- return out.slice(0, 12000);
139
- }
140
- catch { /* fall through */ }
141
- return '';
142
- }
143
- // ---------------------------------------------------------------------------
144
- // Path validation (mirrors file_read.ts)
145
- // ---------------------------------------------------------------------------
146
- function validatePdfPath(filePath) {
147
- if (!filePath || typeof filePath !== 'string') {
148
- throw new Error('pdf_read: `path` must be a non-empty string.');
149
- }
150
- if (!path.isAbsolute(filePath)) {
151
- throw new Error(`pdf_read: path must be absolute. Got: "${filePath}".`);
152
- }
153
- if (filePath.includes('\0')) {
154
- throw new Error('pdf_read: path contains null byte — rejected.');
155
- }
156
- const ext = path.extname(filePath).toLowerCase();
157
- if (ext !== '.pdf') {
158
- throw new Error(`pdf_read: expected a .pdf file, got extension "${ext}". Use file_read for other formats.`);
159
- }
160
- }
161
- // ---------------------------------------------------------------------------
162
- // GaiaTool implementation
163
- // ---------------------------------------------------------------------------
164
- export class PdfReadTool {
165
- name = 'pdf_read';
166
- definition = {
167
- name: 'pdf_read',
168
- description: 'Extract text content from a PDF file. ' +
169
- 'Path must be absolute. ' +
170
- 'Tries pdfminer.six, pdfplumber, pypdf, and pdftotext in order. ' +
171
- 'Returns extracted text or a note if the PDF is image-only (scanned). ' +
172
- `Output truncated to ${MAX_OUTPUT_CHARS} characters.`,
173
- input_schema: {
174
- type: 'object',
175
- properties: {
176
- path: {
177
- type: 'string',
178
- description: 'Absolute path to the PDF file.',
179
- },
180
- },
181
- required: ['path'],
182
- },
183
- };
184
- async execute(input) {
185
- const filePath = String(input['path'] ?? '').trim();
186
- validatePdfPath(filePath);
187
- // Check existence
188
- try {
189
- const stat = fs.statSync(filePath);
190
- if (!stat.isFile())
191
- throw new Error(`pdf_read: "${filePath}" is not a regular file.`);
192
- }
193
- catch (e) {
194
- const err = e;
195
- if (err.code === 'ENOENT')
196
- throw new Error(`pdf_read: file not found: ${filePath}`);
197
- throw e;
198
- }
199
- const filename = path.basename(filePath);
200
- // Try extractors in order
201
- let text = extractViaPdfminer(filePath);
202
- if (!text)
203
- text = extractViaPdfplumber(filePath);
204
- if (!text)
205
- text = extractViaPypdf(filePath);
206
- if (!text)
207
- text = extractViaPdftotext(filePath);
208
- if (!text || text.length < 20) {
209
- return (`[PDF: ${filename}]\n` +
210
- `Text extraction returned no content. This may be a scanned/image-only PDF.\n` +
211
- `If the PDF contains images, consider using describe_image on specific pages.\n` +
212
- `File: ${filePath}`);
213
- }
214
- const truncated = text.length > MAX_OUTPUT_CHARS;
215
- const output = text.slice(0, MAX_OUTPUT_CHARS);
216
- return (`[PDF: ${filename}]\n\n${output}` +
217
- (truncated ? `\n\n[... truncated at ${MAX_OUTPUT_CHARS} chars ...]` : ''));
218
- }
219
- }
220
- // ---------------------------------------------------------------------------
221
- // Convenience factory
222
- // ---------------------------------------------------------------------------
223
- export function createPdfReadTool() {
224
- return new PdfReadTool();
225
- }
226
- //# sourceMappingURL=pdf_read.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pdf_read.js","sourceRoot":"","sources":["../../../../src/benchmarks/gaia-tools/pdf_read.ts"],"names":[],"mappings":"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"}
@@ -1,31 +0,0 @@
1
- /**
2
- * GAIA Tool: python_exec — DAG actor catalogue (iter-65 Fix 1)
3
- *
4
- * Executes a Python script in a sandboxed subprocess and returns stdout.
5
- * Designed for use by DAG actors that need to simulate probabilities,
6
- * run numeric computations, or process data programmatically.
7
- *
8
- * Security:
9
- * - Code is passed via stdin (not shell args) to avoid injection.
10
- * - Hard timeout: 30 seconds.
11
- * - No network access inside the script (subprocess environment is the
12
- * same user-level Python, not a full sandbox — adequate for GAIA L1
13
- * computations which are math/logic only, not I/O heavy).
14
- *
15
- * Input schema:
16
- * code — Python source to execute (passed via stdin to python3 -)
17
- *
18
- * Output:
19
- * stdout of the script, trimmed.
20
- * On non-zero exit or timeout, returns a descriptive error string.
21
- *
22
- * Refs: ADR-139, iter-65, #2156
23
- */
24
- import { GaiaTool, ToolDefinition } from './types.js';
25
- export declare class PythonExecTool implements GaiaTool {
26
- readonly name = "python_exec";
27
- readonly definition: ToolDefinition;
28
- execute(input: Record<string, unknown>): Promise<string>;
29
- }
30
- export declare function createPythonExecTool(): PythonExecTool;
31
- //# sourceMappingURL=python_exec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"python_exec.d.ts","sourceRoot":"","sources":["../../../../src/benchmarks/gaia-tools/python_exec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAatD,qBAAa,cAAe,YAAW,QAAQ;IAC7C,QAAQ,CAAC,IAAI,iBAAiB;IAE9B,QAAQ,CAAC,UAAU,EAAE,cAAc,CAmBjC;IAEI,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;CAiC/D;AAMD,wBAAgB,oBAAoB,IAAI,cAAc,CAErD"}
@@ -1,94 +0,0 @@
1
- /**
2
- * GAIA Tool: python_exec — DAG actor catalogue (iter-65 Fix 1)
3
- *
4
- * Executes a Python script in a sandboxed subprocess and returns stdout.
5
- * Designed for use by DAG actors that need to simulate probabilities,
6
- * run numeric computations, or process data programmatically.
7
- *
8
- * Security:
9
- * - Code is passed via stdin (not shell args) to avoid injection.
10
- * - Hard timeout: 30 seconds.
11
- * - No network access inside the script (subprocess environment is the
12
- * same user-level Python, not a full sandbox — adequate for GAIA L1
13
- * computations which are math/logic only, not I/O heavy).
14
- *
15
- * Input schema:
16
- * code — Python source to execute (passed via stdin to python3 -)
17
- *
18
- * Output:
19
- * stdout of the script, trimmed.
20
- * On non-zero exit or timeout, returns a descriptive error string.
21
- *
22
- * Refs: ADR-139, iter-65, #2156
23
- */
24
- import { execFileSync } from 'node:child_process';
25
- // ---------------------------------------------------------------------------
26
- // Constants
27
- // ---------------------------------------------------------------------------
28
- const PYTHON_EXEC_TIMEOUT_MS = 30_000;
29
- const PYTHON_OUTPUT_MAX_CHARS = 4_000;
30
- // ---------------------------------------------------------------------------
31
- // PythonExecTool
32
- // ---------------------------------------------------------------------------
33
- export class PythonExecTool {
34
- name = 'python_exec';
35
- definition = {
36
- name: 'python_exec',
37
- description: 'Execute a Python 3 script and return its stdout output. ' +
38
- 'Use this for mathematical calculations, probability simulations, ' +
39
- 'data processing, or any computation that requires running Python code. ' +
40
- 'The code is passed via stdin to python3. ' +
41
- 'Print your result to stdout. ' +
42
- 'Timeout: 30 seconds. Maximum output: 4000 characters.',
43
- input_schema: {
44
- type: 'object',
45
- properties: {
46
- code: {
47
- type: 'string',
48
- description: 'Python 3 source code to execute. Use print() to output results.',
49
- },
50
- },
51
- required: ['code'],
52
- },
53
- };
54
- async execute(input) {
55
- const code = String(input['code'] ?? '').trim();
56
- if (!code) {
57
- return 'python_exec: empty code — nothing to execute.';
58
- }
59
- let stdout;
60
- try {
61
- stdout = execFileSync('python3', ['-'], {
62
- input: code,
63
- encoding: 'utf-8',
64
- timeout: PYTHON_EXEC_TIMEOUT_MS,
65
- }).trim();
66
- }
67
- catch (err) {
68
- if (err instanceof Error) {
69
- // Include stderr in the error output so actors can diagnose
70
- const spawnErr = err;
71
- const stderr = String(spawnErr.stderr ?? '').trim();
72
- const partial = String(spawnErr.stdout ?? '').trim();
73
- const parts = [`python_exec error: ${err.message}`];
74
- if (stderr)
75
- parts.push(`stderr: ${stderr.slice(0, 1000)}`);
76
- if (partial)
77
- parts.push(`partial stdout: ${partial.slice(0, 500)}`);
78
- return parts.join('\n');
79
- }
80
- return `python_exec error: ${String(err)}`;
81
- }
82
- if (!stdout) {
83
- return '(no output — script produced no stdout)';
84
- }
85
- return stdout.slice(0, PYTHON_OUTPUT_MAX_CHARS);
86
- }
87
- }
88
- // ---------------------------------------------------------------------------
89
- // Convenience factory
90
- // ---------------------------------------------------------------------------
91
- export function createPythonExecTool() {
92
- return new PythonExecTool();
93
- }
94
- //# sourceMappingURL=python_exec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"python_exec.js","sourceRoot":"","sources":["../../../../src/benchmarks/gaia-tools/python_exec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,sBAAsB,GAAG,MAAM,CAAC;AACtC,MAAM,uBAAuB,GAAG,KAAK,CAAC;AAEtC,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,MAAM,OAAO,cAAc;IAChB,IAAI,GAAG,aAAa,CAAC;IAErB,UAAU,GAAmB;QACpC,IAAI,EAAE,aAAa;QACnB,WAAW,EACT,0DAA0D;YAC1D,mEAAmE;YACnE,yEAAyE;YACzE,2CAA2C;YAC3C,+BAA+B;YAC/B,uDAAuD;QACzD,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,iEAAiE;iBAC/E;aACF;YACD,QAAQ,EAAE,CAAC,MAAM,CAAC;SACnB;KACF,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,KAA8B;QAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,+CAA+C,CAAC;QACzD,CAAC;QAED,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,EAAE;gBACtC,KAAK,EAAE,IAAI;gBACX,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,sBAAsB;aAChC,CAAC,CAAC,IAAI,EAAE,CAAC;QACZ,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;gBACzB,4DAA4D;gBAC5D,MAAM,QAAQ,GAAG,GAAmE,CAAC;gBACrF,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBACpD,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBACrD,MAAM,KAAK,GAAa,CAAC,sBAAsB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC9D,IAAI,MAAM;oBAAE,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC3D,IAAI,OAAO;oBAAE,KAAK,CAAC,IAAI,CAAC,mBAAmB,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;gBACpE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC;YACD,OAAO,sBAAsB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7C,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,yCAAyC,CAAC;QACnD,CAAC;QAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,uBAAuB,CAAC,CAAC;IAClD,CAAC;CACF;AAED,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,MAAM,UAAU,oBAAoB;IAClC,OAAO,IAAI,cAAc,EAAE,CAAC;AAC9B,CAAC"}
@@ -1,13 +0,0 @@
1
- /**
2
- * Smoke tests for python_exec — ADR-133-PR4
3
- *
4
- * Run with:
5
- * cd v3/@claude-flow/cli
6
- * npx tsx src/benchmarks/gaia-tools/python_exec.smoke.ts
7
- *
8
- * Expects python3 to be installed and on PATH.
9
- *
10
- * Refs: ADR-133, #2156
11
- */
12
- export {};
13
- //# sourceMappingURL=python_exec.smoke.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"python_exec.smoke.d.ts","sourceRoot":"","sources":["../../../../src/benchmarks/gaia-tools/python_exec.smoke.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}