@codeatlas-ai/benchmark 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 CodeAtlas Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,296 @@
1
+ // src/index.ts
2
+ import fs2 from "fs";
3
+ import path2 from "path";
4
+ import chalk from "chalk";
5
+
6
+ // src/datasets.ts
7
+ var EXPRESS_BENCHMARK_DATASET = {
8
+ name: "expressjs/express",
9
+ repositoryUrl: "https://github.com/expressjs/express.git",
10
+ branch: "master",
11
+ tasks: [
12
+ {
13
+ id: "express-routing-matching",
14
+ query: "Find how routes and middleware are registered and dispatched on the express application",
15
+ description: "Locate core application routing and middleware initialization",
16
+ expectedFiles: ["lib/application.js", "lib/express.js"]
17
+ },
18
+ {
19
+ id: "express-app-listen",
20
+ query: "Where is app.listen defined and how does it start the HTTP server",
21
+ description: "Locate application initialization and HTTP server bootstrap",
22
+ expectedFiles: ["lib/application.js", "lib/express.js"]
23
+ },
24
+ {
25
+ id: "express-response-json",
26
+ query: "Locate the logic that formats and serializes response data to JSON with res.json",
27
+ description: "Trace res.json and res.send response prototype helpers",
28
+ expectedFiles: ["lib/response.js"]
29
+ },
30
+ {
31
+ id: "express-request-cookies",
32
+ query: "Where are request cookies and headers parsed in the request prototype",
33
+ description: "Locate req.cookies and header parsing helpers in request prototype",
34
+ expectedFiles: ["lib/request.js"]
35
+ },
36
+ {
37
+ id: "express-view-render",
38
+ query: "Find template rendering and view engine resolution with app.render and res.render",
39
+ description: "Trace view engine lookup and rendering pipeline",
40
+ expectedFiles: ["lib/view.js", "lib/application.js", "lib/response.js"]
41
+ }
42
+ ]
43
+ };
44
+ var ALL_DATASETS = [EXPRESS_BENCHMARK_DATASET];
45
+
46
+ // src/runner.ts
47
+ import fs from "fs";
48
+ import path from "path";
49
+ import { execSync } from "child_process";
50
+ import {
51
+ AtlasDatabase,
52
+ runMigrations,
53
+ FileRepository,
54
+ SearchRepository,
55
+ DependencyRepository
56
+ } from "@codeatlas-ai/storage";
57
+ import { Indexer } from "@codeatlas-ai/indexer";
58
+ import { DependencyGraph } from "@codeatlas-ai/graph";
59
+ import { RetrievalEngine } from "@codeatlas-ai/retrieval";
60
+ import { Ranker } from "@codeatlas-ai/ranking";
61
+ import { ContextEngine } from "@codeatlas-ai/context";
62
+ import { RuleEngine } from "@codeatlas-ai/rules";
63
+ import { TokenCounter } from "@codeatlas-ai/token-counter";
64
+ var BenchmarkRunner = class {
65
+ baseDir;
66
+ tokenCounter;
67
+ constructor(baseDir = path.resolve(process.cwd(), ".benchmarks")) {
68
+ this.baseDir = baseDir;
69
+ this.tokenCounter = new TokenCounter();
70
+ }
71
+ async run(dataset) {
72
+ const repoDir = this.ensureRepository(dataset);
73
+ const dbPath = path.join(repoDir, ".atlas", "atlas.db");
74
+ if (fs.existsSync(path.dirname(dbPath))) {
75
+ fs.rmSync(path.dirname(dbPath), { recursive: true, force: true });
76
+ }
77
+ fs.mkdirSync(path.dirname(dbPath), { recursive: true });
78
+ const db = new AtlasDatabase(dbPath);
79
+ runMigrations(db);
80
+ const projectRow = db.get("SELECT id FROM projects WHERE root = ?", repoDir);
81
+ let projectId = projectRow?.id;
82
+ if (!projectId) {
83
+ const res = db.run("INSERT INTO projects (name, root) VALUES (?, ?)", dataset.name, repoDir);
84
+ projectId = Number(res.lastInsertRowid);
85
+ }
86
+ console.log(`
87
+ \u23F3 Indexing dataset repository: ${dataset.name}...`);
88
+ const indexer = new Indexer({
89
+ root: repoDir,
90
+ db,
91
+ projectId,
92
+ includeTests: false
93
+ });
94
+ await indexer.index();
95
+ const fileRepo = new FileRepository(db);
96
+ const allFiles = fileRepo.getAll(projectId);
97
+ const filesByPath = new Map(allFiles.map((f) => [f.relativePath, f]));
98
+ let totalRepoRawTokens = 0;
99
+ for (const file of allFiles) {
100
+ const fullPath = path.join(repoDir, file.relativePath);
101
+ if (fs.existsSync(fullPath)) {
102
+ try {
103
+ const content = fs.readFileSync(fullPath, "utf-8");
104
+ totalRepoRawTokens += this.tokenCounter.count(content);
105
+ } catch {
106
+ }
107
+ }
108
+ }
109
+ const depRepo = new DependencyRepository(db);
110
+ const deps = depRepo.getAll(projectId);
111
+ const graph = new DependencyGraph();
112
+ graph.addEdges(deps);
113
+ const searchRepo = new SearchRepository(db);
114
+ const retrieval = new RetrievalEngine(searchRepo, graph, filesByPath);
115
+ const ruleEngine = new RuleEngine(repoDir);
116
+ const rules = ruleEngine.discover();
117
+ const projectMeta = {
118
+ name: dataset.name,
119
+ root: repoDir.replace(/\\/g, "/"),
120
+ languages: ["javascript"],
121
+ frameworks: [],
122
+ packageManager: "npm",
123
+ fileCount: allFiles.length,
124
+ symbolCount: 0,
125
+ dependencyCount: deps.length,
126
+ isMonorepo: false,
127
+ workspaces: []
128
+ };
129
+ const taskResults = [];
130
+ console.log(`\u{1F9EA} Running ${dataset.tasks.length} benchmark task queries...`);
131
+ for (const task of dataset.tasks) {
132
+ const start = performance.now();
133
+ const retrievalResult = retrieval.retrieve(task.query, 15);
134
+ const ranker = new Ranker({
135
+ weights: {
136
+ lexical_weight: 0.35,
137
+ symbol_weight: 0.2,
138
+ path_weight: 0.15,
139
+ dependency_weight: 0.1,
140
+ module_weight: 0.1,
141
+ rule_weight: 0.05,
142
+ recency_weight: 0.05
143
+ },
144
+ queryTerms: retrievalResult.queryTerms
145
+ });
146
+ const ranked = ranker.rank(retrievalResult.candidates);
147
+ const contextEngine = new ContextEngine({
148
+ tokenBudget: 8e3,
149
+ defaultMode: "signature",
150
+ repositoryRoot: repoDir
151
+ });
152
+ const pack = contextEngine.build({
153
+ task: task.query,
154
+ project: projectMeta,
155
+ rankedResults: ranked,
156
+ rules
157
+ });
158
+ const durationMs = Math.round(performance.now() - start);
159
+ const retrievedPaths = pack.files.map((f) => f.relativePath.replace(/\\/g, "/"));
160
+ const normalizedExpected = task.expectedFiles.map((f) => f.replace(/\\/g, "/"));
161
+ const hits = normalizedExpected.filter(
162
+ (exp) => retrievedPaths.some((ret) => ret === exp || ret.endsWith(exp))
163
+ );
164
+ const precision = retrievedPaths.length > 0 ? hits.length / retrievedPaths.length : 0;
165
+ const recall = normalizedExpected.length > 0 ? hits.length / normalizedExpected.length : 0;
166
+ const atlasTokens = pack.tokenUsage;
167
+ const tokenSavingsPct = totalRepoRawTokens > 0 ? Math.max(0, Math.round((totalRepoRawTokens - atlasTokens) / totalRepoRawTokens * 100)) : 0;
168
+ taskResults.push({
169
+ taskId: task.id,
170
+ query: task.query,
171
+ retrievedFiles: retrievedPaths,
172
+ expectedFiles: normalizedExpected,
173
+ precision: Math.round(precision * 100) / 100,
174
+ recall: Math.round(recall * 100) / 100,
175
+ rawTokens: totalRepoRawTokens,
176
+ atlasTokens,
177
+ tokenSavingsPct,
178
+ durationMs
179
+ });
180
+ }
181
+ db.close();
182
+ const overallPrecision = Math.round(
183
+ taskResults.reduce((acc, t) => acc + t.precision, 0) / taskResults.length * 100
184
+ ) / 100;
185
+ const overallRecall = Math.round(taskResults.reduce((acc, t) => acc + t.recall, 0) / taskResults.length * 100) / 100;
186
+ const overallTokenSavingsPct = Math.round(
187
+ taskResults.reduce((acc, t) => acc + t.tokenSavingsPct, 0) / taskResults.length
188
+ );
189
+ const averageLatencyMs = Math.round(
190
+ taskResults.reduce((acc, t) => acc + t.durationMs, 0) / taskResults.length
191
+ );
192
+ return {
193
+ datasetName: dataset.name,
194
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
195
+ taskResults,
196
+ overallPrecision,
197
+ overallRecall,
198
+ overallTokenSavingsPct,
199
+ averageLatencyMs
200
+ };
201
+ }
202
+ ensureRepository(dataset) {
203
+ const reposDir = path.join(this.baseDir, "repos");
204
+ fs.mkdirSync(reposDir, { recursive: true });
205
+ const safeRepoName = dataset.name.replace(/[^a-zA-Z0-9_-]/g, "_");
206
+ const targetDir = path.join(reposDir, safeRepoName);
207
+ if (!fs.existsSync(path.join(targetDir, ".git"))) {
208
+ console.log(`\u{1F4E6} Cloning benchmark target [${dataset.name}] into ${targetDir}...`);
209
+ try {
210
+ execSync(
211
+ `git clone --depth 1 --branch ${dataset.branch} ${dataset.repositoryUrl} "${targetDir}"`,
212
+ {
213
+ stdio: "inherit"
214
+ }
215
+ );
216
+ } catch {
217
+ execSync(`git clone --depth 1 ${dataset.repositoryUrl} "${targetDir}"`, {
218
+ stdio: "inherit"
219
+ });
220
+ }
221
+ }
222
+ return targetDir;
223
+ }
224
+ };
225
+
226
+ // src/index.ts
227
+ async function main() {
228
+ console.log(chalk.bold.cyan("\n\u{1F3C6} CodeAtlas Intelligence Benchmark Suite"));
229
+ console.log(chalk.dim("Empirical evaluation of AST Retrieval, Token Savings, and Precision\n"));
230
+ const runner = new BenchmarkRunner();
231
+ const reports = [];
232
+ for (const dataset of ALL_DATASETS) {
233
+ const report = await runner.run(dataset);
234
+ reports.push(report);
235
+ console.log(chalk.bold.green(`
236
+ \u{1F4CA} Benchmark Results for: ${report.datasetName}`));
237
+ console.log("\u2500".repeat(78));
238
+ console.log(
239
+ chalk.bold(
240
+ `${"Task ID".padEnd(28)} ${"Recall".padStart(8)} ${"Precision".padStart(10)} ${"Atlas Tokens".padStart(14)} ${"Savings".padStart(8)} ${"Latency".padStart(8)}`
241
+ )
242
+ );
243
+ console.log("\u2500".repeat(78));
244
+ for (const task of report.taskResults) {
245
+ const recallStr = `${Math.round(task.recall * 100)}%`;
246
+ const precStr = `${Math.round(task.precision * 100)}%`;
247
+ const tokensStr = `${task.atlasTokens.toLocaleString()} tkn`;
248
+ const savingsStr = `${task.tokenSavingsPct}%`;
249
+ const latencyStr = `${task.durationMs}ms`;
250
+ console.log(
251
+ `${chalk.cyan(task.taskId.padEnd(28))} ${chalk.green(recallStr.padStart(8))} ${chalk.yellow(precStr.padStart(10))} ${chalk.magenta(tokensStr.padStart(14))} ${chalk.bold.green(savingsStr.padStart(8))} ${chalk.dim(latencyStr.padStart(8))}`
252
+ );
253
+ }
254
+ console.log("\u2500".repeat(78));
255
+ console.log(
256
+ chalk.bold(
257
+ `${"Overall Averages".padEnd(28)} ${chalk.green((Math.round(report.overallRecall * 100) + "%").padStart(8))} ${chalk.yellow((Math.round(report.overallPrecision * 100) + "%").padStart(10))} ${"\u2500".padStart(14)} ${chalk.bold.green((report.overallTokenSavingsPct + "%").padStart(8))} ${chalk.dim((report.averageLatencyMs + "ms").padStart(8))}`
258
+ )
259
+ );
260
+ console.log("\u2500".repeat(78));
261
+ }
262
+ const resultsDir = path2.resolve(process.cwd(), ".benchmarks", "results");
263
+ fs2.mkdirSync(resultsDir, { recursive: true });
264
+ fs2.writeFileSync(path2.join(resultsDir, "report.json"), JSON.stringify(reports, null, 2), "utf-8");
265
+ let md = "# \u{1F4CA} CodeAtlas Empirical Benchmark Results\n\n";
266
+ md += "> Verified automated evaluation measuring context precision, recall, and token reduction.\n\n";
267
+ for (const report of reports) {
268
+ md += `## \u{1F4E6} Dataset: \`${report.datasetName}\`
269
+
270
+ `;
271
+ md += `| Task | Recall | Precision | Context Tokens | Token Savings | Latency |
272
+ `;
273
+ md += `| :--- | :--- | :--- | :--- | :--- | :--- |
274
+ `;
275
+ for (const task of report.taskResults) {
276
+ md += `| \`${task.taskId}\` | **${Math.round(task.recall * 100)}%** | ${Math.round(task.precision * 100)}% | ${task.atlasTokens.toLocaleString()} | **${task.tokenSavingsPct}%** | ${task.durationMs}ms |
277
+ `;
278
+ }
279
+ md += `| **Overall Average** | **${Math.round(report.overallRecall * 100)}%** | **${Math.round(report.overallPrecision * 100)}%** | \u2014 | **${report.overallTokenSavingsPct}%** | **${report.averageLatencyMs}ms** |
280
+
281
+ `;
282
+ }
283
+ fs2.writeFileSync(path2.join(resultsDir, "LEADERBOARD.md"), md, "utf-8");
284
+ console.log(
285
+ chalk.bold.green(
286
+ `
287
+ \u2705 Benchmark complete! Leaderboard written to .benchmarks/results/LEADERBOARD.md
288
+ `
289
+ )
290
+ );
291
+ }
292
+ main().catch((err) => {
293
+ console.error(chalk.red("Benchmark failed:"), err);
294
+ process.exit(1);
295
+ });
296
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/datasets.ts","../src/runner.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport chalk from 'chalk';\nimport { ALL_DATASETS } from './datasets.js';\nimport { BenchmarkRunner } from './runner.js';\nimport type { BenchmarkReport } from './types.js';\n\nasync function main() {\n console.log(chalk.bold.cyan('\\n๐Ÿ† CodeAtlas Intelligence Benchmark Suite'));\n console.log(chalk.dim('Empirical evaluation of AST Retrieval, Token Savings, and Precision\\n'));\n\n const runner = new BenchmarkRunner();\n const reports: BenchmarkReport[] = [];\n\n for (const dataset of ALL_DATASETS) {\n const report = await runner.run(dataset);\n reports.push(report);\n\n console.log(chalk.bold.green(`\\n๐Ÿ“Š Benchmark Results for: ${report.datasetName}`));\n console.log('โ”€'.repeat(78));\n console.log(\n chalk.bold(\n `${'Task ID'.padEnd(28)} ${'Recall'.padStart(8)} ${'Precision'.padStart(10)} ${'Atlas Tokens'.padStart(14)} ${'Savings'.padStart(8)} ${'Latency'.padStart(8)}`,\n ),\n );\n console.log('โ”€'.repeat(78));\n\n for (const task of report.taskResults) {\n const recallStr = `${Math.round(task.recall * 100)}%`;\n const precStr = `${Math.round(task.precision * 100)}%`;\n const tokensStr = `${task.atlasTokens.toLocaleString()} tkn`;\n const savingsStr = `${task.tokenSavingsPct}%`;\n const latencyStr = `${task.durationMs}ms`;\n\n console.log(\n `${chalk.cyan(task.taskId.padEnd(28))} ${chalk.green(recallStr.padStart(8))} ${chalk.yellow(precStr.padStart(10))} ${chalk.magenta(tokensStr.padStart(14))} ${chalk.bold.green(savingsStr.padStart(8))} ${chalk.dim(latencyStr.padStart(8))}`,\n );\n }\n\n console.log('โ”€'.repeat(78));\n console.log(\n chalk.bold(\n `${'Overall Averages'.padEnd(28)} ${chalk.green((Math.round(report.overallRecall * 100) + '%').padStart(8))} ${chalk.yellow((Math.round(report.overallPrecision * 100) + '%').padStart(10))} ${'โ”€'.padStart(14)} ${chalk.bold.green((report.overallTokenSavingsPct + '%').padStart(8))} ${chalk.dim((report.averageLatencyMs + 'ms').padStart(8))}`,\n ),\n );\n console.log('โ”€'.repeat(78));\n }\n\n // Save report to disk\n const resultsDir = path.resolve(process.cwd(), '.benchmarks', 'results');\n fs.mkdirSync(resultsDir, { recursive: true });\n\n fs.writeFileSync(path.join(resultsDir, 'report.json'), JSON.stringify(reports, null, 2), 'utf-8');\n\n // Generate Markdown Leaderboard\n let md = '# ๐Ÿ“Š CodeAtlas Empirical Benchmark Results\\n\\n';\n md +=\n '> Verified automated evaluation measuring context precision, recall, and token reduction.\\n\\n';\n\n for (const report of reports) {\n md += `## ๐Ÿ“ฆ Dataset: \\`${report.datasetName}\\`\\n\\n`;\n md += `| Task | Recall | Precision | Context Tokens | Token Savings | Latency |\\n`;\n md += `| :--- | :--- | :--- | :--- | :--- | :--- |\\n`;\n\n for (const task of report.taskResults) {\n md += `| \\`${task.taskId}\\` | **${Math.round(task.recall * 100)}%** | ${Math.round(task.precision * 100)}% | ${task.atlasTokens.toLocaleString()} | **${task.tokenSavingsPct}%** | ${task.durationMs}ms |\\n`;\n }\n\n md += `| **Overall Average** | **${Math.round(report.overallRecall * 100)}%** | **${Math.round(report.overallPrecision * 100)}%** | โ€” | **${report.overallTokenSavingsPct}%** | **${report.averageLatencyMs}ms** |\\n\\n`;\n }\n\n fs.writeFileSync(path.join(resultsDir, 'LEADERBOARD.md'), md, 'utf-8');\n\n console.log(\n chalk.bold.green(\n `\\nโœ… Benchmark complete! Leaderboard written to .benchmarks/results/LEADERBOARD.md\\n`,\n ),\n );\n}\n\nmain().catch((err) => {\n console.error(chalk.red('Benchmark failed:'), err);\n process.exit(1);\n});\n","import type { BenchmarkDataset } from './types.js';\n\nexport const EXPRESS_BENCHMARK_DATASET: BenchmarkDataset = {\n name: 'expressjs/express',\n repositoryUrl: 'https://github.com/expressjs/express.git',\n branch: 'master',\n tasks: [\n {\n id: 'express-routing-matching',\n query:\n 'Find how routes and middleware are registered and dispatched on the express application',\n description: 'Locate core application routing and middleware initialization',\n expectedFiles: ['lib/application.js', 'lib/express.js'],\n },\n {\n id: 'express-app-listen',\n query: 'Where is app.listen defined and how does it start the HTTP server',\n description: 'Locate application initialization and HTTP server bootstrap',\n expectedFiles: ['lib/application.js', 'lib/express.js'],\n },\n {\n id: 'express-response-json',\n query: 'Locate the logic that formats and serializes response data to JSON with res.json',\n description: 'Trace res.json and res.send response prototype helpers',\n expectedFiles: ['lib/response.js'],\n },\n {\n id: 'express-request-cookies',\n query: 'Where are request cookies and headers parsed in the request prototype',\n description: 'Locate req.cookies and header parsing helpers in request prototype',\n expectedFiles: ['lib/request.js'],\n },\n {\n id: 'express-view-render',\n query: 'Find template rendering and view engine resolution with app.render and res.render',\n description: 'Trace view engine lookup and rendering pipeline',\n expectedFiles: ['lib/view.js', 'lib/application.js', 'lib/response.js'],\n },\n ],\n};\n\nexport const ALL_DATASETS: BenchmarkDataset[] = [EXPRESS_BENCHMARK_DATASET];\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { execSync } from 'node:child_process';\nimport type { BenchmarkDataset, BenchmarkReport, TaskResult } from './types.js';\nimport {\n AtlasDatabase,\n runMigrations,\n FileRepository,\n SearchRepository,\n DependencyRepository,\n} from '@codeatlas-ai/storage';\nimport { Indexer } from '@codeatlas-ai/indexer';\nimport { DependencyGraph } from '@codeatlas-ai/graph';\nimport { RetrievalEngine } from '@codeatlas-ai/retrieval';\nimport { Ranker } from '@codeatlas-ai/ranking';\nimport { ContextEngine } from '@codeatlas-ai/context';\nimport { RuleEngine } from '@codeatlas-ai/rules';\nimport { TokenCounter } from '@codeatlas-ai/token-counter';\nimport type { FileInfo, ProjectMeta } from '@codeatlas-ai/core';\n\nexport class BenchmarkRunner {\n private baseDir: string;\n private tokenCounter: TokenCounter;\n\n constructor(baseDir: string = path.resolve(process.cwd(), '.benchmarks')) {\n this.baseDir = baseDir;\n this.tokenCounter = new TokenCounter();\n }\n\n public async run(dataset: BenchmarkDataset): Promise<BenchmarkReport> {\n const repoDir = this.ensureRepository(dataset);\n const dbPath = path.join(repoDir, '.atlas', 'atlas.db');\n\n if (fs.existsSync(path.dirname(dbPath))) {\n fs.rmSync(path.dirname(dbPath), { recursive: true, force: true });\n }\n fs.mkdirSync(path.dirname(dbPath), { recursive: true });\n\n const db = new AtlasDatabase(dbPath);\n runMigrations(db);\n\n const projectRow = db.get<{ id: number }>('SELECT id FROM projects WHERE root = ?', repoDir);\n let projectId = projectRow?.id;\n if (!projectId) {\n const res = db.run('INSERT INTO projects (name, root) VALUES (?, ?)', dataset.name, repoDir);\n projectId = Number(res.lastInsertRowid);\n }\n\n console.log(`\\nโณ Indexing dataset repository: ${dataset.name}...`);\n const indexer = new Indexer({\n root: repoDir,\n db,\n projectId: projectId as number,\n includeTests: false,\n });\n await indexer.index();\n\n const fileRepo = new FileRepository(db);\n const allFiles = fileRepo.getAll(projectId as number);\n const filesByPath = new Map<string, FileInfo>(allFiles.map((f) => [f.relativePath, f]));\n\n // Calculate total raw tokens across the entire codebase\n let totalRepoRawTokens = 0;\n for (const file of allFiles) {\n const fullPath = path.join(repoDir, file.relativePath);\n if (fs.existsSync(fullPath)) {\n try {\n const content = fs.readFileSync(fullPath, 'utf-8');\n totalRepoRawTokens += this.tokenCounter.count(content);\n } catch {\n // ignore binary / unreadable\n }\n }\n }\n\n const depRepo = new DependencyRepository(db);\n const deps = depRepo.getAll(projectId as number);\n const graph = new DependencyGraph();\n graph.addEdges(deps);\n\n const searchRepo = new SearchRepository(db);\n const retrieval = new RetrievalEngine(searchRepo, graph, filesByPath);\n const ruleEngine = new RuleEngine(repoDir);\n const rules = ruleEngine.discover();\n\n const projectMeta: ProjectMeta = {\n name: dataset.name,\n root: repoDir.replace(/\\\\/g, '/'),\n languages: ['javascript'],\n frameworks: [],\n packageManager: 'npm',\n fileCount: allFiles.length,\n symbolCount: 0,\n dependencyCount: deps.length,\n isMonorepo: false,\n workspaces: [],\n };\n\n const taskResults: TaskResult[] = [];\n\n console.log(`๐Ÿงช Running ${dataset.tasks.length} benchmark task queries...`);\n\n for (const task of dataset.tasks) {\n const start = performance.now();\n\n // 1. Retrieve candidates\n const retrievalResult = retrieval.retrieve(task.query, 15);\n\n // 2. Rank candidates\n const ranker = new Ranker({\n weights: {\n lexical_weight: 0.35,\n symbol_weight: 0.20,\n path_weight: 0.15,\n dependency_weight: 0.10,\n module_weight: 0.10,\n rule_weight: 0.05,\n recency_weight: 0.05,\n },\n queryTerms: retrievalResult.queryTerms,\n });\n const ranked = ranker.rank(retrievalResult.candidates);\n\n // 3. Build Context Pack\n const contextEngine = new ContextEngine({\n tokenBudget: 8000,\n defaultMode: 'signature',\n repositoryRoot: repoDir,\n });\n const pack = contextEngine.build({\n task: task.query,\n project: projectMeta,\n rankedResults: ranked,\n rules,\n });\n\n const durationMs = Math.round(performance.now() - start);\n\n const retrievedPaths = pack.files.map((f) => f.relativePath.replace(/\\\\/g, '/'));\n const normalizedExpected = task.expectedFiles.map((f) => f.replace(/\\\\/g, '/'));\n\n // Calculate precision and recall\n const hits = normalizedExpected.filter((exp) =>\n retrievedPaths.some((ret) => ret === exp || ret.endsWith(exp)),\n );\n\n const precision = retrievedPaths.length > 0 ? hits.length / retrievedPaths.length : 0;\n const recall = normalizedExpected.length > 0 ? hits.length / normalizedExpected.length : 0;\n\n const atlasTokens = pack.tokenUsage;\n const tokenSavingsPct =\n totalRepoRawTokens > 0\n ? Math.max(0, Math.round(((totalRepoRawTokens - atlasTokens) / totalRepoRawTokens) * 100))\n : 0;\n\n taskResults.push({\n taskId: task.id,\n query: task.query,\n retrievedFiles: retrievedPaths,\n expectedFiles: normalizedExpected,\n precision: Math.round(precision * 100) / 100,\n recall: Math.round(recall * 100) / 100,\n rawTokens: totalRepoRawTokens,\n atlasTokens,\n tokenSavingsPct,\n durationMs,\n });\n }\n\n db.close();\n\n const overallPrecision =\n Math.round(\n (taskResults.reduce((acc, t) => acc + t.precision, 0) / taskResults.length) * 100,\n ) / 100;\n const overallRecall =\n Math.round((taskResults.reduce((acc, t) => acc + t.recall, 0) / taskResults.length) * 100) /\n 100;\n const overallTokenSavingsPct = Math.round(\n taskResults.reduce((acc, t) => acc + t.tokenSavingsPct, 0) / taskResults.length,\n );\n const averageLatencyMs = Math.round(\n taskResults.reduce((acc, t) => acc + t.durationMs, 0) / taskResults.length,\n );\n\n return {\n datasetName: dataset.name,\n timestamp: new Date().toISOString(),\n taskResults,\n overallPrecision,\n overallRecall,\n overallTokenSavingsPct,\n averageLatencyMs,\n };\n }\n\n private ensureRepository(dataset: BenchmarkDataset): string {\n const reposDir = path.join(this.baseDir, 'repos');\n fs.mkdirSync(reposDir, { recursive: true });\n\n const safeRepoName = dataset.name.replace(/[^a-zA-Z0-9_-]/g, '_');\n const targetDir = path.join(reposDir, safeRepoName);\n\n if (!fs.existsSync(path.join(targetDir, '.git'))) {\n console.log(`๐Ÿ“ฆ Cloning benchmark target [${dataset.name}] into ${targetDir}...`);\n try {\n execSync(\n `git clone --depth 1 --branch ${dataset.branch} ${dataset.repositoryUrl} \"${targetDir}\"`,\n {\n stdio: 'inherit',\n },\n );\n } catch {\n // Fallback without branch if shallow branch fails\n execSync(`git clone --depth 1 ${dataset.repositoryUrl} \"${targetDir}\"`, {\n stdio: 'inherit',\n });\n }\n }\n\n return targetDir;\n }\n}\n"],"mappings":"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","names":["fs","path","path","fs"]}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@codeatlas-ai/benchmark",
3
+ "version": "0.4.0",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "import": "./dist/index.js",
8
+ "types": "./dist/index.d.ts"
9
+ }
10
+ },
11
+ "main": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "dependencies": {
17
+ "chalk": "^5.3.0",
18
+ "@codeatlas-ai/core": "0.4.0",
19
+ "@codeatlas-ai/shared": "0.4.0",
20
+ "@codeatlas-ai/storage": "0.4.0",
21
+ "@codeatlas-ai/indexer": "0.4.0",
22
+ "@codeatlas-ai/graph": "0.4.0",
23
+ "@codeatlas-ai/retrieval": "0.4.0",
24
+ "@codeatlas-ai/ranking": "0.4.0",
25
+ "@codeatlas-ai/context": "0.4.0",
26
+ "@codeatlas-ai/rules": "0.4.0",
27
+ "@codeatlas-ai/token-counter": "0.4.0"
28
+ },
29
+ "license": "MIT",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/shditz/codeatlas.git",
33
+ "directory": "packages/benchmark"
34
+ },
35
+ "scripts": {
36
+ "build": "tsup",
37
+ "start": "node dist/index.js",
38
+ "dev": "tsup --watch",
39
+ "typecheck": "tsc --noEmit",
40
+ "clean": "rimraf dist"
41
+ }
42
+ }