monomind 1.18.8 → 1.18.10
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/commands/doctor-project-checks.d.ts +1 -0
- package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.js +17 -1
- package/packages/@monomind/cli/dist/src/commands/doctor.js +15 -1
- 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 -4
- package/packages/@monomind/cli/dist/src/commands/index.js +0 -22
- 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/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
package/packages/@monomind/cli/dist/src/mcp-tools/quality/coverage-analysis/track-trends.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export declare const TrackTrendsInputSchema: z.ZodObject<{
|
|
|
15
15
|
includeProjections: z.ZodDefault<z.ZodBoolean>;
|
|
16
16
|
compareBaseline: z.ZodOptional<z.ZodString>;
|
|
17
17
|
}, "strip", z.ZodTypeAny, {
|
|
18
|
-
metrics: ("function" | "line" | "
|
|
18
|
+
metrics: ("function" | "line" | "branch" | "statement" | "overall")[];
|
|
19
19
|
timeRange: "30d" | "7d" | "14d" | "90d" | "180d" | "365d";
|
|
20
20
|
groupBy: "commit" | "day" | "week" | "month";
|
|
21
21
|
detectRegressions: boolean;
|
|
@@ -24,7 +24,7 @@ export declare const TrackTrendsInputSchema: z.ZodObject<{
|
|
|
24
24
|
targetPath?: string | undefined;
|
|
25
25
|
compareBaseline?: string | undefined;
|
|
26
26
|
}, {
|
|
27
|
-
metrics?: ("function" | "line" | "
|
|
27
|
+
metrics?: ("function" | "line" | "branch" | "statement" | "overall")[] | undefined;
|
|
28
28
|
timeRange?: "30d" | "7d" | "14d" | "90d" | "180d" | "365d" | undefined;
|
|
29
29
|
targetPath?: string | undefined;
|
|
30
30
|
groupBy?: "commit" | "day" | "week" | "month" | undefined;
|
|
@@ -141,7 +141,7 @@ export declare const toolDefinition: {
|
|
|
141
141
|
includeProjections: z.ZodDefault<z.ZodBoolean>;
|
|
142
142
|
compareBaseline: z.ZodOptional<z.ZodString>;
|
|
143
143
|
}, "strip", z.ZodTypeAny, {
|
|
144
|
-
metrics: ("function" | "line" | "
|
|
144
|
+
metrics: ("function" | "line" | "branch" | "statement" | "overall")[];
|
|
145
145
|
timeRange: "30d" | "7d" | "14d" | "90d" | "180d" | "365d";
|
|
146
146
|
groupBy: "commit" | "day" | "week" | "month";
|
|
147
147
|
detectRegressions: boolean;
|
|
@@ -150,7 +150,7 @@ export declare const toolDefinition: {
|
|
|
150
150
|
targetPath?: string | undefined;
|
|
151
151
|
compareBaseline?: string | undefined;
|
|
152
152
|
}, {
|
|
153
|
-
metrics?: ("function" | "line" | "
|
|
153
|
+
metrics?: ("function" | "line" | "branch" | "statement" | "overall")[] | undefined;
|
|
154
154
|
timeRange?: "30d" | "7d" | "14d" | "90d" | "180d" | "365d" | undefined;
|
|
155
155
|
targetPath?: string | undefined;
|
|
156
156
|
groupBy?: "commit" | "day" | "week" | "month" | undefined;
|
package/packages/@monomind/cli/dist/src/mcp-tools/quality/test-generation/suggest-tests.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export declare const SuggestTestsInputSchema: z.ZodObject<{
|
|
|
16
16
|
}, "strip", z.ZodTypeAny, {
|
|
17
17
|
framework: "vitest" | "jest" | "mocha" | "pytest" | "junit";
|
|
18
18
|
targetPath: string;
|
|
19
|
-
focusAreas: ("
|
|
19
|
+
focusAreas: ("branches" | "lines" | "functions" | "edge-cases" | "error-handling" | "boundaries")[];
|
|
20
20
|
maxSuggestions: number;
|
|
21
21
|
priorityBy: "risk" | "complexity" | "coverage-impact" | "change-frequency";
|
|
22
22
|
includeCode: boolean;
|
|
@@ -25,7 +25,7 @@ export declare const SuggestTestsInputSchema: z.ZodObject<{
|
|
|
25
25
|
targetPath: string;
|
|
26
26
|
framework?: "vitest" | "jest" | "mocha" | "pytest" | "junit" | undefined;
|
|
27
27
|
coverageReport?: string | undefined;
|
|
28
|
-
focusAreas?: ("
|
|
28
|
+
focusAreas?: ("branches" | "lines" | "functions" | "edge-cases" | "error-handling" | "boundaries")[] | undefined;
|
|
29
29
|
maxSuggestions?: number | undefined;
|
|
30
30
|
priorityBy?: "risk" | "complexity" | "coverage-impact" | "change-frequency" | undefined;
|
|
31
31
|
includeCode?: boolean | undefined;
|
|
@@ -121,7 +121,7 @@ export declare const toolDefinition: {
|
|
|
121
121
|
}, "strip", z.ZodTypeAny, {
|
|
122
122
|
framework: "vitest" | "jest" | "mocha" | "pytest" | "junit";
|
|
123
123
|
targetPath: string;
|
|
124
|
-
focusAreas: ("
|
|
124
|
+
focusAreas: ("branches" | "lines" | "functions" | "edge-cases" | "error-handling" | "boundaries")[];
|
|
125
125
|
maxSuggestions: number;
|
|
126
126
|
priorityBy: "risk" | "complexity" | "coverage-impact" | "change-frequency";
|
|
127
127
|
includeCode: boolean;
|
|
@@ -130,7 +130,7 @@ export declare const toolDefinition: {
|
|
|
130
130
|
targetPath: string;
|
|
131
131
|
framework?: "vitest" | "jest" | "mocha" | "pytest" | "junit" | undefined;
|
|
132
132
|
coverageReport?: string | undefined;
|
|
133
|
-
focusAreas?: ("
|
|
133
|
+
focusAreas?: ("branches" | "lines" | "functions" | "edge-cases" | "error-handling" | "boundaries")[] | undefined;
|
|
134
134
|
maxSuggestions?: number | undefined;
|
|
135
135
|
priorityBy?: "risk" | "complexity" | "coverage-impact" | "change-frequency" | undefined;
|
|
136
136
|
includeCode?: boolean | undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monoes/monomindcli",
|
|
3
|
-
"version": "1.18.
|
|
3
|
+
"version": "1.18.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Monomind CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -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
|