@workbench-ai/workbench 0.0.52 → 0.0.54

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,4 +1,6 @@
1
+ import { type WorkbenchProjectStateSource } from "@workbench-ai/workbench-core";
1
2
  import { type LocalProjectSource } from "./project-source.js";
2
3
  export declare function localBenchmarkFingerprint(project: LocalProjectSource): string;
4
+ export declare function projectStateBenchmarkFingerprint(source: WorkbenchProjectStateSource): string;
3
5
  export declare function localCandidateFingerprint(project: LocalProjectSource): string;
4
6
  //# sourceMappingURL=benchmark-fingerprint.d.ts.map
@@ -1 +1 @@
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
+ {"version":3,"file":"benchmark-fingerprint.d.ts","sourceRoot":"","sources":["../src/benchmark-fingerprint.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,2BAA2B,EACjC,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,qBAAqB,CAAC;AAE7B,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAW7E;AAED,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,2BAA2B,GAAG,MAAM,CAU5F;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAO7E"}
@@ -12,6 +12,17 @@ export function localBenchmarkFingerprint(project) {
12
12
  network: project.spec.environment.network?.egress === "open" ? "on" : "off",
13
13
  });
14
14
  }
15
+ export function projectStateBenchmarkFingerprint(source) {
16
+ return workbenchBenchmarkContentFingerprint({
17
+ sourceYaml: source.source,
18
+ engineResolveFiles: source.engineResolveFiles,
19
+ engineResolveBinding: source.engineResolveBinding,
20
+ adapterFiles: source.adapterFiles,
21
+ runtimeFiles: source.runtimeFiles,
22
+ resources: source.resources,
23
+ network: source.network,
24
+ });
25
+ }
15
26
  export function localCandidateFingerprint(project) {
16
27
  return workbenchCandidateContentFingerprint({
17
28
  sourceYaml: project.specSource,
@@ -235,7 +235,7 @@ export async function localBenchmarkSnapshot(context) {
235
235
  const summaries = candidates.map(candidateSummary);
236
236
  const activeId = snapshot.activeId && candidates.some((candidate) => candidate.id === snapshot.activeId)
237
237
  ? snapshot.activeId
238
- : candidates.at(-1)?.id ?? null;
238
+ : null;
239
239
  const currentBenchmarkFingerprint = await readCurrentBenchmarkFingerprint(context);
240
240
  return {
241
241
  workspaceRoot: path.resolve(workspace),
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA0IA,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;AA4K9B,wBAAsB,MAAM,CAC1B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,EAAE,GAAE,KAIH,EACD,cAAc,GAAE,iBAAsB,GACrC,OAAO,CAAC,MAAM,CAAC,CAmHjB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA4IA,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;AA4K9B,wBAAsB,MAAM,CAC1B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,EAAE,GAAE,KAIH,EACD,cAAc,GAAE,iBAAsB,GACrC,OAAO,CAAC,MAAM,CAAC,CAmHjB"}
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { createRequire } from "node:module";
5
5
  import os from "node:os";
6
6
  import path from "node:path";
7
7
  import { Writable } from "node:stream";
8
- import { createCandidateFilePreview, createBaselineCandidateJob as createRuntimeBaselineCandidateJob, evaluationScorecardId, evaluationMeanMetrics, executeWorkbenchExecutionJob, engineResolveBindingForSpec, filterOptimizerTraceJobsForCaseIds, filterCandidateSourceFiles, formatWorkbenchCaseSelector, formatWorkbenchSelectionPolicy, workbenchCaseSelectorUsesAllCases, workbenchExecutionPurpose, workbenchRunExecutionFingerprint, createWorkbenchAdapterAuthBundle, createOptimizerTraceInputFiles, DOCKER_SANDBOX_BACKEND, localWorkbenchAdapterAuthStore, materializeWorkbenchRunResult, normalizeSurfaceFiles, planWorkbenchExecutionJobsForPurpose, runWorkbenchExecutionDag, resolveEngineCaseExecutionConfig, resolveWorkbenchResolvedSourceYaml, summarizeCandidateFiles, validateWorkbenchRunEnvelope, parseWorkbenchAdapterAuthTarget, workbenchEngineCaseIdsForImproveEvaluation, workbenchEngineCaseIdsForSelector, workbenchImproveOptimizeSelector, workbenchImproveSelectionPolicy, workbenchProjectSourceFingerprint, workbenchRuntimeBundleFingerprint, } from "@workbench-ai/workbench-core";
8
+ import { createCandidateFilePreview, createBaselineCandidateJob as createRuntimeBaselineCandidateJob, evaluationScorecardId, evaluationMeanMetrics, executeWorkbenchExecutionJob, engineResolveBindingForSpec, filterOptimizerTraceJobsForCaseIds, filterCandidateSourceFiles, formatWorkbenchCaseSelector, formatWorkbenchSelectionPolicy, workbenchCaseSelectorUsesAllCases, workbenchExecutionPurpose, workbenchRunExecutionFingerprint, createWorkbenchAdapterAuthBundle, createOptimizerTraceInputFiles, DOCKER_SANDBOX_BACKEND, localWorkbenchAdapterAuthStore, materializeWorkbenchRunResult, normalizeSurfaceFiles, planWorkbenchExecutionJobsForPurpose, runWorkbenchExecutionDag, resolveEngineCaseExecutionConfig, resolveWorkbenchResolvedSourceYaml, summarizeCandidateFiles, validateWorkbenchRunEnvelope, parseWorkbenchAdapterAuthTarget, workbenchEngineCaseIdsForImproveEvaluation, workbenchEngineCaseIdsForSelector, workbenchImproveOptimizeSelector, workbenchImproveSelectionPolicy, workbenchProjectSourceFingerprint, workbenchRuntimeBundleFingerprint, workbenchRuntimeExplicitActiveId, } from "@workbench-ai/workbench-core";
9
9
  import { assertWorkbenchAdapterOperationResultOk, collectWorkbenchAdapterAuthRequirements, normalizeWorkbenchAdapterOperationRequest, readWorkbenchAdapterOperationResult, workbenchAdapterOperationCommand, workbenchAdapterOperationResultPath, withDefaultWorkbenchAdapterAuthProfiles as applyDefaultWorkbenchAdapterAuthProfiles, } from "@workbench-ai/workbench-protocol";
10
10
  import { builtinLocalTraceAdapter, builtinLocalTraceAdapters, sortLocalTraceRefs, } from "@workbench-ai/workbench-built-in-adapters/local-traces";
11
11
  import { commandUsage, HOSTED_WATCH_LIFECYCLE_NOTE, LOCAL_DEV_OPEN_LIFECYCLE_NOTE, rootUsage, } from "./command-model.js";
@@ -16,7 +16,7 @@ import { createAdapterCommandEnv } from "./adapter-command-env.js";
16
16
  import { loadLocalArchive, loadLocalArchiveIndex, exportLocalRuntimeBundle, importLocalRuntimeBundle, runtimeBundleStats, materializeCandidateRoot, readLocalCandidate, readLocalCandidateFiles, readLocalJobs, saveLocalArchive, saveLocalJobs, setLocalActive, upsertLocalRun, upsertLocalCandidate, upsertLocalEvaluation, } from "./local-archive.js";
17
17
  import { WorkspaceSnapshotError, } from "./workspace-snapshot.js";
18
18
  import { hostedEngineResolveFiles, readLocalProjectSource, WORKBENCH_BENCHMARK_FILE, } from "./project-source.js";
19
- import { localBenchmarkFingerprint, localCandidateFingerprint, } from "./benchmark-fingerprint.js";
19
+ import { localBenchmarkFingerprint, localCandidateFingerprint, projectStateBenchmarkFingerprint, } from "./benchmark-fingerprint.js";
20
20
  const require = createRequire(import.meta.url);
21
21
  function getCliVersion() {
22
22
  const manifest = require("../package.json");
@@ -2919,7 +2919,9 @@ async function pushBenchmark(argv, io) {
2919
2919
  const visibility = readOptionalBenchmarkVisibility(parsed.flags.visibility);
2920
2920
  const createVisibility = visibility ?? "public";
2921
2921
  const dryRun = parsed.flags["dry-run"] === true;
2922
- const runtime = await exportLocalRuntimeBundle(dir);
2922
+ const runtime = await exportLocalRuntimeBundle(dir, {
2923
+ currentBenchmarkFingerprint: localBenchmarkFingerprint(source),
2924
+ });
2923
2925
  const state = localProjectState({
2924
2926
  source,
2925
2927
  runtime,
@@ -3003,7 +3005,8 @@ async function pushBenchmark(argv, io) {
3003
3005
  responseProject,
3004
3006
  visibility,
3005
3007
  });
3006
- const nextOrigin = await writeWorkbenchOriginFromState(dir, {
3008
+ const applied = await acceptPushedProjectStateToLocal({
3009
+ dir,
3007
3010
  baseUrl,
3008
3011
  state: response.state,
3009
3012
  });
@@ -3013,13 +3016,13 @@ async function pushBenchmark(argv, io) {
3013
3016
  changed: response.changed === true,
3014
3017
  benchmark: publishedProject,
3015
3018
  visibility: visibility ?? "unchanged",
3016
- origin: nextOrigin,
3019
+ origin: applied.origin,
3017
3020
  source: response.source,
3018
3021
  runtime: response.runtime.stats,
3019
3022
  urls: buildWorkbenchResourceUrls({
3020
3023
  baseUrl,
3021
3024
  projectId: publishedProject.id ?? responseProject.id,
3022
- ...originRemoteUrlParts(nextOrigin),
3025
+ ...originRemoteUrlParts(applied.origin),
3023
3026
  }),
3024
3027
  }, parsed, io, (record) => {
3025
3028
  const value = record;
@@ -3036,11 +3039,12 @@ async function createHostedBenchmarkFromState(args) {
3036
3039
  body: args.state,
3037
3040
  }, args.baseUrl);
3038
3041
  const project = hostedProjectSummaryFromState(result.state);
3039
- const origin = await writeWorkbenchOriginFromState(args.dir, {
3042
+ const applied = await acceptPushedProjectStateToLocal({
3043
+ dir: args.dir,
3040
3044
  baseUrl: args.baseUrl,
3041
3045
  state: result.state,
3042
3046
  });
3043
- return { project, origin, result };
3047
+ return { project, origin: applied.origin, result };
3044
3048
  }
3045
3049
  async function applyRequestedProjectVisibility(args) {
3046
3050
  if (args.visibility === "public") {
@@ -3077,7 +3081,7 @@ async function cloneProject(argv, io) {
3077
3081
  ref,
3078
3082
  outputDir,
3079
3083
  fileCount: state.source.files.length,
3080
- runtime: runtimeBundleStats(state.runtime),
3084
+ runtime: projectStateRuntimeStats(state),
3081
3085
  sourceFingerprint: state.source.fingerprint ?? state.base.sourceFingerprint ?? null,
3082
3086
  runtimeFingerprint: state.base.runtimeFingerprint ?? null,
3083
3087
  }, parsed, io, () => `Would clone ${formatBenchmarkRef(ref)} to ${outputDir}.`);
@@ -3117,7 +3121,7 @@ async function pullProject(argv, io) {
3117
3121
  dryRun: true,
3118
3122
  dir,
3119
3123
  fileCount: state.source.files.length,
3120
- runtime: runtimeBundleStats(state.runtime),
3124
+ runtime: projectStateRuntimeStats(state),
3121
3125
  sourceFingerprint: state.source.fingerprint ?? state.base.sourceFingerprint ?? null,
3122
3126
  runtimeFingerprint: state.base.runtimeFingerprint ?? null,
3123
3127
  }, parsed, io, () => `Would pull ${state.source.files.length} source file(s) and runtime history into ${dir}.`);
@@ -3159,6 +3163,15 @@ async function applyProjectStateToLocal(args) {
3159
3163
  runtime: runtimeImport.stats,
3160
3164
  };
3161
3165
  }
3166
+ async function acceptPushedProjectStateToLocal(args) {
3167
+ const benchmarkFingerprint = localBenchmarkFingerprint(await readLocalProjectSource(args.dir));
3168
+ const runtime = await importLocalRuntimeBundle(args.dir, args.state.runtime, benchmarkFingerprint);
3169
+ const origin = await writeWorkbenchOriginFromState(args.dir, {
3170
+ baseUrl: args.baseUrl,
3171
+ state: args.state,
3172
+ });
3173
+ return { origin, runtime: runtime.stats };
3174
+ }
3162
3175
  async function retryHostedWorkflow(argv, io) {
3163
3176
  const parsed = parseArgs(argv);
3164
3177
  rejectUnknownFlags(parsed, new Set([
@@ -3889,6 +3902,18 @@ function localProjectState(args) {
3889
3902
  runtime,
3890
3903
  };
3891
3904
  }
3905
+ function projectStateRuntimeStats(state) {
3906
+ const activeId = workbenchRuntimeExplicitActiveId({
3907
+ candidates: state.runtime.candidates,
3908
+ runs: state.runtime.runs,
3909
+ preferredActiveId: state.runtime.activeId ?? null,
3910
+ benchmarkFingerprint: projectStateBenchmarkFingerprint(state.source),
3911
+ });
3912
+ return runtimeBundleStats({
3913
+ ...state.runtime,
3914
+ activeId,
3915
+ });
3916
+ }
3892
3917
  function localCandidateRecord(candidate) {
3893
3918
  return {
3894
3919
  ...candidate,
@@ -23,7 +23,9 @@ export declare function loadLocalArchive(workspace: string): Promise<LocalArchiv
23
23
  export declare function loadLocalArchiveIndex(workspace: string): Promise<LocalArchiveIndex>;
24
24
  export declare function saveLocalArchive(workspace: string, snapshot: LocalArchiveSnapshot): Promise<void>;
25
25
  export declare function saveLocalJobs(workspace: string, jobs: readonly HostedWorkbenchJob[]): Promise<void>;
26
- export declare function exportLocalRuntimeBundle(workspace: string): Promise<WorkbenchRuntimeBundle>;
26
+ export declare function exportLocalRuntimeBundle(workspace: string, options?: {
27
+ currentBenchmarkFingerprint?: string;
28
+ }): Promise<WorkbenchRuntimeBundle>;
27
29
  export declare function importLocalRuntimeBundle(workspace: string, bundle: WorkbenchRuntimeBundle, currentBenchmarkFingerprint: string): Promise<WorkbenchRuntimeImportResult>;
28
30
  export declare function runtimeBundleStats(bundle: WorkbenchRuntimeBundle): WorkbenchRuntimeBundleStats;
29
31
  export declare function sanitizeRuntimeJobForExchange(job: HostedWorkbenchJob): HostedWorkbenchJob;
@@ -1 +1 @@
1
- {"version":3,"file":"local-archive.d.ts","sourceRoot":"","sources":["../src/local-archive.ts"],"names":[],"mappings":"AAGA,OAAO,EAQL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,UAAU,EACf,KAAK,YAAY,EAEjB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC3B,MAAM,8BAA8B,CAAC;AAOtC,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC,CAAC;IACtD,WAAW,EAAE,mBAAmB,EAAE,CAAC;IACnC,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,MAAM,EAAE,YAAY,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,WAAW,EAAE,mBAAmB,EAAE,CAAC;IACnC,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,MAAM,EAAE,YAAY,EAAE,CAAC;CACxB;AAED,MAAM,MAAM,gBAAgB,GAAG,kBAAkB,GAAG;IAClD,KAAK,CAAC,EAAE,uBAAuB,CAAC;IAChC,aAAa,CAAC,EAAE,qBAAqB,EAAE,CAAC;CACzC,CAAC;AASF,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAevF;AAED,wBAAsB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAkBzF;AAED,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,oBAAoB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAyBf;AAED,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,SAAS,kBAAkB,EAAE,GAClC,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,sBAAsB,CAAC,CAuBjC;AAED,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,sBAAsB,EAC9B,2BAA2B,EAAE,MAAM,GAClC,OAAO,CAAC,4BAA4B,CAAC,CAkHvC;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,sBAAsB,GAC7B,2BAA2B,CAE7B;AAED,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,kBAAkB,GACtB,kBAAkB,CAEpB;AAyDD,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAIhC;AAED,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CAU1B;AAED,wBAAsB,4BAA4B,CAChD,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAKhC;AAED,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,mBAAmB,CAAC,CAU9B;AAED,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,UAAU,CAAC,CAUrB;AAED,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAM7B;AAED,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAE7B;AAED,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAElC;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,oBAAoB,EAC9B,SAAS,EAAE,eAAe,EAC1B,KAAK,EAAE,SAAS,mBAAmB,EAAE,GACpC,oBAAoB,CAYtB;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,oBAAoB,EAC9B,UAAU,EAAE,mBAAmB,GAC9B,oBAAoB,CAQtB;AAED,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,oBAAoB,EAC9B,GAAG,EAAE,UAAU,EACf,MAAM,EAAE,SAAS,YAAY,EAAE,GAC9B,oBAAoB,CAYtB;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,oBAAoB,CAK5G;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,GAAG,eAAe,CAMvG;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAGlH;AAkoBD,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,SAAS,mBAAmB,EAAE,GACpC,OAAO,CAAC,MAAM,EAAE,CAAC,CAOnB;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,mBAAmB,EAAE,EACrC,QAAQ,EAAE,MAAM,GACf,mBAAmB,GAAG,IAAI,CAG5B"}
1
+ {"version":3,"file":"local-archive.d.ts","sourceRoot":"","sources":["../src/local-archive.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { promises as fs } from "node:fs";
2
2
  import path from "node:path";
3
- import { buildWorkbenchTraceSessionsFromFiles, candidateRecordWithoutDerivedFields, sanitizeWorkbenchRuntimeCandidateForExchange, sanitizeWorkbenchRuntimeJobForExchange, selectExecutionOutputFilesForInspection, workbenchRuntimeBundleStats, workbenchSurfaceFilesEqualForExchange, } from "@workbench-ai/workbench-core";
3
+ import { buildWorkbenchTraceSessionsFromFiles, candidateRecordWithoutDerivedFields, sanitizeWorkbenchRuntimeCandidateForExchange, sanitizeWorkbenchRuntimeJobForExchange, selectExecutionOutputFilesForInspection, workbenchRuntimeExplicitActiveId, workbenchRuntimeBundleStats, workbenchSurfaceFilesEqualForExchange, } from "@workbench-ai/workbench-core";
4
4
  const RUNTIME_DIR = ".workbench/runtime";
5
5
  const CANDIDATE_RECORDS_DIR = "candidates";
6
6
  export function localRuntimeDir(workspace) {
@@ -71,16 +71,24 @@ export async function saveLocalJobs(workspace, jobs) {
71
71
  }
72
72
  await writeArchivedLocalJobs(workspace, jobs, new Map());
73
73
  }
74
- export async function exportLocalRuntimeBundle(workspace) {
74
+ export async function exportLocalRuntimeBundle(workspace, options = {}) {
75
75
  const snapshot = await loadLocalArchive(workspace);
76
76
  const jobs = (await readLocalJobs(workspace)).map(sanitizeRuntimeJobForExchange);
77
77
  const executionFiles = await Promise.all(jobs.map(async (job) => ({
78
78
  jobId: job.id,
79
79
  files: await readLocalExecutionFiles(workspace, job.id),
80
80
  })));
81
+ const activeId = options.currentBenchmarkFingerprint
82
+ ? workbenchRuntimeExplicitActiveId({
83
+ candidates: snapshot.candidates,
84
+ runs: snapshot.runs,
85
+ preferredActiveId: snapshot.activeId,
86
+ benchmarkFingerprint: options.currentBenchmarkFingerprint,
87
+ })
88
+ : snapshot.activeId;
81
89
  return {
82
90
  schema: "workbench.runtime.bundle.v1",
83
- activeId: snapshot.activeId,
91
+ activeId,
84
92
  candidates: snapshot.candidates.map(sanitizeWorkbenchRuntimeCandidateForExchange),
85
93
  candidateFiles: Object.entries(snapshot.candidateFiles).map(([candidateId, files]) => ({
86
94
  candidateId,
@@ -121,12 +129,6 @@ export async function importLocalRuntimeBundle(workspace, bundle, currentBenchma
121
129
  }
122
130
  candidateFiles[candidateId] = files;
123
131
  }
124
- const activeId = compatibleRuntimeActiveCandidateId(candidates, bundle.activeId ?? null, currentBenchmarkFingerprint) ??
125
- compatibleRuntimeActiveCandidateId(candidates, snapshot.activeId, currentBenchmarkFingerprint) ??
126
- latestCompatibleRuntimeCandidateId(candidates, currentBenchmarkFingerprint);
127
- if (activeId !== snapshot.activeId) {
128
- changed = true;
129
- }
130
132
  const evaluations = mergeRecordsById(snapshot.evaluations, bundle.evaluations, (evaluation) => evaluation.id, (didChange) => {
131
133
  changed ||= didChange;
132
134
  }, runtimeEvaluationsCompatibleForExchange).sort((left, right) => left.createdAt.localeCompare(right.createdAt) || left.id.localeCompare(right.id));
@@ -165,6 +167,15 @@ export async function importLocalRuntimeBundle(workspace, bundle, currentBenchma
165
167
  changed ||= didChange;
166
168
  }, runtimeJobsEqualForExchange).sort((left, right) => (left.startedAt ?? left.createdAt).localeCompare(right.startedAt ?? right.createdAt) ||
167
169
  left.id.localeCompare(right.id));
170
+ const activeId = workbenchRuntimeExplicitActiveId({
171
+ candidates,
172
+ runs,
173
+ preferredActiveId: bundle.activeId ?? null,
174
+ benchmarkFingerprint: currentBenchmarkFingerprint,
175
+ });
176
+ if (activeId !== snapshot.activeId) {
177
+ changed = true;
178
+ }
168
179
  await saveLocalArchive(workspace, {
169
180
  activeId,
170
181
  candidates,
@@ -446,19 +457,6 @@ function runtimeJobIdentityForExchange(job) {
446
457
  attempt: job.attempt,
447
458
  };
448
459
  }
449
- function compatibleRuntimeActiveCandidateId(candidates, candidateId, benchmarkFingerprint) {
450
- if (!candidateId) {
451
- return null;
452
- }
453
- const candidate = candidates.find((entry) => entry.id === candidateId) ?? null;
454
- return candidate?.benchmarkFingerprint === benchmarkFingerprint ? candidate.id : null;
455
- }
456
- function latestCompatibleRuntimeCandidateId(candidates, benchmarkFingerprint) {
457
- return candidates
458
- .filter((candidate) => candidate.benchmarkFingerprint === benchmarkFingerprint &&
459
- candidate.status === "evaluated")
460
- .at(-1)?.id ?? null;
461
- }
462
460
  function canonicalRuntimeJson(value) {
463
461
  if (Array.isArray(value)) {
464
462
  return value.map(canonicalRuntimeJson);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workbench-ai/workbench",
3
- "version": "0.0.52",
3
+ "version": "0.0.54",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "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.52",
25
- "@workbench-ai/workbench-core": "0.0.52",
26
- "@workbench-ai/workbench-protocol": "0.0.52"
24
+ "@workbench-ai/workbench-built-in-adapters": "0.0.54",
25
+ "@workbench-ai/workbench-core": "0.0.54",
26
+ "@workbench-ai/workbench-protocol": "0.0.54"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@tailwindcss/postcss": "^4.2.2",