@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.
- package/dist/command-model.js +2 -2
- package/dist/dev-open/client.css +0 -3
- package/dist/dev-open/client.js +204 -204
- package/dist/dev-open-server.js +21 -28
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +236 -41
- package/dist/local-archive.d.ts.map +1 -1
- package/dist/local-archive.js +12 -7
- package/dist/local-inspection.d.ts.map +1 -1
- package/dist/local-inspection.js +72 -35
- package/package.json +4 -4
package/dist/dev-open-server.js
CHANGED
|
@@ -101,13 +101,26 @@ function isKnownWorkbenchDocumentPath(pathname) {
|
|
|
101
101
|
if (segments.length === 0) {
|
|
102
102
|
return true;
|
|
103
103
|
}
|
|
104
|
+
if (segments.length === 1 && (segments[0] === "manifest" || segments[0] === "files")) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
104
107
|
if (segments[0] === "evaluations") {
|
|
105
|
-
|
|
108
|
+
if (segments.length === 1 || segments.length === 2) {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
if (segments.length < 4 || segments[2] !== "cases") {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
return segments.length === 4 ||
|
|
115
|
+
(segments.length === 5 && (segments[4] === "attempts" || segments[4] === "files"));
|
|
106
116
|
}
|
|
107
117
|
if (segments[0] !== "candidates") {
|
|
108
118
|
return false;
|
|
109
119
|
}
|
|
110
|
-
if (segments.length === 1 || segments.length === 2) {
|
|
120
|
+
if (segments.length === 1 || (segments.length === 2 && segments[1] === "lineage")) {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
if (segments.length === 2) {
|
|
111
124
|
return true;
|
|
112
125
|
}
|
|
113
126
|
return segments.length === 3 && (segments[2] === "files" || segments[2] === "manifest");
|
|
@@ -132,14 +145,9 @@ async function handleApiRequest(request, response, context, url) {
|
|
|
132
145
|
}), 200, request.method);
|
|
133
146
|
return;
|
|
134
147
|
case "/api/source/files":
|
|
135
|
-
sendJson(response, await inspection.
|
|
148
|
+
sendJson(response, await inspection.sourceFileSurface({
|
|
136
149
|
fingerprint: readOptionalSearchString(url.searchParams, "fingerprint"),
|
|
137
|
-
|
|
138
|
-
return;
|
|
139
|
-
case "/api/source/preview":
|
|
140
|
-
sendJson(response, await inspection.sourcePreview({
|
|
141
|
-
fingerprint: readOptionalSearchString(url.searchParams, "fingerprint"),
|
|
142
|
-
path: readSearchString(url.searchParams, "path"),
|
|
150
|
+
path: readOptionalSearchString(url.searchParams, "path"),
|
|
143
151
|
view: readPreviewMode(url.searchParams),
|
|
144
152
|
}), 200, request.method);
|
|
145
153
|
return;
|
|
@@ -151,14 +159,9 @@ async function handleApiRequest(request, response, context, url) {
|
|
|
151
159
|
return;
|
|
152
160
|
case "/api/candidate/files": {
|
|
153
161
|
const candidateId = readSearchString(url.searchParams, "id");
|
|
154
|
-
sendJson(response, await inspection.
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
case "/api/candidate/preview": {
|
|
158
|
-
const candidateId = readSearchString(url.searchParams, "id");
|
|
159
|
-
sendJson(response, await inspection.candidatePreview({
|
|
162
|
+
sendJson(response, await inspection.candidateFileSurface({
|
|
160
163
|
id: candidateId,
|
|
161
|
-
path:
|
|
164
|
+
path: readOptionalSearchString(url.searchParams, "path"),
|
|
162
165
|
view: readPreviewMode(url.searchParams),
|
|
163
166
|
}), 200, request.method);
|
|
164
167
|
return;
|
|
@@ -186,20 +189,10 @@ async function handleApiRequest(request, response, context, url) {
|
|
|
186
189
|
case "/api/execution/files": {
|
|
187
190
|
const execRunId = readSearchString(url.searchParams, "run");
|
|
188
191
|
const execJobId = readSearchString(url.searchParams, "id");
|
|
189
|
-
sendJson(response, await inspection.
|
|
192
|
+
sendJson(response, await inspection.executionFileSurface({
|
|
190
193
|
runId: execRunId,
|
|
191
194
|
jobId: execJobId,
|
|
192
|
-
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
case "/api/execution/preview": {
|
|
196
|
-
const previewRunId = readSearchString(url.searchParams, "run");
|
|
197
|
-
const previewJobId = readSearchString(url.searchParams, "id");
|
|
198
|
-
const previewFilePath = readSearchString(url.searchParams, "path");
|
|
199
|
-
sendJson(response, await inspection.executionPreview({
|
|
200
|
-
runId: previewRunId,
|
|
201
|
-
jobId: previewJobId,
|
|
202
|
-
path: previewFilePath,
|
|
195
|
+
path: readOptionalSearchString(url.searchParams, "path"),
|
|
203
196
|
view: readPreviewMode(url.searchParams),
|
|
204
197
|
}), 200, request.method);
|
|
205
198
|
return;
|
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":"AAmJA,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;AA8BD,UAAU,iBAAiB;CAAG;AAsN9B,wBAAsB,MAAM,CAC1B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,EAAE,GAAE,KAIH,EACD,cAAc,GAAE,iBAAsB,GACrC,OAAO,CAAC,MAAM,CAAC,CA4HjB"}
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,8 @@ 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 {
|
|
8
|
+
import { gzipSync } from "node:zlib";
|
|
9
|
+
import { createBaselineCandidateJob as createRuntimeBaselineCandidateJob, evaluationScorecardId, evaluationMeanMetrics, executeWorkbenchExecutionJob, engineResolveBindingForSpec, filterOptimizerTraceJobsForCaseIds, filterCandidateSourceFiles, formatWorkbenchCaseSelector, formatWorkbenchSelectionPolicy, workbenchCaseSelectorUsesAllCases, workbenchExecutionPurpose, workbenchRunExecutionFingerprint, createWorkbenchAdapterAuthBundle, createOptimizerTraceInputFiles, DOCKER_SANDBOX_BACKEND, localWorkbenchAdapterAuthStore, materializeWorkbenchRunResult, normalizeRelativePath, normalizeSurfaceFiles, isSurfaceSnapshotFile, jsonRecord, planWorkbenchExecutionJobsForPurpose, runWorkbenchExecutionDag, resolveEngineCaseExecutionConfig, resolveWorkbenchResolvedSourceYaml, runtimeResources, validateWorkbenchRunEnvelope, parseWorkbenchAdapterAuthTarget, workbenchEngineCaseIdsForImproveEvaluation, workbenchEngineCaseIdsForSelector, workbenchImproveOptimizeSelector, workbenchImproveSelectionPolicy, workbenchProjectSourceFingerprint, workbenchRuntimeCandidateIdentityForExchange, workbenchRuntimeBundleFingerprint, workbenchRuntimeProjectedActiveId, } from "@workbench-ai/workbench-core";
|
|
9
10
|
import { assertWorkbenchAdapterOperationResultOk, collectWorkbenchAdapterAuthRequirements, normalizeWorkbenchAdapterOperationRequest, readWorkbenchAdapterOperationResult, workbenchAdapterOperationCommand, workbenchAdapterOperationResultPath, withDefaultWorkbenchAdapterAuthProfiles as applyDefaultWorkbenchAdapterAuthProfiles, } from "@workbench-ai/workbench-protocol";
|
|
10
11
|
import { builtinLocalTraceAdapter, builtinLocalTraceAdapters, sortLocalTraceRefs, } from "@workbench-ai/workbench-built-in-adapters/local-traces";
|
|
11
12
|
import { commandUsage, REMOTE_WATCH_LIFECYCLE_NOTE, LOCAL_DEV_OPEN_LIFECYCLE_NOTE, rootUsage, } from "./command-model.js";
|
|
@@ -34,6 +35,7 @@ class WorkbenchApiRequestError extends Error {
|
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
const API_REQUEST_MAX_ATTEMPTS = 3;
|
|
38
|
+
const API_REQUEST_GZIP_THRESHOLD_BYTES = 1024 * 1024;
|
|
37
39
|
const DEFAULT_BASE_URL = "https://v2.workbench.ai";
|
|
38
40
|
const AUTH_COMMAND_HANDLERS = {
|
|
39
41
|
connect: authConnect,
|
|
@@ -764,6 +766,11 @@ async function localRun(argv, io, runtimeOptions) {
|
|
|
764
766
|
detail: { budget, samples, strategy: "greedy", optimizeOn: optimizeOnLabel, selectBy: selectByLabel },
|
|
765
767
|
}),
|
|
766
768
|
];
|
|
769
|
+
const runInput = localRunInput({
|
|
770
|
+
benchmarkFingerprint,
|
|
771
|
+
sourceYaml: projectSource.specSource,
|
|
772
|
+
engineResolveFiles,
|
|
773
|
+
});
|
|
767
774
|
const runningRun = {
|
|
768
775
|
id: runId,
|
|
769
776
|
workflow: "improve",
|
|
@@ -786,6 +793,7 @@ async function localRun(argv, io, runtimeOptions) {
|
|
|
786
793
|
executionFingerprint,
|
|
787
794
|
activeCandidateId: snapshot.activeId,
|
|
788
795
|
outputCandidateId: null,
|
|
796
|
+
input: runInput,
|
|
789
797
|
};
|
|
790
798
|
snapshot = upsertLocalRun(snapshot, runningRun, events);
|
|
791
799
|
await saveLocalArchive(workspace, snapshot);
|
|
@@ -954,6 +962,7 @@ async function localRun(argv, io, runtimeOptions) {
|
|
|
954
962
|
outcome: failedJobCount > 0 ? "error" : "ok",
|
|
955
963
|
activeCandidateId: snapshot.activeId,
|
|
956
964
|
outputCandidateId: outputCandidateId ?? snapshot.activeId,
|
|
965
|
+
input: runInput,
|
|
957
966
|
};
|
|
958
967
|
events.push(createLocalEvent("run_finished", finishedAt, {
|
|
959
968
|
runId,
|
|
@@ -1245,6 +1254,11 @@ async function localEvaluateCandidate(argv, io, runtimeOptions) {
|
|
|
1245
1254
|
candidateId: evaluatedCandidateId,
|
|
1246
1255
|
detail: { samples, strategy: "direct" },
|
|
1247
1256
|
});
|
|
1257
|
+
const runInput = localRunInput({
|
|
1258
|
+
benchmarkFingerprint,
|
|
1259
|
+
sourceYaml: projectSource.specSource,
|
|
1260
|
+
engineResolveFiles,
|
|
1261
|
+
});
|
|
1248
1262
|
const runningRun = {
|
|
1249
1263
|
id: runId,
|
|
1250
1264
|
workflow: "eval",
|
|
@@ -1265,6 +1279,7 @@ async function localEvaluateCandidate(argv, io, runtimeOptions) {
|
|
|
1265
1279
|
executionFingerprint,
|
|
1266
1280
|
activeCandidateId: activeCandidateIdBeforeEval,
|
|
1267
1281
|
outputCandidateId: evaluatedCandidateId,
|
|
1282
|
+
input: runInput,
|
|
1268
1283
|
};
|
|
1269
1284
|
snapshot = upsertLocalRun(snapshot, runningRun, [runStartedEvent]);
|
|
1270
1285
|
await saveLocalArchive(workspace, snapshot);
|
|
@@ -1350,7 +1365,7 @@ async function localEvaluateCandidate(argv, io, runtimeOptions) {
|
|
|
1350
1365
|
durationMs: Math.max(0, Date.parse(finishedAt) - Date.parse(startedAt)),
|
|
1351
1366
|
},
|
|
1352
1367
|
});
|
|
1353
|
-
|
|
1368
|
+
const finishedRun = {
|
|
1354
1369
|
id: runId,
|
|
1355
1370
|
workflow: "eval",
|
|
1356
1371
|
benchmarkFingerprint,
|
|
@@ -1374,7 +1389,9 @@ async function localEvaluateCandidate(argv, io, runtimeOptions) {
|
|
|
1374
1389
|
outcome: currentRunFailedJobCount > 0 ? "error" : "ok",
|
|
1375
1390
|
activeCandidateId,
|
|
1376
1391
|
outputCandidateId: evaluatedCandidateId,
|
|
1377
|
-
|
|
1392
|
+
input: runInput,
|
|
1393
|
+
};
|
|
1394
|
+
snapshot = upsertLocalRun(snapshot, finishedRun, [runFinishedEvent]);
|
|
1378
1395
|
await saveLocalJobs(workspace, currentRunJobs);
|
|
1379
1396
|
await saveLocalArchive(workspace, snapshot);
|
|
1380
1397
|
const evaluation = materialized.evaluations[0] ?? null;
|
|
@@ -1578,8 +1595,7 @@ function localDevOpenUrl(baseUrl, snapshot, runId) {
|
|
|
1578
1595
|
if (!evaluation) {
|
|
1579
1596
|
return new URL("candidates", baseUrl).toString();
|
|
1580
1597
|
}
|
|
1581
|
-
|
|
1582
|
-
return new URL(`candidates/${encodeURIComponent(evaluation.candidateId)}?${params.toString()}`, baseUrl).toString();
|
|
1598
|
+
return new URL(`evaluations/${encodeURIComponent(evaluation.id)}`, baseUrl).toString();
|
|
1583
1599
|
}
|
|
1584
1600
|
async function readLocalBenchmarkFingerprint(workspace) {
|
|
1585
1601
|
return localBenchmarkFingerprint(await readLocalProjectSource(workspace));
|
|
@@ -1608,6 +1624,13 @@ function authoredBenchmarkSourceFiles(projectSource) {
|
|
|
1608
1624
|
executable: false,
|
|
1609
1625
|
}];
|
|
1610
1626
|
}
|
|
1627
|
+
function localRunInput(input) {
|
|
1628
|
+
return {
|
|
1629
|
+
benchmarkFingerprint: input.benchmarkFingerprint,
|
|
1630
|
+
sourceYaml: input.sourceYaml,
|
|
1631
|
+
engineResolveFiles: normalizeSurfaceFiles(input.engineResolveFiles),
|
|
1632
|
+
};
|
|
1633
|
+
}
|
|
1611
1634
|
function shellQuote(value) {
|
|
1612
1635
|
return `'${value.replace(/'/gu, "'\\''")}'`;
|
|
1613
1636
|
}
|
|
@@ -1873,11 +1896,16 @@ async function localCandidatePreview(argv, io) {
|
|
|
1873
1896
|
const inspection = localInspectionFromParsed(parsed);
|
|
1874
1897
|
const snapshot = await inspection.snapshot();
|
|
1875
1898
|
const candidateId = readCandidateIdFlag(parsed, snapshot);
|
|
1876
|
-
const
|
|
1899
|
+
const requestedPath = requireFlag(parsed, "path");
|
|
1900
|
+
const surface = await inspection.candidateFileSurface({
|
|
1877
1901
|
id: candidateId,
|
|
1878
|
-
path:
|
|
1902
|
+
path: requestedPath,
|
|
1879
1903
|
view: readPreviewMode(parsed),
|
|
1880
1904
|
});
|
|
1905
|
+
const preview = surface.preview;
|
|
1906
|
+
if (!preview || preview.path !== normalizeRelativePath(requestedPath)) {
|
|
1907
|
+
throw new UsageError(`File not found: ${requestedPath}`);
|
|
1908
|
+
}
|
|
1881
1909
|
const content = preview.source?.content ?? preview.rendered_html ?? preview.diff ?? "";
|
|
1882
1910
|
const outputPath = asOptionalString(parsed.flags.output);
|
|
1883
1911
|
if (outputPath && outputPath !== "-") {
|
|
@@ -3034,7 +3062,7 @@ function adapterAuthRecord(value) {
|
|
|
3034
3062
|
}
|
|
3035
3063
|
async function pushBenchmark(argv, io) {
|
|
3036
3064
|
const parsed = parseArgs(argv);
|
|
3037
|
-
rejectUnknownFlags(parsed, new Set(["dir", "visibility", "dry-run", "json"]));
|
|
3065
|
+
rejectUnknownFlags(parsed, new Set(["dir", "visibility", "dry-run", "force", "json"]));
|
|
3038
3066
|
const dir = resolveSourceDir(parsed);
|
|
3039
3067
|
const source = await readLocalProjectSource(dir);
|
|
3040
3068
|
const origin = await readWorkbenchOrigin(dir);
|
|
@@ -3042,17 +3070,18 @@ async function pushBenchmark(argv, io) {
|
|
|
3042
3070
|
const visibility = readOptionalBenchmarkVisibility(parsed.flags.visibility);
|
|
3043
3071
|
const createVisibility = visibility ?? "public";
|
|
3044
3072
|
const dryRun = parsed.flags["dry-run"] === true;
|
|
3073
|
+
const force = parsed.flags.force === true;
|
|
3045
3074
|
const runtime = await exportLocalRuntimeBundle(dir, {
|
|
3046
3075
|
currentBenchmarkFingerprint: localBenchmarkFingerprint(source),
|
|
3047
3076
|
});
|
|
3048
3077
|
const localRuntimeFingerprint = workbenchRuntimeBundleFingerprint(runtime);
|
|
3049
|
-
const state = localProjectState({
|
|
3050
|
-
source,
|
|
3051
|
-
runtime,
|
|
3052
|
-
origin,
|
|
3053
|
-
visibility: createVisibility,
|
|
3054
|
-
});
|
|
3055
3078
|
if (!origin) {
|
|
3079
|
+
const state = localProjectState({
|
|
3080
|
+
source,
|
|
3081
|
+
runtime,
|
|
3082
|
+
origin,
|
|
3083
|
+
visibility: createVisibility,
|
|
3084
|
+
});
|
|
3056
3085
|
if (dryRun) {
|
|
3057
3086
|
writeOutput({
|
|
3058
3087
|
ok: true,
|
|
@@ -3100,30 +3129,135 @@ async function pushBenchmark(argv, io) {
|
|
|
3100
3129
|
if (!projectId) {
|
|
3101
3130
|
throw new UsageError("Missing remote benchmark. Run workbench push from a source directory.");
|
|
3102
3131
|
}
|
|
3132
|
+
const remoteProject = force || dryRun
|
|
3133
|
+
? await readOriginProjectIfPresent({ baseUrl, origin })
|
|
3134
|
+
: null;
|
|
3103
3135
|
if (dryRun) {
|
|
3104
|
-
const
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3136
|
+
const state = localProjectState({
|
|
3137
|
+
source,
|
|
3138
|
+
runtime,
|
|
3139
|
+
origin: remoteProject
|
|
3140
|
+
? { ...origin, projectId: remoteProject.id }
|
|
3141
|
+
: origin,
|
|
3142
|
+
visibility: visibility ?? remoteProject?.visibility ?? createVisibility,
|
|
3108
3143
|
});
|
|
3144
|
+
if (!remoteProject && !force) {
|
|
3145
|
+
throw new WorkbenchApiRequestError(404, `Workbench benchmark not found: ${origin.remote}`, "");
|
|
3146
|
+
}
|
|
3147
|
+
if (!remoteProject && force) {
|
|
3148
|
+
await assertForceCreateAllowed({ baseUrl, origin, sourceName: source.spec.name });
|
|
3149
|
+
}
|
|
3150
|
+
const action = force && !remoteProject ? "create" : force ? "replace" : "update";
|
|
3109
3151
|
writeOutput({
|
|
3110
3152
|
ok: true,
|
|
3111
3153
|
dryRun: true,
|
|
3112
|
-
action
|
|
3154
|
+
action,
|
|
3113
3155
|
dir,
|
|
3114
3156
|
baseUrl,
|
|
3115
|
-
benchmarkId: projectId,
|
|
3157
|
+
benchmarkId: remoteProject?.id ?? projectId,
|
|
3116
3158
|
remote: origin.remote,
|
|
3117
|
-
benchmark: remoteProjectSummaryForOutput(remoteProject),
|
|
3159
|
+
...(remoteProject ? { benchmark: remoteProjectSummaryForOutput(remoteProject) } : {}),
|
|
3118
3160
|
benchmarkName: source.spec.name,
|
|
3119
|
-
visibility: visibility ?? "unchanged",
|
|
3161
|
+
visibility: visibility ?? (remoteProject ? remoteProject.visibility ?? "unchanged" : createVisibility),
|
|
3120
3162
|
sourceFileCount: sourceFileCount(source),
|
|
3121
3163
|
runtime: runtimeBundleStats(runtime),
|
|
3122
3164
|
sourceFingerprint: state.source.fingerprint,
|
|
3123
3165
|
runtimeFingerprint: localRuntimeFingerprint,
|
|
3124
|
-
}, parsed, io, () =>
|
|
3166
|
+
}, parsed, io, () => force && !remoteProject
|
|
3167
|
+
? `Would create ${origin.remote} from local project state.`
|
|
3168
|
+
: force
|
|
3169
|
+
? `Would replace ${origin.remote} with local project state.`
|
|
3170
|
+
: `Would push ${sourceFileCount(source)} source file(s) and runtime history to ${origin.remote}.`);
|
|
3171
|
+
return 0;
|
|
3172
|
+
}
|
|
3173
|
+
if (force) {
|
|
3174
|
+
const targetOrigin = remoteProject
|
|
3175
|
+
? { ...origin, projectId: remoteProject.id }
|
|
3176
|
+
: null;
|
|
3177
|
+
const state = localProjectState({
|
|
3178
|
+
source,
|
|
3179
|
+
runtime,
|
|
3180
|
+
origin: targetOrigin,
|
|
3181
|
+
visibility: visibility ?? remoteProject?.visibility ?? createVisibility,
|
|
3182
|
+
});
|
|
3183
|
+
if (!remoteProject) {
|
|
3184
|
+
await assertForceCreateAllowed({ baseUrl, origin, sourceName: source.spec.name });
|
|
3185
|
+
const { project, origin: nextOrigin, result } = await createRemoteBenchmarkFromState({
|
|
3186
|
+
baseUrl,
|
|
3187
|
+
dir,
|
|
3188
|
+
state,
|
|
3189
|
+
});
|
|
3190
|
+
writeOutput({
|
|
3191
|
+
ok: true,
|
|
3192
|
+
action: "create",
|
|
3193
|
+
benchmark: project,
|
|
3194
|
+
visibility: project.visibility ?? createVisibility,
|
|
3195
|
+
origin: nextOrigin,
|
|
3196
|
+
source: result.source,
|
|
3197
|
+
runtime: result.runtime.stats,
|
|
3198
|
+
urls: buildWorkbenchResourceUrls({
|
|
3199
|
+
baseUrl,
|
|
3200
|
+
projectId: project.id,
|
|
3201
|
+
...originRemoteUrlParts(nextOrigin),
|
|
3202
|
+
}),
|
|
3203
|
+
}, parsed, io, (record) => {
|
|
3204
|
+
const value = record;
|
|
3205
|
+
return [
|
|
3206
|
+
`Pushed ${value.origin.remote} (${value.origin.projectId}).`,
|
|
3207
|
+
`Open benchmark: ${value.urls.benchmark}`,
|
|
3208
|
+
].join("\n");
|
|
3209
|
+
});
|
|
3210
|
+
return 0;
|
|
3211
|
+
}
|
|
3212
|
+
const response = await apiRequest(projectApiPath(remoteProject.id, "/state?force=true"), {
|
|
3213
|
+
method: "PUT",
|
|
3214
|
+
body: state,
|
|
3215
|
+
}, baseUrl);
|
|
3216
|
+
assertAcceptedForceReplacement({
|
|
3217
|
+
expected: state,
|
|
3218
|
+
actual: response.state,
|
|
3219
|
+
});
|
|
3220
|
+
const responseProject = remoteProjectSummaryFromState(response.state);
|
|
3221
|
+
const publishedProject = await applyRequestedProjectVisibility({
|
|
3222
|
+
baseUrl,
|
|
3223
|
+
projectId: responseProject.id,
|
|
3224
|
+
responseProject,
|
|
3225
|
+
visibility,
|
|
3226
|
+
});
|
|
3227
|
+
const applied = await acceptPushedProjectStateToLocal({
|
|
3228
|
+
dir,
|
|
3229
|
+
baseUrl,
|
|
3230
|
+
state: response.state,
|
|
3231
|
+
});
|
|
3232
|
+
writeOutput({
|
|
3233
|
+
ok: true,
|
|
3234
|
+
action: "replace",
|
|
3235
|
+
changed: true,
|
|
3236
|
+
benchmark: publishedProject,
|
|
3237
|
+
visibility: visibility ?? publishedProject.visibility ?? "unchanged",
|
|
3238
|
+
origin: applied.origin,
|
|
3239
|
+
source: response.source,
|
|
3240
|
+
runtime: response.runtime.stats,
|
|
3241
|
+
urls: buildWorkbenchResourceUrls({
|
|
3242
|
+
baseUrl,
|
|
3243
|
+
projectId: publishedProject.id ?? responseProject.id,
|
|
3244
|
+
...originRemoteUrlParts(applied.origin),
|
|
3245
|
+
}),
|
|
3246
|
+
}, parsed, io, (record) => {
|
|
3247
|
+
const value = record;
|
|
3248
|
+
return [
|
|
3249
|
+
`Replaced ${value.origin.remote} (${value.origin.projectId}).`,
|
|
3250
|
+
`Open benchmark: ${value.urls.benchmark}`,
|
|
3251
|
+
].join("\n");
|
|
3252
|
+
});
|
|
3125
3253
|
return 0;
|
|
3126
3254
|
}
|
|
3255
|
+
const state = localProjectState({
|
|
3256
|
+
source,
|
|
3257
|
+
runtime,
|
|
3258
|
+
origin,
|
|
3259
|
+
visibility: createVisibility,
|
|
3260
|
+
});
|
|
3127
3261
|
const response = await apiRequest(projectApiPath(projectId, "/state"), {
|
|
3128
3262
|
method: "PUT",
|
|
3129
3263
|
body: state,
|
|
@@ -3163,18 +3297,62 @@ async function pushBenchmark(argv, io) {
|
|
|
3163
3297
|
});
|
|
3164
3298
|
return 0;
|
|
3165
3299
|
}
|
|
3166
|
-
async function
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
throw
|
|
3300
|
+
async function readOriginProjectIfPresent(args) {
|
|
3301
|
+
try {
|
|
3302
|
+
const response = await apiRequest(publicProjectApiPath(parseOriginRemote(args.origin)), {}, args.baseUrl);
|
|
3303
|
+
return response.benchmark;
|
|
3304
|
+
}
|
|
3305
|
+
catch (error) {
|
|
3306
|
+
if (error instanceof WorkbenchApiRequestError && error.status === 404) {
|
|
3307
|
+
return null;
|
|
3308
|
+
}
|
|
3309
|
+
throw error;
|
|
3176
3310
|
}
|
|
3177
|
-
|
|
3311
|
+
}
|
|
3312
|
+
async function assertForceCreateAllowed(args) {
|
|
3313
|
+
const target = parseOriginRemote(args.origin);
|
|
3314
|
+
if (args.sourceName !== target.project) {
|
|
3315
|
+
throw new UsageError(`Local benchmark name ${args.sourceName} does not match force push target ${args.origin.remote}.`);
|
|
3316
|
+
}
|
|
3317
|
+
const expectedOwner = target.owner;
|
|
3318
|
+
const profileStatus = await readWorkbenchProfileStatus(await loadConfig(), args.baseUrl);
|
|
3319
|
+
const actualOwner = profileStatus.profile?.username ?? null;
|
|
3320
|
+
if (!profileStatus.authenticated || actualOwner !== expectedOwner) {
|
|
3321
|
+
throw new WorkbenchApiRequestError(404, `Workbench benchmark not found or not writable: ${args.origin.remote}`, "");
|
|
3322
|
+
}
|
|
3323
|
+
}
|
|
3324
|
+
function assertAcceptedForceReplacement(args) {
|
|
3325
|
+
const expectedSourceFingerprint = args.expected.source.fingerprint ??
|
|
3326
|
+
workbenchProjectSourceFingerprint(args.expected.source);
|
|
3327
|
+
const actualSourceFingerprint = args.actual.source.fingerprint ??
|
|
3328
|
+
workbenchProjectSourceFingerprint(args.actual.source);
|
|
3329
|
+
if (actualSourceFingerprint !== expectedSourceFingerprint) {
|
|
3330
|
+
throw new Error(`Workbench force push did not replace remote source. Expected ${expectedSourceFingerprint}, received ${actualSourceFingerprint}.`);
|
|
3331
|
+
}
|
|
3332
|
+
const expectedRuntime = runtimeReplacementSignature(args.expected.runtime);
|
|
3333
|
+
const actualRuntime = runtimeReplacementSignature(args.actual.runtime);
|
|
3334
|
+
if (JSON.stringify(actualRuntime) !== JSON.stringify(expectedRuntime)) {
|
|
3335
|
+
throw new Error(`Workbench force push did not replace remote runtime. Remote returned different record identity.`);
|
|
3336
|
+
}
|
|
3337
|
+
}
|
|
3338
|
+
function runtimeReplacementSignature(runtime) {
|
|
3339
|
+
return {
|
|
3340
|
+
activeId: runtime.activeId ?? null,
|
|
3341
|
+
candidates: runtime.candidates
|
|
3342
|
+
.map(workbenchRuntimeCandidateIdentityForExchange)
|
|
3343
|
+
.sort((left, right) => left.id.localeCompare(right.id)),
|
|
3344
|
+
candidateFiles: runtimeFileGroupSignature(runtime.candidateFiles, (group) => group.candidateId),
|
|
3345
|
+
evaluations: runtime.evaluations.map((evaluation) => evaluation.id).sort(),
|
|
3346
|
+
runs: runtime.runs.map((run) => run.id).sort(),
|
|
3347
|
+
jobs: runtime.jobs.map((job) => job.id).sort(),
|
|
3348
|
+
executionFiles: runtimeFileGroupSignature(runtime.executionFiles, (group) => group.jobId),
|
|
3349
|
+
events: runtime.events.map((event) => event.id).sort(),
|
|
3350
|
+
};
|
|
3351
|
+
}
|
|
3352
|
+
function runtimeFileGroupSignature(groups, idForGroup) {
|
|
3353
|
+
return groups
|
|
3354
|
+
.map((group) => `${idForGroup(group)}:${group.files.map((file) => file.path).sort().join("\n")}`)
|
|
3355
|
+
.sort();
|
|
3178
3356
|
}
|
|
3179
3357
|
function remoteProjectSummaryForOutput(project) {
|
|
3180
3358
|
return {
|
|
@@ -3951,7 +4129,7 @@ function buildWorkbenchResourceUrls(target, refs = {}) {
|
|
|
3951
4129
|
? evaluationScorecardId(refs.runId, refs.candidateId)
|
|
3952
4130
|
: null;
|
|
3953
4131
|
urls.candidateEvaluation = evaluationId
|
|
3954
|
-
? `${benchmark}/
|
|
4132
|
+
? `${benchmark}/evaluations/${encodeURIComponent(evaluationId)}`
|
|
3955
4133
|
: `${benchmark}/candidates/${encodeURIComponent(refs.candidateId)}`;
|
|
3956
4134
|
}
|
|
3957
4135
|
return urls;
|
|
@@ -4064,10 +4242,10 @@ function localProjectState(args) {
|
|
|
4064
4242
|
};
|
|
4065
4243
|
}
|
|
4066
4244
|
function projectStateRuntimeStats(state) {
|
|
4067
|
-
const activeId =
|
|
4245
|
+
const activeId = workbenchRuntimeProjectedActiveId({
|
|
4068
4246
|
candidates: state.runtime.candidates,
|
|
4247
|
+
evaluations: state.runtime.evaluations,
|
|
4069
4248
|
runs: state.runtime.runs,
|
|
4070
|
-
preferredActiveId: state.runtime.activeId ?? null,
|
|
4071
4249
|
benchmarkFingerprint: projectStateBenchmarkFingerprint(state.source),
|
|
4072
4250
|
});
|
|
4073
4251
|
return runtimeBundleStats({
|
|
@@ -4397,11 +4575,11 @@ function selectWorkbenchBaseUrl(input = {}) {
|
|
|
4397
4575
|
input.configBaseUrl ??
|
|
4398
4576
|
DEFAULT_BASE_URL);
|
|
4399
4577
|
}
|
|
4400
|
-
async function readWorkbenchProfileStatus(config) {
|
|
4578
|
+
async function readWorkbenchProfileStatus(config, baseUrlOverride) {
|
|
4401
4579
|
if (!config.accessToken) {
|
|
4402
4580
|
return { authenticated: false, profile: null };
|
|
4403
4581
|
}
|
|
4404
|
-
const baseUrl = selectWorkbenchBaseUrl({ configBaseUrl: config.baseUrl });
|
|
4582
|
+
const baseUrl = baseUrlOverride ?? selectWorkbenchBaseUrl({ configBaseUrl: config.baseUrl });
|
|
4405
4583
|
try {
|
|
4406
4584
|
const response = await fetch(`${baseUrl}/api/workbench/profile`, {
|
|
4407
4585
|
headers: {
|
|
@@ -4432,6 +4610,7 @@ async function apiRequest(apiPath, options = {}, baseUrlOverride) {
|
|
|
4432
4610
|
: selectWorkbenchBaseUrl({ configBaseUrl: config.baseUrl });
|
|
4433
4611
|
const method = options.method ?? "GET";
|
|
4434
4612
|
const canRetry = method === "GET";
|
|
4613
|
+
const requestBody = encodeJsonRequestBody(options.body);
|
|
4435
4614
|
let lastError = null;
|
|
4436
4615
|
for (let attempt = 1; attempt <= API_REQUEST_MAX_ATTEMPTS; attempt += 1) {
|
|
4437
4616
|
let response;
|
|
@@ -4439,12 +4618,12 @@ async function apiRequest(apiPath, options = {}, baseUrlOverride) {
|
|
|
4439
4618
|
response = await fetch(`${baseUrl}${apiPath}`, {
|
|
4440
4619
|
method,
|
|
4441
4620
|
headers: {
|
|
4442
|
-
|
|
4621
|
+
...requestBody.headers,
|
|
4443
4622
|
...(config.accessToken
|
|
4444
4623
|
? { authorization: `Bearer ${config.accessToken}` }
|
|
4445
4624
|
: {}),
|
|
4446
4625
|
},
|
|
4447
|
-
body:
|
|
4626
|
+
body: requestBody.body,
|
|
4448
4627
|
});
|
|
4449
4628
|
}
|
|
4450
4629
|
catch (error) {
|
|
@@ -4470,6 +4649,22 @@ async function apiRequest(apiPath, options = {}, baseUrlOverride) {
|
|
|
4470
4649
|
}
|
|
4471
4650
|
throw lastError instanceof Error ? lastError : new Error(String(lastError ?? "Workbench API request failed."));
|
|
4472
4651
|
}
|
|
4652
|
+
function encodeJsonRequestBody(body) {
|
|
4653
|
+
if (body == null) {
|
|
4654
|
+
return { headers: { "content-type": "application/json" } };
|
|
4655
|
+
}
|
|
4656
|
+
const text = JSON.stringify(body);
|
|
4657
|
+
if (Buffer.byteLength(text) < API_REQUEST_GZIP_THRESHOLD_BYTES) {
|
|
4658
|
+
return { body: text, headers: { "content-type": "application/json" } };
|
|
4659
|
+
}
|
|
4660
|
+
return {
|
|
4661
|
+
body: gzipSync(text),
|
|
4662
|
+
headers: {
|
|
4663
|
+
"content-encoding": "gzip",
|
|
4664
|
+
"content-type": "application/json",
|
|
4665
|
+
},
|
|
4666
|
+
};
|
|
4667
|
+
}
|
|
4473
4668
|
function apiRequestRetryDelayMs(attempt) {
|
|
4474
4669
|
return 250 * attempt;
|
|
4475
4670
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-archive.d.ts","sourceRoot":"","sources":["../src/local-archive.ts"],"names":[],"mappings":"AAGA,OAAO,EAiBL,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,EACjB,OAAO,GAAE;IAAE,2BAA2B,CAAC,EAAE,MAAM,CAAA;CAAO,GACrD,OAAO,CAAC,sBAAsB,CAAC,
|
|
1
|
+
{"version":3,"file":"local-archive.d.ts","sourceRoot":"","sources":["../src/local-archive.ts"],"names":[],"mappings":"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"}
|
package/dist/local-archive.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { promises as fs } from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { buildWorkbenchTraceSessionsFromFiles, candidateRecordWithoutDerivedFields, compactWorkbenchRuntimeJobForExchange, mergeWorkbenchRuntimeCandidateForExchange, sanitizeWorkbenchRuntimeCandidateForExchange, sanitizeWorkbenchRuntimeJobForExchange, selectExecutionOutputFilesForInspection, isSurfaceSnapshotFile, jsonRecord, normalizeRelativePath, readSurfaceFiles,
|
|
3
|
+
import { buildWorkbenchTraceSessionsFromFiles, candidateRecordWithoutDerivedFields, compactWorkbenchRuntimeJobForExchange, mergeWorkbenchRuntimeCandidateForExchange, sanitizeWorkbenchRuntimeCandidateForExchange, sanitizeWorkbenchRuntimeJobForExchange, selectExecutionOutputFilesForInspection, isSurfaceSnapshotFile, jsonRecord, normalizeRelativePath, readSurfaceFiles, workbenchRuntimeBundleStats, workbenchRuntimeCandidateIdentityForExchange, workbenchRuntimeProjectedActiveId, workbenchSurfaceFilesEqualForExchange, writeSurfaceFiles, } 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) {
|
|
@@ -73,12 +73,17 @@ export async function saveLocalJobs(workspace, jobs) {
|
|
|
73
73
|
}
|
|
74
74
|
export async function exportLocalRuntimeBundle(workspace, options = {}) {
|
|
75
75
|
const snapshot = await loadLocalArchive(workspace);
|
|
76
|
-
const
|
|
76
|
+
const archivedJobs = await readLocalJobs(workspace);
|
|
77
|
+
const jobs = archivedJobs.map(compactWorkbenchRuntimeJobForExchange);
|
|
78
|
+
const executionFiles = (await Promise.all(archivedJobs.map(async (job) => ({
|
|
79
|
+
jobId: job.id,
|
|
80
|
+
files: await readLocalExecutionFiles(workspace, job.id),
|
|
81
|
+
})))).filter((group) => group.files.length > 0);
|
|
77
82
|
const activeId = options.currentBenchmarkFingerprint
|
|
78
|
-
?
|
|
83
|
+
? workbenchRuntimeProjectedActiveId({
|
|
79
84
|
candidates: snapshot.candidates,
|
|
85
|
+
evaluations: snapshot.evaluations,
|
|
80
86
|
runs: snapshot.runs,
|
|
81
|
-
preferredActiveId: snapshot.activeId,
|
|
82
87
|
benchmarkFingerprint: options.currentBenchmarkFingerprint,
|
|
83
88
|
})
|
|
84
89
|
: snapshot.activeId;
|
|
@@ -93,7 +98,7 @@ export async function exportLocalRuntimeBundle(workspace, options = {}) {
|
|
|
93
98
|
evaluations: snapshot.evaluations.map((evaluation) => ({ ...evaluation })),
|
|
94
99
|
runs: snapshot.runs.map((run) => ({ ...run })),
|
|
95
100
|
jobs,
|
|
96
|
-
executionFiles
|
|
101
|
+
executionFiles,
|
|
97
102
|
events: snapshot.events.map((event) => ({ ...event })),
|
|
98
103
|
};
|
|
99
104
|
}
|
|
@@ -163,10 +168,10 @@ export async function importLocalRuntimeBundle(workspace, bundle, currentBenchma
|
|
|
163
168
|
changed ||= didChange;
|
|
164
169
|
}, runtimeJobsEqualForExchange).sort((left, right) => (left.startedAt ?? left.createdAt).localeCompare(right.startedAt ?? right.createdAt) ||
|
|
165
170
|
left.id.localeCompare(right.id));
|
|
166
|
-
const activeId =
|
|
171
|
+
const activeId = workbenchRuntimeProjectedActiveId({
|
|
167
172
|
candidates,
|
|
173
|
+
evaluations,
|
|
168
174
|
runs,
|
|
169
|
-
preferredActiveId: bundle.activeId ?? null,
|
|
170
175
|
benchmarkFingerprint: currentBenchmarkFingerprint,
|
|
171
176
|
});
|
|
172
177
|
if (activeId !== snapshot.activeId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-inspection.d.ts","sourceRoot":"","sources":["../src/local-inspection.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"local-inspection.d.ts","sourceRoot":"","sources":["../src/local-inspection.ts"],"names":[],"mappings":"AAEA,OAAO,EAgBL,KAAK,mBAAmB,EAIzB,MAAM,8BAA8B,CAAC;AAetC,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,qBAAqB,CAAC;AAgB7B,MAAM,WAAW,+BAA+B;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACvD;AAED,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,+BAA+B,GACvC,mBAAmB,CA2DrB;AAkBD,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,MAAM,GAChB,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAiBnC"}
|