@workbench-ai/workbench 0.0.51 → 0.0.52

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,6 +1,4 @@
1
- import type { SurfaceSnapshotFile } from "@workbench-ai/workbench-core";
2
- import type { LocalProjectSource } from "./project-source.js";
1
+ import { type LocalProjectSource } from "./project-source.js";
3
2
  export declare function localBenchmarkFingerprint(project: LocalProjectSource): string;
4
3
  export declare function localCandidateFingerprint(project: LocalProjectSource): string;
5
- export declare function benchmarkFingerprintForFiles(files: readonly SurfaceSnapshotFile[]): string;
6
4
  //# sourceMappingURL=benchmark-fingerprint.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"benchmark-fingerprint.d.ts","sourceRoot":"","sources":["../src/benchmark-fingerprint.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAExE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAO7E;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAM7E;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,SAAS,mBAAmB,EAAE,GACpC,MAAM,CAgBR"}
1
+ {"version":3,"file":"benchmark-fingerprint.d.ts","sourceRoot":"","sources":["../src/benchmark-fingerprint.ts"],"names":[],"mappings":"AAOA,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,qBAAqB,CAAC;AAE7B,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAW7E;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAO7E"}
@@ -1,99 +1,31 @@
1
- import { createHash } from "node:crypto";
1
+ import { engineResolveBindingForSpec, workbenchBenchmarkContentFingerprint, workbenchCandidateContentFingerprint, } from "@workbench-ai/workbench-core";
2
+ import { hostedEngineResolveFiles, } from "./project-source.js";
2
3
  export function localBenchmarkFingerprint(project) {
3
- return benchmarkFingerprintForFiles([
4
- textFile("benchmark.yaml", project.benchmarkSource),
5
- ...prefixFiles(project.engineResolveFiles.map(toSurfaceFile), project.engineResolveFingerprintPath),
6
- ...benchmarkDockerfileFiles(project),
7
- ...benchmarkAdapterFiles(project),
8
- ]);
4
+ return workbenchBenchmarkContentFingerprint({
5
+ sourceYaml: project.specSource,
6
+ engineResolveFiles: hostedEngineResolveFiles(project).map(toSurfaceFile),
7
+ engineResolveBinding: engineResolveBindingForSpec(project.spec),
8
+ adapterFiles: project.adapterFiles.map(toSurfaceFile),
9
+ adapterManifests: project.adapters.map((adapter) => adapter.manifest),
10
+ runtimeFiles: project.dockerfileFiles.map(toSurfaceFile),
11
+ resources: project.spec.environment.resources ?? {},
12
+ network: project.spec.environment.network?.egress === "open" ? "on" : "off",
13
+ });
9
14
  }
10
15
  export function localCandidateFingerprint(project) {
11
- const hash = createHash("sha256");
12
- hash.update("workbench-candidate-v1\0");
13
- hash.update(project.candidateSource);
14
- hashSurfaceFiles(hash, project.candidateFiles);
15
- return hash.digest("hex");
16
- }
17
- export function benchmarkFingerprintForFiles(files) {
18
- const hash = createHash("sha256");
19
- hash.update("workbench-benchmark-fingerprint-v1\0");
20
- for (const file of files
21
- .map((entry) => ({ ...entry, path: normalizeLocalPath(entry.path) }))
22
- .sort((left, right) => left.path.localeCompare(right.path))) {
23
- hash.update(file.path);
24
- hash.update("\0");
25
- hash.update(file.encoding ?? "utf8");
26
- hash.update("\0");
27
- hash.update(file.executable ? "1" : "0");
28
- hash.update("\0");
29
- hash.update(file.content);
30
- hash.update("\0");
31
- }
32
- return hash.digest("hex");
33
- }
34
- function benchmarkDockerfileFiles(project) {
35
- const dockerfilePath = normalizeLocalPath(project.spec.environment.dockerfile);
36
- return project.dockerfileFiles.filter((file) => normalizeLocalPath(file.path) === dockerfilePath).map(toSurfaceFile);
37
- }
38
- function benchmarkAdapterFiles(project) {
39
- const roots = project.benchmarkAdapterSources.map(normalizeLocalPath);
40
- const adapterIdRoots = project.benchmarkAdapterIds.map((id) => normalizeLocalPath(`adapters/${id}`));
41
- const allRoots = [...roots, ...adapterIdRoots];
42
- if (allRoots.length === 0) {
43
- return [];
44
- }
45
- return project.adapterFiles.filter((file) => allRoots.some((root) => isWithinLocalPath(file.path, root))).map(toSurfaceFile);
46
- }
47
- function hashSurfaceFiles(hash, files) {
48
- for (const file of files.slice().sort((left, right) => left.path.localeCompare(right.path))) {
49
- hash.update("\0file\0");
50
- hash.update(file.path);
51
- hash.update("\0");
52
- hash.update(file.encoding ?? "utf8");
53
- hash.update("\0");
54
- hash.update(file.content);
55
- hash.update("\0");
56
- hash.update(file.executable ? "1" : "0");
57
- }
58
- }
59
- function prefixFiles(files, rootPath) {
60
- const root = normalizeLocalPath(rootPath);
61
- return files.map((file) => {
62
- const filePath = normalizeLocalPath(file.path);
63
- return {
64
- ...file,
65
- path: isWithinLocalPath(filePath, root) ? filePath : `${root}/${filePath}`,
66
- };
16
+ return workbenchCandidateContentFingerprint({
17
+ sourceYaml: project.specSource,
18
+ candidateFiles: project.candidateFiles.map(toSurfaceFile),
19
+ adapterFiles: project.adapterFiles.map(toSurfaceFile),
20
+ adapterManifests: project.adapters.map((adapter) => adapter.manifest),
67
21
  });
68
22
  }
69
- function textFile(filePath, content) {
70
- return {
71
- path: filePath,
72
- kind: "text",
73
- encoding: "utf8",
74
- content,
75
- executable: false,
76
- };
77
- }
78
23
  function toSurfaceFile(file) {
79
24
  return {
80
25
  path: file.path,
81
- kind: "text",
26
+ kind: "kind" in file ? file.kind : file.encoding === "base64" ? "binary" : "text",
82
27
  encoding: file.encoding ?? "utf8",
83
28
  content: file.content,
84
- executable: file.executable ?? false,
29
+ executable: file.executable === true,
85
30
  };
86
31
  }
87
- function isWithinLocalPath(filePath, rootPath) {
88
- const normalizedFile = normalizeLocalPath(filePath);
89
- const normalizedRoot = normalizeLocalPath(rootPath);
90
- return normalizedFile === normalizedRoot ||
91
- normalizedFile.startsWith(`${normalizedRoot}/`);
92
- }
93
- function normalizeLocalPath(value) {
94
- return value
95
- .replace(/\\/gu, "/")
96
- .replace(/^\/+/u, "")
97
- .replace(/\/+/gu, "/")
98
- .replace(/^(?:\.\/)+/u, "");
99
- }
@@ -1 +1 @@
1
- {"version":3,"file":"command-model.d.ts","sourceRoot":"","sources":["../src/command-model.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,6BAA6B,sHAC2E,CAAC;AAOtH,eAAO,MAAM,2BAA2B,QAA0C,CAAC;AA0EnF,eAAO,MAAM,SAAS,QAAuB,CAAC;AAoY9C,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE/D"}
1
+ {"version":3,"file":"command-model.d.ts","sourceRoot":"","sources":["../src/command-model.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,6BAA6B,sHAC2E,CAAC;AAOtH,eAAO,MAAM,2BAA2B,QAA0C,CAAC;AA4EnF,eAAO,MAAM,SAAS,QAAuB,CAAC;AAoY9C,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE/D"}
@@ -35,8 +35,10 @@ const rootLines = [
35
35
  " workbench adapters test ID|SOURCE [--dir DIR] [--request PATH] [--output DIR] [--json]",
36
36
  "",
37
37
  "Runs:",
38
- " workbench eval [SOURCE] [--dir DIR] [--hosted] [--benchmark OWNER/BENCHMARK] [--candidate CANDIDATE_ID] [--base CANDIDATE_ID] [--runs RUNS|all] [--samples N] [--rerun] [--watch] [--dry-run] [--json]",
39
- " workbench improve [SOURCE] [--dir DIR] [--hosted] [--benchmark OWNER/BENCHMARK] [--from CANDIDATE_ID] [--base CANDIDATE_ID] [--runs RUN] [--budget N] [--samples N] [--rerun] [--watch] [--dry-run] [--json]",
38
+ " workbench eval [SOURCE] [--dir DIR] [--candidate CANDIDATE_ID] [--runs RUNS|all] [--samples N] [--rerun] [--json]",
39
+ " workbench eval --hosted [SOURCE] [--dir DIR] [--benchmark OWNER/BENCHMARK] [--candidate CANDIDATE_ID] [--runs RUNS|all] [--samples N] [--rerun] [--watch] [--dry-run] [--json]",
40
+ " workbench improve [SOURCE] [--dir DIR] [--from CANDIDATE_ID] [--runs RUN] [--budget N] [--samples N] [--rerun] [--json]",
41
+ " workbench improve --hosted [SOURCE] [--dir DIR] [--benchmark OWNER/BENCHMARK] [--base CANDIDATE_ID] [--runs RUN] [--budget N] [--samples N] [--rerun] [--watch] [--dry-run] [--json]",
40
42
  " workbench retry TARGET_ID [--dir DIR] [--hosted] [--benchmark OWNER/BENCHMARK] [--watch] [--interval-ms N] [--timeout-ms N] [--json]",
41
43
  " workbench open [SOURCE|OWNER/BENCHMARK|RUN_ID|CANDIDATE_ID] [--dir DIR] [--hosted] [--benchmark OWNER/BENCHMARK] [--run RUN_ID] [--host HOST] [--port N] [--no-open] [--json]",
42
44
  " workbench restore [--dir DIR] [--candidate CANDIDATE_ID] [--dry-run] [--yes] [--json]",
@@ -124,7 +126,7 @@ const commandHelp = Object.fromEntries(Object.entries({
124
126
  eval: withSourceDirectoryHelp(withLifecycleHelp([
125
127
  "Usage:",
126
128
  " workbench eval [SOURCE] [--dir DIR] [--candidate CANDIDATE_ID] [--runs RUNS|all] [--samples N] [--rerun] [--json]",
127
- " workbench eval --hosted [SOURCE] [--dir DIR] [--benchmark OWNER/BENCHMARK] [--base CANDIDATE_ID] [--runs RUNS|all] [--samples N] [--rerun] [--watch] [--dry-run] [--json]",
129
+ " workbench eval --hosted [SOURCE] [--dir DIR] [--benchmark OWNER/BENCHMARK] [--candidate CANDIDATE_ID] [--runs RUNS|all] [--samples N] [--rerun] [--watch] [--dry-run] [--json]",
128
130
  "",
129
131
  "Ensure the selected candidate run has an evaluation for the current benchmark. Without --hosted, execution writes local records. With --hosted, Workbench starts or reuses a hosted run against the configured remote or --benchmark target. Completed work is reused only when candidate, run configuration, source, adapters, benchmark, and samples match; use --rerun to intentionally spend again.",
130
132
  "",