monomind 1.18.9 → 1.18.11
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/packages/@monomind/cli/dist/src/agents/registry-builder.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.js +2 -3
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.d.ts +1 -2
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.js +1 -2
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.d.ts +1 -2
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.js +2 -117
- package/packages/@monomind/cli/dist/src/commands/hooks.js +1 -2
- package/packages/@monomind/cli/dist/src/commands/index.d.ts +0 -1
- package/packages/@monomind/cli/dist/src/commands/index.js +0 -1
- package/packages/@monomind/cli/dist/src/commands/security-misc.js +0 -1
- package/packages/@monomind/cli/dist/src/init/executor.d.ts +3 -0
- package/packages/@monomind/cli/dist/src/init/executor.js +20 -111
- package/packages/@monomind/cli/dist/src/mcp-client.js +0 -2
- package/packages/@monomind/cli/dist/src/mcp-tools/index.d.ts +0 -1
- package/packages/@monomind/cli/dist/src/mcp-tools/index.js +0 -1
- package/packages/@monomind/cli/dist/src/mcp-tools/quality/coverage-analysis/track-trends.d.ts +4 -4
- package/packages/@monomind/cli/dist/src/mcp-tools/quality/test-generation/suggest-tests.d.ts +4 -4
- package/packages/@monomind/cli/dist/src/mcp-tools/security-tools.js +0 -1
- package/packages/@monomind/cli/package.json +1 -1
- package/packages/@monomind/cli/dist/src/benchmarks/benchmark-runner.d.ts +0 -134
- package/packages/@monomind/cli/dist/src/benchmarks/benchmark-runner.js +0 -340
- package/packages/@monomind/cli/dist/src/benchmarks/metric-evaluators.d.ts +0 -36
- package/packages/@monomind/cli/dist/src/benchmarks/metric-evaluators.js +0 -125
- package/packages/@monomind/cli/dist/src/commands/benchmark.d.ts +0 -10
- package/packages/@monomind/cli/dist/src/commands/benchmark.js +0 -586
- package/packages/@monomind/cli/dist/src/commands/migrate.d.ts +0 -8
- package/packages/@monomind/cli/dist/src/commands/migrate.js +0 -789
- package/packages/@monomind/cli/dist/src/commands/monovector/backup.d.ts +0 -11
- package/packages/@monomind/cli/dist/src/commands/monovector/backup.js +0 -752
- package/packages/@monomind/cli/dist/src/commands/monovector/benchmark.d.ts +0 -11
- package/packages/@monomind/cli/dist/src/commands/monovector/benchmark.js +0 -502
- package/packages/@monomind/cli/dist/src/commands/monovector/import.d.ts +0 -18
- package/packages/@monomind/cli/dist/src/commands/monovector/import.js +0 -374
- package/packages/@monomind/cli/dist/src/commands/monovector/index.d.ts +0 -29
- package/packages/@monomind/cli/dist/src/commands/monovector/index.js +0 -129
- package/packages/@monomind/cli/dist/src/commands/monovector/init.d.ts +0 -11
- package/packages/@monomind/cli/dist/src/commands/monovector/init.js +0 -481
- package/packages/@monomind/cli/dist/src/commands/monovector/migrate.d.ts +0 -11
- package/packages/@monomind/cli/dist/src/commands/monovector/migrate.js +0 -500
- package/packages/@monomind/cli/dist/src/commands/monovector/optimize.d.ts +0 -11
- package/packages/@monomind/cli/dist/src/commands/monovector/optimize.js +0 -515
- package/packages/@monomind/cli/dist/src/commands/monovector/setup.d.ts +0 -18
- package/packages/@monomind/cli/dist/src/commands/monovector/setup.js +0 -775
- package/packages/@monomind/cli/dist/src/commands/monovector/status.d.ts +0 -11
- package/packages/@monomind/cli/dist/src/commands/monovector/status.js +0 -491
- package/packages/@monomind/cli/dist/src/commands/progress.d.ts +0 -11
- package/packages/@monomind/cli/dist/src/commands/progress.js +0 -261
- package/packages/@monomind/cli/dist/src/mcp-tools/progress-tools.d.ts +0 -14
- package/packages/@monomind/cli/dist/src/mcp-tools/progress-tools.js +0 -353
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
/** A single quality metric to evaluate against agent output. */
|
|
2
|
-
export interface QualityMetric {
|
|
3
|
-
/** Discriminator selecting which evaluator runs. */
|
|
4
|
-
type: 'contains_expected' | 'length_range' | 'no_hallucination' | 'json_valid' | 'custom_regex' | string;
|
|
5
|
-
/** Per-metric configuration; shape depends on `type`. */
|
|
6
|
-
config?: Record<string, unknown>;
|
|
7
|
-
}
|
|
8
|
-
/** Result of evaluating one quality metric. */
|
|
9
|
-
export interface MetricResult {
|
|
10
|
-
/** The metric type that produced this result. */
|
|
11
|
-
type: string;
|
|
12
|
-
/** Whether the metric passed. */
|
|
13
|
-
passed: boolean;
|
|
14
|
-
/** Observed value (metric-specific). */
|
|
15
|
-
actual: unknown;
|
|
16
|
-
/** Expected value (metric-specific). */
|
|
17
|
-
expected: unknown;
|
|
18
|
-
/** Human-readable explanation. */
|
|
19
|
-
message: string;
|
|
20
|
-
}
|
|
21
|
-
/** A benchmark definition loaded from a JSON file. */
|
|
22
|
-
export interface BenchmarkDefinition {
|
|
23
|
-
/** Unique benchmark identifier. */
|
|
24
|
-
benchmarkId: string;
|
|
25
|
-
/** Agent slug this benchmark targets. */
|
|
26
|
-
agentSlug: string;
|
|
27
|
-
/** Quality metrics to evaluate. */
|
|
28
|
-
qualityMetrics: QualityMetric[];
|
|
29
|
-
}
|
|
30
|
-
/** Result of running a single benchmark. */
|
|
31
|
-
export interface BenchmarkResult {
|
|
32
|
-
/** The benchmark that was run. */
|
|
33
|
-
benchmarkId: string;
|
|
34
|
-
/** Unique run identifier. */
|
|
35
|
-
runId: string;
|
|
36
|
-
/** Agent slug the benchmark targeted. */
|
|
37
|
-
agentSlug: string;
|
|
38
|
-
/** Whether all metrics passed. */
|
|
39
|
-
passed: boolean;
|
|
40
|
-
/** Per-metric results. */
|
|
41
|
-
metricResults: MetricResult[];
|
|
42
|
-
/** ISO timestamp of the run. */
|
|
43
|
-
runAt: string;
|
|
44
|
-
/** Wall-clock duration in milliseconds. */
|
|
45
|
-
durationMs: number;
|
|
46
|
-
}
|
|
47
|
-
/** A pinned baseline for regression comparison. */
|
|
48
|
-
export interface BenchmarkBaseline {
|
|
49
|
-
/** ISO timestamp when the baseline was pinned. */
|
|
50
|
-
pinnedAt: string;
|
|
51
|
-
/** Fraction of results that passed [0, 1]. */
|
|
52
|
-
passRate: number;
|
|
53
|
-
/** Average run duration in milliseconds. */
|
|
54
|
-
avgDurationMs: number;
|
|
55
|
-
}
|
|
56
|
-
export declare class BenchmarkRunner {
|
|
57
|
-
private baselines;
|
|
58
|
-
/**
|
|
59
|
-
* Load benchmark definitions from JSON files in a directory.
|
|
60
|
-
* Each JSON file should contain a single BenchmarkDefinition or an array of them.
|
|
61
|
-
*/
|
|
62
|
-
loadBenchmarks(dir: string): BenchmarkDefinition[];
|
|
63
|
-
/**
|
|
64
|
-
* Evaluate quality metrics against an output string.
|
|
65
|
-
*/
|
|
66
|
-
evaluateMetrics(output: string, metrics: QualityMetric[]): MetricResult[];
|
|
67
|
-
/**
|
|
68
|
-
* Run a single benchmark against provided agent output.
|
|
69
|
-
*/
|
|
70
|
-
runBenchmark(def: BenchmarkDefinition, agentOutput: string): BenchmarkResult;
|
|
71
|
-
/**
|
|
72
|
-
* Pin current results as the baseline for a benchmark.
|
|
73
|
-
*/
|
|
74
|
-
pinBaseline(benchmarkId: string, results: BenchmarkResult[]): BenchmarkBaseline;
|
|
75
|
-
/**
|
|
76
|
-
* Detect regression by comparing current results against a baseline.
|
|
77
|
-
* Returns true if the current pass rate is strictly below the baseline pass rate.
|
|
78
|
-
*/
|
|
79
|
-
detectRegression(current: BenchmarkResult[], baseline: BenchmarkBaseline): boolean;
|
|
80
|
-
/**
|
|
81
|
-
* Get a stored baseline by benchmark ID.
|
|
82
|
-
*/
|
|
83
|
-
getBaseline(benchmarkId: string): BenchmarkBaseline | undefined;
|
|
84
|
-
private evaluateSingleMetric;
|
|
85
|
-
}
|
|
86
|
-
export interface SwarmBenchTask {
|
|
87
|
-
/** Unique task ID */
|
|
88
|
-
id: string;
|
|
89
|
-
/** One of the 5 SwarmBench coordination categories */
|
|
90
|
-
type: 'pursuit' | 'synchronization' | 'foraging' | 'flocking' | 'transport';
|
|
91
|
-
/** Human-readable description */
|
|
92
|
-
description: string;
|
|
93
|
-
/** Number of agents participating */
|
|
94
|
-
agentCount: number;
|
|
95
|
-
/** Steps / budget allowed */
|
|
96
|
-
stepBudget: number;
|
|
97
|
-
/** Success criterion function */
|
|
98
|
-
evaluate: (agentOutputs: string[]) => SwarmBenchResult;
|
|
99
|
-
}
|
|
100
|
-
export interface SwarmBenchResult {
|
|
101
|
-
taskId: string;
|
|
102
|
-
type: SwarmBenchTask['type'];
|
|
103
|
-
passed: boolean;
|
|
104
|
-
score: number;
|
|
105
|
-
stepsTaken: number;
|
|
106
|
-
agentCount: number;
|
|
107
|
-
details: string;
|
|
108
|
-
}
|
|
109
|
-
export declare const SWARM_BENCH_TASKS: readonly SwarmBenchTask[];
|
|
110
|
-
/**
|
|
111
|
-
* Alias for {@link SWARM_BENCH_TASKS}. Kept for ergonomic imports.
|
|
112
|
-
*/
|
|
113
|
-
export declare const SWARM: readonly SwarmBenchTask[];
|
|
114
|
-
/**
|
|
115
|
-
* SwarmBenchRunner — runs the 5 SwarmBench coordination task types.
|
|
116
|
-
* Wraps BenchmarkRunner for regression baseline tracking.
|
|
117
|
-
*
|
|
118
|
-
* Source: https://arxiv.org/abs/2505.04364
|
|
119
|
-
*/
|
|
120
|
-
export declare class SwarmBenchRunner {
|
|
121
|
-
private readonly inner;
|
|
122
|
-
private baselines;
|
|
123
|
-
/** Run all (or a subset of) SwarmBench tasks against simulated agent outputs. */
|
|
124
|
-
runAll(agentOutputsByTask: Map<string, string[]>): SwarmBenchResult[];
|
|
125
|
-
/** Run a single task type by id. */
|
|
126
|
-
runTask(taskId: string, agentOutputs: string[]): SwarmBenchResult | undefined;
|
|
127
|
-
/** Pin current results as the regression baseline. */
|
|
128
|
-
pinBaseline(results: SwarmBenchResult[]): void;
|
|
129
|
-
/** Detect regression: returns task IDs whose score dropped below baseline. */
|
|
130
|
-
detectRegressions(current: SwarmBenchResult[]): string[];
|
|
131
|
-
/** Expose underlying BenchmarkRunner for general benchmarks. */
|
|
132
|
-
get benchmarkRunner(): BenchmarkRunner;
|
|
133
|
-
}
|
|
134
|
-
//# sourceMappingURL=benchmark-runner.d.ts.map
|
|
@@ -1,340 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Benchmark Runner for Regression Testing (Task 34)
|
|
3
|
-
* Loads benchmark definitions, evaluates quality metrics, and detects regressions.
|
|
4
|
-
*/
|
|
5
|
-
import * as fs from 'fs';
|
|
6
|
-
import * as path from 'path';
|
|
7
|
-
import { randomUUID } from 'crypto';
|
|
8
|
-
import { containsExpected, lengthRange, noHallucination, jsonValid, customRegex, } from './metric-evaluators.js';
|
|
9
|
-
export class BenchmarkRunner {
|
|
10
|
-
baselines = new Map();
|
|
11
|
-
/**
|
|
12
|
-
* Load benchmark definitions from JSON files in a directory.
|
|
13
|
-
* Each JSON file should contain a single BenchmarkDefinition or an array of them.
|
|
14
|
-
*/
|
|
15
|
-
loadBenchmarks(dir) {
|
|
16
|
-
const benchmarks = [];
|
|
17
|
-
// Safe-root constraint: reject any path that escapes the working directory
|
|
18
|
-
const safeRoot = path.resolve(process.cwd());
|
|
19
|
-
const resolved = path.resolve(dir);
|
|
20
|
-
const rel = path.relative(safeRoot, resolved);
|
|
21
|
-
if (rel.startsWith('..') || path.isAbsolute(rel))
|
|
22
|
-
return [];
|
|
23
|
-
if (!fs.existsSync(resolved)) {
|
|
24
|
-
return benchmarks;
|
|
25
|
-
}
|
|
26
|
-
const MAX_BENCH_FILE_SIZE = 1 * 1024 * 1024; // 1 MB per benchmark file
|
|
27
|
-
const files = fs.readdirSync(resolved).filter((f) => f.endsWith('.json'));
|
|
28
|
-
for (const file of files) {
|
|
29
|
-
const filePath = path.join(resolved, file);
|
|
30
|
-
// Guard against OOM: reject symlinks and oversized files before reading
|
|
31
|
-
let stat;
|
|
32
|
-
try {
|
|
33
|
-
stat = fs.lstatSync(filePath);
|
|
34
|
-
}
|
|
35
|
-
catch {
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
if (stat.isSymbolicLink())
|
|
39
|
-
continue;
|
|
40
|
-
if (stat.size > MAX_BENCH_FILE_SIZE)
|
|
41
|
-
continue;
|
|
42
|
-
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
43
|
-
try {
|
|
44
|
-
const parsed = JSON.parse(raw);
|
|
45
|
-
if (Array.isArray(parsed)) {
|
|
46
|
-
benchmarks.push(...parsed);
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
benchmarks.push(parsed);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
catch {
|
|
53
|
-
// skip malformed file
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return benchmarks;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Evaluate quality metrics against an output string.
|
|
61
|
-
*/
|
|
62
|
-
evaluateMetrics(output, metrics) {
|
|
63
|
-
return metrics.map((metric) => this.evaluateSingleMetric(output, metric));
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Run a single benchmark against provided agent output.
|
|
67
|
-
*/
|
|
68
|
-
runBenchmark(def, agentOutput) {
|
|
69
|
-
const startTime = Date.now();
|
|
70
|
-
const metricResults = this.evaluateMetrics(agentOutput, def.qualityMetrics);
|
|
71
|
-
const durationMs = Date.now() - startTime;
|
|
72
|
-
const passed = metricResults.every((r) => r.passed);
|
|
73
|
-
return {
|
|
74
|
-
benchmarkId: def.benchmarkId,
|
|
75
|
-
runId: randomUUID(),
|
|
76
|
-
agentSlug: def.agentSlug,
|
|
77
|
-
passed,
|
|
78
|
-
metricResults,
|
|
79
|
-
runAt: new Date().toISOString(),
|
|
80
|
-
durationMs,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Pin current results as the baseline for a benchmark.
|
|
85
|
-
*/
|
|
86
|
-
pinBaseline(benchmarkId, results) {
|
|
87
|
-
const relevantResults = results.filter((r) => r.benchmarkId === benchmarkId);
|
|
88
|
-
if (relevantResults.length === 0) {
|
|
89
|
-
const baseline = {
|
|
90
|
-
pinnedAt: new Date().toISOString(),
|
|
91
|
-
passRate: 0,
|
|
92
|
-
avgDurationMs: 0,
|
|
93
|
-
};
|
|
94
|
-
this.baselines.set(benchmarkId, baseline);
|
|
95
|
-
return baseline;
|
|
96
|
-
}
|
|
97
|
-
const passCount = relevantResults.filter((r) => r.passed).length;
|
|
98
|
-
const passRate = passCount / relevantResults.length;
|
|
99
|
-
const avgDurationMs = relevantResults.reduce((sum, r) => sum + r.durationMs, 0) /
|
|
100
|
-
relevantResults.length;
|
|
101
|
-
const baseline = {
|
|
102
|
-
pinnedAt: new Date().toISOString(),
|
|
103
|
-
passRate,
|
|
104
|
-
avgDurationMs,
|
|
105
|
-
};
|
|
106
|
-
this.baselines.set(benchmarkId, baseline);
|
|
107
|
-
return baseline;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Detect regression by comparing current results against a baseline.
|
|
111
|
-
* Returns true if the current pass rate is strictly below the baseline pass rate.
|
|
112
|
-
*/
|
|
113
|
-
detectRegression(current, baseline) {
|
|
114
|
-
if (current.length === 0) {
|
|
115
|
-
return false;
|
|
116
|
-
}
|
|
117
|
-
const passCount = current.filter((r) => r.passed).length;
|
|
118
|
-
const currentPassRate = passCount / current.length;
|
|
119
|
-
return currentPassRate < baseline.passRate;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Get a stored baseline by benchmark ID.
|
|
123
|
-
*/
|
|
124
|
-
getBaseline(benchmarkId) {
|
|
125
|
-
return this.baselines.get(benchmarkId);
|
|
126
|
-
}
|
|
127
|
-
// ------------------------------------------------------------------
|
|
128
|
-
// Private helpers
|
|
129
|
-
// ------------------------------------------------------------------
|
|
130
|
-
evaluateSingleMetric(output, metric) {
|
|
131
|
-
switch (metric.type) {
|
|
132
|
-
case 'contains_expected':
|
|
133
|
-
return containsExpected(output, metric.config);
|
|
134
|
-
case 'length_range':
|
|
135
|
-
return lengthRange(output, metric.config);
|
|
136
|
-
case 'no_hallucination':
|
|
137
|
-
return noHallucination(output, metric.config);
|
|
138
|
-
case 'json_valid':
|
|
139
|
-
return jsonValid(output);
|
|
140
|
-
case 'custom_regex':
|
|
141
|
-
return customRegex(output, metric.config);
|
|
142
|
-
default:
|
|
143
|
-
return {
|
|
144
|
-
type: metric.type,
|
|
145
|
-
passed: false,
|
|
146
|
-
actual: null,
|
|
147
|
-
expected: null,
|
|
148
|
-
message: `Unknown metric type: ${metric.type}`,
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
// ------------------------------------------------------------------
|
|
154
|
-
// Default benchmark suite (5 coordination task types)
|
|
155
|
-
// ------------------------------------------------------------------
|
|
156
|
-
/** Pursuit — agents must collectively report a common target string. */
|
|
157
|
-
const pursuitTask = {
|
|
158
|
-
id: 'swarm-pursuit-01',
|
|
159
|
-
type: 'pursuit',
|
|
160
|
-
description: 'All agents converge on and name the same moving target within the step budget',
|
|
161
|
-
agentCount: 4,
|
|
162
|
-
stepBudget: 10,
|
|
163
|
-
evaluate(agentOutputs) {
|
|
164
|
-
const target = 'TARGET_FOUND';
|
|
165
|
-
const hits = agentOutputs.filter((o) => o.includes(target)).length;
|
|
166
|
-
const score = agentOutputs.length > 0 ? hits / agentOutputs.length : 0;
|
|
167
|
-
return {
|
|
168
|
-
taskId: this.id,
|
|
169
|
-
type: this.type,
|
|
170
|
-
passed: score >= 0.75,
|
|
171
|
-
score,
|
|
172
|
-
stepsTaken: 1,
|
|
173
|
-
agentCount: agentOutputs.length,
|
|
174
|
-
details: `${hits}/${agentOutputs.length} agents converged`,
|
|
175
|
-
};
|
|
176
|
-
},
|
|
177
|
-
};
|
|
178
|
-
/** Synchronization — all agents must emit the same token at the same logical step. */
|
|
179
|
-
const synchronizationTask = {
|
|
180
|
-
id: 'swarm-sync-01',
|
|
181
|
-
type: 'synchronization',
|
|
182
|
-
description: 'Agents reach consensus on a shared value simultaneously without direct communication',
|
|
183
|
-
agentCount: 6,
|
|
184
|
-
stepBudget: 5,
|
|
185
|
-
evaluate(agentOutputs) {
|
|
186
|
-
if (agentOutputs.length === 0)
|
|
187
|
-
return {
|
|
188
|
-
taskId: this.id,
|
|
189
|
-
type: this.type,
|
|
190
|
-
passed: false,
|
|
191
|
-
score: 0,
|
|
192
|
-
stepsTaken: 0,
|
|
193
|
-
agentCount: 0,
|
|
194
|
-
details: 'no outputs',
|
|
195
|
-
};
|
|
196
|
-
const counts = new Map();
|
|
197
|
-
for (const o of agentOutputs) {
|
|
198
|
-
const tok = o.trim().split(/\s+/)[0] ?? '';
|
|
199
|
-
counts.set(tok, (counts.get(tok) ?? 0) + 1);
|
|
200
|
-
}
|
|
201
|
-
const maxAgree = Math.max(...counts.values());
|
|
202
|
-
const score = maxAgree / agentOutputs.length;
|
|
203
|
-
return {
|
|
204
|
-
taskId: this.id,
|
|
205
|
-
type: this.type,
|
|
206
|
-
passed: score >= 0.8,
|
|
207
|
-
score,
|
|
208
|
-
stepsTaken: 1,
|
|
209
|
-
agentCount: agentOutputs.length,
|
|
210
|
-
details: `majority agreement: ${(score * 100).toFixed(0)}%`,
|
|
211
|
-
};
|
|
212
|
-
},
|
|
213
|
-
};
|
|
214
|
-
/** Foraging — agents must collectively mention ≥ N distinct resources. */
|
|
215
|
-
const foragingTask = {
|
|
216
|
-
id: 'swarm-forage-01',
|
|
217
|
-
type: 'foraging',
|
|
218
|
-
description: 'Agents distribute to discover and collect distinct resources from the environment',
|
|
219
|
-
agentCount: 5,
|
|
220
|
-
stepBudget: 15,
|
|
221
|
-
evaluate(agentOutputs) {
|
|
222
|
-
const resourcePattern = /RESOURCE_[A-Z]+/g;
|
|
223
|
-
const found = new Set();
|
|
224
|
-
for (const o of agentOutputs) {
|
|
225
|
-
for (const m of o.matchAll(resourcePattern))
|
|
226
|
-
found.add(m[0]);
|
|
227
|
-
}
|
|
228
|
-
const goal = 4;
|
|
229
|
-
const score = Math.min(1, found.size / goal);
|
|
230
|
-
return {
|
|
231
|
-
taskId: this.id,
|
|
232
|
-
type: this.type,
|
|
233
|
-
passed: found.size >= goal,
|
|
234
|
-
score,
|
|
235
|
-
stepsTaken: 1,
|
|
236
|
-
agentCount: agentOutputs.length,
|
|
237
|
-
details: `${found.size}/${goal} resources found: ${[...found].join(', ')}`,
|
|
238
|
-
};
|
|
239
|
-
},
|
|
240
|
-
};
|
|
241
|
-
/** Flocking — each agent must maintain formation by referencing its neighbour. */
|
|
242
|
-
const flockingTask = {
|
|
243
|
-
id: 'swarm-flock-01',
|
|
244
|
-
type: 'flocking',
|
|
245
|
-
description: 'Agents maintain cohesion and alignment while navigating toward a goal',
|
|
246
|
-
agentCount: 8,
|
|
247
|
-
stepBudget: 20,
|
|
248
|
-
evaluate(agentOutputs) {
|
|
249
|
-
const cohesionKeyword = 'NEIGHBOUR_OK';
|
|
250
|
-
const aligned = agentOutputs.filter((o) => o.includes(cohesionKeyword)).length;
|
|
251
|
-
const score = agentOutputs.length > 0 ? aligned / agentOutputs.length : 0;
|
|
252
|
-
return {
|
|
253
|
-
taskId: this.id,
|
|
254
|
-
type: this.type,
|
|
255
|
-
passed: score >= 0.7,
|
|
256
|
-
score,
|
|
257
|
-
stepsTaken: 1,
|
|
258
|
-
agentCount: agentOutputs.length,
|
|
259
|
-
details: `${aligned}/${agentOutputs.length} in formation`,
|
|
260
|
-
};
|
|
261
|
-
},
|
|
262
|
-
};
|
|
263
|
-
/** Transport — item must appear in successive agent outputs showing relay progress. */
|
|
264
|
-
const transportTask = {
|
|
265
|
-
id: 'swarm-transport-01',
|
|
266
|
-
type: 'transport',
|
|
267
|
-
description: 'Agents relay a payload across a chain; payload must appear in last agent output',
|
|
268
|
-
agentCount: 4,
|
|
269
|
-
stepBudget: 8,
|
|
270
|
-
evaluate(agentOutputs) {
|
|
271
|
-
const payload = 'PAYLOAD_DELIVERED';
|
|
272
|
-
const lastAgentDelivered = agentOutputs.length > 0 && agentOutputs[agentOutputs.length - 1].includes(payload);
|
|
273
|
-
const relayCount = agentOutputs.filter((o) => o.includes('RELAY')).length;
|
|
274
|
-
const score = lastAgentDelivered ? 1 : relayCount / Math.max(agentOutputs.length, 1);
|
|
275
|
-
return {
|
|
276
|
-
taskId: this.id,
|
|
277
|
-
type: this.type,
|
|
278
|
-
passed: lastAgentDelivered,
|
|
279
|
-
score,
|
|
280
|
-
stepsTaken: agentOutputs.length,
|
|
281
|
-
agentCount: agentOutputs.length,
|
|
282
|
-
details: lastAgentDelivered
|
|
283
|
-
? 'payload delivered'
|
|
284
|
-
: `relay progress: ${relayCount}/${agentOutputs.length}`,
|
|
285
|
-
};
|
|
286
|
-
},
|
|
287
|
-
};
|
|
288
|
-
export const SWARM_BENCH_TASKS = [
|
|
289
|
-
pursuitTask,
|
|
290
|
-
synchronizationTask,
|
|
291
|
-
foragingTask,
|
|
292
|
-
flockingTask,
|
|
293
|
-
transportTask,
|
|
294
|
-
];
|
|
295
|
-
/**
|
|
296
|
-
* Alias for {@link SWARM_BENCH_TASKS}. Kept for ergonomic imports.
|
|
297
|
-
*/
|
|
298
|
-
export const SWARM = SWARM_BENCH_TASKS;
|
|
299
|
-
/**
|
|
300
|
-
* SwarmBenchRunner — runs the 5 SwarmBench coordination task types.
|
|
301
|
-
* Wraps BenchmarkRunner for regression baseline tracking.
|
|
302
|
-
*
|
|
303
|
-
* Source: https://arxiv.org/abs/2505.04364
|
|
304
|
-
*/
|
|
305
|
-
export class SwarmBenchRunner {
|
|
306
|
-
inner = new BenchmarkRunner();
|
|
307
|
-
baselines = new Map();
|
|
308
|
-
/** Run all (or a subset of) SwarmBench tasks against simulated agent outputs. */
|
|
309
|
-
runAll(agentOutputsByTask) {
|
|
310
|
-
return SWARM_BENCH_TASKS.map((task) => {
|
|
311
|
-
const outputs = agentOutputsByTask.get(task.id) ?? [];
|
|
312
|
-
return task.evaluate(outputs);
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
/** Run a single task type by id. */
|
|
316
|
-
runTask(taskId, agentOutputs) {
|
|
317
|
-
const task = SWARM_BENCH_TASKS.find((t) => t.id === taskId);
|
|
318
|
-
return task?.evaluate(agentOutputs);
|
|
319
|
-
}
|
|
320
|
-
/** Pin current results as the regression baseline. */
|
|
321
|
-
pinBaseline(results) {
|
|
322
|
-
for (const r of results) {
|
|
323
|
-
this.baselines.set(r.taskId, r);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
/** Detect regression: returns task IDs whose score dropped below baseline. */
|
|
327
|
-
detectRegressions(current) {
|
|
328
|
-
return current
|
|
329
|
-
.filter((r) => {
|
|
330
|
-
const baseline = this.baselines.get(r.taskId);
|
|
331
|
-
return baseline !== undefined && r.score < baseline.score;
|
|
332
|
-
})
|
|
333
|
-
.map((r) => r.taskId);
|
|
334
|
-
}
|
|
335
|
-
/** Expose underlying BenchmarkRunner for general benchmarks. */
|
|
336
|
-
get benchmarkRunner() {
|
|
337
|
-
return this.inner;
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
//# sourceMappingURL=benchmark-runner.js.map
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Metric Evaluators for Benchmark Runner (Task 34)
|
|
3
|
-
* Individual metric evaluation functions for quality assessment.
|
|
4
|
-
*/
|
|
5
|
-
type MetricResult = any;
|
|
6
|
-
/**
|
|
7
|
-
* Checks whether the output contains the expected substring.
|
|
8
|
-
*/
|
|
9
|
-
export declare function containsExpected(output: string, config: {
|
|
10
|
-
expected: string;
|
|
11
|
-
}): MetricResult;
|
|
12
|
-
/**
|
|
13
|
-
* Checks whether the output length falls within the specified range.
|
|
14
|
-
*/
|
|
15
|
-
export declare function lengthRange(output: string, config: {
|
|
16
|
-
min: number;
|
|
17
|
-
max: number;
|
|
18
|
-
}): MetricResult;
|
|
19
|
-
/**
|
|
20
|
-
* Checks that the output does not contain any forbidden words (hallucination markers).
|
|
21
|
-
*/
|
|
22
|
-
export declare function noHallucination(output: string, config: {
|
|
23
|
-
forbidden: string[];
|
|
24
|
-
}): MetricResult;
|
|
25
|
-
/**
|
|
26
|
-
* Checks whether the output is valid JSON.
|
|
27
|
-
*/
|
|
28
|
-
export declare function jsonValid(output: string): MetricResult;
|
|
29
|
-
/**
|
|
30
|
-
* Checks whether the output matches a custom regex pattern.
|
|
31
|
-
*/
|
|
32
|
-
export declare function customRegex(output: string, config: {
|
|
33
|
-
pattern: string;
|
|
34
|
-
}): MetricResult;
|
|
35
|
-
export {};
|
|
36
|
-
//# sourceMappingURL=metric-evaluators.d.ts.map
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Metric Evaluators for Benchmark Runner (Task 34)
|
|
3
|
-
* Individual metric evaluation functions for quality assessment.
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Checks whether the output contains the expected substring.
|
|
7
|
-
*/
|
|
8
|
-
export function containsExpected(output, config) {
|
|
9
|
-
// Cap expected to prevent huge strings from inflating returned objects
|
|
10
|
-
const expected = typeof config.expected === 'string' ? config.expected.slice(0, 200) : '';
|
|
11
|
-
const found = output.includes(expected);
|
|
12
|
-
return {
|
|
13
|
-
type: 'contains_expected',
|
|
14
|
-
passed: found,
|
|
15
|
-
actual: found ? expected : null,
|
|
16
|
-
expected,
|
|
17
|
-
message: found
|
|
18
|
-
? `Output contains expected string "${expected}"`
|
|
19
|
-
: `Output missing expected string "${expected}"`,
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Checks whether the output length falls within the specified range.
|
|
24
|
-
*/
|
|
25
|
-
export function lengthRange(output, config) {
|
|
26
|
-
const len = output.length;
|
|
27
|
-
const passed = len >= config.min && len <= config.max;
|
|
28
|
-
return {
|
|
29
|
-
type: 'length_range',
|
|
30
|
-
passed,
|
|
31
|
-
actual: len,
|
|
32
|
-
expected: { min: config.min, max: config.max },
|
|
33
|
-
message: passed
|
|
34
|
-
? `Output length ${len} within range [${config.min}, ${config.max}]`
|
|
35
|
-
: `Output length ${len} outside range [${config.min}, ${config.max}]`,
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Checks that the output does not contain any forbidden words (hallucination markers).
|
|
40
|
-
*/
|
|
41
|
-
export function noHallucination(output, config) {
|
|
42
|
-
const lowerOutput = output.toLowerCase();
|
|
43
|
-
// Cap forbidden array to 200 entries to prevent unbounded O(n) scan
|
|
44
|
-
const forbidden = Array.isArray(config.forbidden) ? config.forbidden.slice(0, 200) : [];
|
|
45
|
-
const found = forbidden.filter((word) => typeof word === 'string' && lowerOutput.includes(word.toLowerCase()));
|
|
46
|
-
const passed = found.length === 0;
|
|
47
|
-
// Truncate reflected words to avoid inflated messages
|
|
48
|
-
const truncatedFound = found.map((w) => w.slice(0, 50));
|
|
49
|
-
return {
|
|
50
|
-
type: 'no_hallucination',
|
|
51
|
-
passed,
|
|
52
|
-
actual: found.length > 0 ? truncatedFound : null,
|
|
53
|
-
expected: null,
|
|
54
|
-
message: passed
|
|
55
|
-
? 'No forbidden words found in output'
|
|
56
|
-
: `Forbidden words found: ${truncatedFound.join(', ')}`,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Checks whether the output is valid JSON.
|
|
61
|
-
*/
|
|
62
|
-
export function jsonValid(output) {
|
|
63
|
-
let passed = false;
|
|
64
|
-
let parsedType = null;
|
|
65
|
-
// Cap output before JSON.parse to prevent OOM on huge strings
|
|
66
|
-
const MAX_JSON_BYTES = 1 * 1024 * 1024; // 1 MB
|
|
67
|
-
const bounded = typeof output === 'string' && output.length > MAX_JSON_BYTES
|
|
68
|
-
? output.slice(0, MAX_JSON_BYTES)
|
|
69
|
-
: output;
|
|
70
|
-
try {
|
|
71
|
-
const parsed = JSON.parse(bounded);
|
|
72
|
-
passed = true;
|
|
73
|
-
parsedType = typeof parsed;
|
|
74
|
-
}
|
|
75
|
-
catch {
|
|
76
|
-
// not valid JSON
|
|
77
|
-
}
|
|
78
|
-
return {
|
|
79
|
-
type: 'json_valid',
|
|
80
|
-
passed,
|
|
81
|
-
actual: passed ? parsedType : 'invalid',
|
|
82
|
-
expected: 'valid JSON',
|
|
83
|
-
message: passed ? 'Output is valid JSON' : 'Output is not valid JSON',
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Checks whether the output matches a custom regex pattern.
|
|
88
|
-
*/
|
|
89
|
-
export function customRegex(output, config) {
|
|
90
|
-
// Reject overly long patterns and those with nested/repeated quantifiers
|
|
91
|
-
// (catastrophic backtracking — a malicious benchmark definition could
|
|
92
|
-
// pin CI runners with `^(a+)+$` against a long output string).
|
|
93
|
-
if (typeof config.pattern !== 'string' || config.pattern.length > 200) {
|
|
94
|
-
return {
|
|
95
|
-
type: 'custom_regex',
|
|
96
|
-
passed: false,
|
|
97
|
-
actual: null,
|
|
98
|
-
expected: config.pattern,
|
|
99
|
-
message: 'Pattern rejected: too long or invalid',
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
if (/(\(.*[+*?].*\)|[+*?]){2,}|\{[0-9,]+\}.*[+*?]|\([^)]*\|[^)]*\)[+*?{]/.test(config.pattern)) {
|
|
103
|
-
return {
|
|
104
|
-
type: 'custom_regex',
|
|
105
|
-
passed: false,
|
|
106
|
-
actual: null,
|
|
107
|
-
expected: config.pattern,
|
|
108
|
-
message: 'Pattern rejected: nested quantifiers risk catastrophic backtracking',
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
// Cap output length so even slow patterns can't burn unlimited CPU
|
|
112
|
-
const boundedOutput = output.length > 1024 * 1024 ? output.slice(0, 1024 * 1024) : output;
|
|
113
|
-
const regex = new RegExp(config.pattern);
|
|
114
|
-
const match = regex.test(boundedOutput);
|
|
115
|
-
return {
|
|
116
|
-
type: 'custom_regex',
|
|
117
|
-
passed: match,
|
|
118
|
-
actual: match ? boundedOutput.match(regex)?.[0] ?? null : null,
|
|
119
|
-
expected: config.pattern,
|
|
120
|
-
message: match
|
|
121
|
-
? `Output matches pattern /${config.pattern}/`
|
|
122
|
-
: `Output does not match pattern /${config.pattern}/`,
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
//# sourceMappingURL=metric-evaluators.js.map
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLI Benchmark Command
|
|
3
|
-
* Comprehensive benchmarking for self-learning, pre-training, and neural systems
|
|
4
|
-
*
|
|
5
|
-
* @module v1/cli/commands/benchmark
|
|
6
|
-
*/
|
|
7
|
-
import type { Command } from '../types.js';
|
|
8
|
-
export declare const benchmarkCommand: Command;
|
|
9
|
-
export default benchmarkCommand;
|
|
10
|
-
//# sourceMappingURL=benchmark.d.ts.map
|