@workbench-ai/workbench-core 0.0.49 → 0.0.50

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.
@@ -0,0 +1,8 @@
1
+ import type { SurfaceSnapshotFile, WorkbenchCandidatePatch } from "@workbench-ai/workbench-contract";
2
+ export interface ApplyWorkbenchCandidatePatchInput {
3
+ baseFiles: readonly SurfaceSnapshotFile[];
4
+ patch: WorkbenchCandidatePatch;
5
+ edits: readonly string[];
6
+ }
7
+ export declare function applyWorkbenchCandidatePatch(input: ApplyWorkbenchCandidatePatchInput): SurfaceSnapshotFile[];
8
+ //# sourceMappingURL=candidate-patch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidate-patch.d.ts","sourceRoot":"","sources":["../src/candidate-patch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,kCAAkC,CAAC;AAE1C,MAAM,WAAW,iCAAiC;IAChD,SAAS,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC1C,KAAK,EAAE,uBAAuB,CAAC;IAC/B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,iCAAiC,GAAG,mBAAmB,EAAE,CAgD5G"}
@@ -1,24 +1,24 @@
1
- export function applyWorkbenchSubjectPatch(input) {
1
+ export function applyWorkbenchCandidatePatch(input) {
2
2
  const issues = [];
3
3
  const edits = input.edits.map(normalizeRelativePath).filter(Boolean);
4
4
  const patchPaths = new Set();
5
5
  for (const file of input.patch.files) {
6
6
  const filePath = normalizeRelativePath(file.path);
7
7
  if (!isSafeRelativePath(filePath)) {
8
- issues.push(`Subject patch contains unsafe path ${file.path}.`);
8
+ issues.push(`Candidate patch contains unsafe path ${file.path}.`);
9
9
  }
10
10
  if (!isAllowedEditPath(filePath, edits)) {
11
- issues.push(`Subject patch contains path outside optimizer edits: ${file.path}.`);
11
+ issues.push(`Candidate patch contains path outside improve edits: ${file.path}.`);
12
12
  }
13
13
  patchPaths.add(filePath);
14
14
  }
15
15
  for (const fileChange of input.patch.fileChanges) {
16
16
  const filePath = normalizeRelativePath(fileChange);
17
17
  if (!isSafeRelativePath(filePath)) {
18
- issues.push(`Subject patch fileChanges contains unsafe path ${fileChange}.`);
18
+ issues.push(`Candidate patch fileChanges contains unsafe path ${fileChange}.`);
19
19
  }
20
20
  if (!isAllowedEditPath(filePath, edits)) {
21
- issues.push(`Subject patch fileChanges contains path outside optimizer edits: ${fileChange}.`);
21
+ issues.push(`Candidate patch fileChanges contains path outside improve edits: ${fileChange}.`);
22
22
  }
23
23
  }
24
24
  if (issues.length > 0) {
@@ -1,10 +1,10 @@
1
- import type { SubjectCaseReview, HostedWorkbenchJob, HostedWorkbenchJobStatus, WorkbenchExecutionEventRole, WorkbenchExecutionSpec, WorkbenchExecutionTrace, WorkbenchExecutionEvidence, WorkbenchTraceSession } from "@workbench-ai/workbench-contract";
2
- export declare function buildSubjectCaseExecutionRefs(args: {
1
+ import type { CandidateCaseReview, HostedWorkbenchJob, HostedWorkbenchJobStatus, WorkbenchExecutionEventRole, WorkbenchExecutionSpec, WorkbenchExecutionTrace, WorkbenchExecutionEvidence, WorkbenchTraceSession } from "@workbench-ai/workbench-contract";
2
+ export declare function buildCandidateCaseExecutionRefs(args: {
3
3
  jobs: readonly HostedWorkbenchJob[];
4
- subjectId: string;
4
+ candidateId: string;
5
5
  caseId: string;
6
6
  sampleIndex?: number;
7
- }): SubjectCaseReview["executions"];
7
+ }): CandidateCaseReview["executions"];
8
8
  export declare function buildWorkbenchExecutionEvidence(args: {
9
9
  jobs: readonly HostedWorkbenchJob[];
10
10
  traceIdPrefix: string;
@@ -15,7 +15,7 @@ export declare function readWorkbenchExecutionPurpose(job: HostedWorkbenchJob):
15
15
  export declare function readWorkbenchExecutionId(job: HostedWorkbenchJob): string | null;
16
16
  export declare function readWorkbenchExecutionMetadataString(job: HostedWorkbenchJob, key: string): string | null;
17
17
  export declare function readWorkbenchExecutionMetadataNumber(job: HostedWorkbenchJob, key: string): number | null;
18
- export declare function isWorkbenchExecutionActive(execution: SubjectCaseReview["executions"][number]): boolean;
18
+ export declare function isWorkbenchExecutionActive(execution: CandidateCaseReview["executions"][number]): boolean;
19
19
  export declare function resolveWorkbenchJobGroupStatus(jobs: readonly {
20
20
  status: HostedWorkbenchJobStatus;
21
21
  }[]): HostedWorkbenchJobStatus;
@@ -1 +1 @@
1
- {"version":3,"file":"execution-evidence.d.ts","sourceRoot":"","sources":["../src/execution-evidence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EAExB,2BAA2B,EAC3B,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,EACtB,MAAM,kCAAkC,CAAC;AAI1C,wBAAgB,6BAA6B,CAAC,IAAI,EAAE;IAClD,IAAI,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAgElC;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE;IACpD,IAAI,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,CACX,GAAG,EAAE,kBAAkB,EACvB,IAAI,EAAE,2BAA2B,KAC9B,uBAAuB,CAAC;IAC7B,mBAAmB,CAAC,EAAE,CACpB,GAAG,EAAE,kBAAkB,EACvB,IAAI,EAAE,2BAA2B,KAC9B,qBAAqB,EAAE,CAAC;CAC9B,GAAG,0BAA0B,EAAE,CAgF/B;AAED,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,kBAAkB,GACtB,sBAAsB,CAAC,SAAS,CAAC,GAAG,IAAI,CAQ1C;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,GAAG,IAAI,CAG/E;AAED,wBAAgB,oCAAoC,CAClD,GAAG,EAAE,kBAAkB,EACvB,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,IAAI,CAGf;AAED,wBAAgB,oCAAoC,CAClD,GAAG,EAAE,kBAAkB,EACvB,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,IAAI,CAGf;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,GACjD,OAAO,CAET;AAED,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,SAAS;IAAE,MAAM,EAAE,wBAAwB,CAAA;CAAE,EAAE,GACpD,wBAAwB,CAc1B"}
1
+ {"version":3,"file":"execution-evidence.d.ts","sourceRoot":"","sources":["../src/execution-evidence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EAExB,2BAA2B,EAC3B,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,EACtB,MAAM,kCAAkC,CAAC;AAI1C,wBAAgB,+BAA+B,CAAC,IAAI,EAAE;IACpD,IAAI,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,mBAAmB,CAAC,YAAY,CAAC,CAgEpC;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE;IACpD,IAAI,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,CACX,GAAG,EAAE,kBAAkB,EACvB,IAAI,EAAE,2BAA2B,KAC9B,uBAAuB,CAAC;IAC7B,mBAAmB,CAAC,EAAE,CACpB,GAAG,EAAE,kBAAkB,EACvB,IAAI,EAAE,2BAA2B,KAC9B,qBAAqB,EAAE,CAAC;CAC9B,GAAG,0BAA0B,EAAE,CAgF/B;AAED,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,kBAAkB,GACtB,sBAAsB,CAAC,SAAS,CAAC,GAAG,IAAI,CAQ1C;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,GAAG,IAAI,CAG/E;AAED,wBAAgB,oCAAoC,CAClD,GAAG,EAAE,kBAAkB,EACvB,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,IAAI,CAGf;AAED,wBAAgB,oCAAoC,CAClD,GAAG,EAAE,kBAAkB,EACvB,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,IAAI,CAGf;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,mBAAmB,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,GACnD,OAAO,CAET;AAED,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,SAAS;IAAE,MAAM,EAAE,wBAAwB,CAAA;CAAE,EAAE,GACpD,wBAAwB,CAc1B"}
@@ -1,11 +1,11 @@
1
1
  import { mergeWorkbenchExecutionTracesByJob } from "./execution-traces.js";
2
- export function buildSubjectCaseExecutionRefs(args) {
2
+ export function buildCandidateCaseExecutionRefs(args) {
3
3
  const groups = new Map();
4
4
  for (const job of args.jobs) {
5
5
  const kind = readWorkbenchExecutionPurpose(job);
6
- const jobSubjectId = job.subjectId ?? readWorkbenchExecutionMetadataString(job, "subjectId");
6
+ const jobCandidateId = job.candidateId ?? readWorkbenchExecutionMetadataString(job, "candidateId");
7
7
  const jobCaseId = readWorkbenchExecutionMetadataString(job, "caseId");
8
- if (jobSubjectId === args.subjectId &&
8
+ if (jobCandidateId === args.candidateId &&
9
9
  kind === "attempt" &&
10
10
  caseReviewCaseIdsMatch(jobCaseId, args.caseId) &&
11
11
  caseReviewSampleIndicesMatch(readWorkbenchExecutionMetadataNumber(job, "sampleIndex"), args.sampleIndex)) {
@@ -53,7 +53,7 @@ export function buildSubjectCaseExecutionRefs(args) {
53
53
  ...optionalNumber("attemptIndex", readWorkbenchExecutionMetadataNumber(first, "attemptIndex")),
54
54
  }];
55
55
  })
56
- .sort(compareSubjectCaseExecutions);
56
+ .sort(compareCandidateCaseExecutions);
57
57
  return selectCurrentExecutionRun(executions);
58
58
  }
59
59
  export function buildWorkbenchExecutionEvidence(args) {
@@ -69,7 +69,7 @@ export function buildWorkbenchExecutionEvidence(args) {
69
69
  const key = [
70
70
  job.runId,
71
71
  purpose,
72
- job.subjectId ?? readWorkbenchExecutionMetadataString(job, "subjectId") ?? "",
72
+ job.candidateId ?? readWorkbenchExecutionMetadataString(job, "candidateId") ?? "",
73
73
  readWorkbenchExecutionMetadataString(job, "caseId") ?? "",
74
74
  readWorkbenchExecutionMetadataNumber(job, "sampleIndex") ?? "",
75
75
  readWorkbenchExecutionMetadataNumber(job, "attemptIndex") ?? "",
@@ -111,7 +111,7 @@ export function buildWorkbenchExecutionEvidence(args) {
111
111
  status: resolveWorkbenchJobGroupStatus(group),
112
112
  jobIds,
113
113
  executionIds,
114
- ...(first.subjectId ? { subjectId: first.subjectId } : {}),
114
+ ...(first.candidateId ? { candidateId: first.candidateId } : {}),
115
115
  ...optionalString("caseId", readWorkbenchExecutionMetadataString(first, "caseId")),
116
116
  ...optionalNumber("sampleIndex", readWorkbenchExecutionMetadataNumber(first, "sampleIndex")),
117
117
  ...optionalNumber("attemptIndex", readWorkbenchExecutionMetadataNumber(first, "attemptIndex")),
@@ -209,7 +209,7 @@ function selectCurrentExecutionRun(executions) {
209
209
  ? executions.filter((execution) => execution.runId === selectedRunId)
210
210
  : executions;
211
211
  }
212
- function compareSubjectCaseExecutions(left, right) {
212
+ function compareCandidateCaseExecutions(left, right) {
213
213
  return (executionKindOrder(left.kind) - executionKindOrder(right.kind) ||
214
214
  (left.sampleIndex ?? -1) - (right.sampleIndex ?? -1) ||
215
215
  readExecutionRecencyMs(right) - readExecutionRecencyMs(left));
@@ -244,7 +244,7 @@ function compareWorkbenchExecutionEvidence(left, right) {
244
244
  }
245
245
  function traceRoleForPurpose(purpose) {
246
246
  if (purpose === "improve") {
247
- return "optimizer";
247
+ return "improver";
248
248
  }
249
249
  return "engine";
250
250
  }
@@ -4,14 +4,14 @@ export interface CompileExecutionGraphInput {
4
4
  ownerUserId: string;
5
5
  projectId: string;
6
6
  runId: string;
7
- subjectId: string;
7
+ candidateId: string;
8
8
  attemptIndex: number;
9
9
  sampleIndex?: number;
10
10
  caseId?: string;
11
11
  engineCase?: GenericEngineCaseSpec;
12
12
  spec: GenericRunSpec;
13
13
  workflow?: "eval" | "improve";
14
- subjectRef?: string;
14
+ candidateRef?: string;
15
15
  caseRef?: string;
16
16
  environmentRef?: string;
17
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"execution-graph.d.ts","sourceRoot":"","sources":["../src/execution-graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,sBAAsB,EAEvB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAE3B,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,2BAA2B,EAAE,CAAC;IACrC,UAAU,EAAE,sBAAsB,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,sBAAsB,CAAC;IAClC,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,0BAA0B,GAAG,uBAAuB,CAoEzG"}
1
+ {"version":3,"file":"execution-graph.d.ts","sourceRoot":"","sources":["../src/execution-graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,sBAAsB,EAEvB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAE3B,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,2BAA2B,EAAE,CAAC;IACrC,UAAU,EAAE,sBAAsB,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,sBAAsB,CAAC;IAClC,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,0BAA0B,GAAG,uBAAuB,CAoEzG"}
@@ -3,7 +3,7 @@ export function compileWorkbenchExecutionGraph(input) {
3
3
  const workflow = input.workflow ?? "improve";
4
4
  const sampleIndex = input.sampleIndex ?? 0;
5
5
  const caseId = input.caseId ?? "current";
6
- const subjectRef = input.subjectRef ?? `workbench://benchmarks/${input.projectId}/subjects/${input.subjectId}`;
6
+ const candidateRef = input.candidateRef ?? `workbench://benchmarks/${input.projectId}/candidates/${input.candidateId}`;
7
7
  const caseRef = input.caseRef ?? `workbench://benchmarks/${input.projectId}/engine-cases/${caseId}`;
8
8
  if (!input.engineCase) {
9
9
  throw new Error("Execution graph compilation requires an engine case.");
@@ -15,41 +15,41 @@ export function compileWorkbenchExecutionGraph(input) {
15
15
  });
16
16
  const nodes = [];
17
17
  const executions = [];
18
- const optimizerExecutionId = executionId(input, "improve", "current", 0);
19
- const optimizerOutputRef = `execution://${optimizerExecutionId}/subject_patch`;
18
+ const improveExecutionId = executionId(input, "improve", "current", 0);
19
+ const improveOutputRef = `execution://${improveExecutionId}/candidate_patch`;
20
20
  const engineAdapter = input.spec.engineRun;
21
21
  if (workflow === "improve") {
22
- if (!input.spec.optimizer || !input.spec.improve) {
23
- throw new Error("Optimizer YAML is required for improve execution graphs.");
22
+ if (!input.spec.candidate.improve || !input.spec.improve) {
23
+ throw new Error("Candidate improve configuration is required for improve execution graphs.");
24
24
  }
25
25
  pushExecution(nodes, executions, createExecution({
26
26
  input,
27
27
  purpose: "improve",
28
28
  adapter: input.spec.improve,
29
29
  inputs: [
30
- inputRef("subject", subjectRef, "/workspace/input/subject", false),
30
+ inputRef("candidate", candidateRef, "/workspace", true),
31
31
  inputRef("traces", `workbench://benchmarks/${input.projectId}/runs/${input.runId}/traces`, "/workspace/input/traces", false),
32
32
  ],
33
- outputs: [outputContract("subject_patch", "workbench.subject_patch.v1")],
33
+ outputs: [outputContract("candidate_patch", "workbench.candidate_patch.v1")],
34
34
  metadata: {
35
35
  attemptIndex: input.attemptIndex,
36
36
  sampleIndex: 0,
37
37
  caseId: "current",
38
38
  benchmark: input.spec.benchmark.name,
39
- edits: input.spec.optimizer.edits,
39
+ edits: input.spec.candidate.improve.edits,
40
40
  },
41
41
  runtime: input.spec.environment,
42
- idOverride: optimizerExecutionId,
42
+ idOverride: improveExecutionId,
43
43
  }), []);
44
44
  }
45
- const runSubjectRef = workflow === "improve" ? optimizerOutputRef : subjectRef;
45
+ const runCandidateRef = workflow === "improve" ? improveOutputRef : candidateRef;
46
46
  const attemptExecutionId = executionId(input, "attempt", caseId, sampleIndex);
47
47
  pushExecution(nodes, executions, createExecution({
48
48
  input,
49
49
  purpose: "attempt",
50
50
  adapter: engineAdapter,
51
51
  inputs: [
52
- inputRef("subject", runSubjectRef, "/workspace/input/subject", false),
52
+ inputRef("candidate", runCandidateRef, "/workspace/input/candidate", false),
53
53
  inputRef("case", caseRef, "/workspace/input/case", false),
54
54
  ],
55
55
  outputs: [outputContract("result", "workbench.result.v1")],
@@ -62,7 +62,7 @@ export function compileWorkbenchExecutionGraph(input) {
62
62
  },
63
63
  runtime: executionConfig.environment,
64
64
  idOverride: attemptExecutionId,
65
- }), workflow === "improve" ? [optimizerExecutionId] : []);
65
+ }), workflow === "improve" ? [improveExecutionId] : []);
66
66
  return { nodes, executions };
67
67
  }
68
68
  function pushExecution(nodes, executions, execution, dependsOn) {
@@ -77,7 +77,7 @@ function createExecution(args) {
77
77
  id: args.idOverride ?? executionId(args.input, args.purpose, args.input.caseId ?? "current", args.input.sampleIndex ?? 0),
78
78
  projectId: args.input.projectId,
79
79
  runId: args.input.runId,
80
- subjectId: args.input.subjectId,
80
+ candidateId: args.input.candidateId,
81
81
  purpose: args.purpose,
82
82
  adapter: args.adapter,
83
83
  sandbox: args.input.environmentRef
@@ -19,10 +19,11 @@ export declare function planWorkbenchExecutionJobsForPurpose(args: {
19
19
  ownerUserId: string;
20
20
  projectId: string;
21
21
  runId: string;
22
- subjectId: string;
22
+ candidateId: string;
23
23
  attemptIndex: number;
24
24
  samples: number;
25
25
  caseIds?: readonly string[];
26
+ sampleIndexesByCase?: ReadonlyMap<string, readonly number[]>;
26
27
  spec: GenericRunSpec;
27
28
  workflow: WorkbenchRunWorkflow;
28
29
  purpose: WorkbenchExecutionSpec["purpose"];
@@ -39,7 +40,7 @@ export declare function engineCaseForCase(engineCases: readonly WorkbenchEngineC
39
40
  export declare function createWorkbenchExecutionJob(args: {
40
41
  projectId: string;
41
42
  runId: string;
42
- subjectId: string;
43
+ candidateId: string;
43
44
  execution: WorkbenchExecutionSpec;
44
45
  dependsOn: readonly string[];
45
46
  now: string;
@@ -47,18 +48,18 @@ export declare function createWorkbenchExecutionJob(args: {
47
48
  traceFiles?: readonly SurfaceSnapshotFile[];
48
49
  baseId?: string | null;
49
50
  }): HostedWorkbenchJob;
50
- export declare function createBaselineSubjectExecution(args: {
51
+ export declare function createBaselineCandidateExecution(args: {
51
52
  ownerUserId: string;
52
53
  projectId: string;
53
54
  runId: string;
54
- subjectId: string;
55
+ candidateId: string;
55
56
  attemptIndex: number;
56
57
  }): WorkbenchExecutionSpec;
57
- export declare function createBaselineSubjectJob(args: {
58
+ export declare function createBaselineCandidateJob(args: {
58
59
  ownerUserId: string;
59
60
  projectId: string;
60
61
  runId: string;
61
- subjectId: string;
62
+ candidateId: string;
62
63
  files: readonly SurfaceSnapshotFile[];
63
64
  now: string;
64
65
  baseId: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"execution-jobs.d.ts","sourceRoot":"","sources":["../src/execution-jobs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,IAAI,EACJ,mBAAmB,EACnB,sBAAsB,EACvB,MAAM,kCAAkC,CAAC;AAK1C,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACpB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,SAAS,CAAC;AAEtD,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,wBAAgB,4BAA4B,CAAC,IAAI,EAAE;IACjD,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,MAAM,CAMT;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE;IACjD,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,MAAM,GAAG,IAAI,CAchB;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAEvE;AAED,wBAAgB,oCAAoC,CAAC,IAAI,EAAE;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,OAAO,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC3C,WAAW,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC5C,UAAU,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qBAAqB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpD,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,GAAG,kBAAkB,EAAE,CA4CvB;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,SAAS,mBAAmB,EAAE,GAAG,MAAM,EAAE,CAEnF;AAED,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,SAAS,mBAAmB,EAAE,EAC3C,MAAM,EAAE,MAAM,GACb,mBAAmB,CAMrB;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,sBAAsB,CAAC;IAClC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC3C,UAAU,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC5C,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,GAAG,kBAAkB,CA0BrB;AAED,wBAAgB,8BAA8B,CAAC,IAAI,EAAE;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,sBAAsB,CAwCzB;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,IAAI,CAAC;CAChB,GAAG,kBAAkB,CA6CrB;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,kBAAkB,GAAG,sBAAsB,CAAC,SAAS,CAAC,GAAG,IAAI,CAO9G"}
1
+ {"version":3,"file":"execution-jobs.d.ts","sourceRoot":"","sources":["../src/execution-jobs.ts"],"names":[],"mappings":"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"}
@@ -36,12 +36,17 @@ export function planWorkbenchExecutionJobsForPurpose(args) {
36
36
  }
37
37
  for (const caseId of caseIds) {
38
38
  const engineCase = engineCaseForCase(engineCases, caseId);
39
- for (let sampleIndex = 0; sampleIndex < args.samples; sampleIndex += 1) {
39
+ const sampleIndexes = sampleIndexesForCase({
40
+ caseId,
41
+ samples: args.samples,
42
+ sampleIndexesByCase: args.sampleIndexesByCase,
43
+ });
44
+ for (const sampleIndex of sampleIndexes) {
40
45
  const graph = compileWorkbenchExecutionGraph({
41
46
  ownerUserId: args.ownerUserId,
42
47
  projectId: args.projectId,
43
48
  runId: args.runId,
44
- subjectId: args.subjectId,
49
+ candidateId: args.candidateId,
45
50
  attemptIndex: args.attemptIndex,
46
51
  sampleIndex,
47
52
  caseId,
@@ -57,7 +62,7 @@ export function planWorkbenchExecutionJobsForPurpose(args) {
57
62
  jobs.push(createWorkbenchExecutionJob({
58
63
  projectId: args.projectId,
59
64
  runId: args.runId,
60
- subjectId: args.subjectId,
65
+ candidateId: args.candidateId,
61
66
  execution: node.execution,
62
67
  dependsOn: node.dependsOn,
63
68
  now: args.now,
@@ -70,6 +75,16 @@ export function planWorkbenchExecutionJobsForPurpose(args) {
70
75
  }
71
76
  return jobs.filter((job, index) => jobs.findIndex((entry) => entry.id === job.id) === index);
72
77
  }
78
+ function sampleIndexesForCase(args) {
79
+ if (!args.sampleIndexesByCase) {
80
+ return Array.from({ length: args.samples }, (_, index) => index);
81
+ }
82
+ return [...new Set(args.sampleIndexesByCase.get(args.caseId) ?? [])]
83
+ .filter((sampleIndex) => Number.isSafeInteger(sampleIndex) &&
84
+ sampleIndex >= 0 &&
85
+ sampleIndex < args.samples)
86
+ .sort((left, right) => left - right);
87
+ }
73
88
  export function engineCaseIds(engineCases) {
74
89
  return [...new Set(engineCases.map((bundle) => bundle.id))].sort();
75
90
  }
@@ -88,7 +103,7 @@ export function createWorkbenchExecutionJob(args) {
88
103
  id: workbenchExecutionJobId(args.execution.id),
89
104
  projectId: args.projectId,
90
105
  runId: args.runId,
91
- subjectId: args.subjectId,
106
+ candidateId: args.candidateId,
92
107
  kind: "execute",
93
108
  status: "queued",
94
109
  attempt: 0,
@@ -97,7 +112,7 @@ export function createWorkbenchExecutionJob(args) {
97
112
  input: {
98
113
  execution: args.execution,
99
114
  dependsOn: args.dependsOn.map(workbenchExecutionJobId),
100
- subjectId: args.subjectId,
115
+ candidateId: args.candidateId,
101
116
  attemptIndex,
102
117
  sampleIndex,
103
118
  caseId,
@@ -107,12 +122,12 @@ export function createWorkbenchExecutionJob(args) {
107
122
  },
108
123
  };
109
124
  }
110
- export function createBaselineSubjectExecution(args) {
125
+ export function createBaselineCandidateExecution(args) {
111
126
  return {
112
127
  id: `exec_${args.runId.replace(/[^a-z0-9_]/giu, "_")}_attempt_${String(args.attemptIndex).padStart(3, "0")}_case_current_sample_000_improve`,
113
128
  projectId: args.projectId,
114
129
  runId: args.runId,
115
- subjectId: args.subjectId,
130
+ candidateId: args.candidateId,
116
131
  purpose: "improve",
117
132
  adapter: {
118
133
  use: "baseline",
@@ -120,12 +135,12 @@ export function createBaselineSubjectExecution(args) {
120
135
  },
121
136
  sandbox: {
122
137
  kind: "snapshot",
123
- ref: "workbench/baseline-subject",
138
+ ref: "workbench/baseline-candidate",
124
139
  },
125
140
  inputs: [],
126
141
  outputs: [{
127
- name: "subject_patch",
128
- schema: "workbench.subject_patch.v1",
142
+ name: "candidate_patch",
143
+ schema: "workbench.candidate_patch.v1",
129
144
  required: true,
130
145
  }],
131
146
  policy: {
@@ -148,12 +163,12 @@ export function createBaselineSubjectExecution(args) {
148
163
  },
149
164
  };
150
165
  }
151
- export function createBaselineSubjectJob(args) {
152
- const execution = createBaselineSubjectExecution({
166
+ export function createBaselineCandidateJob(args) {
167
+ const execution = createBaselineCandidateExecution({
153
168
  ownerUserId: args.ownerUserId,
154
169
  projectId: args.projectId,
155
170
  runId: args.runId,
156
- subjectId: args.subjectId,
171
+ candidateId: args.candidateId,
157
172
  attemptIndex: args.attemptIndex,
158
173
  });
159
174
  const files = args.files.map((file) => ({ ...file }));
@@ -161,7 +176,7 @@ export function createBaselineSubjectJob(args) {
161
176
  id: workbenchExecutionJobId(execution.id),
162
177
  projectId: args.projectId,
163
178
  runId: args.runId,
164
- subjectId: args.subjectId,
179
+ candidateId: args.candidateId,
165
180
  kind: "execute",
166
181
  status: "succeeded",
167
182
  attempt: 1,
@@ -172,7 +187,7 @@ export function createBaselineSubjectJob(args) {
172
187
  input: {
173
188
  execution,
174
189
  dependsOn: [],
175
- subjectId: args.subjectId,
190
+ candidateId: args.candidateId,
176
191
  attemptIndex: args.attemptIndex,
177
192
  baseline: true,
178
193
  },
@@ -180,10 +195,10 @@ export function createBaselineSubjectJob(args) {
180
195
  ok: true,
181
196
  executionId: execution.id,
182
197
  purpose: "improve",
183
- subjectId: args.subjectId,
198
+ candidateId: args.candidateId,
184
199
  attemptIndex: args.attemptIndex,
185
200
  baseId: args.baseId,
186
- subjectPatch: {
201
+ candidatePatch: {
187
202
  files,
188
203
  fileChanges: [],
189
204
  },
@@ -1,6 +1,6 @@
1
- import type { Json, WorkbenchSubjectPatch, WorkbenchExecutionSpec, WorkbenchResult } from "@workbench-ai/workbench-contract";
1
+ import type { Json, WorkbenchCandidatePatch, WorkbenchExecutionSpec, WorkbenchResult } from "@workbench-ai/workbench-contract";
2
2
  export interface WorkbenchExecutionOutputPayloads {
3
- subjectPatch?: WorkbenchSubjectPatch;
3
+ candidatePatch?: WorkbenchCandidatePatch;
4
4
  result?: WorkbenchResult;
5
5
  }
6
6
  export declare function validateWorkbenchExecutionOutputPayloads(execution: WorkbenchExecutionSpec, payloads: Record<string, Json>): WorkbenchExecutionOutputPayloads;
@@ -1 +1 @@
1
- {"version":3,"file":"execution-outputs.d.ts","sourceRoot":"","sources":["../src/execution-outputs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,IAAI,EAEJ,qBAAqB,EAErB,sBAAsB,EACtB,eAAe,EAChB,MAAM,kCAAkC,CAAC;AAI1C,MAAM,WAAW,gCAAgC;IAC/C,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED,wBAAgB,wCAAwC,CACtD,SAAS,EAAE,sBAAsB,EACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAC7B,gCAAgC,CAoClC;AAED,wBAAgB,wCAAwC,CAAC,SAAS,EAAE,sBAAsB,GAAG,MAAM,EAAE,CAkFpG;AAsBD,wBAAgB,iCAAiC,CAAC,SAAS,EAAE,sBAAsB,GAAG,IAAI,CAKzF"}
1
+ {"version":3,"file":"execution-outputs.d.ts","sourceRoot":"","sources":["../src/execution-outputs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,IAAI,EAEJ,uBAAuB,EAEvB,sBAAsB,EACtB,eAAe,EAChB,MAAM,kCAAkC,CAAC;AAI1C,MAAM,WAAW,gCAAgC;IAC/C,cAAc,CAAC,EAAE,uBAAuB,CAAC;IACzC,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED,wBAAgB,wCAAwC,CACtD,SAAS,EAAE,sBAAsB,EACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAC7B,gCAAgC,CAoClC;AAED,wBAAgB,wCAAwC,CAAC,SAAS,EAAE,sBAAsB,GAAG,MAAM,EAAE,CAuFpG;AAuCD,wBAAgB,iCAAiC,CAAC,SAAS,EAAE,sBAAsB,GAAG,IAAI,CAKzF"}
@@ -19,8 +19,8 @@ export function validateWorkbenchExecutionOutputPayloads(execution, payloads) {
19
19
  continue;
20
20
  }
21
21
  switch (contract.schema) {
22
- case "workbench.subject_patch.v1":
23
- validated.subjectPatch = normalizeSubjectPatch(payload, execution, contract, issues);
22
+ case "workbench.candidate_patch.v1":
23
+ validated.candidatePatch = normalizeCandidatePatch(payload, execution, contract, issues);
24
24
  break;
25
25
  case "workbench.result.v1":
26
26
  validated.result = normalizeResult(payload, execution, contract, issues);
@@ -68,7 +68,7 @@ export function collectWorkbenchExecutionIsolationIssues(execution) {
68
68
  if (!expectedInputs.has(input.name)) {
69
69
  issues.push(`Execution ${execution.id} declares unsupported input ${input.name} for purpose ${execution.purpose}.`);
70
70
  }
71
- const expectedMountPath = `/workspace/input/${input.name}`;
71
+ const expectedMountPath = expectedInputMountPath(execution.purpose, input.name);
72
72
  if (input.mountPath !== expectedMountPath) {
73
73
  issues.push(`Execution ${execution.id} input ${input.name} must mount at ${expectedMountPath}.`);
74
74
  }
@@ -76,8 +76,11 @@ export function collectWorkbenchExecutionIsolationIssues(execution) {
76
76
  issues.push(`Execution ${execution.id} declares duplicate mount path ${input.mountPath}.`);
77
77
  }
78
78
  mountPaths.add(input.mountPath);
79
- if (input.writable) {
80
- issues.push(`Execution ${execution.id} inputs must be read-only.`);
79
+ const expectedWritable = expectedInputWritable(execution.purpose, input.name);
80
+ if (input.writable !== expectedWritable) {
81
+ issues.push(expectedWritable
82
+ ? `Execution ${execution.id} input ${input.name} must be writable.`
83
+ : `Execution ${execution.id} input ${input.name} must be read-only.`);
81
84
  }
82
85
  }
83
86
  for (const expectedInput of expectedInputs) {
@@ -116,16 +119,25 @@ export function collectWorkbenchExecutionIsolationIssues(execution) {
116
119
  }
117
120
  function expectedInputsForPurpose(purpose) {
118
121
  if (purpose === "improve") {
119
- return new Set(["subject", "traces"]);
122
+ return new Set(["candidate", "traces"]);
120
123
  }
121
124
  if (purpose === "attempt") {
122
- return new Set(["subject", "case"]);
125
+ return new Set(["candidate", "case"]);
123
126
  }
124
127
  return new Set();
125
128
  }
129
+ function expectedInputMountPath(purpose, name) {
130
+ if (purpose === "improve" && name === "candidate") {
131
+ return "/workspace";
132
+ }
133
+ return `/workspace/input/${name}`;
134
+ }
135
+ function expectedInputWritable(purpose, name) {
136
+ return purpose === "improve" && name === "candidate";
137
+ }
126
138
  function expectedOutputForPurpose(purpose) {
127
139
  if (purpose === "improve") {
128
- return "subject_patch";
140
+ return "candidate_patch";
129
141
  }
130
142
  if (purpose === "attempt") {
131
143
  return "result";
@@ -140,24 +152,24 @@ export function assertWorkbenchExecutionIsolation(execution) {
140
152
  }
141
153
  function outputAllowedForPurpose(purpose, output) {
142
154
  if (purpose === "improve") {
143
- return output.schema === "workbench.subject_patch.v1";
155
+ return output.schema === "workbench.candidate_patch.v1";
144
156
  }
145
157
  if (purpose === "attempt") {
146
158
  return output.schema === "workbench.result.v1";
147
159
  }
148
160
  return false;
149
161
  }
150
- function normalizeSubjectPatch(value, execution, contract, issues) {
162
+ function normalizeCandidatePatch(value, execution, contract, issues) {
151
163
  const record = readRecord(value, contract.name, issues);
152
164
  const files = normalizeSnapshotFiles(record?.files, `${contract.name}.files`, issues);
153
165
  const fileChanges = normalizeStringArray(record?.fileChanges, `${contract.name}.fileChanges`, issues);
154
166
  const edits = normalizeMetadataStringArray(execution.metadata.edits);
155
167
  if (edits.length === 0) {
156
- issues.push(`Execution ${execution.id} subject patch validation requires metadata.edits.`);
168
+ issues.push(`Execution ${execution.id} candidate patch validation requires metadata.edits.`);
157
169
  }
158
170
  for (const file of files) {
159
171
  if (!isAllowedEditPath(file.path, edits)) {
160
- issues.push(`${contract.name}.files contains path outside optimizer edits: ${file.path}.`);
172
+ issues.push(`${contract.name}.files contains path outside improve edits: ${file.path}.`);
161
173
  }
162
174
  }
163
175
  for (const fileChange of fileChanges) {
@@ -165,7 +177,7 @@ function normalizeSubjectPatch(value, execution, contract, issues) {
165
177
  issues.push(`${contract.name}.fileChanges contains unsafe path ${fileChange}.`);
166
178
  }
167
179
  else if (!isAllowedEditPath(fileChange, edits)) {
168
- issues.push(`${contract.name}.fileChanges contains path outside optimizer edits: ${fileChange}.`);
180
+ issues.push(`${contract.name}.fileChanges contains path outside improve edits: ${fileChange}.`);
169
181
  }
170
182
  }
171
183
  return {
@@ -28,7 +28,7 @@ export interface WorkbenchExecutionRuntimeInput {
28
28
  runtimeControlOperation?: WorkbenchRuntimeControlOperationSequenceRequest;
29
29
  }
30
30
  export interface WorkbenchWorkloadStepCommand {
31
- kind: "optimizer" | "subject" | "engine";
31
+ kind: "improver" | "candidate" | "engine";
32
32
  label: string;
33
33
  operation: WorkbenchAdapterOperation;
34
34
  executor: WorkbenchAdapterOperationExecutor;
@@ -1 +1 @@
1
- {"version":3,"file":"execution-runtime-types.d.ts","sourceRoot":"","sources":["../src/execution-runtime-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iCAAiC,EACjC,kBAAkB,EAClB,IAAI,EACJ,mBAAmB,EACnB,0BAA0B,EAC3B,MAAM,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,gCAAgC,EACjC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EACV,0BAA0B,EAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,yBAAyB,EACzB,iCAAiC,EACjC,wBAAwB,EACxB,+CAA+C,EAChD,MAAM,kCAAkC,CAAC;AAE1C,MAAM,WAAW,8BAA8B;IAC7C,GAAG,EAAE,kBAAkB,CAAC;IACxB,IAAI,EAAE,cAAc,CAAC;IACrB,kBAAkB,CAAC,EAAE,IAAI,CAAC,iCAAiC,EAAE,IAAI,GAAG,UAAU,GAAG,YAAY,GAAG,MAAM,CAAC,CAAC;IACxG,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,SAAS,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC1C,kBAAkB,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACnD,WAAW,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC5C,YAAY,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC9C,UAAU,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC5C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mBAAmB,CAAC,EAAE,SAAS,0BAA0B,EAAE,CAAC;IAC5D,gBAAgB,CAAC,EAAE,SAAS,wBAAwB,EAAE,CAAC;IACvD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,IAAI,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE,gCAAgC,CAAC;IAC5C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uBAAuB,CAAC,EAAE,+CAA+C,CAAC;CAC3E;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,yBAAyB,CAAC;IACrC,QAAQ,EAAE,iCAAiC,CAAC;IAC5C,OAAO,CAAC,EAAE,0BAA0B,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB"}
1
+ {"version":3,"file":"execution-runtime-types.d.ts","sourceRoot":"","sources":["../src/execution-runtime-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iCAAiC,EACjC,kBAAkB,EAClB,IAAI,EACJ,mBAAmB,EACnB,0BAA0B,EAC3B,MAAM,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,gCAAgC,EACjC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EACV,0BAA0B,EAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,yBAAyB,EACzB,iCAAiC,EACjC,wBAAwB,EACxB,+CAA+C,EAChD,MAAM,kCAAkC,CAAC;AAE1C,MAAM,WAAW,8BAA8B;IAC7C,GAAG,EAAE,kBAAkB,CAAC;IACxB,IAAI,EAAE,cAAc,CAAC;IACrB,kBAAkB,CAAC,EAAE,IAAI,CAAC,iCAAiC,EAAE,IAAI,GAAG,UAAU,GAAG,YAAY,GAAG,MAAM,CAAC,CAAC;IACxG,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,SAAS,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC1C,kBAAkB,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACnD,WAAW,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC5C,YAAY,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC9C,UAAU,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC5C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mBAAmB,CAAC,EAAE,SAAS,0BAA0B,EAAE,CAAC;IAC5D,gBAAgB,CAAC,EAAE,SAAS,wBAAwB,EAAE,CAAC;IACvD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,IAAI,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE,gCAAgC,CAAC;IAC5C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uBAAuB,CAAC,EAAE,+CAA+C,CAAC;CAC3E;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,yBAAyB,CAAC;IACrC,QAAQ,EAAE,iCAAiC,CAAC;IAC5C,OAAO,CAAC,EAAE,0BAA0B,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB"}
@@ -140,10 +140,10 @@ export function readWorkbenchExecutionTraceFiles(files) {
140
140
  export function traceSessionLabel(filePath, role) {
141
141
  const innerPath = traceSessionInnerPath(filePath);
142
142
  if (innerPath === "runner/session") {
143
- return "Subject runner";
143
+ return "Candidate run";
144
144
  }
145
- if (innerPath === "optimizer/session") {
146
- return "Optimizer";
145
+ if (innerPath === "improver/session") {
146
+ return "Improver";
147
147
  }
148
148
  const parts = innerPath
149
149
  .split("/")
@@ -215,7 +215,7 @@ function traceFilePrefix(filePath, index) {
215
215
  return safe || `trace-${index + 1}`;
216
216
  }
217
217
  function traceFileDisplayOrder(filePath) {
218
- if (filePath.includes("/runner/") || filePath.includes("/optimizer/")) {
218
+ if (filePath.includes("/runner/") || filePath.includes("/improver/")) {
219
219
  return 0;
220
220
  }
221
221
  return 1;
@@ -224,8 +224,8 @@ function traceRoleForFilePath(filePath, purpose, fallbackRole) {
224
224
  if (filePath.includes("/runner/")) {
225
225
  return "runner";
226
226
  }
227
- if (filePath.includes("/optimizer/") || purpose === "improve") {
228
- return "optimizer";
227
+ if (filePath.includes("/improver/") || purpose === "improve") {
228
+ return "improver";
229
229
  }
230
230
  if (filePath.includes("/engine/")) {
231
231
  return "engine";
@@ -236,7 +236,7 @@ function traceSessionInnerPath(filePath) {
236
236
  const withoutTraceFile = filePath.replace(/\/trace\.json$/u, "");
237
237
  const markerIndexes = [
238
238
  withoutTraceFile.indexOf("/runner/"),
239
- withoutTraceFile.indexOf("/optimizer/"),
239
+ withoutTraceFile.indexOf("/improver/"),
240
240
  withoutTraceFile.indexOf("/engine/"),
241
241
  ].filter((index) => index >= 0);
242
242
  const firstMarker = Math.min(...markerIndexes);