@workbench-ai/workbench 0.0.63 → 0.0.65
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/benchmark-fingerprint.js +2 -2
- package/dist/command-model.d.ts +1 -1
- package/dist/command-model.d.ts.map +1 -1
- package/dist/command-model.js +106 -35
- package/dist/dev-open/client.js +109 -109
- package/dist/dev-open-server.d.ts +2 -37
- package/dist/dev-open-server.d.ts.map +1 -1
- package/dist/dev-open-server.js +39 -322
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +333 -193
- package/dist/local-archive.d.ts +4 -4
- package/dist/local-archive.d.ts.map +1 -1
- package/dist/local-archive.js +3 -7
- package/dist/local-inspection.d.ts +9 -0
- package/dist/local-inspection.d.ts.map +1 -0
- package/dist/local-inspection.js +317 -0
- package/dist/project-source.d.ts +6 -6
- package/dist/project-source.js +6 -6
- package/package.json +4 -4
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { type LocalProjectSource } from "./project-source.js";
|
|
1
|
+
import type { WorkbenchInspection } from "@workbench-ai/workbench-core";
|
|
3
2
|
export interface LocalWorkbenchDevServer {
|
|
4
3
|
url: string;
|
|
5
4
|
close: () => Promise<void>;
|
|
@@ -13,41 +12,7 @@ export interface LocalWorkbenchDevServerOptions {
|
|
|
13
12
|
export interface LocalWorkbenchRequestContext {
|
|
14
13
|
workspace: string;
|
|
15
14
|
assetsRoot: string;
|
|
16
|
-
|
|
15
|
+
inspection: WorkbenchInspection;
|
|
17
16
|
}
|
|
18
17
|
export declare function startLocalWorkbenchDevServer(options: LocalWorkbenchDevServerOptions): Promise<LocalWorkbenchDevServer>;
|
|
19
|
-
export declare function localBenchmarkSnapshot(context: LocalWorkbenchRequestContext): Promise<{
|
|
20
|
-
workspaceRoot: string;
|
|
21
|
-
activeId: string | null;
|
|
22
|
-
currentBenchmarkFingerprint: string | null;
|
|
23
|
-
summaries: import("@workbench-ai/workbench-contract").CandidateSummary[];
|
|
24
|
-
evaluations: {
|
|
25
|
-
id: string;
|
|
26
|
-
runId: string;
|
|
27
|
-
benchmarkFingerprint: string;
|
|
28
|
-
candidateFingerprint: string;
|
|
29
|
-
candidateId: string;
|
|
30
|
-
candidateName?: string;
|
|
31
|
-
candidateVersion: number;
|
|
32
|
-
candidateRunId?: string;
|
|
33
|
-
candidateRunName?: string;
|
|
34
|
-
createdAt: string;
|
|
35
|
-
updatedAt: string;
|
|
36
|
-
status: import("@workbench-ai/workbench-contract").EvaluationStatus;
|
|
37
|
-
sampleCount: number;
|
|
38
|
-
completedSampleCount: number;
|
|
39
|
-
errorSampleCount: number;
|
|
40
|
-
metrics?: Record<string, import("@workbench-ai/workbench-contract").MetricStats>;
|
|
41
|
-
selectionMetric?: string;
|
|
42
|
-
selectionLabel?: string;
|
|
43
|
-
selectionScore?: import("@workbench-ai/workbench-contract").MetricStats;
|
|
44
|
-
durationMs?: import("@workbench-ai/workbench-contract").MetricStats;
|
|
45
|
-
usage?: import("@workbench-ai/workbench-contract").EvaluationUsageStats;
|
|
46
|
-
error?: string;
|
|
47
|
-
}[];
|
|
48
|
-
runs: RunSummary[];
|
|
49
|
-
}>;
|
|
50
|
-
export declare function localSpecDocument(context: LocalWorkbenchRequestContext, benchmarkFingerprint?: string | null): Promise<import("@workbench-ai/workbench-contract").AuthoredWorkbenchSourceDocument>;
|
|
51
|
-
export declare function localSourceFiles(workspace: string): Promise<SurfaceSnapshotFile[]>;
|
|
52
|
-
export declare function localBenchmarkMountedFiles(context: LocalWorkbenchRequestContext, benchmarkFingerprint?: string | null): Promise<SurfaceSnapshotFile[]>;
|
|
53
18
|
//# sourceMappingURL=dev-open-server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-open-server.d.ts","sourceRoot":"","sources":["../src/dev-open-server.ts"],"names":[],"mappings":"AAKA,OAAO,
|
|
1
|
+
{"version":3,"file":"dev-open-server.d.ts","sourceRoot":"","sources":["../src/dev-open-server.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAOxE,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,8BAA8B;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAWD,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,mBAAmB,CAAC;CACjC;AAID,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,uBAAuB,CAAC,CA4ClC"}
|
package/dist/dev-open-server.js
CHANGED
|
@@ -2,10 +2,7 @@ import { promises as fs } from "node:fs";
|
|
|
2
2
|
import http from "node:http";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import {
|
|
6
|
-
import { readLocalExecutionFiles, loadLocalArchiveIndex, readLocalEvaluationRecord, readLocalJobInRun, readLocalRunJobs, readLocalCandidateFilesForId, readLocalCandidateRecord, } from "./local-archive.js";
|
|
7
|
-
import { readLocalAuthoredProjectSource, readLocalProjectSource, WORKBENCH_BENCHMARK_FILE, } from "./project-source.js";
|
|
8
|
-
import { localBenchmarkFingerprint } from "./benchmark-fingerprint.js";
|
|
5
|
+
import { createLocalProjectSourceReader, createLocalWorkbenchInspection, } from "./local-inspection.js";
|
|
9
6
|
class LocalApiError extends Error {
|
|
10
7
|
status;
|
|
11
8
|
constructor(message, status = 400) {
|
|
@@ -14,15 +11,18 @@ class LocalApiError extends Error {
|
|
|
14
11
|
}
|
|
15
12
|
}
|
|
16
13
|
const DEV_OPEN_ASSET_DIR = "dev-open";
|
|
17
|
-
const PROJECT_SOURCE_CACHE_TTL_MS = 1000;
|
|
18
14
|
export async function startLocalWorkbenchDevServer(options) {
|
|
19
15
|
const workspace = path.resolve(options.workspace);
|
|
20
16
|
const assetsRoot = options.assetsRoot ?? defaultDevOpenAssetsRoot();
|
|
21
17
|
await assertDevOpenAssets(assetsRoot);
|
|
18
|
+
const readProjectSource = createLocalProjectSourceReader(workspace);
|
|
22
19
|
const context = {
|
|
23
20
|
workspace,
|
|
24
21
|
assetsRoot,
|
|
25
|
-
|
|
22
|
+
inspection: createLocalWorkbenchInspection({
|
|
23
|
+
workspace,
|
|
24
|
+
readProjectSource,
|
|
25
|
+
}),
|
|
26
26
|
};
|
|
27
27
|
const server = http.createServer((request, response) => {
|
|
28
28
|
void handleLocalWorkbenchRequest({
|
|
@@ -64,23 +64,6 @@ async function assertDevOpenAssets(assetsRoot) {
|
|
|
64
64
|
throw new Error(`Workbench local browser assets are missing from ${assetsRoot}. Run pnpm --dir products/workbench/packages/cli build.`);
|
|
65
65
|
});
|
|
66
66
|
}
|
|
67
|
-
function createProjectSourceReader(workspace) {
|
|
68
|
-
let cached = null;
|
|
69
|
-
return () => {
|
|
70
|
-
const now = Date.now();
|
|
71
|
-
if (cached && now - cached.loadedAt < PROJECT_SOURCE_CACHE_TTL_MS) {
|
|
72
|
-
return cached.promise;
|
|
73
|
-
}
|
|
74
|
-
const promise = readLocalProjectSource(workspace);
|
|
75
|
-
cached = { loadedAt: now, promise };
|
|
76
|
-
promise.catch(() => {
|
|
77
|
-
if (cached?.promise === promise) {
|
|
78
|
-
cached = null;
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
return promise;
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
67
|
async function closeServer(server) {
|
|
85
68
|
await new Promise((resolve, reject) => {
|
|
86
69
|
server.close((error) => error ? reject(error) : resolve());
|
|
@@ -138,40 +121,43 @@ function decodeDocumentPathSegment(segment) {
|
|
|
138
121
|
}
|
|
139
122
|
}
|
|
140
123
|
async function handleApiRequest(request, response, context, url) {
|
|
141
|
-
const {
|
|
124
|
+
const { inspection } = context;
|
|
142
125
|
switch (url.pathname) {
|
|
143
126
|
case "/api/snapshot":
|
|
144
|
-
sendJson(response, await
|
|
127
|
+
sendJson(response, await inspection.snapshot(), 200, request.method);
|
|
145
128
|
return;
|
|
146
129
|
case "/api/spec":
|
|
147
|
-
sendJson(response, await
|
|
130
|
+
sendJson(response, await inspection.spec({
|
|
131
|
+
fingerprint: readOptionalSearchString(url.searchParams, "fingerprint"),
|
|
132
|
+
}), 200, request.method);
|
|
148
133
|
return;
|
|
149
134
|
case "/api/source/files":
|
|
150
|
-
sendJson(response,
|
|
135
|
+
sendJson(response, await inspection.sourceFiles({
|
|
136
|
+
fingerprint: readOptionalSearchString(url.searchParams, "fingerprint"),
|
|
137
|
+
}), 200, request.method);
|
|
151
138
|
return;
|
|
152
139
|
case "/api/source/preview":
|
|
153
|
-
sendJson(response,
|
|
154
|
-
|
|
140
|
+
sendJson(response, await inspection.sourcePreview({
|
|
141
|
+
fingerprint: readOptionalSearchString(url.searchParams, "fingerprint"),
|
|
155
142
|
path: readSearchString(url.searchParams, "path"),
|
|
156
143
|
view: readPreviewMode(url.searchParams),
|
|
157
144
|
}), 200, request.method);
|
|
158
145
|
return;
|
|
159
146
|
case "/api/record":
|
|
160
|
-
sendJson(response, await
|
|
147
|
+
sendJson(response, await inspection.candidate({ id: readSearchString(url.searchParams, "id") }), 200, request.method);
|
|
161
148
|
return;
|
|
162
149
|
case "/api/evaluation":
|
|
163
|
-
sendJson(response, await
|
|
150
|
+
sendJson(response, await inspection.evaluation({ id: readSearchString(url.searchParams, "id") }), 200, request.method);
|
|
164
151
|
return;
|
|
165
152
|
case "/api/candidate/files": {
|
|
166
153
|
const candidateId = readSearchString(url.searchParams, "id");
|
|
167
|
-
|
|
168
|
-
sendJson(response, summarizeCandidateFiles(await readCandidateFilesForApi(workspace, candidateId), candidate.fileChanges), 200, request.method);
|
|
154
|
+
sendJson(response, await inspection.candidateFiles({ id: candidateId }), 200, request.method);
|
|
169
155
|
return;
|
|
170
156
|
}
|
|
171
157
|
case "/api/candidate/preview": {
|
|
172
158
|
const candidateId = readSearchString(url.searchParams, "id");
|
|
173
|
-
sendJson(response,
|
|
174
|
-
|
|
159
|
+
sendJson(response, await inspection.candidatePreview({
|
|
160
|
+
id: candidateId,
|
|
175
161
|
path: readSearchString(url.searchParams, "path"),
|
|
176
162
|
view: readPreviewMode(url.searchParams),
|
|
177
163
|
}), 200, request.method);
|
|
@@ -181,44 +167,38 @@ async function handleApiRequest(request, response, context, url) {
|
|
|
181
167
|
const candidateId = readSearchString(url.searchParams, "id");
|
|
182
168
|
const caseId = readSearchString(url.searchParams, "case");
|
|
183
169
|
const runId = readSearchString(url.searchParams, "run");
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
candidate: await readCandidateForApi(workspace, candidateId),
|
|
170
|
+
sendJson(response, await inspection.caseReview({
|
|
171
|
+
candidateId,
|
|
187
172
|
caseId,
|
|
188
|
-
|
|
173
|
+
runId,
|
|
189
174
|
}), 200, request.method);
|
|
190
175
|
return;
|
|
191
176
|
}
|
|
192
177
|
case "/api/traces": {
|
|
193
178
|
const traceRunId = readSearchString(url.searchParams, "run");
|
|
194
179
|
const traceJobId = readSearchString(url.searchParams, "job");
|
|
195
|
-
|
|
196
|
-
sendJson(response, {
|
|
197
|
-
projectId: "local",
|
|
180
|
+
sendJson(response, await inspection.executionTrace({
|
|
198
181
|
runId: traceRunId,
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
traceIdPrefix: "local-execution",
|
|
202
|
-
traceForJob: readLocalAggregateTrace,
|
|
203
|
-
traceSessionsForJob: readLocalTraceSessions,
|
|
204
|
-
}),
|
|
205
|
-
}, 200, request.method);
|
|
182
|
+
jobId: traceJobId,
|
|
183
|
+
}), 200, request.method);
|
|
206
184
|
return;
|
|
207
185
|
}
|
|
208
186
|
case "/api/execution/files": {
|
|
209
187
|
const execRunId = readSearchString(url.searchParams, "run");
|
|
210
188
|
const execJobId = readSearchString(url.searchParams, "id");
|
|
211
|
-
|
|
212
|
-
|
|
189
|
+
sendJson(response, await inspection.executionFiles({
|
|
190
|
+
runId: execRunId,
|
|
191
|
+
jobId: execJobId,
|
|
192
|
+
}), 200, request.method);
|
|
213
193
|
return;
|
|
214
194
|
}
|
|
215
195
|
case "/api/execution/preview": {
|
|
216
196
|
const previewRunId = readSearchString(url.searchParams, "run");
|
|
217
197
|
const previewJobId = readSearchString(url.searchParams, "id");
|
|
218
198
|
const previewFilePath = readSearchString(url.searchParams, "path");
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
199
|
+
sendJson(response, await inspection.executionPreview({
|
|
200
|
+
runId: previewRunId,
|
|
201
|
+
jobId: previewJobId,
|
|
222
202
|
path: previewFilePath,
|
|
223
203
|
view: readPreviewMode(url.searchParams),
|
|
224
204
|
}), 200, request.method);
|
|
@@ -228,273 +208,6 @@ async function handleApiRequest(request, response, context, url) {
|
|
|
228
208
|
throw new LocalApiError(`Unknown Workbench local API route: ${url.pathname}`, 404);
|
|
229
209
|
}
|
|
230
210
|
}
|
|
231
|
-
export async function localBenchmarkSnapshot(context) {
|
|
232
|
-
const { workspace } = context;
|
|
233
|
-
const snapshot = await loadLocalArchiveIndex(workspace);
|
|
234
|
-
const candidates = snapshot.candidates.filter(isInspectableCandidateRecord);
|
|
235
|
-
const summaries = candidates.map(candidateSummary);
|
|
236
|
-
const activeId = snapshot.activeId && candidates.some((candidate) => candidate.id === snapshot.activeId)
|
|
237
|
-
? snapshot.activeId
|
|
238
|
-
: null;
|
|
239
|
-
const currentBenchmarkFingerprint = await readCurrentBenchmarkFingerprint(context);
|
|
240
|
-
return {
|
|
241
|
-
workspaceRoot: path.resolve(workspace),
|
|
242
|
-
activeId,
|
|
243
|
-
currentBenchmarkFingerprint,
|
|
244
|
-
summaries,
|
|
245
|
-
evaluations: snapshot.evaluations.map(evaluationSummary),
|
|
246
|
-
runs: snapshot.runs.map(publicLocalRunSummary),
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
function publicLocalRunSummary(run) {
|
|
250
|
-
const { executionFingerprint: _executionFingerprint, ...summary } = run;
|
|
251
|
-
return summary;
|
|
252
|
-
}
|
|
253
|
-
async function readCurrentBenchmarkFingerprint(context) {
|
|
254
|
-
return await context.readProjectSource()
|
|
255
|
-
.then(localBenchmarkFingerprint)
|
|
256
|
-
.catch(() => null);
|
|
257
|
-
}
|
|
258
|
-
export async function localSpecDocument(context, benchmarkFingerprint) {
|
|
259
|
-
const { workspace } = context;
|
|
260
|
-
const projectSource = await context.readProjectSource().catch(() => null);
|
|
261
|
-
const authoredSource = projectSource
|
|
262
|
-
? null
|
|
263
|
-
: await readLocalAuthoredProjectSource(workspace).catch(() => null);
|
|
264
|
-
const requestedFingerprint = normalizeOptionalFingerprint(benchmarkFingerprint);
|
|
265
|
-
const currentFingerprint = projectSource
|
|
266
|
-
? localBenchmarkFingerprint(projectSource)
|
|
267
|
-
: null;
|
|
268
|
-
if (requestedFingerprint &&
|
|
269
|
-
currentFingerprint &&
|
|
270
|
-
requestedFingerprint !== currentFingerprint) {
|
|
271
|
-
const snapshot = await loadLocalArchiveIndex(workspace);
|
|
272
|
-
const document = localHistoricalBenchmarkDocument(snapshot, requestedFingerprint);
|
|
273
|
-
if (document) {
|
|
274
|
-
return document;
|
|
275
|
-
}
|
|
276
|
-
throw new LocalApiError(`Benchmark version not found: ${requestedFingerprint}`, 404);
|
|
277
|
-
}
|
|
278
|
-
const sourceYaml = projectSource?.specSource ?? authoredSource?.specSource ?? "";
|
|
279
|
-
const cases = projectSource
|
|
280
|
-
? caseSummaryFilesFromEngineCases(projectSource.engineCases, projectSource.engineResolveFiles)
|
|
281
|
-
: [];
|
|
282
|
-
return loadAuthoredWorkbenchSourceDocument({
|
|
283
|
-
sourceYaml,
|
|
284
|
-
path: WORKBENCH_BENCHMARK_FILE,
|
|
285
|
-
sourceFiles: projectSource?.sourceFiles ?? authoredSource?.sourceFiles,
|
|
286
|
-
cases,
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
function caseSummaryFilesFromEngineCases(engineCases, files) {
|
|
290
|
-
const existingCaseIds = new Set(files.flatMap((file) => {
|
|
291
|
-
const normalized = file.path.replace(/\\/gu, "/").replace(/^\/+/u, "");
|
|
292
|
-
const slash = normalized.indexOf("/");
|
|
293
|
-
return slash > 0 ? [normalized.slice(0, slash)] : [];
|
|
294
|
-
}));
|
|
295
|
-
return [
|
|
296
|
-
...files.map((file) => ({ ...file })),
|
|
297
|
-
...engineCases
|
|
298
|
-
.filter((engineCase) => !existingCaseIds.has(engineCase.id))
|
|
299
|
-
.map((engineCase) => ({
|
|
300
|
-
path: `${engineCase.id}/.workbench-case.json`,
|
|
301
|
-
encoding: "utf8",
|
|
302
|
-
content: `${JSON.stringify({ id: engineCase.id })}\n`,
|
|
303
|
-
executable: false,
|
|
304
|
-
})),
|
|
305
|
-
];
|
|
306
|
-
}
|
|
307
|
-
export async function localSourceFiles(workspace) {
|
|
308
|
-
return (await readLocalProjectSource(workspace)).sourceFiles;
|
|
309
|
-
}
|
|
310
|
-
export async function localBenchmarkMountedFiles(context, benchmarkFingerprint) {
|
|
311
|
-
const requestedFingerprint = normalizeOptionalFingerprint(benchmarkFingerprint);
|
|
312
|
-
const { workspace } = context;
|
|
313
|
-
const projectSource = await context.readProjectSource();
|
|
314
|
-
const currentFingerprint = localBenchmarkFingerprint(projectSource);
|
|
315
|
-
if (requestedFingerprint &&
|
|
316
|
-
currentFingerprint &&
|
|
317
|
-
requestedFingerprint !== currentFingerprint) {
|
|
318
|
-
const snapshot = await loadLocalArchiveIndex(workspace);
|
|
319
|
-
return localHistoricalBenchmarkFiles(snapshot, requestedFingerprint);
|
|
320
|
-
}
|
|
321
|
-
return inspectableEngineCaseFiles(projectSource.engineCases);
|
|
322
|
-
}
|
|
323
|
-
function localHistoricalBenchmarkDocument(snapshot, benchmarkFingerprint) {
|
|
324
|
-
const candidate = snapshot.candidates.find((entry) => entry.benchmarkFingerprint === benchmarkFingerprint && readBenchmarkSourceMetadata(entry));
|
|
325
|
-
const source = candidate ? readBenchmarkSourceMetadata(candidate) : null;
|
|
326
|
-
if (!source?.sourceYaml) {
|
|
327
|
-
return null;
|
|
328
|
-
}
|
|
329
|
-
return loadAuthoredWorkbenchSourceDocument({
|
|
330
|
-
sourceYaml: source.sourceYaml,
|
|
331
|
-
path: WORKBENCH_BENCHMARK_FILE,
|
|
332
|
-
sourceFiles: source.files,
|
|
333
|
-
cases: localHistoricalBenchmarkFiles(snapshot, benchmarkFingerprint),
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
function localHistoricalBenchmarkFiles(_snapshot, _benchmarkFingerprint) {
|
|
337
|
-
return [];
|
|
338
|
-
}
|
|
339
|
-
function inspectableEngineCaseFiles(engineCases) {
|
|
340
|
-
return engineCases.flatMap((bundle) => engineCaseFiles(bundle).map((file) => ({
|
|
341
|
-
...file,
|
|
342
|
-
path: `${bundle.id}/${file.path}`,
|
|
343
|
-
}))).sort((left, right) => left.path.localeCompare(right.path));
|
|
344
|
-
}
|
|
345
|
-
function engineCaseFiles(bundle) {
|
|
346
|
-
const buckets = bundle.files;
|
|
347
|
-
return buckets.source?.length
|
|
348
|
-
? buckets.source
|
|
349
|
-
: [...(buckets.public ?? []), ...(buckets.private ?? [])];
|
|
350
|
-
}
|
|
351
|
-
function candidateSummary(candidate) {
|
|
352
|
-
return candidateSummaryFromRecord(candidate);
|
|
353
|
-
}
|
|
354
|
-
function isInspectableCandidateRecord(candidate) {
|
|
355
|
-
return Boolean(candidate.eval || asRecord(asRecord(candidate.meta)?.source));
|
|
356
|
-
}
|
|
357
|
-
function evaluationSummary(evaluation) {
|
|
358
|
-
const { evaluation: _evaluation, ...summary } = evaluation;
|
|
359
|
-
return summary;
|
|
360
|
-
}
|
|
361
|
-
async function readCandidateForApi(workspace, candidateId) {
|
|
362
|
-
const candidate = await readArchiveRecord("Candidate", candidateId, () => readLocalCandidateRecord(workspace, candidateId));
|
|
363
|
-
return candidateRecordWithoutDerivedFields(candidate);
|
|
364
|
-
}
|
|
365
|
-
async function readEvaluationForApi(workspace, evaluationId) {
|
|
366
|
-
return await readArchiveRecord("Evaluation", evaluationId, () => readLocalEvaluationRecord(workspace, evaluationId));
|
|
367
|
-
}
|
|
368
|
-
async function readCandidateFilesForApi(workspace, candidateId) {
|
|
369
|
-
return await readArchiveRecord("Candidate", candidateId, () => readLocalCandidateFilesForId(workspace, candidateId));
|
|
370
|
-
}
|
|
371
|
-
function readBenchmarkSourceMetadata(candidate) {
|
|
372
|
-
const benchmark = asRecord(asRecord(candidate.meta)?.benchmark);
|
|
373
|
-
const files = Array.isArray(benchmark?.files)
|
|
374
|
-
? benchmark.files
|
|
375
|
-
.map(readSurfaceSnapshotFile)
|
|
376
|
-
.filter((file) => file !== null)
|
|
377
|
-
: [];
|
|
378
|
-
const sourceYaml = files.find((file) => file.path === WORKBENCH_BENCHMARK_FILE)?.content ?? null;
|
|
379
|
-
if (!sourceYaml) {
|
|
380
|
-
return null;
|
|
381
|
-
}
|
|
382
|
-
return { sourceYaml, files };
|
|
383
|
-
}
|
|
384
|
-
function readSurfaceSnapshotFile(value) {
|
|
385
|
-
const record = asRecord(value);
|
|
386
|
-
if (!record) {
|
|
387
|
-
return null;
|
|
388
|
-
}
|
|
389
|
-
const filePath = typeof record?.path === "string" ? record.path : "";
|
|
390
|
-
const content = typeof record?.content === "string" ? record.content : null;
|
|
391
|
-
if (!filePath || content === null) {
|
|
392
|
-
return null;
|
|
393
|
-
}
|
|
394
|
-
return {
|
|
395
|
-
path: filePath,
|
|
396
|
-
kind: record.kind === "binary" ? "binary" : "text",
|
|
397
|
-
encoding: record.encoding === "base64" ? "base64" : "utf8",
|
|
398
|
-
content,
|
|
399
|
-
executable: record.executable === true,
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
function asRecord(value) {
|
|
403
|
-
return value && typeof value === "object" && !Array.isArray(value)
|
|
404
|
-
? value
|
|
405
|
-
: null;
|
|
406
|
-
}
|
|
407
|
-
function normalizeOptionalFingerprint(value) {
|
|
408
|
-
const normalized = value?.trim();
|
|
409
|
-
return normalized ? normalized : null;
|
|
410
|
-
}
|
|
411
|
-
async function readArchiveRecord(kind, id, read) {
|
|
412
|
-
try {
|
|
413
|
-
return await read();
|
|
414
|
-
}
|
|
415
|
-
catch (error) {
|
|
416
|
-
if (error instanceof Error && error.message === `${kind} not found: ${id}`) {
|
|
417
|
-
throw new LocalApiError(error.message, 404);
|
|
418
|
-
}
|
|
419
|
-
throw error;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
async function loadExecutionFiles(workspace, runId, jobId) {
|
|
423
|
-
const files = await readExecutionFilesForRun(workspace, runId, jobId);
|
|
424
|
-
return summarizeCandidateFiles(files);
|
|
425
|
-
}
|
|
426
|
-
async function readExecutionFilesForRun(workspace, runId, jobId) {
|
|
427
|
-
await assertExecutionJobInRun(workspace, runId, jobId);
|
|
428
|
-
return await readLocalExecutionFiles(workspace, jobId);
|
|
429
|
-
}
|
|
430
|
-
async function assertExecutionJobInRun(workspace, runId, jobId) {
|
|
431
|
-
await readExecutionJobForRun(workspace, runId, jobId);
|
|
432
|
-
}
|
|
433
|
-
async function readExecutionJobForRun(workspace, runId, jobId) {
|
|
434
|
-
const job = await readLocalJobInRun(workspace, runId, jobId);
|
|
435
|
-
if (!job) {
|
|
436
|
-
throw new LocalApiError(`Execution job not found: ${jobId}`, 404);
|
|
437
|
-
}
|
|
438
|
-
return job;
|
|
439
|
-
}
|
|
440
|
-
function readLocalAggregateTrace(job) {
|
|
441
|
-
const trace = job.trace;
|
|
442
|
-
if (!trace || typeof trace !== "object" || Array.isArray(trace)) {
|
|
443
|
-
return { trace_id: job.id, spans: [], events: [], summaries: [] };
|
|
444
|
-
}
|
|
445
|
-
const record = trace;
|
|
446
|
-
return {
|
|
447
|
-
trace_id: typeof record.trace_id === "string" ? record.trace_id : job.id,
|
|
448
|
-
spans: Array.isArray(record.spans) ? record.spans : [],
|
|
449
|
-
events: Array.isArray(record.events) ? record.events : [],
|
|
450
|
-
summaries: Array.isArray(record.summaries) ? record.summaries : [],
|
|
451
|
-
};
|
|
452
|
-
}
|
|
453
|
-
function readLocalTraceSessions(job, role) {
|
|
454
|
-
if (!Array.isArray(job.traceSessions)) {
|
|
455
|
-
return [];
|
|
456
|
-
}
|
|
457
|
-
return job.traceSessions.map((session) => ({
|
|
458
|
-
id: typeof session.id === "string" && session.id.length > 0
|
|
459
|
-
? session.id
|
|
460
|
-
: `${job.id}:trace`,
|
|
461
|
-
jobId: typeof session.jobId === "string" && session.jobId.length > 0
|
|
462
|
-
? session.jobId
|
|
463
|
-
: job.id,
|
|
464
|
-
role: session.role === "improver" || session.role === "runner" || session.role === "engine"
|
|
465
|
-
? session.role
|
|
466
|
-
: role,
|
|
467
|
-
kind: typeof session.kind === "string" && session.kind.length > 0 ? session.kind : "trace",
|
|
468
|
-
label: traceSessionDisplayLabel(session, role),
|
|
469
|
-
sourcePath: typeof session.sourcePath === "string" ? session.sourcePath : null,
|
|
470
|
-
trace: sanitizeLocalTrace(session.trace, session.id),
|
|
471
|
-
...(session.metadata && typeof session.metadata === "object" && !Array.isArray(session.metadata)
|
|
472
|
-
? { metadata: session.metadata }
|
|
473
|
-
: {}),
|
|
474
|
-
}));
|
|
475
|
-
}
|
|
476
|
-
function traceSessionDisplayLabel(session, fallbackRole) {
|
|
477
|
-
const role = session.role === "improver" || session.role === "runner" || session.role === "engine"
|
|
478
|
-
? session.role
|
|
479
|
-
: fallbackRole;
|
|
480
|
-
return typeof session.label === "string" && session.label.length > 0
|
|
481
|
-
? session.label
|
|
482
|
-
: typeof session.sourcePath === "string" && session.sourcePath.length > 0
|
|
483
|
-
? traceSessionLabel(session.sourcePath, role)
|
|
484
|
-
: "Trace";
|
|
485
|
-
}
|
|
486
|
-
function sanitizeLocalTrace(trace, fallbackId) {
|
|
487
|
-
if (!trace || typeof trace !== "object" || Array.isArray(trace)) {
|
|
488
|
-
return { trace_id: fallbackId, spans: [], events: [], summaries: [] };
|
|
489
|
-
}
|
|
490
|
-
const record = trace;
|
|
491
|
-
return {
|
|
492
|
-
trace_id: typeof record.trace_id === "string" ? record.trace_id : fallbackId,
|
|
493
|
-
spans: Array.isArray(record.spans) ? record.spans : [],
|
|
494
|
-
events: Array.isArray(record.events) ? record.events : [],
|
|
495
|
-
summaries: Array.isArray(record.summaries) ? record.summaries : [],
|
|
496
|
-
};
|
|
497
|
-
}
|
|
498
211
|
function readSearchString(params, key) {
|
|
499
212
|
const value = params.get(key);
|
|
500
213
|
if (!value) {
|
|
@@ -576,7 +289,11 @@ function sendJson(response, value, status = 200, method = "GET") {
|
|
|
576
289
|
}
|
|
577
290
|
function sendError(response, error, method = "GET") {
|
|
578
291
|
const message = error instanceof Error ? error.message : String(error);
|
|
579
|
-
const status = error instanceof LocalApiError
|
|
292
|
+
const status = error instanceof LocalApiError
|
|
293
|
+
? error.status
|
|
294
|
+
: typeof error?.statusCode === "number"
|
|
295
|
+
? error.statusCode
|
|
296
|
+
: 500;
|
|
580
297
|
sendJson(response, { message }, status, method);
|
|
581
298
|
}
|
|
582
299
|
function displayHost(host) {
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA8IA,UAAU,KAAK;IACb,KAAK,EAAE,MAAM,CAAC,cAAc,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;CAC/B;AA4BD,UAAU,iBAAiB;CAAG;AAkL9B,wBAAsB,MAAM,CAC1B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,EAAE,GAAE,KAIH,EACD,cAAc,GAAE,iBAAsB,GACrC,OAAO,CAAC,MAAM,CAAC,CA4HjB"}
|