@sverka/benchmark 0.0.0 → 0.1.1

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/dist/bin.d.mts ADDED
@@ -0,0 +1 @@
1
+ export {}
package/dist/bin.mjs ADDED
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+ import { c as BENCHMARK_TASKS, f as runBenchmark, l as DEFAULT_AGENTS, p as writeReport } from "./src-PvGPQO8c.mjs";
3
+ import { join } from "node:path";
4
+ import process from "node:process";
5
+ //#region src/bin.ts
6
+ async function main() {
7
+ const model = process.env.DEVIN_MODEL ?? "glm-5-2";
8
+ const outputDir = process.argv[2] ?? process.cwd();
9
+ process.stderr.write(`Sverka Benchmark Arena\n`);
10
+ process.stderr.write(`Model: ${model}\n`);
11
+ process.stderr.write(`Tasks: ${BENCHMARK_TASKS.length}\n`);
12
+ process.stderr.write(`Agents: ${DEFAULT_AGENTS.length}\n\n`);
13
+ const result = await runBenchmark({
14
+ tasks: [...BENCHMARK_TASKS],
15
+ agents: [...DEFAULT_AGENTS],
16
+ model,
17
+ outputDir
18
+ });
19
+ const filename = `benchmark-${result.timestamp.replace(/[:.]/g, "-")}.json`;
20
+ const outputPath = join(outputDir, filename);
21
+ await writeReport(result, outputPath);
22
+ process.stderr.write(`\nReport written to: ${outputPath}\n`);
23
+ process.stderr.write(`\nSummary:\n`);
24
+ process.stderr.write(` raw-shell: ${result.summary["raw-shell"].successCount}/${result.summary["raw-shell"].totalTasks} pass, avg ${result.summary["raw-shell"].avgTotalTokens} tokens\n`);
25
+ process.stderr.write(` sverka: ${result.summary.sverka.successCount}/${result.summary.sverka.totalTasks} pass, avg ${result.summary.sverka.avgTotalTokens} tokens\n`);
26
+ return 0;
27
+ }
28
+ main().then(process.exit).catch((err) => {
29
+ process.stderr.write(`Fatal: ${err}\n`);
30
+ process.exit(1);
31
+ });
32
+ //#endregion
33
+ export {};
34
+
35
+ //# sourceMappingURL=bin.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.mjs","names":[],"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\nimport process from \"node:process\";\nimport { join } from \"node:path\";\nimport { runBenchmark, writeReport, BENCHMARK_TASKS, DEFAULT_AGENTS } from \"./index.js\";\n\nasync function main(): Promise<number> {\n const model = process.env.DEVIN_MODEL ?? \"glm-5-2\";\n const outputDir = process.argv[2] ?? process.cwd();\n\n process.stderr.write(`Sverka Benchmark Arena\\n`);\n process.stderr.write(`Model: ${model}\\n`);\n process.stderr.write(`Tasks: ${BENCHMARK_TASKS.length}\\n`);\n process.stderr.write(`Agents: ${DEFAULT_AGENTS.length}\\n\\n`);\n\n const result = await runBenchmark({\n tasks: [...BENCHMARK_TASKS],\n agents: [...DEFAULT_AGENTS],\n model,\n outputDir,\n });\n\n const filename = `benchmark-${result.timestamp.replace(/[:.]/g, \"-\")}.json`;\n const outputPath = join(outputDir, filename);\n await writeReport(result, outputPath);\n\n process.stderr.write(`\\nReport written to: ${outputPath}\\n`);\n process.stderr.write(`\\nSummary:\\n`);\n process.stderr.write(` raw-shell: ${result.summary[\"raw-shell\"].successCount}/${result.summary[\"raw-shell\"].totalTasks} pass, avg ${result.summary[\"raw-shell\"].avgTotalTokens} tokens\\n`);\n process.stderr.write(` sverka: ${result.summary.sverka.successCount}/${result.summary.sverka.totalTasks} pass, avg ${result.summary.sverka.avgTotalTokens} tokens\\n`);\n\n return 0;\n}\n\nmain().then(process.exit).catch((err) => {\n process.stderr.write(`Fatal: ${err}\\n`);\n process.exit(1);\n});\n"],"mappings":";;;;;AAKA,eAAe,OAAwB;CACrC,MAAM,QAAQ,QAAQ,IAAI,eAAe;CACzC,MAAM,YAAY,QAAQ,KAAK,MAAM,QAAQ,IAAI;CAEjD,QAAQ,OAAO,MAAM,0BAA0B;CAC/C,QAAQ,OAAO,MAAM,UAAU,MAAM,GAAG;CACxC,QAAQ,OAAO,MAAM,UAAU,gBAAgB,OAAO,GAAG;CACzD,QAAQ,OAAO,MAAM,WAAW,eAAe,OAAO,KAAK;CAE3D,MAAM,SAAS,MAAM,aAAa;EAChC,OAAO,CAAC,GAAG,eAAe;EAC1B,QAAQ,CAAC,GAAG,cAAc;EAC1B;EACA;CACF,CAAC;CAED,MAAM,WAAW,aAAa,OAAO,UAAU,QAAQ,SAAS,GAAG,EAAE;CACrE,MAAM,aAAa,KAAK,WAAW,QAAQ;CAC3C,MAAM,YAAY,QAAQ,UAAU;CAEpC,QAAQ,OAAO,MAAM,wBAAwB,WAAW,GAAG;CAC3D,QAAQ,OAAO,MAAM,cAAc;CACnC,QAAQ,OAAO,MAAM,gBAAgB,OAAO,QAAQ,YAAY,CAAC,aAAa,GAAG,OAAO,QAAQ,YAAY,CAAC,WAAW,aAAa,OAAO,QAAQ,YAAY,CAAC,eAAe,UAAU;CAC1L,QAAQ,OAAO,MAAM,gBAAgB,OAAO,QAAQ,OAAO,aAAa,GAAG,OAAO,QAAQ,OAAO,WAAW,aAAa,OAAO,QAAQ,OAAO,eAAe,UAAU;CAExK,OAAO;AACT;AAEA,KAAK,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,QAAQ;CACvC,QAAQ,OAAO,MAAM,UAAU,IAAI,GAAG;CACtC,QAAQ,KAAK,CAAC;AAChB,CAAC"}
@@ -0,0 +1,164 @@
1
+ import { Usage } from "@agentclientprotocol/sdk";
2
+ //#region src/types.d.ts
3
+ /** A benchmark task scenario. */
4
+ interface Task {
5
+ id: string;
6
+ name: string;
7
+ prompt: string;
8
+ timeoutMs?: number;
9
+ }
10
+ /** Agent configuration — determines workspace setup. */
11
+ interface AgentConfig {
12
+ id: string;
13
+ name: string;
14
+ type: "raw-shell" | "sverka";
15
+ }
16
+ /** Metrics collected from ACP events + timing. */
17
+ interface RunMetrics {
18
+ inputTokens: number;
19
+ outputTokens: number;
20
+ thoughtTokens: number;
21
+ totalTokens: number;
22
+ toolCallCount: number;
23
+ executionTimeMs: number;
24
+ stopReason: string;
25
+ }
26
+ /** Result of a single task+agent run. */
27
+ interface RunResult {
28
+ taskId: string;
29
+ agentId: string;
30
+ agentType: string;
31
+ metrics: RunMetrics;
32
+ success: boolean;
33
+ error?: string;
34
+ }
35
+ /** Aggregate metrics for one agent type across all tasks. */
36
+ interface AggregateMetrics {
37
+ totalTasks: number;
38
+ successCount: number;
39
+ avgInputTokens: number;
40
+ avgOutputTokens: number;
41
+ avgTotalTokens: number;
42
+ avgToolCalls: number;
43
+ avgExecutionTimeMs: number;
44
+ }
45
+ /** Full benchmark output. */
46
+ interface BenchmarkResult {
47
+ timestamp: string;
48
+ model: string;
49
+ results: RunResult[];
50
+ summary: {
51
+ "raw-shell": AggregateMetrics;
52
+ sverka: AggregateMetrics;
53
+ };
54
+ }
55
+ /** Arena configuration. */
56
+ interface BenchmarkConfig {
57
+ tasks: Task[];
58
+ agents: AgentConfig[];
59
+ model?: string;
60
+ outputDir?: string;
61
+ }
62
+ //#endregion
63
+ //#region src/arena.d.ts
64
+ /** Extract RunMetrics from a PromptResponse + collected event data. */
65
+ export declare function extractMetrics(promptResult: {
66
+ stopReason: string;
67
+ usage?: Usage | null;
68
+ }, toolCallCount: number, startTime: number): RunMetrics;
69
+ /** Aggregate metrics for one agent type across multiple RunResults. */
70
+ export declare function aggregateMetrics(results: RunResult[], agentType: string): AggregateMetrics;
71
+ /** Run the full benchmark: each task × each agent, sequentially. */
72
+ export declare function runBenchmark(config: BenchmarkConfig): Promise<BenchmarkResult>;
73
+ /** Write benchmark results to a JSON file. */
74
+ export declare function writeReport(result: BenchmarkResult, outputPath: string): Promise<void>;
75
+ //#endregion
76
+ //#region src/tasks.d.ts
77
+ /** 5 task scenarios, ordered simple → complex. */
78
+ export declare const BENCHMARK_TASKS: readonly Task[];
79
+ /** Default agent configs: raw-shell (no sverka) vs sverka (CLI + skill). */
80
+ export declare const DEFAULT_AGENTS: readonly AgentConfig[];
81
+ //#endregion
82
+ //#region src/collector.d.ts
83
+ /**
84
+ * Transcript collector — reads Devin CLI transcripts and transforms them
85
+ * to trace data for the benchmark trace viewer.
86
+ *
87
+ * Transcript source: ~/.local/share/devin/cli/transcripts/<session-id>.json
88
+ * Each transcript has steps[] with source, message, timestamp, and extra.telemetry.
89
+ * Agent steps with telemetry.operation === "inference" are LLM calls.
90
+ */
91
+ interface TranscriptStep {
92
+ step_id: number;
93
+ source: "system" | "agent" | "user";
94
+ message: string;
95
+ timestamp: string;
96
+ extra?: {
97
+ generation_model?: string | null;
98
+ telemetry?: {
99
+ source?: string;
100
+ operation?: string;
101
+ };
102
+ };
103
+ }
104
+ interface TranscriptMetrics {
105
+ total_prompt_tokens: number;
106
+ total_completion_tokens: number;
107
+ total_cached_tokens: number;
108
+ total_steps: number;
109
+ }
110
+ interface Transcript {
111
+ session_id: string;
112
+ schema_version: string;
113
+ agent: {
114
+ name: string;
115
+ version: string;
116
+ model_name: string;
117
+ };
118
+ final_metrics: TranscriptMetrics;
119
+ steps: TranscriptStep[];
120
+ }
121
+ interface TraceStep {
122
+ stepId: number;
123
+ source: "system" | "agent" | "user";
124
+ timestamp: string;
125
+ message: string;
126
+ isLlmCall: boolean;
127
+ }
128
+ interface TraceAgentData {
129
+ sessionId: string;
130
+ model: string;
131
+ finalMetrics: {
132
+ totalPromptTokens: number;
133
+ totalCompletionTokens: number;
134
+ totalCachedTokens: number;
135
+ totalSteps: number;
136
+ };
137
+ llmCallCount: number;
138
+ steps: TraceStep[];
139
+ }
140
+ interface TraceData {
141
+ taskId: string;
142
+ prompt: string;
143
+ agents: {
144
+ "raw-shell"?: TraceAgentData;
145
+ sverka?: TraceAgentData;
146
+ };
147
+ }
148
+ /** Default transcript directory. */
149
+ export declare function transcriptDir(): string;
150
+ /** Read a transcript JSON file by session ID. */
151
+ export declare function readTranscript(sessionId: string, dir?: string): Transcript;
152
+ /** Transform a raw transcript step to a trace step. */
153
+ export declare function transformStep(step: TranscriptStep): TraceStep;
154
+ /** Count LLM inference calls in a transcript. */
155
+ export declare function countLlmCalls(transcript: Transcript): number;
156
+ /** Transform a full transcript to agent trace data. */
157
+ export declare function transformTranscript(transcript: Transcript, agentType: "raw-shell" | "sverka"): TraceAgentData;
158
+ /** Build a combined trace data object for a task from two transcripts. */
159
+ export declare function buildTraceData(taskId: string, prompt: string, rawShellSessionId: string, sverkaSessionId: string, dir?: string): TraceData;
160
+ /** Write trace data to the benchmark traces directory. */
161
+ export declare function writeTraceData(trace: TraceData, outputDir: string): Promise<string>;
162
+ //#endregion
163
+ export type { AgentConfig, AggregateMetrics, BenchmarkConfig, BenchmarkResult, RunMetrics, RunResult, Task, TraceAgentData, TraceData, TraceStep, Transcript, TranscriptMetrics, TranscriptStep };
164
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/arena.ts","../src/tasks.ts","../src/collector.ts"],"mappings":";;;UACiB;EACf;EACA;EACA;EACA;;;UAIe;EACf;EACA;EACA;;;UAIe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;;;UAIe;EACf;EACA;EACA;EACA,SAAS;EACT;EACA;;;UAIe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;;;UAIe;EACf;EACA;EACA,SAAS;EACT;IACE,aAAa;IACb,QAAQ;;;;UAKK;EACf,OAAO;EACP,QAAQ;EACR;EACA;;;;;wBC1Cc,eACd;EAAgB;EAAoB,QAAQ;GAC5C,uBACA,oBACC;;wBAUa,iBACd,SAAS,aACT,oBACC;;wBA2BmB,aACpB,QAAQ,kBACP,QAAQ;;wBA6HW,YACpB,QAAQ,iBACR,qBACC;;;;qBChMU,0BAA0B;;qBAuC1B,yBAAyB;;;;;;;;;;;UC1BrB;EACf;EACA;EACA;EACA;EACA;IACE;IACA;MACE;MACA;;;;UAKW;EACf;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;IACE;IACA;IACA;;EAEF,eAAe;EACf,OAAO;;UAKQ;EACf;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;IACE;IACA;IACA;IACA;;EAEF;EACA,OAAO;;UAGQ;EACf;EACA;EACA;IACE,cAAc;IACd,SAAS;;;;wBAOG;;wBAKA,eACd,mBACA,eACC;;wBASa,cAAc,MAAM,iBAAiB;;wBAcrC,cAAc,YAAY;;wBAS1B,oBACd,YAAY,YACZ,oCACC;;wBAgBa,eACd,gBACA,gBACA,2BACA,yBACA,eACC;;wBAcmB,eACpB,OAAO,WACP,oBACC"}
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { a as transformStep, c as BENCHMARK_TASKS, d as extractMetrics, f as runBenchmark, i as transcriptDir, l as DEFAULT_AGENTS, n as countLlmCalls, o as transformTranscript, p as writeReport, r as readTranscript, s as writeTraceData, t as buildTraceData, u as aggregateMetrics } from "./src-PvGPQO8c.mjs";
2
+ export { BENCHMARK_TASKS, DEFAULT_AGENTS, aggregateMetrics, buildTraceData, countLlmCalls, extractMetrics, readTranscript, runBenchmark, transcriptDir, transformStep, transformTranscript, writeReport, writeTraceData };
@@ -0,0 +1,279 @@
1
+ import { spawn } from "node:child_process";
2
+ import { cp, mkdir, writeFile } from "node:fs/promises";
3
+ import { dirname, join, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { extractUsageTokens, runAcpSession, sanitizeEnv } from "@sverka/arena";
6
+ import { existsSync, readFileSync } from "node:fs";
7
+ import { homedir } from "node:os";
8
+ //#region src/arena.ts
9
+ /** Extract RunMetrics from a PromptResponse + collected event data. */
10
+ function extractMetrics(promptResult, toolCallCount, startTime) {
11
+ return {
12
+ ...extractUsageTokens(promptResult.usage),
13
+ toolCallCount,
14
+ executionTimeMs: Date.now() - startTime,
15
+ stopReason: promptResult.stopReason
16
+ };
17
+ }
18
+ /** Aggregate metrics for one agent type across multiple RunResults. */
19
+ function aggregateMetrics(results, agentType) {
20
+ const filtered = results.filter((r) => r.agentType === agentType);
21
+ const n = filtered.length;
22
+ if (n === 0) return {
23
+ totalTasks: 0,
24
+ successCount: 0,
25
+ avgInputTokens: 0,
26
+ avgOutputTokens: 0,
27
+ avgTotalTokens: 0,
28
+ avgToolCalls: 0,
29
+ avgExecutionTimeMs: 0
30
+ };
31
+ const sum = (f) => filtered.reduce((a, r) => a + f(r), 0);
32
+ return {
33
+ totalTasks: n,
34
+ successCount: filtered.filter((r) => r.success).length,
35
+ avgInputTokens: Math.round(sum((r) => r.metrics.inputTokens) / n),
36
+ avgOutputTokens: Math.round(sum((r) => r.metrics.outputTokens) / n),
37
+ avgTotalTokens: Math.round(sum((r) => r.metrics.totalTokens) / n),
38
+ avgToolCalls: Math.round(sum((r) => r.metrics.toolCallCount) / n * 100) / 100,
39
+ avgExecutionTimeMs: Math.round(sum((r) => r.metrics.executionTimeMs) / n)
40
+ };
41
+ }
42
+ /** Run the full benchmark: each task × each agent, sequentially. */
43
+ async function runBenchmark(config) {
44
+ const model = config.model ?? "glm-5-2";
45
+ const results = [];
46
+ for (const task of config.tasks) for (const agent of config.agents) {
47
+ process.stderr.write(`[${task.id}/${agent.id}] Running...\n`);
48
+ const result = await runTask(task, agent, model);
49
+ results.push(result);
50
+ process.stderr.write(`[${task.id}/${agent.id}] ${result.success ? "PASS" : "FAIL"} — ${result.metrics.totalTokens} tokens, ${result.metrics.toolCallCount} tools, ${result.metrics.executionTimeMs}ms\n`);
51
+ }
52
+ return {
53
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
54
+ model,
55
+ results,
56
+ summary: {
57
+ "raw-shell": aggregateMetrics(results, "raw-shell"),
58
+ sverka: aggregateMetrics(results, "sverka")
59
+ }
60
+ };
61
+ }
62
+ /** Run a single task with one agent. */
63
+ async function runTask(task, agent, model) {
64
+ const workspace = await setupWorkspace(agent);
65
+ const startTime = Date.now();
66
+ let proc = null;
67
+ try {
68
+ proc = spawnAcpAgent(workspace, model);
69
+ let toolCallCount = 0;
70
+ const metrics = extractMetrics(await runAcpSession(proc, workspace, task.prompt, task.timeoutMs ?? 12e4, () => {
71
+ toolCallCount++;
72
+ }), toolCallCount, startTime);
73
+ return {
74
+ taskId: task.id,
75
+ agentId: agent.id,
76
+ agentType: agent.type,
77
+ metrics,
78
+ success: metrics.stopReason === "end_turn"
79
+ };
80
+ } catch (error) {
81
+ const metrics = extractMetrics({
82
+ stopReason: "cancelled",
83
+ usage: null
84
+ }, 0, startTime);
85
+ return {
86
+ taskId: task.id,
87
+ agentId: agent.id,
88
+ agentType: agent.type,
89
+ metrics,
90
+ success: false,
91
+ error: error instanceof Error ? error.message : String(error)
92
+ };
93
+ } finally {
94
+ proc?.kill("SIGTERM");
95
+ }
96
+ }
97
+ /** Set up workspace for an agent.
98
+ *
99
+ * Both agents work in the actual Sverka repo so they have the real project
100
+ * to operate on. The only difference is that the "sverka" agent gets the
101
+ * Sverka skill installed in .agents/skills/sverka/.
102
+ *
103
+ * We do NOT create a temp copy — copying node_modules + dist is too slow
104
+ * and the agents need the real build artifacts to run `sverka` commands.
105
+ */
106
+ async function setupWorkspace(agent) {
107
+ const here = dirname(fileURLToPath(import.meta.url));
108
+ const workspace = resolve(here, "..", "..", "..");
109
+ if (agent.type === "sverka") {
110
+ const skillDir = join(workspace, ".agents", "skills", "sverka");
111
+ const skillFile = join(skillDir, "SKILL.md");
112
+ try {
113
+ await mkdir(skillDir, { recursive: true });
114
+ const repoSkillPath = resolveRepoFile(".agents/skills/sverka/SKILL.md");
115
+ if (repoSkillPath && resolve(repoSkillPath) !== resolve(skillFile)) await cp(repoSkillPath, skillFile, { recursive: true });
116
+ } catch {}
117
+ }
118
+ return workspace;
119
+ }
120
+ /** Spawn `devin acp` as a subprocess in the given workspace. */
121
+ function spawnAcpAgent(workspace, model) {
122
+ const env = sanitizeEnv({
123
+ model: {
124
+ id: model,
125
+ name: model
126
+ },
127
+ workspace,
128
+ plugins: []
129
+ });
130
+ return spawn("devin", [
131
+ "acp",
132
+ "--model",
133
+ model
134
+ ], {
135
+ cwd: workspace,
136
+ stdio: [
137
+ "pipe",
138
+ "pipe",
139
+ "inherit"
140
+ ],
141
+ env
142
+ });
143
+ }
144
+ /** Write benchmark results to a JSON file. */
145
+ async function writeReport(result, outputPath) {
146
+ const json = JSON.stringify(result, null, 2);
147
+ await writeFile(outputPath, json, "utf-8");
148
+ }
149
+ /** Resolve a file path relative to the repo root. */
150
+ function resolveRepoFile(relPath) {
151
+ try {
152
+ const here = dirname(fileURLToPath(import.meta.url));
153
+ const repoRoot = resolve(here, "..", "..", "..");
154
+ return join(repoRoot, relPath);
155
+ } catch {
156
+ return null;
157
+ }
158
+ }
159
+ //#endregion
160
+ //#region src/tasks.ts
161
+ /** 5 task scenarios, ordered simple → complex. */
162
+ const BENCHMARK_TASKS = [
163
+ {
164
+ id: "run-checks",
165
+ name: "run-checks",
166
+ prompt: "Run all quality checks (lint, typecheck, test, build) for this TypeScript project and report the results. If any check fails, report which one failed and why.",
167
+ timeoutMs: 12e4
168
+ },
169
+ {
170
+ id: "discover",
171
+ name: "discover",
172
+ prompt: "Discover what checks are available in this project by reading package.json scripts and looking for config files. List each check with its command.",
173
+ timeoutMs: 6e4
174
+ },
175
+ {
176
+ id: "create-config",
177
+ name: "create-config",
178
+ prompt: "Create a CI workflow configuration file for this project that runs lint, typecheck, test, and build in dependency order. The config should define steps with dependencies: lint and typecheck run first (parallel), test depends on both, build depends on test.",
179
+ timeoutMs: 12e4
180
+ },
181
+ {
182
+ id: "compile-github",
183
+ name: "compile-github",
184
+ prompt: "Compile a CI workflow to GitHub Actions YAML format for this project. The workflow should run lint, typecheck, test, and build on push events. Output the complete YAML.",
185
+ timeoutMs: 12e4
186
+ },
187
+ {
188
+ id: "multi-step",
189
+ name: "multi-step",
190
+ prompt: "Create a multi-step pipeline with dependencies: lint and typecheck run in parallel, test depends on both, build depends on test. Define the pipeline as code and validate it works correctly.",
191
+ timeoutMs: 12e4
192
+ }
193
+ ];
194
+ /** Default agent configs: raw-shell (no sverka) vs sverka (CLI + skill). */
195
+ const DEFAULT_AGENTS = [{
196
+ id: "raw-shell",
197
+ name: "Raw Shell Agent",
198
+ type: "raw-shell"
199
+ }, {
200
+ id: "sverka",
201
+ name: "Sverka CLI Agent",
202
+ type: "sverka"
203
+ }];
204
+ //#endregion
205
+ //#region src/collector.ts
206
+ /**
207
+ * Transcript collector — reads Devin CLI transcripts and transforms them
208
+ * to trace data for the benchmark trace viewer.
209
+ *
210
+ * Transcript source: ~/.local/share/devin/cli/transcripts/<session-id>.json
211
+ * Each transcript has steps[] with source, message, timestamp, and extra.telemetry.
212
+ * Agent steps with telemetry.operation === "inference" are LLM calls.
213
+ */
214
+ /** Default transcript directory. */
215
+ function transcriptDir() {
216
+ return join(homedir(), ".local", "share", "devin", "cli", "transcripts");
217
+ }
218
+ /** Read a transcript JSON file by session ID. */
219
+ function readTranscript(sessionId, dir) {
220
+ const path = join(dir ?? transcriptDir(), `${sessionId}.json`);
221
+ if (!existsSync(path)) throw new Error(`Transcript not found: ${path}`);
222
+ return JSON.parse(readFileSync(path, "utf-8"));
223
+ }
224
+ /** Transform a raw transcript step to a trace step. */
225
+ function transformStep(step) {
226
+ const isLlmCall = step.source === "agent" && step.extra?.telemetry?.operation === "inference";
227
+ return {
228
+ stepId: step.step_id,
229
+ source: step.source,
230
+ timestamp: step.timestamp,
231
+ message: step.message,
232
+ isLlmCall
233
+ };
234
+ }
235
+ /** Count LLM inference calls in a transcript. */
236
+ function countLlmCalls(transcript) {
237
+ return transcript.steps.filter((s) => s.source === "agent" && s.extra?.telemetry?.operation === "inference").length;
238
+ }
239
+ /** Transform a full transcript to agent trace data. */
240
+ function transformTranscript(transcript, agentType) {
241
+ return {
242
+ sessionId: transcript.session_id,
243
+ model: transcript.agent.model_name,
244
+ finalMetrics: {
245
+ totalPromptTokens: transcript.final_metrics.total_prompt_tokens,
246
+ totalCompletionTokens: transcript.final_metrics.total_completion_tokens,
247
+ totalCachedTokens: transcript.final_metrics.total_cached_tokens,
248
+ totalSteps: transcript.final_metrics.total_steps
249
+ },
250
+ llmCallCount: countLlmCalls(transcript),
251
+ steps: transcript.steps.map(transformStep)
252
+ };
253
+ }
254
+ /** Build a combined trace data object for a task from two transcripts. */
255
+ function buildTraceData(taskId, prompt, rawShellSessionId, sverkaSessionId, dir) {
256
+ const rawTranscript = readTranscript(rawShellSessionId, dir);
257
+ const sverkaTranscript = readTranscript(sverkaSessionId, dir);
258
+ return {
259
+ taskId,
260
+ prompt,
261
+ agents: {
262
+ "raw-shell": transformTranscript(rawTranscript, "raw-shell"),
263
+ sverka: transformTranscript(sverkaTranscript, "sverka")
264
+ }
265
+ };
266
+ }
267
+ /** Write trace data to the benchmark traces directory. */
268
+ async function writeTraceData(trace, outputDir) {
269
+ if (trace.taskId.includes("..") || trace.taskId.includes("/") || trace.taskId.includes("\\")) throw new Error(`Invalid taskId for trace output: ${trace.taskId}`);
270
+ const taskDir = join(outputDir, trace.taskId);
271
+ await mkdir(taskDir, { recursive: true });
272
+ const path = join(taskDir, "trace.json");
273
+ await writeFile(path, JSON.stringify(trace, null, 2), "utf-8");
274
+ return path;
275
+ }
276
+ //#endregion
277
+ export { transformStep as a, BENCHMARK_TASKS as c, extractMetrics as d, runBenchmark as f, transcriptDir as i, DEFAULT_AGENTS as l, countLlmCalls as n, transformTranscript as o, writeReport as p, readTranscript as r, writeTraceData as s, buildTraceData as t, aggregateMetrics as u };
278
+
279
+ //# sourceMappingURL=src-PvGPQO8c.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"src-PvGPQO8c.mjs","names":[],"sources":["../src/arena.ts","../src/tasks.ts","../src/collector.ts"],"sourcesContent":["import { spawn, type ChildProcess } from \"node:child_process\";\nimport { cp, mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, resolve } from \"node:path\";\n\nimport type { Usage } from \"@agentclientprotocol/sdk\";\n\nimport { sanitizeEnv, runAcpSession, extractUsageTokens } from \"@sverka/arena\";\n\nimport type {\n Task,\n AgentConfig,\n RunMetrics,\n RunResult,\n AggregateMetrics,\n BenchmarkResult,\n BenchmarkConfig,\n} from \"./types.js\";\n\n/** Extract RunMetrics from a PromptResponse + collected event data. */\nexport function extractMetrics(\n promptResult: { stopReason: string; usage?: Usage | null },\n toolCallCount: number,\n startTime: number,\n): RunMetrics {\n return {\n ...extractUsageTokens(promptResult.usage),\n toolCallCount,\n executionTimeMs: Date.now() - startTime,\n stopReason: promptResult.stopReason,\n };\n}\n\n/** Aggregate metrics for one agent type across multiple RunResults. */\nexport function aggregateMetrics(\n results: RunResult[],\n agentType: string,\n): AggregateMetrics {\n const filtered = results.filter((r) => r.agentType === agentType);\n const n = filtered.length;\n if (n === 0) {\n return {\n totalTasks: 0,\n successCount: 0,\n avgInputTokens: 0,\n avgOutputTokens: 0,\n avgTotalTokens: 0,\n avgToolCalls: 0,\n avgExecutionTimeMs: 0,\n };\n }\n const sum = (f: (r: RunResult) => number) => filtered.reduce((a, r) => a + f(r), 0);\n return {\n totalTasks: n,\n successCount: filtered.filter((r) => r.success).length,\n avgInputTokens: Math.round(sum((r) => r.metrics.inputTokens) / n),\n avgOutputTokens: Math.round(sum((r) => r.metrics.outputTokens) / n),\n avgTotalTokens: Math.round(sum((r) => r.metrics.totalTokens) / n),\n avgToolCalls: Math.round((sum((r) => r.metrics.toolCallCount) / n) * 100) / 100,\n avgExecutionTimeMs: Math.round(sum((r) => r.metrics.executionTimeMs) / n),\n };\n}\n\n/** Run the full benchmark: each task × each agent, sequentially. */\nexport async function runBenchmark(\n config: BenchmarkConfig,\n): Promise<BenchmarkResult> {\n const model = config.model ?? \"glm-5-2\";\n const results: RunResult[] = [];\n\n for (const task of config.tasks) {\n for (const agent of config.agents) {\n process.stderr.write(`[${task.id}/${agent.id}] Running...\\n`);\n const result = await runTask(task, agent, model);\n results.push(result);\n process.stderr.write(\n `[${task.id}/${agent.id}] ${result.success ? \"PASS\" : \"FAIL\"} — ` +\n `${result.metrics.totalTokens} tokens, ${result.metrics.toolCallCount} tools, ` +\n `${result.metrics.executionTimeMs}ms\\n`,\n );\n }\n }\n\n return {\n timestamp: new Date().toISOString(),\n model,\n results,\n summary: {\n \"raw-shell\": aggregateMetrics(results, \"raw-shell\"),\n sverka: aggregateMetrics(results, \"sverka\"),\n },\n };\n}\n\n/** Run a single task with one agent. */\nasync function runTask(\n task: Task,\n agent: AgentConfig,\n model: string,\n): Promise<RunResult> {\n const workspace = await setupWorkspace(agent);\n const startTime = Date.now();\n let proc: ChildProcess | null = null;\n\n try {\n proc = spawnAcpAgent(workspace, model);\n let toolCallCount = 0;\n const promptResult = await runAcpSession(\n proc,\n workspace,\n task.prompt,\n task.timeoutMs ?? 120000,\n () => {\n toolCallCount++;\n },\n );\n const metrics = extractMetrics(promptResult, toolCallCount, startTime);\n return {\n taskId: task.id,\n agentId: agent.id,\n agentType: agent.type,\n metrics,\n success: metrics.stopReason === \"end_turn\",\n };\n } catch (error) {\n const metrics = extractMetrics(\n { stopReason: \"cancelled\", usage: null },\n 0,\n startTime,\n );\n return {\n taskId: task.id,\n agentId: agent.id,\n agentType: agent.type,\n metrics,\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n } finally {\n proc?.kill(\"SIGTERM\");\n }\n}\n\n/** Set up workspace for an agent.\n *\n * Both agents work in the actual Sverka repo so they have the real project\n * to operate on. The only difference is that the \"sverka\" agent gets the\n * Sverka skill installed in .agents/skills/sverka/.\n *\n * We do NOT create a temp copy — copying node_modules + dist is too slow\n * and the agents need the real build artifacts to run `sverka` commands.\n */\nasync function setupWorkspace(agent: AgentConfig): Promise<string> {\n const here = dirname(fileURLToPath(import.meta.url));\n const repoRoot = resolve(here, \"..\", \"..\", \"..\");\n const workspace = repoRoot;\n\n if (agent.type === \"sverka\") {\n // Skill is already in the repo at .agents/skills/sverka/SKILL.md\n // No need to copy — just ensure the directory exists\n const skillDir = join(workspace, \".agents\", \"skills\", \"sverka\");\n const skillFile = join(skillDir, \"SKILL.md\");\n try {\n await mkdir(skillDir, { recursive: true });\n const repoSkillPath = resolveRepoFile(\".agents/skills/sverka/SKILL.md\");\n if (repoSkillPath && resolve(repoSkillPath) !== resolve(skillFile)) {\n await cp(repoSkillPath, skillFile, { recursive: true });\n }\n } catch {\n // Skill already exists — that's fine\n }\n }\n\n return workspace;\n}\n\n/** Spawn `devin acp` as a subprocess in the given workspace. */\nfunction spawnAcpAgent(workspace: string, model: string): ChildProcess {\n const env = sanitizeEnv({\n model: { id: model, name: model },\n workspace,\n plugins: [],\n });\n return spawn(\"devin\", [\"acp\", \"--model\", model], { // NOSONAR — PATH needed for devin binary\n cwd: workspace,\n stdio: [\"pipe\", \"pipe\", \"inherit\"],\n env,\n });\n}\n\n/** Write benchmark results to a JSON file. */\nexport async function writeReport(\n result: BenchmarkResult,\n outputPath: string,\n): Promise<void> {\n const json = JSON.stringify(result, null, 2);\n await writeFile(outputPath, json, \"utf-8\");\n}\n\n/** Resolve a file path relative to the repo root. */\nfunction resolveRepoFile(relPath: string): string | null {\n try {\n const here = dirname(fileURLToPath(import.meta.url));\n // From packages/benchmark/src/ or packages/benchmark/dist/ go up to repo root\n const repoRoot = resolve(here, \"..\", \"..\", \"..\");\n return join(repoRoot, relPath);\n } catch {\n return null;\n }\n}\n","import type { Task, AgentConfig } from \"./types.js\";\n\n/** 5 task scenarios, ordered simple → complex. */\nexport const BENCHMARK_TASKS: readonly Task[] = [\n {\n id: \"run-checks\",\n name: \"run-checks\",\n prompt:\n \"Run all quality checks (lint, typecheck, test, build) for this TypeScript project and report the results. If any check fails, report which one failed and why.\",\n timeoutMs: 120000,\n },\n {\n id: \"discover\",\n name: \"discover\",\n prompt:\n \"Discover what checks are available in this project by reading package.json scripts and looking for config files. List each check with its command.\",\n timeoutMs: 60000,\n },\n {\n id: \"create-config\",\n name: \"create-config\",\n prompt:\n \"Create a CI workflow configuration file for this project that runs lint, typecheck, test, and build in dependency order. The config should define steps with dependencies: lint and typecheck run first (parallel), test depends on both, build depends on test.\",\n timeoutMs: 120000,\n },\n {\n id: \"compile-github\",\n name: \"compile-github\",\n prompt:\n \"Compile a CI workflow to GitHub Actions YAML format for this project. The workflow should run lint, typecheck, test, and build on push events. Output the complete YAML.\",\n timeoutMs: 120000,\n },\n {\n id: \"multi-step\",\n name: \"multi-step\",\n prompt:\n \"Create a multi-step pipeline with dependencies: lint and typecheck run in parallel, test depends on both, build depends on test. Define the pipeline as code and validate it works correctly.\",\n timeoutMs: 120000,\n },\n] as const;\n\n/** Default agent configs: raw-shell (no sverka) vs sverka (CLI + skill). */\nexport const DEFAULT_AGENTS: readonly AgentConfig[] = [\n {\n id: \"raw-shell\",\n name: \"Raw Shell Agent\",\n type: \"raw-shell\",\n },\n {\n id: \"sverka\",\n name: \"Sverka CLI Agent\",\n type: \"sverka\",\n },\n] as const;\n","/**\n * Transcript collector — reads Devin CLI transcripts and transforms them\n * to trace data for the benchmark trace viewer.\n *\n * Transcript source: ~/.local/share/devin/cli/transcripts/<session-id>.json\n * Each transcript has steps[] with source, message, timestamp, and extra.telemetry.\n * Agent steps with telemetry.operation === \"inference\" are LLM calls.\n */\n\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { writeFile, mkdir } from \"node:fs/promises\";\n\n// ─── Transcript source types (raw JSON from Devin CLI) ───────────────\n\nexport interface TranscriptStep {\n step_id: number;\n source: \"system\" | \"agent\" | \"user\";\n message: string;\n timestamp: string;\n extra?: {\n generation_model?: string | null;\n telemetry?: {\n source?: string;\n operation?: string;\n };\n };\n}\n\nexport interface TranscriptMetrics {\n total_prompt_tokens: number;\n total_completion_tokens: number;\n total_cached_tokens: number;\n total_steps: number;\n}\n\nexport interface Transcript {\n session_id: string;\n schema_version: string;\n agent: {\n name: string;\n version: string;\n model_name: string;\n };\n final_metrics: TranscriptMetrics;\n steps: TranscriptStep[];\n}\n\n// ─── Trace data types (transformed for viewer) ───────────────────────\n\nexport interface TraceStep {\n stepId: number;\n source: \"system\" | \"agent\" | \"user\";\n timestamp: string;\n message: string;\n isLlmCall: boolean;\n}\n\nexport interface TraceAgentData {\n sessionId: string;\n model: string;\n finalMetrics: {\n totalPromptTokens: number;\n totalCompletionTokens: number;\n totalCachedTokens: number;\n totalSteps: number;\n };\n llmCallCount: number;\n steps: TraceStep[];\n}\n\nexport interface TraceData {\n taskId: string;\n prompt: string;\n agents: {\n \"raw-shell\"?: TraceAgentData;\n sverka?: TraceAgentData;\n };\n}\n\n// ─── Collector functions ─────────────────────────────────────────────\n\n/** Default transcript directory. */\nexport function transcriptDir(): string {\n return join(homedir(), \".local\", \"share\", \"devin\", \"cli\", \"transcripts\");\n}\n\n/** Read a transcript JSON file by session ID. */\nexport function readTranscript(\n sessionId: string,\n dir?: string,\n): Transcript {\n const path = join(dir ?? transcriptDir(), `${sessionId}.json`);\n if (!existsSync(path)) {\n throw new Error(`Transcript not found: ${path}`);\n }\n return JSON.parse(readFileSync(path, \"utf-8\")) as Transcript;\n}\n\n/** Transform a raw transcript step to a trace step. */\nexport function transformStep(step: TranscriptStep): TraceStep {\n const isLlmCall =\n step.source === \"agent\" &&\n step.extra?.telemetry?.operation === \"inference\";\n return {\n stepId: step.step_id,\n source: step.source,\n timestamp: step.timestamp,\n message: step.message,\n isLlmCall,\n };\n}\n\n/** Count LLM inference calls in a transcript. */\nexport function countLlmCalls(transcript: Transcript): number {\n return transcript.steps.filter(\n (s) =>\n s.source === \"agent\" &&\n s.extra?.telemetry?.operation === \"inference\",\n ).length;\n}\n\n/** Transform a full transcript to agent trace data. */\nexport function transformTranscript(\n transcript: Transcript,\n agentType: \"raw-shell\" | \"sverka\",\n): TraceAgentData {\n return {\n sessionId: transcript.session_id,\n model: transcript.agent.model_name,\n finalMetrics: {\n totalPromptTokens: transcript.final_metrics.total_prompt_tokens,\n totalCompletionTokens: transcript.final_metrics.total_completion_tokens,\n totalCachedTokens: transcript.final_metrics.total_cached_tokens,\n totalSteps: transcript.final_metrics.total_steps,\n },\n llmCallCount: countLlmCalls(transcript),\n steps: transcript.steps.map(transformStep),\n };\n}\n\n/** Build a combined trace data object for a task from two transcripts. */\nexport function buildTraceData(\n taskId: string,\n prompt: string,\n rawShellSessionId: string,\n sverkaSessionId: string,\n dir?: string,\n): TraceData {\n const rawTranscript = readTranscript(rawShellSessionId, dir);\n const sverkaTranscript = readTranscript(sverkaSessionId, dir);\n return {\n taskId,\n prompt,\n agents: {\n \"raw-shell\": transformTranscript(rawTranscript, \"raw-shell\"),\n sverka: transformTranscript(sverkaTranscript, \"sverka\"),\n },\n };\n}\n\n/** Write trace data to the benchmark traces directory. */\nexport async function writeTraceData(\n trace: TraceData,\n outputDir: string,\n): Promise<string> {\n // Reject path traversal in taskId to prevent writing outside outputDir\n if (trace.taskId.includes(\"..\") || trace.taskId.includes(\"/\") || trace.taskId.includes(\"\\\\\")) {\n throw new Error(`Invalid taskId for trace output: ${trace.taskId}`);\n }\n const taskDir = join(outputDir, trace.taskId);\n await mkdir(taskDir, { recursive: true });\n const path = join(taskDir, \"trace.json\");\n await writeFile(path, JSON.stringify(trace, null, 2), \"utf-8\");\n return path;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,20 +1,52 @@
1
1
  {
2
- "bugs": {
3
- "url": "https://github.com/sverka-dev/sverka/issues"
4
- },
5
- "description": "Placeholder for @sverka/benchmark published by @nx-devkit/prepare-for-release.",
6
- "homepage": "https://sverka.dev",
7
- "license": "MIT",
8
2
  "name": "@sverka/benchmark",
9
- "publishConfig": {
10
- "access": "public",
11
- "registry": "https://registry.npmjs.org/"
12
- },
3
+ "version": "0.1.1",
4
+ "description": "Sverka benchmark arena — two-agent comparison harness",
5
+ "license": "MIT",
13
6
  "repository": {
14
7
  "type": "git",
15
8
  "url": "https://github.com/sverka-dev/sverka",
16
9
  "directory": "packages/benchmark"
17
10
  },
11
+ "homepage": "https://sverka.dev",
12
+ "bugs": {
13
+ "url": "https://github.com/sverka-dev/sverka/issues"
14
+ },
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
18
  "type": "module",
19
- "version": "0.0.0"
20
- }
19
+ "engines": {
20
+ "node": ">=22.5.0"
21
+ },
22
+ "main": "./dist/index.mjs",
23
+ "module": "./dist/index.mjs",
24
+ "types": "./dist/index.d.mts",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.mts",
28
+ "import": "./dist/index.mjs"
29
+ }
30
+ },
31
+ "files": [
32
+ "dist"
33
+ ],
34
+ "bin": {
35
+ "sverka-benchmark": "./dist/bin.mjs"
36
+ },
37
+ "scripts": {
38
+ "build": "tsdown",
39
+ "test": "vitest run --passWithNoTests",
40
+ "lint": "eslint src",
41
+ "typecheck": "tsc --noEmit"
42
+ },
43
+ "dependencies": {
44
+ "@agentclientprotocol/sdk": "^1.4.0",
45
+ "@sverka/arena": "^0.1.1"
46
+ },
47
+ "devDependencies": {
48
+ "tsdown": "^0.23.0",
49
+ "typescript": "^5.8.0",
50
+ "vitest": "^5.0.0"
51
+ }
52
+ }