@workbench-ai/workbench-protocol 0.0.43 → 0.0.44
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/adapter-definition.d.ts +46 -0
- package/dist/adapter-definition.d.ts.map +1 -0
- package/dist/adapter-definition.js +172 -0
- package/dist/adapter-manifest.d.ts +20 -6
- package/dist/adapter-manifest.d.ts.map +1 -1
- package/dist/adapter-manifest.js +149 -43
- package/dist/adapter-protocol.d.ts +47 -41
- package/dist/adapter-protocol.d.ts.map +1 -1
- package/dist/adapter-protocol.js +139 -125
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/task-source-result.d.ts +29 -0
- package/dist/task-source-result.d.ts.map +1 -0
- package/dist/task-source-result.js +160 -0
- package/package.json +2 -2
|
@@ -1,65 +1,71 @@
|
|
|
1
|
-
import type { Json, UsageSummary,
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
};
|
|
14
|
-
adapter: {
|
|
1
|
+
import type { Json, UsageSummary, WorkbenchScorecard, WorkbenchSubjectPatch } from "@workbench-ai/workbench-contract";
|
|
2
|
+
import { type WorkbenchTaskSourceResult } from "./task-source-result.ts";
|
|
3
|
+
import type { WorkbenchAdapterOperation } from "./adapter-manifest.ts";
|
|
4
|
+
export declare const WORKBENCH_ADAPTER_PROTOCOL = "workbench.adapter.v2";
|
|
5
|
+
export declare const WORKBENCH_ADAPTER_RESULT_PROTOCOL = "workbench.adapter-result.v1";
|
|
6
|
+
export declare const WORKBENCH_ADAPTER_RESULT_FILE = "workbench-result.json";
|
|
7
|
+
export interface WorkbenchAdapterOperationRequest {
|
|
8
|
+
protocol: typeof WORKBENCH_ADAPTER_PROTOCOL;
|
|
9
|
+
id: string;
|
|
10
|
+
jobId?: string;
|
|
11
|
+
operation: WorkbenchAdapterOperation;
|
|
12
|
+
invocation: {
|
|
15
13
|
use: string;
|
|
16
14
|
with?: Json;
|
|
17
15
|
auth?: Json;
|
|
18
16
|
};
|
|
19
17
|
auth?: Json;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
18
|
+
context?: {
|
|
19
|
+
benchmark?: {
|
|
20
|
+
name?: string;
|
|
21
|
+
description?: string;
|
|
22
|
+
};
|
|
23
|
+
subject?: {
|
|
24
|
+
id?: string;
|
|
25
|
+
path?: string;
|
|
26
|
+
};
|
|
27
|
+
optimizer?: {
|
|
28
|
+
edits?: string[];
|
|
29
|
+
};
|
|
30
|
+
trial?: {
|
|
31
|
+
trialIndex?: number;
|
|
32
|
+
sampleIndex?: number;
|
|
33
|
+
caseId?: string;
|
|
34
|
+
};
|
|
35
|
+
task?: {
|
|
36
|
+
text?: string;
|
|
37
|
+
};
|
|
29
38
|
};
|
|
30
|
-
task?: {
|
|
31
|
-
text?: string;
|
|
32
|
-
};
|
|
33
|
-
expectedOutputs?: Array<{
|
|
34
|
-
name?: string;
|
|
35
|
-
path?: string;
|
|
36
|
-
}>;
|
|
37
39
|
paths: {
|
|
38
40
|
workspace: string;
|
|
39
|
-
input?: string;
|
|
40
41
|
output: string;
|
|
41
|
-
|
|
42
|
+
result: string;
|
|
43
|
+
input?: string;
|
|
42
44
|
task?: string;
|
|
43
|
-
runnerOutput?: string;
|
|
44
45
|
traces?: string;
|
|
45
46
|
cwd?: string;
|
|
46
47
|
subject?: string;
|
|
47
48
|
tests?: string;
|
|
48
49
|
logs?: string;
|
|
49
50
|
artifacts?: string;
|
|
50
|
-
scorecard?: string;
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
|
-
export
|
|
53
|
+
export type WorkbenchAdapterOperationResultValue = WorkbenchTaskSourceResult | WorkbenchScorecard | WorkbenchSubjectPatch | Json | null;
|
|
54
|
+
export interface WorkbenchAdapterOperationResult<TValue extends WorkbenchAdapterOperationResultValue = WorkbenchAdapterOperationResultValue> {
|
|
55
|
+
protocol: typeof WORKBENCH_ADAPTER_RESULT_PROTOCOL;
|
|
56
|
+
operation: WorkbenchAdapterOperation;
|
|
54
57
|
ok?: boolean;
|
|
58
|
+
value?: TValue;
|
|
55
59
|
summary?: string;
|
|
56
60
|
feedback?: Json;
|
|
57
61
|
usage?: UsageSummary;
|
|
58
62
|
}
|
|
59
|
-
export declare function
|
|
60
|
-
export declare function
|
|
61
|
-
export declare function ensureWorkbenchAdapterOutputDir(request:
|
|
62
|
-
export declare function
|
|
63
|
-
export declare function
|
|
64
|
-
export declare function
|
|
63
|
+
export declare function readWorkbenchAdapterOperationRequest(configuredPath?: string): Promise<WorkbenchAdapterOperationRequest>;
|
|
64
|
+
export declare function normalizeWorkbenchAdapterOperationRequest(value: unknown): WorkbenchAdapterOperationRequest;
|
|
65
|
+
export declare function ensureWorkbenchAdapterOutputDir(request: WorkbenchAdapterOperationRequest): Promise<void>;
|
|
66
|
+
export declare function workbenchAdapterOperationResultPath(outputRoot: string): string;
|
|
67
|
+
export declare function writeWorkbenchAdapterOperationResult<TValue extends WorkbenchAdapterOperationResultValue>(outputRoot: string, result: WorkbenchAdapterOperationResult<TValue>): Promise<void>;
|
|
68
|
+
export declare function readWorkbenchAdapterOperationResult(outputRoot: string, operation?: WorkbenchAdapterOperation): Promise<WorkbenchAdapterOperationResult>;
|
|
69
|
+
export declare function normalizeWorkbenchAdapterOperationResult(value: unknown, operation?: WorkbenchAdapterOperation): WorkbenchAdapterOperationResult;
|
|
70
|
+
export declare function assertWorkbenchAdapterOperationResultOk(result: WorkbenchAdapterOperationResult, label?: string): void;
|
|
65
71
|
//# sourceMappingURL=adapter-protocol.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter-protocol.d.ts","sourceRoot":"","sources":["../src/adapter-protocol.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,IAAI,EACJ,YAAY,EACZ,
|
|
1
|
+
{"version":3,"file":"adapter-protocol.d.ts","sourceRoot":"","sources":["../src/adapter-protocol.ts"],"names":[],"mappings":"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"}
|
package/dist/adapter-protocol.js
CHANGED
|
@@ -1,145 +1,211 @@
|
|
|
1
1
|
import { promises as fs } from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
|
|
3
|
+
import { normalizeWorkbenchTaskSourceResult, } from "./task-source-result.js";
|
|
4
|
+
export const WORKBENCH_ADAPTER_PROTOCOL = "workbench.adapter.v2";
|
|
5
|
+
export const WORKBENCH_ADAPTER_RESULT_PROTOCOL = "workbench.adapter-result.v1";
|
|
6
|
+
export const WORKBENCH_ADAPTER_RESULT_FILE = "workbench-result.json";
|
|
7
|
+
export async function readWorkbenchAdapterOperationRequest(configuredPath) {
|
|
4
8
|
const requestPath = configuredPath ?? process.env.WORKBENCH_ADAPTER_REQUEST;
|
|
5
9
|
if (!requestPath) {
|
|
6
10
|
throw new Error("WORKBENCH_ADAPTER_REQUEST is required.");
|
|
7
11
|
}
|
|
8
12
|
const parsed = JSON.parse(await fs.readFile(requestPath, "utf8"));
|
|
9
|
-
return
|
|
13
|
+
return normalizeWorkbenchAdapterOperationRequest(parsed);
|
|
10
14
|
}
|
|
11
|
-
export function
|
|
15
|
+
export function normalizeWorkbenchAdapterOperationRequest(value) {
|
|
12
16
|
const record = requiredJsonRecord(value, "adapter request");
|
|
13
|
-
if (record.protocol !==
|
|
14
|
-
throw new Error(
|
|
17
|
+
if (record.protocol !== WORKBENCH_ADAPTER_PROTOCOL) {
|
|
18
|
+
throw new Error(`Adapter request protocol must be ${WORKBENCH_ADAPTER_PROTOCOL}.`);
|
|
15
19
|
}
|
|
16
|
-
const
|
|
17
|
-
const adapter = requiredJsonRecord(record.adapter, "adapter request adapter");
|
|
20
|
+
const invocation = requiredJsonRecord(record.invocation, "adapter request invocation");
|
|
18
21
|
const paths = requiredJsonRecord(record.paths, "adapter request paths");
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const use = requiredString(adapter.use, "adapter request adapter.use");
|
|
22
|
+
const operation = requiredOperation(record.operation, "adapter request operation");
|
|
23
|
+
const use = requiredString(invocation.use, "adapter request invocation.use");
|
|
22
24
|
return {
|
|
23
|
-
protocol:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
role,
|
|
29
|
-
...(typeof execution.candidateId === "string" ? { candidateId: execution.candidateId } : {}),
|
|
30
|
-
...(typeof execution.trialIndex === "number" ? { trialIndex: execution.trialIndex } : {}),
|
|
31
|
-
...(typeof execution.sampleIndex === "number" ? { sampleIndex: execution.sampleIndex } : {}),
|
|
32
|
-
...(typeof execution.caseId === "string" ? { caseId: execution.caseId } : {}),
|
|
33
|
-
},
|
|
34
|
-
adapter: {
|
|
25
|
+
protocol: WORKBENCH_ADAPTER_PROTOCOL,
|
|
26
|
+
id: requiredString(record.id, "adapter request id"),
|
|
27
|
+
...(typeof record.jobId === "string" ? { jobId: record.jobId } : {}),
|
|
28
|
+
operation,
|
|
29
|
+
invocation: {
|
|
35
30
|
use,
|
|
36
|
-
with:
|
|
37
|
-
...(
|
|
31
|
+
with: invocation.with !== undefined ? invocation.with : {},
|
|
32
|
+
...(invocation.auth !== undefined ? { auth: invocation.auth } : {}),
|
|
38
33
|
},
|
|
39
34
|
...(record.auth !== undefined ? { auth: record.auth } : {}),
|
|
40
|
-
...(record.
|
|
41
|
-
...(record.candidate !== undefined ? { candidate: normalizeAdapterCommandCandidate(record.candidate) } : {}),
|
|
42
|
-
...(record.optimizer !== undefined ? { optimizer: normalizeAdapterCommandOptimizer(record.optimizer) } : {}),
|
|
43
|
-
...(record.task !== undefined ? { task: normalizeAdapterCommandTask(record.task) } : {}),
|
|
44
|
-
...(Array.isArray(record.expectedOutputs)
|
|
45
|
-
? { expectedOutputs: normalizeAdapterCommandExpectedOutputs(record.expectedOutputs) }
|
|
46
|
-
: {}),
|
|
35
|
+
...(record.context !== undefined ? { context: normalizeAdapterRequestContext(record.context) } : {}),
|
|
47
36
|
paths: {
|
|
48
37
|
workspace: requiredString(paths.workspace, "adapter request paths.workspace"),
|
|
49
38
|
output: requiredString(paths.output, "adapter request paths.output"),
|
|
39
|
+
result: requiredString(paths.result, "adapter request paths.result"),
|
|
50
40
|
...(typeof paths.input === "string" ? { input: paths.input } : {}),
|
|
51
|
-
...(typeof paths.candidate === "string" ? { candidate: paths.candidate } : {}),
|
|
52
41
|
...(typeof paths.task === "string" ? { task: paths.task } : {}),
|
|
53
|
-
...(typeof paths.runnerOutput === "string" ? { runnerOutput: paths.runnerOutput } : {}),
|
|
54
42
|
...(typeof paths.traces === "string" ? { traces: paths.traces } : {}),
|
|
55
43
|
...(typeof paths.cwd === "string" ? { cwd: paths.cwd } : {}),
|
|
56
44
|
...(typeof paths.subject === "string" ? { subject: paths.subject } : {}),
|
|
57
45
|
...(typeof paths.tests === "string" ? { tests: paths.tests } : {}),
|
|
58
46
|
...(typeof paths.logs === "string" ? { logs: paths.logs } : {}),
|
|
59
47
|
...(typeof paths.artifacts === "string" ? { artifacts: paths.artifacts } : {}),
|
|
60
|
-
...(typeof paths.scorecard === "string" ? { scorecard: paths.scorecard } : {}),
|
|
61
48
|
},
|
|
62
49
|
};
|
|
63
50
|
}
|
|
64
51
|
export async function ensureWorkbenchAdapterOutputDir(request) {
|
|
65
52
|
await fs.mkdir(request.paths.output, { recursive: true });
|
|
66
53
|
}
|
|
67
|
-
export function
|
|
68
|
-
return path.join(outputRoot,
|
|
54
|
+
export function workbenchAdapterOperationResultPath(outputRoot) {
|
|
55
|
+
return path.join(outputRoot, WORKBENCH_ADAPTER_RESULT_FILE);
|
|
69
56
|
}
|
|
70
|
-
export async function
|
|
71
|
-
const
|
|
57
|
+
export async function writeWorkbenchAdapterOperationResult(outputRoot, result) {
|
|
58
|
+
const normalized = normalizeWorkbenchAdapterOperationResult(result);
|
|
59
|
+
const resultPath = workbenchAdapterOperationResultPath(outputRoot);
|
|
72
60
|
await fs.mkdir(path.dirname(resultPath), { recursive: true });
|
|
73
|
-
await fs.writeFile(resultPath, `${JSON.stringify(
|
|
74
|
-
}
|
|
75
|
-
export async function
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
61
|
+
await fs.writeFile(resultPath, `${JSON.stringify(normalized, null, 2)}\n`);
|
|
62
|
+
}
|
|
63
|
+
export async function readWorkbenchAdapterOperationResult(outputRoot, operation) {
|
|
64
|
+
const parsed = JSON.parse(await fs.readFile(workbenchAdapterOperationResultPath(outputRoot), "utf8"));
|
|
65
|
+
return normalizeWorkbenchAdapterOperationResult(parsed, operation);
|
|
66
|
+
}
|
|
67
|
+
export function normalizeWorkbenchAdapterOperationResult(value, operation) {
|
|
68
|
+
const record = requiredJsonRecord(value, WORKBENCH_ADAPTER_RESULT_FILE);
|
|
69
|
+
if (record.protocol !== WORKBENCH_ADAPTER_RESULT_PROTOCOL) {
|
|
70
|
+
throw new Error(`${WORKBENCH_ADAPTER_RESULT_FILE}.protocol must be ${WORKBENCH_ADAPTER_RESULT_PROTOCOL}.`);
|
|
71
|
+
}
|
|
72
|
+
const resultOperation = requiredOperation(record.operation, `${WORKBENCH_ADAPTER_RESULT_FILE}.operation`);
|
|
73
|
+
if (operation && resultOperation !== operation) {
|
|
74
|
+
throw new Error(`${WORKBENCH_ADAPTER_RESULT_FILE}.operation must be ${operation}.`);
|
|
84
75
|
}
|
|
85
|
-
const parsed = JSON.parse(source);
|
|
86
|
-
const record = jsonRecord(parsed);
|
|
87
76
|
return {
|
|
77
|
+
protocol: WORKBENCH_ADAPTER_RESULT_PROTOCOL,
|
|
78
|
+
operation: resultOperation,
|
|
88
79
|
...(record.ok === true || record.ok === false ? { ok: record.ok } : {}),
|
|
80
|
+
...(record.value !== undefined
|
|
81
|
+
? { value: normalizeOperationResultValue(resultOperation, record.value) }
|
|
82
|
+
: {}),
|
|
89
83
|
...(typeof record.summary === "string" ? { summary: record.summary } : {}),
|
|
90
84
|
...(record.feedback !== undefined ? { feedback: record.feedback } : {}),
|
|
91
85
|
...(record.usage !== undefined ? { usage: normalizeUsageSummary(record.usage) } : {}),
|
|
92
86
|
};
|
|
93
87
|
}
|
|
94
|
-
function
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
88
|
+
export function assertWorkbenchAdapterOperationResultOk(result, label = "Adapter operation") {
|
|
89
|
+
if (result.ok !== false) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
throw new Error(`${label} returned ok false${result.summary ? `: ${result.summary}` : "."}`);
|
|
93
|
+
}
|
|
94
|
+
function normalizeOperationResultValue(operation, value) {
|
|
95
|
+
if (operation === "tasks.resolve") {
|
|
96
|
+
return normalizeWorkbenchTaskSourceResult(value);
|
|
97
|
+
}
|
|
98
|
+
if (operation === "trial.score") {
|
|
99
|
+
return normalizeScorecard(value, `${WORKBENCH_ADAPTER_RESULT_FILE}.value`);
|
|
100
|
+
}
|
|
101
|
+
if (operation === "subject.improve") {
|
|
102
|
+
return normalizeSubjectPatch(value, `${WORKBENCH_ADAPTER_RESULT_FILE}.value`);
|
|
103
|
+
}
|
|
104
|
+
if (value === undefined || value === null) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
return value;
|
|
108
|
+
}
|
|
109
|
+
function normalizeAdapterRequestContext(value) {
|
|
110
|
+
const record = requiredJsonRecord(value, "adapter request context");
|
|
111
|
+
return {
|
|
112
|
+
...(record.benchmark !== undefined ? { benchmark: normalizeBenchmarkContext(record.benchmark) } : {}),
|
|
113
|
+
...(record.subject !== undefined ? { subject: normalizeSubjectContext(record.subject) } : {}),
|
|
114
|
+
...(record.optimizer !== undefined ? { optimizer: normalizeOptimizerContext(record.optimizer) } : {}),
|
|
115
|
+
...(record.trial !== undefined ? { trial: normalizeTrialContext(record.trial) } : {}),
|
|
116
|
+
...(record.task !== undefined ? { task: normalizeTaskContext(record.task) } : {}),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function normalizeBenchmarkContext(value) {
|
|
120
|
+
const record = requiredJsonRecord(value, "adapter request context.benchmark");
|
|
107
121
|
return {
|
|
108
122
|
...(typeof record.name === "string" ? { name: record.name } : {}),
|
|
109
123
|
...(typeof record.description === "string" ? { description: record.description } : {}),
|
|
110
124
|
};
|
|
111
125
|
}
|
|
112
|
-
function
|
|
113
|
-
const record = requiredJsonRecord(value, "adapter request
|
|
126
|
+
function normalizeSubjectContext(value) {
|
|
127
|
+
const record = requiredJsonRecord(value, "adapter request context.subject");
|
|
114
128
|
return {
|
|
129
|
+
...(typeof record.id === "string" ? { id: record.id } : {}),
|
|
115
130
|
...(typeof record.path === "string" ? { path: record.path } : {}),
|
|
116
131
|
};
|
|
117
132
|
}
|
|
118
|
-
function
|
|
119
|
-
const record = requiredJsonRecord(value, "adapter request optimizer");
|
|
133
|
+
function normalizeOptimizerContext(value) {
|
|
134
|
+
const record = requiredJsonRecord(value, "adapter request context.optimizer");
|
|
120
135
|
return {
|
|
121
136
|
edits: Array.isArray(record.edits)
|
|
122
137
|
? record.edits.filter((entry) => typeof entry === "string")
|
|
123
138
|
: [],
|
|
124
139
|
};
|
|
125
140
|
}
|
|
126
|
-
function
|
|
127
|
-
const record = requiredJsonRecord(value, "adapter request
|
|
141
|
+
function normalizeTrialContext(value) {
|
|
142
|
+
const record = requiredJsonRecord(value, "adapter request context.trial");
|
|
143
|
+
return {
|
|
144
|
+
...(typeof record.trialIndex === "number" ? { trialIndex: record.trialIndex } : {}),
|
|
145
|
+
...(typeof record.sampleIndex === "number" ? { sampleIndex: record.sampleIndex } : {}),
|
|
146
|
+
...(typeof record.caseId === "string" ? { caseId: record.caseId } : {}),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function normalizeTaskContext(value) {
|
|
150
|
+
const record = requiredJsonRecord(value, "adapter request context.task");
|
|
128
151
|
return {
|
|
129
152
|
...(typeof record.text === "string" ? { text: record.text } : {}),
|
|
130
153
|
};
|
|
131
154
|
}
|
|
155
|
+
function normalizeScorecard(value, label) {
|
|
156
|
+
const record = requiredJsonRecord(value, label);
|
|
157
|
+
if (typeof record.score !== "number" || !Number.isFinite(record.score)) {
|
|
158
|
+
throw new Error(`${label}.score must be a finite number.`);
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
score: record.score,
|
|
162
|
+
...(isNumberRecord(record.metrics) ? { metrics: record.metrics } : {}),
|
|
163
|
+
...(Array.isArray(record.cases) ? { cases: record.cases } : {}),
|
|
164
|
+
...(record.usage !== undefined ? { usage: normalizeUsageSummary(record.usage) } : {}),
|
|
165
|
+
...(typeof record.summary === "string" ? { summary: record.summary } : {}),
|
|
166
|
+
...(record.feedback !== undefined ? { feedback: record.feedback } : {}),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function normalizeSubjectPatch(value, label) {
|
|
170
|
+
const record = requiredJsonRecord(value, label);
|
|
171
|
+
if (!Array.isArray(record.files)) {
|
|
172
|
+
throw new Error(`${label}.files must be an array.`);
|
|
173
|
+
}
|
|
174
|
+
if (!Array.isArray(record.fileChanges) || !record.fileChanges.every((entry) => typeof entry === "string")) {
|
|
175
|
+
throw new Error(`${label}.fileChanges must be a string array.`);
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
files: record.files,
|
|
179
|
+
fileChanges: [...record.fileChanges],
|
|
180
|
+
...(typeof record.summary === "string" ? { summary: record.summary } : {}),
|
|
181
|
+
...(record.feedback !== undefined ? { feedback: record.feedback } : {}),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function normalizeUsageSummary(value) {
|
|
185
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
186
|
+
? value
|
|
187
|
+
: {};
|
|
188
|
+
}
|
|
189
|
+
function isNumberRecord(value) {
|
|
190
|
+
return !!value &&
|
|
191
|
+
typeof value === "object" &&
|
|
192
|
+
!Array.isArray(value) &&
|
|
193
|
+
Object.values(value).every((entry) => typeof entry === "number" && Number.isFinite(entry));
|
|
194
|
+
}
|
|
132
195
|
function requiredJsonRecord(value, label) {
|
|
133
196
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
134
197
|
throw new Error(`${label} must be an object.`);
|
|
135
198
|
}
|
|
136
199
|
return value;
|
|
137
200
|
}
|
|
138
|
-
function
|
|
139
|
-
if (value === "
|
|
201
|
+
function requiredOperation(value, label) {
|
|
202
|
+
if (value === "tasks.resolve" ||
|
|
203
|
+
value === "subject.run" ||
|
|
204
|
+
value === "trial.score" ||
|
|
205
|
+
value === "subject.improve") {
|
|
140
206
|
return value;
|
|
141
207
|
}
|
|
142
|
-
throw new Error(`${label} must be
|
|
208
|
+
throw new Error(`${label} must be tasks.resolve, subject.run, trial.score, or subject.improve.`);
|
|
143
209
|
}
|
|
144
210
|
function requiredString(value, label) {
|
|
145
211
|
if (typeof value !== "string" || value.length === 0) {
|
|
@@ -147,55 +213,3 @@ function requiredString(value, label) {
|
|
|
147
213
|
}
|
|
148
214
|
return value;
|
|
149
215
|
}
|
|
150
|
-
function executionPurposeRole(purpose) {
|
|
151
|
-
if (purpose === "improve") {
|
|
152
|
-
return "optimizer";
|
|
153
|
-
}
|
|
154
|
-
if (purpose === "run-task") {
|
|
155
|
-
return "runner";
|
|
156
|
-
}
|
|
157
|
-
if (purpose === "trial") {
|
|
158
|
-
return "runner";
|
|
159
|
-
}
|
|
160
|
-
return "grader";
|
|
161
|
-
}
|
|
162
|
-
function normalizeExecutionRole(value, purpose) {
|
|
163
|
-
if (value === "optimizer" || value === "runner" || value === "grader") {
|
|
164
|
-
return value;
|
|
165
|
-
}
|
|
166
|
-
return executionPurposeRole(purpose);
|
|
167
|
-
}
|
|
168
|
-
function jsonRecord(value) {
|
|
169
|
-
return value && typeof value === "object" && !Array.isArray(value)
|
|
170
|
-
? value
|
|
171
|
-
: {};
|
|
172
|
-
}
|
|
173
|
-
function normalizeUsageSummary(value) {
|
|
174
|
-
const record = jsonRecord(value);
|
|
175
|
-
return {
|
|
176
|
-
...(record.total !== undefined ? { total: normalizeExecutionUsage(record.total) } : {}),
|
|
177
|
-
...(record.optimizer !== undefined ? { optimizer: normalizeExecutionUsage(record.optimizer) } : {}),
|
|
178
|
-
...(record.runner !== undefined ? { runner: normalizeExecutionUsage(record.runner) } : {}),
|
|
179
|
-
...(record.grader !== undefined ? { grader: normalizeExecutionUsage(record.grader) } : {}),
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
function normalizeExecutionUsage(value) {
|
|
183
|
-
const record = jsonRecord(value);
|
|
184
|
-
return {
|
|
185
|
-
...(typeof record.provider === "string" ? { provider: record.provider } : {}),
|
|
186
|
-
...(typeof record.model === "string" ? { model: record.model } : {}),
|
|
187
|
-
...(typeof record.inputTokens === "number" ? { inputTokens: record.inputTokens } : {}),
|
|
188
|
-
...(typeof record.uncachedInputTokens === "number" ? { uncachedInputTokens: record.uncachedInputTokens } : {}),
|
|
189
|
-
...(typeof record.cachedInputTokens === "number" ? { cachedInputTokens: record.cachedInputTokens } : {}),
|
|
190
|
-
...(typeof record.cacheCreationInputTokens === "number" ? { cacheCreationInputTokens: record.cacheCreationInputTokens } : {}),
|
|
191
|
-
...(typeof record.cacheReadInputTokens === "number" ? { cacheReadInputTokens: record.cacheReadInputTokens } : {}),
|
|
192
|
-
...(typeof record.outputTokens === "number" ? { outputTokens: record.outputTokens } : {}),
|
|
193
|
-
...(typeof record.reasoningOutputTokens === "number" ? { reasoningOutputTokens: record.reasoningOutputTokens } : {}),
|
|
194
|
-
...(typeof record.totalTokens === "number" ? { totalTokens: record.totalTokens } : {}),
|
|
195
|
-
...(typeof record.costUsd === "number" ? { costUsd: record.costUsd } : {}),
|
|
196
|
-
...(record.costSource === "provider" || record.costSource === "estimated" || record.costSource === "mixed"
|
|
197
|
-
? { costSource: record.costSource }
|
|
198
|
-
: {}),
|
|
199
|
-
...(typeof record.pricingSource === "string" ? { pricingSource: record.pricingSource } : {}),
|
|
200
|
-
};
|
|
201
|
-
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export { adapterCommandName, cloneWorkbenchAdapterManifest, collectWorkbenchAdapterAuthRequirements, collectWorkbenchAdapterInvocations, parseWorkbenchAdapterManifest, workbenchAdapterManifestRequiresAuth, withDefaultWorkbenchAdapterAuth, withDefaultWorkbenchAdapterAuthProfiles, type WorkbenchAdapterAuthEnvManifest, type WorkbenchAdapterAuthFileManifest, type WorkbenchAdapterAuthManifest, type WorkbenchAdapterAuthMethodManifest, type WorkbenchAdapterAuthRequirement, type WorkbenchAdapterInvocationLike, type WorkbenchAdapterManifest, } from "./adapter-manifest.ts";
|
|
2
|
-
export { ensureWorkbenchAdapterOutputDir,
|
|
1
|
+
export { adapterCommandName, assertWorkbenchAdapterOperationSupport, cloneWorkbenchAdapterManifest, collectWorkbenchAdapterAuthRequirements, collectWorkbenchAdapterInvocations, collectWorkbenchAdapterOperationIssues, collectWorkbenchAdapterOperationRequirements, parseWorkbenchAdapterManifest, workbenchAdapterManifestSupportsOperation, workbenchAdapterOperationCommand, workbenchAdapterManifestRequiresAuth, withDefaultWorkbenchAdapterAuth, withDefaultWorkbenchAdapterAuthProfiles, type WorkbenchAdapterOperation, type WorkbenchAdapterOperationManifest, type WorkbenchAdapterSlotManifest, type WorkbenchAdapterAuthEnvManifest, type WorkbenchAdapterAuthFileManifest, type WorkbenchAdapterAuthManifest, type WorkbenchAdapterAuthMethodManifest, type WorkbenchAdapterAuthRequirement, type WorkbenchAdapterInvocationLike, type WorkbenchAdapterManifest, type WorkbenchAdapterOperationRequirement, } from "./adapter-manifest.ts";
|
|
2
|
+
export { WORKBENCH_ADAPTER_PROTOCOL, WORKBENCH_ADAPTER_RESULT_FILE, WORKBENCH_ADAPTER_RESULT_PROTOCOL, assertWorkbenchAdapterOperationResultOk, ensureWorkbenchAdapterOutputDir, normalizeWorkbenchAdapterOperationRequest, normalizeWorkbenchAdapterOperationResult, readWorkbenchAdapterOperationRequest, readWorkbenchAdapterOperationResult, workbenchAdapterOperationResultPath, writeWorkbenchAdapterOperationResult, type WorkbenchAdapterOperationRequest, type WorkbenchAdapterOperationResult, type WorkbenchAdapterOperationResultValue, } from "./adapter-protocol.ts";
|
|
3
|
+
export { normalizeWorkbenchTaskBundle, normalizeWorkbenchTaskSourceResult, normalizeWorkbenchTaskSpec, type WorkbenchTaskBundle, type WorkbenchTaskEnvironmentSpec, type WorkbenchTaskSourceResult, type WorkbenchTaskSpec, } from "./task-source-result.ts";
|
|
4
|
+
export { adapterResult, adapterSlot, adapterSlotInvocation, defineAdapter, defineOptimizer, defineRunner, defineScorer, defineTaskSource, operationDefinitionForRequest, runDefinedAdapter, workbenchAdapterManifestFromDefinition, type WorkbenchAdapterDefinition, type WorkbenchAdapterHandlerContext, type WorkbenchAdapterHandlerReturn, type WorkbenchAdapterOperationDefinition, type WorkbenchAdapterOperationHandler, type RunDefinedWorkbenchAdapterOptions, } from "./adapter-definition.ts";
|
|
3
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,6BAA6B,EAC7B,uCAAuC,EACvC,kCAAkC,EAClC,6BAA6B,EAC7B,oCAAoC,EACpC,+BAA+B,EAC/B,uCAAuC,EACvC,KAAK,+BAA+B,EACpC,KAAK,gCAAgC,EACrC,KAAK,4BAA4B,EACjC,KAAK,kCAAkC,EACvC,KAAK,+BAA+B,EACpC,KAAK,8BAA8B,EACnC,KAAK,wBAAwB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,sCAAsC,EACtC,6BAA6B,EAC7B,uCAAuC,EACvC,kCAAkC,EAClC,sCAAsC,EACtC,4CAA4C,EAC5C,6BAA6B,EAC7B,yCAAyC,EACzC,gCAAgC,EAChC,oCAAoC,EACpC,+BAA+B,EAC/B,uCAAuC,EACvC,KAAK,yBAAyB,EAC9B,KAAK,iCAAiC,EACtC,KAAK,4BAA4B,EACjC,KAAK,+BAA+B,EACpC,KAAK,gCAAgC,EACrC,KAAK,4BAA4B,EACjC,KAAK,kCAAkC,EACvC,KAAK,+BAA+B,EACpC,KAAK,8BAA8B,EACnC,KAAK,wBAAwB,EAC7B,KAAK,oCAAoC,GAC1C,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,0BAA0B,EAC1B,6BAA6B,EAC7B,iCAAiC,EACjC,uCAAuC,EACvC,+BAA+B,EAC/B,yCAAyC,EACzC,wCAAwC,EACxC,oCAAoC,EACpC,mCAAmC,EACnC,mCAAmC,EACnC,oCAAoC,EACpC,KAAK,gCAAgC,EACrC,KAAK,+BAA+B,EACpC,KAAK,oCAAoC,GAC1C,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,4BAA4B,EAC5B,kCAAkC,EAClC,0BAA0B,EAC1B,KAAK,mBAAmB,EACxB,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,EAC9B,KAAK,iBAAiB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,aAAa,EACb,WAAW,EACX,qBAAqB,EACrB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,6BAA6B,EAC7B,iBAAiB,EACjB,sCAAsC,EACtC,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EACnC,KAAK,6BAA6B,EAClC,KAAK,mCAAmC,EACxC,KAAK,gCAAgC,EACrC,KAAK,iCAAiC,GACvC,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
export { adapterCommandName, cloneWorkbenchAdapterManifest, collectWorkbenchAdapterAuthRequirements, collectWorkbenchAdapterInvocations, parseWorkbenchAdapterManifest, workbenchAdapterManifestRequiresAuth, withDefaultWorkbenchAdapterAuth, withDefaultWorkbenchAdapterAuthProfiles, } from "./adapter-manifest.js";
|
|
2
|
-
export { ensureWorkbenchAdapterOutputDir,
|
|
1
|
+
export { adapterCommandName, assertWorkbenchAdapterOperationSupport, cloneWorkbenchAdapterManifest, collectWorkbenchAdapterAuthRequirements, collectWorkbenchAdapterInvocations, collectWorkbenchAdapterOperationIssues, collectWorkbenchAdapterOperationRequirements, parseWorkbenchAdapterManifest, workbenchAdapterManifestSupportsOperation, workbenchAdapterOperationCommand, workbenchAdapterManifestRequiresAuth, withDefaultWorkbenchAdapterAuth, withDefaultWorkbenchAdapterAuthProfiles, } from "./adapter-manifest.js";
|
|
2
|
+
export { WORKBENCH_ADAPTER_PROTOCOL, WORKBENCH_ADAPTER_RESULT_FILE, WORKBENCH_ADAPTER_RESULT_PROTOCOL, assertWorkbenchAdapterOperationResultOk, ensureWorkbenchAdapterOutputDir, normalizeWorkbenchAdapterOperationRequest, normalizeWorkbenchAdapterOperationResult, readWorkbenchAdapterOperationRequest, readWorkbenchAdapterOperationResult, workbenchAdapterOperationResultPath, writeWorkbenchAdapterOperationResult, } from "./adapter-protocol.js";
|
|
3
|
+
export { normalizeWorkbenchTaskBundle, normalizeWorkbenchTaskSourceResult, normalizeWorkbenchTaskSpec, } from "./task-source-result.js";
|
|
4
|
+
export { adapterResult, adapterSlot, adapterSlotInvocation, defineAdapter, defineOptimizer, defineRunner, defineScorer, defineTaskSource, operationDefinitionForRequest, runDefinedAdapter, workbenchAdapterManifestFromDefinition, } from "./adapter-definition.js";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { SurfaceSnapshotFile, WorkbenchAdapterInvocation, WorkbenchExecutionNetworkPolicy, WorkbenchExecutionResources } from "@workbench-ai/workbench-contract";
|
|
2
|
+
export interface WorkbenchTaskEnvironmentSpec {
|
|
3
|
+
dockerfile?: string;
|
|
4
|
+
workdir?: string;
|
|
5
|
+
resources?: Partial<WorkbenchExecutionResources>;
|
|
6
|
+
network?: WorkbenchExecutionNetworkPolicy;
|
|
7
|
+
}
|
|
8
|
+
export interface WorkbenchTaskSpec {
|
|
9
|
+
version: 2;
|
|
10
|
+
task: string;
|
|
11
|
+
environment?: WorkbenchTaskEnvironmentSpec;
|
|
12
|
+
score?: WorkbenchAdapterInvocation;
|
|
13
|
+
}
|
|
14
|
+
export interface WorkbenchTaskBundle {
|
|
15
|
+
id: string;
|
|
16
|
+
task: WorkbenchTaskSpec;
|
|
17
|
+
publicFiles: SurfaceSnapshotFile[];
|
|
18
|
+
testFiles: SurfaceSnapshotFile[];
|
|
19
|
+
solutionFiles?: SurfaceSnapshotFile[];
|
|
20
|
+
sourceFiles?: SurfaceSnapshotFile[];
|
|
21
|
+
}
|
|
22
|
+
export interface WorkbenchTaskSourceResult {
|
|
23
|
+
tasks: WorkbenchTaskBundle[];
|
|
24
|
+
environment?: WorkbenchTaskEnvironmentSpec;
|
|
25
|
+
}
|
|
26
|
+
export declare function normalizeWorkbenchTaskSourceResult(value: unknown, label?: string): WorkbenchTaskSourceResult;
|
|
27
|
+
export declare function normalizeWorkbenchTaskBundle(value: unknown, label: string): WorkbenchTaskBundle;
|
|
28
|
+
export declare function normalizeWorkbenchTaskSpec(value: unknown, label: string): WorkbenchTaskSpec;
|
|
29
|
+
//# sourceMappingURL=task-source-result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-source-result.d.ts","sourceRoot":"","sources":["../src/task-source-result.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,mBAAmB,EACnB,0BAA0B,EAC1B,+BAA+B,EAC/B,2BAA2B,EAC5B,MAAM,kCAAkC,CAAC;AAE1C,MAAM,WAAW,4BAA4B;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACjD,OAAO,CAAC,EAAE,+BAA+B,CAAC;CAC3C;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,CAAC,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,4BAA4B,CAAC;IAC3C,KAAK,CAAC,EAAE,0BAA0B,CAAC;CACpC;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,iBAAiB,CAAC;IACxB,WAAW,EAAE,mBAAmB,EAAE,CAAC;IACnC,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,aAAa,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACtC,WAAW,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,mBAAmB,EAAE,CAAC;IAC7B,WAAW,CAAC,EAAE,4BAA4B,CAAC;CAC5C;AAED,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,OAAO,EACd,KAAK,SAAyB,GAC7B,yBAAyB,CAkB3B;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,GACZ,mBAAmB,CAiBrB;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,GACZ,iBAAiB,CAkBnB"}
|