@workbench-ai/workbench 0.0.66 → 0.0.67

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.
@@ -1,5 +1,5 @@
1
1
  import path from "node:path";
2
- import { WorkbenchInspectionError, candidateRecordWithoutDerivedFields, candidateSummaryFromRecord, createWorkbenchInspection, loadAuthoredWorkbenchSourceDocument, traceSessionLabel, } from "@workbench-ai/workbench-core";
2
+ import { WorkbenchInspectionError, candidateRecordWithoutDerivedFields, candidateSummaryFromRecord, createCandidateFilePreview, createWorkbenchInspection, loadAuthoredWorkbenchSourceDocument, selectedFilePath, summarizeCandidateFiles, traceSessionLabel, } from "@workbench-ai/workbench-core";
3
3
  import { localBenchmarkFingerprint } from "./benchmark-fingerprint.js";
4
4
  import { loadLocalArchiveIndex, readLocalCandidateFilesForId, readLocalCandidateRecord, readLocalEvaluationRecord, readLocalExecutionFiles, readLocalJobInRun, readLocalRunJobs, readLocalRunRecord, } from "./local-archive.js";
5
5
  import { readLocalAuthoredProjectSource, readLocalProjectSource, WORKBENCH_BENCHMARK_FILE, } from "./project-source.js";
@@ -14,14 +14,22 @@ export function createLocalWorkbenchInspection(options) {
14
14
  projectId: "local",
15
15
  snapshot: () => localBenchmarkSnapshot(context),
16
16
  spec: (input) => localSpecDocument(context, input.fingerprint),
17
- sourceFiles: (input) => localBenchmarkMountedFiles(context, input.fingerprint),
17
+ sourceFiles: async (input) => {
18
+ const files = await localBenchmarkMountedFiles(context, input.fingerprint);
19
+ return summarizeCandidateFiles(files, files.map((file) => file.path));
20
+ },
21
+ sourceFileSurface: async (input) => {
22
+ const files = await localBenchmarkMountedFiles(context, input.fingerprint);
23
+ return localFileSurface(files, files.map((file) => file.path), input.path, input.view);
24
+ },
18
25
  candidate: (input) => readCandidateForInspection(context.workspace, input.id),
19
26
  candidateFiles: async (input) => {
20
27
  const candidate = await readCandidateForInspection(context.workspace, input.id);
21
- return {
22
- files: await readCandidateFilesForInspection(context.workspace, input.id),
23
- changedPaths: candidate.fileChanges,
24
- };
28
+ return summarizeCandidateFiles(await readCandidateFilesForInspection(context.workspace, input.id), candidate.fileChanges);
29
+ },
30
+ candidateFileSurface: async (input) => {
31
+ const candidate = await readCandidateForInspection(context.workspace, input.id);
32
+ return localFileSurface(await readCandidateFilesForInspection(context.workspace, input.id), candidate.fileChanges, input.path, input.view);
25
33
  },
26
34
  evaluation: (input) => readEvaluationForInspection(context.workspace, input.id),
27
35
  run: async (input) => {
@@ -34,12 +42,29 @@ export function createLocalWorkbenchInspection(options) {
34
42
  };
35
43
  },
36
44
  jobInRun: (input) => readExecutionJobForRun(context.workspace, input.runId, input.jobId),
37
- executionFiles: (input) => readExecutionFilesForRun(context.workspace, input.runId, input.jobId),
45
+ executionFiles: async (input) => {
46
+ const files = await readExecutionFilesForRun(context.workspace, input.runId, input.jobId);
47
+ return summarizeCandidateFiles(files, files.map((file) => file.path));
48
+ },
49
+ executionFileSurface: async (input) => {
50
+ const files = await readExecutionFilesForRun(context.workspace, input.runId, input.jobId);
51
+ return localFileSurface(files, files.map((file) => file.path), input.path, input.view);
52
+ },
38
53
  traceForJob: readLocalAggregateTrace,
39
54
  traceSessionsForJob: readLocalTraceSessions,
40
55
  };
41
56
  return createWorkbenchInspection(backend);
42
57
  }
58
+ function localFileSurface(files, changedPaths, path, view = "rendered") {
59
+ const summaries = summarizeCandidateFiles(files, changedPaths);
60
+ const previewPath = selectedFilePath(path, summaries);
61
+ return {
62
+ files: summaries,
63
+ preview: previewPath
64
+ ? createCandidateFilePreview({ files, path: previewPath, view })
65
+ : null,
66
+ };
67
+ }
43
68
  export function createLocalProjectSourceReader(workspace) {
44
69
  const resolvedWorkspace = path.resolve(workspace);
45
70
  let cached = null;
@@ -90,9 +115,20 @@ async function localSpecDocument(context, benchmarkFingerprint) {
90
115
  currentFingerprint &&
91
116
  requestedFingerprint !== currentFingerprint) {
92
117
  const snapshot = await loadLocalArchiveIndex(workspace);
93
- const document = localHistoricalBenchmarkDocument(snapshot, requestedFingerprint);
94
- if (document) {
95
- return document;
118
+ const source = localHistoricalBenchmarkSource(snapshot, requestedFingerprint);
119
+ if (source) {
120
+ return loadAuthoredWorkbenchSourceDocument({
121
+ sourceYaml: source.sourceYaml,
122
+ path: WORKBENCH_BENCHMARK_FILE,
123
+ sourceFiles: [{
124
+ path: WORKBENCH_BENCHMARK_FILE,
125
+ kind: "text",
126
+ encoding: "utf8",
127
+ content: source.sourceYaml,
128
+ executable: false,
129
+ }],
130
+ cases: source.engineResolveFiles,
131
+ });
96
132
  }
97
133
  throw new WorkbenchInspectionError(`Benchmark version not found: ${requestedFingerprint}`, { status: 404 });
98
134
  }
@@ -116,12 +152,16 @@ async function localBenchmarkMountedFiles(context, benchmarkFingerprint) {
116
152
  currentFingerprint &&
117
153
  requestedFingerprint !== currentFingerprint) {
118
154
  const snapshot = await loadLocalArchiveIndex(workspace);
119
- return localHistoricalBenchmarkFiles(snapshot, requestedFingerprint);
155
+ const source = localHistoricalBenchmarkSource(snapshot, requestedFingerprint);
156
+ if (source) {
157
+ return source.engineResolveFiles.map((file) => ({ ...file }));
158
+ }
159
+ throw new WorkbenchInspectionError(`Benchmark version not found: ${requestedFingerprint}`, { status: 404 });
120
160
  }
121
161
  return inspectableEngineCaseFiles(projectSource.engineCases);
122
162
  }
123
163
  function publicLocalRunSummary(run) {
124
- const { executionFingerprint: _executionFingerprint, ...summary } = run;
164
+ const { executionFingerprint: _executionFingerprint, input: _input, ...summary } = run;
125
165
  return summary;
126
166
  }
127
167
  async function readCurrentBenchmarkFingerprint(context) {
@@ -147,21 +187,17 @@ function caseSummaryFilesFromEngineCases(engineCases, files) {
147
187
  })),
148
188
  ];
149
189
  }
150
- function localHistoricalBenchmarkDocument(snapshot, benchmarkFingerprint) {
151
- const candidate = snapshot.candidates.find((entry) => entry.benchmarkFingerprint === benchmarkFingerprint && readBenchmarkSourceMetadata(entry));
152
- const source = candidate ? readBenchmarkSourceMetadata(candidate) : null;
153
- if (!source?.sourceYaml) {
154
- return null;
190
+ function localHistoricalBenchmarkSource(snapshot, benchmarkFingerprint) {
191
+ for (const run of snapshot.runs) {
192
+ if (run.benchmarkFingerprint !== benchmarkFingerprint) {
193
+ continue;
194
+ }
195
+ const source = readRunSourceInput(run);
196
+ if (source) {
197
+ return source;
198
+ }
155
199
  }
156
- return loadAuthoredWorkbenchSourceDocument({
157
- sourceYaml: source.sourceYaml,
158
- path: WORKBENCH_BENCHMARK_FILE,
159
- sourceFiles: source.files,
160
- cases: localHistoricalBenchmarkFiles(snapshot, benchmarkFingerprint),
161
- });
162
- }
163
- function localHistoricalBenchmarkFiles(_snapshot, _benchmarkFingerprint) {
164
- return [];
200
+ return null;
165
201
  }
166
202
  function inspectableEngineCaseFiles(engineCases) {
167
203
  return engineCases.flatMap((bundle) => engineCaseFiles(bundle).map((file) => ({
@@ -195,18 +231,19 @@ async function readRunForInspection(workspace, runId) {
195
231
  async function readCandidateFilesForInspection(workspace, candidateId) {
196
232
  return await readArchiveRecord("Candidate", candidateId, () => readLocalCandidateFilesForId(workspace, candidateId));
197
233
  }
198
- function readBenchmarkSourceMetadata(candidate) {
199
- const benchmark = asRecord(asRecord(candidate.meta)?.benchmark);
200
- const files = Array.isArray(benchmark?.files)
201
- ? benchmark.files
234
+ function readRunSourceInput(run) {
235
+ const input = asRecord(run.input);
236
+ const sourceYaml = typeof input?.sourceYaml === "string" ? input.sourceYaml : null;
237
+ if (!input || !sourceYaml) {
238
+ return null;
239
+ }
240
+ const engineResolveFiles = Array.isArray(input.engineResolveFiles)
241
+ ? input.engineResolveFiles
202
242
  .map(readSurfaceSnapshotFile)
203
243
  .filter((file) => file !== null)
244
+ .sort((left, right) => left.path.localeCompare(right.path))
204
245
  : [];
205
- const sourceYaml = files.find((file) => file.path === WORKBENCH_BENCHMARK_FILE)?.content ?? null;
206
- if (!sourceYaml) {
207
- return null;
208
- }
209
- return { sourceYaml, files };
246
+ return { sourceYaml, engineResolveFiles };
210
247
  }
211
248
  function readSurfaceSnapshotFile(value) {
212
249
  const record = asRecord(value);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workbench-ai/workbench",
3
- "version": "0.0.66",
3
+ "version": "0.0.67",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/workbench-ai/workbench.git",
@@ -21,9 +21,9 @@
21
21
  ],
22
22
  "dependencies": {
23
23
  "yaml": "^2.8.2",
24
- "@workbench-ai/workbench-built-in-adapters": "0.0.66",
25
- "@workbench-ai/workbench-protocol": "0.0.66",
26
- "@workbench-ai/workbench-core": "0.0.66"
24
+ "@workbench-ai/workbench-built-in-adapters": "0.0.67",
25
+ "@workbench-ai/workbench-core": "0.0.67",
26
+ "@workbench-ai/workbench-protocol": "0.0.67"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@tailwindcss/postcss": "^4.2.2",