@tangle-network/agent-interface 0.45.0 → 0.46.0
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/README.md +1 -1
- package/dist/agent-candidate-profile-schema.d.ts +2 -2
- package/dist/agent-candidate-promotion-schema.d.ts +22 -22
- package/dist/agent-candidate-schema-common.js +1 -1
- package/dist/agent-candidate-schema.d.ts +2 -2
- package/dist/agent-execution-preparation.d.ts +26 -26
- package/dist/agent-profile.d.ts +10 -3
- package/dist/agent-profile.js +45 -22
- package/dist/backend-message.d.ts +14 -0
- package/dist/backend-message.js +1 -0
- package/dist/contract-limits.d.ts +26 -0
- package/dist/contract-limits.js +175 -0
- package/dist/environment-exact-process.d.ts +161 -0
- package/dist/environment-exact-process.js +1 -0
- package/dist/environment-profile-capabilities.d.ts +26 -0
- package/dist/environment-profile-capabilities.js +34 -0
- package/dist/environment-provider.d.ts +3 -730
- package/dist/environment-provider.js +3 -245
- package/dist/environment-requests.d.ts +70 -0
- package/dist/environment-requests.js +1 -0
- package/dist/environment-runtime.d.ts +834 -0
- package/dist/environment-runtime.js +228 -0
- package/dist/execution-types.d.ts +47 -0
- package/dist/execution-types.js +1 -0
- package/dist/host-services.d.ts +91 -0
- package/dist/host-services.js +1 -0
- package/dist/index.d.ts +10 -617
- package/dist/index.js +10 -125
- package/dist/interaction-answer-validation.d.ts +13 -0
- package/dist/interaction-answer-validation.js +149 -0
- package/dist/interaction-data.d.ts +22 -0
- package/dist/interaction-data.js +46 -0
- package/dist/interaction-envelope.d.ts +258 -0
- package/dist/interaction-envelope.js +245 -0
- package/dist/interaction-fields.d.ts +130 -0
- package/dist/interaction-fields.js +227 -0
- package/dist/interaction-permissions.d.ts +28 -0
- package/dist/interaction-permissions.js +57 -0
- package/dist/interaction-resolution-validation.d.ts +9 -0
- package/dist/interaction-resolution-validation.js +50 -0
- package/dist/interaction-response-validation.d.ts +17 -0
- package/dist/interaction-response-validation.js +102 -0
- package/dist/interaction.d.ts +6 -397
- package/dist/interaction.js +6 -603
- package/dist/mcp.d.ts +38 -0
- package/dist/mcp.js +1 -0
- package/dist/parts.d.ts +104 -0
- package/dist/parts.js +55 -0
- package/dist/portable-context-base.d.ts +82 -0
- package/dist/portable-context-base.js +63 -0
- package/dist/portable-context-continuation.d.ts +168 -0
- package/dist/portable-context-continuation.js +194 -0
- package/dist/portable-context-plan-request.d.ts +86 -0
- package/dist/portable-context-plan-request.js +102 -0
- package/dist/portable-context-plan.d.ts +229 -0
- package/dist/portable-context-plan.js +241 -0
- package/dist/portable-context-shared.d.ts +36 -0
- package/dist/portable-context-shared.js +46 -0
- package/dist/portable-context-transfer.d.ts +319 -0
- package/dist/portable-context-transfer.js +206 -0
- package/dist/portable-context.d.ts +5 -753
- package/dist/portable-context.js +5 -754
- package/dist/profile-diff.js +56 -47
- package/dist/provider-adapter.d.ts +45 -0
- package/dist/provider-adapter.js +1 -0
- package/dist/provider-config.d.ts +58 -0
- package/dist/provider-config.js +42 -0
- package/dist/runtime-control.d.ts +87 -10
- package/dist/runtime-control.js +159 -38
- package/dist/stream-events.d.ts +55 -0
- package/dist/stream-events.js +1 -0
- package/dist/workspace-branching-shared.d.ts +7 -0
- package/dist/workspace-branching-shared.js +20 -0
- package/dist/workspace-branching.d.ts +4 -254
- package/dist/workspace-branching.js +4 -400
- package/dist/workspace-checkpoint.d.ts +99 -0
- package/dist/workspace-checkpoint.js +169 -0
- package/dist/workspace-cleanup.d.ts +85 -0
- package/dist/workspace-cleanup.js +156 -0
- package/dist/workspace-confidentiality.d.ts +59 -0
- package/dist/workspace-confidentiality.js +123 -0
- package/dist/workspace-fork.d.ts +182 -0
- package/dist/workspace-fork.js +267 -0
- package/package.json +1 -1
|
@@ -1,400 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const jsonRecordSchema = z.record(z.string(), z.json());
|
|
6
|
-
function wireDigest(value) {
|
|
7
|
-
const serialized = JSON.stringify(value);
|
|
8
|
-
if (serialized === undefined) {
|
|
9
|
-
throw new Error("operation material must be JSON serializable");
|
|
10
|
-
}
|
|
11
|
-
return canonicalCandidateDigest(JSON.parse(serialized));
|
|
12
|
-
}
|
|
13
|
-
export function workspaceCheckpointRequestDigest(material) {
|
|
14
|
-
return wireDigest(material);
|
|
15
|
-
}
|
|
16
|
-
export const WorkspaceCheckpointRequestSchema = z
|
|
17
|
-
.strictObject({
|
|
18
|
-
source: AgentRunControlRefSchema,
|
|
19
|
-
name: z.string().min(1).optional(),
|
|
20
|
-
metadata: jsonRecordSchema.optional(),
|
|
21
|
-
idempotencyKey: idSchema,
|
|
22
|
-
requestDigest: sha256DigestSchema,
|
|
23
|
-
})
|
|
24
|
-
.superRefine((request, refinement) => {
|
|
25
|
-
if (request.requestDigest !==
|
|
26
|
-
workspaceCheckpointRequestDigest({
|
|
27
|
-
source: request.source,
|
|
28
|
-
name: request.name,
|
|
29
|
-
metadata: request.metadata,
|
|
30
|
-
})) {
|
|
31
|
-
refinement.addIssue({
|
|
32
|
-
code: "custom",
|
|
33
|
-
path: ["requestDigest"],
|
|
34
|
-
message: "checkpoint request digest does not match its material",
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
export const WorkspaceCheckpointRefSchema = z
|
|
39
|
-
.strictObject({
|
|
40
|
-
checkpointId: idSchema,
|
|
41
|
-
provider: idSchema,
|
|
42
|
-
source: AgentRunControlRefSchema,
|
|
43
|
-
idempotencyKey: idSchema,
|
|
44
|
-
requestDigest: sha256DigestSchema,
|
|
45
|
-
createdAt: z.iso.datetime(),
|
|
46
|
-
metadata: jsonRecordSchema.optional(),
|
|
47
|
-
})
|
|
48
|
-
.superRefine((checkpoint, refinement) => {
|
|
49
|
-
if (checkpoint.provider !== checkpoint.source.provider) {
|
|
50
|
-
refinement.addIssue({
|
|
51
|
-
code: "custom",
|
|
52
|
-
path: ["provider"],
|
|
53
|
-
message: "checkpoint provider must match its source run",
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
const checkpointOperationBase = {
|
|
58
|
-
idempotencyKey: idSchema,
|
|
59
|
-
requestDigest: sha256DigestSchema,
|
|
60
|
-
};
|
|
61
|
-
export const WorkspaceCheckpointResultSchema = z.discriminatedUnion("status", [
|
|
62
|
-
z.strictObject({
|
|
63
|
-
status: z.enum(["created", "replayed"]),
|
|
64
|
-
...checkpointOperationBase,
|
|
65
|
-
checkpoint: WorkspaceCheckpointRefSchema,
|
|
66
|
-
}),
|
|
67
|
-
z.strictObject({
|
|
68
|
-
status: z.literal("conflict"),
|
|
69
|
-
...checkpointOperationBase,
|
|
70
|
-
existingRequestDigest: sha256DigestSchema,
|
|
71
|
-
}),
|
|
72
|
-
z.strictObject({
|
|
73
|
-
status: z.literal("unknown"),
|
|
74
|
-
...checkpointOperationBase,
|
|
75
|
-
message: z.string().min(1),
|
|
76
|
-
retryable: z.boolean(),
|
|
77
|
-
}),
|
|
78
|
-
]).superRefine((result, refinement) => {
|
|
79
|
-
if ((result.status === "created" || result.status === "replayed") &&
|
|
80
|
-
(result.checkpoint.idempotencyKey !== result.idempotencyKey ||
|
|
81
|
-
result.checkpoint.requestDigest !== result.requestDigest)) {
|
|
82
|
-
refinement.addIssue({
|
|
83
|
-
code: "custom",
|
|
84
|
-
path: ["checkpoint"],
|
|
85
|
-
message: "checkpoint identity must match its operation",
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
if (result.status === "conflict" &&
|
|
89
|
-
result.existingRequestDigest === result.requestDigest) {
|
|
90
|
-
refinement.addIssue({
|
|
91
|
-
code: "custom",
|
|
92
|
-
path: ["existingRequestDigest"],
|
|
93
|
-
message: "a conflict must identify a different existing request",
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
export const WorkspaceOperationLookupRequestSchema = z.strictObject({
|
|
98
|
-
idempotencyKey: idSchema,
|
|
99
|
-
requestDigest: sha256DigestSchema,
|
|
100
|
-
});
|
|
101
|
-
export const WorkspaceCheckpointLookupResultSchema = z.discriminatedUnion("status", [
|
|
102
|
-
z.strictObject({
|
|
103
|
-
status: z.literal("found"),
|
|
104
|
-
...checkpointOperationBase,
|
|
105
|
-
checkpoint: WorkspaceCheckpointRefSchema,
|
|
106
|
-
}),
|
|
107
|
-
z.strictObject({
|
|
108
|
-
status: z.literal("not_found"),
|
|
109
|
-
...checkpointOperationBase,
|
|
110
|
-
}),
|
|
111
|
-
z.strictObject({
|
|
112
|
-
status: z.literal("conflict"),
|
|
113
|
-
...checkpointOperationBase,
|
|
114
|
-
existingRequestDigest: sha256DigestSchema,
|
|
115
|
-
}),
|
|
116
|
-
z.strictObject({
|
|
117
|
-
status: z.literal("unknown"),
|
|
118
|
-
...checkpointOperationBase,
|
|
119
|
-
message: z.string().min(1),
|
|
120
|
-
retryable: z.boolean(),
|
|
121
|
-
}),
|
|
122
|
-
]).superRefine((result, refinement) => {
|
|
123
|
-
if (result.status === "found" &&
|
|
124
|
-
(result.checkpoint.idempotencyKey !== result.idempotencyKey ||
|
|
125
|
-
result.checkpoint.requestDigest !== result.requestDigest)) {
|
|
126
|
-
refinement.addIssue({
|
|
127
|
-
code: "custom",
|
|
128
|
-
path: ["checkpoint"],
|
|
129
|
-
message: "checkpoint identity must match its lookup operation",
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
if (result.status === "conflict" &&
|
|
133
|
-
result.existingRequestDigest === result.requestDigest) {
|
|
134
|
-
refinement.addIssue({
|
|
135
|
-
code: "custom",
|
|
136
|
-
path: ["existingRequestDigest"],
|
|
137
|
-
message: "a conflict must identify a different existing request",
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
export function workspaceForkRequestDigest(material) {
|
|
142
|
-
return wireDigest(material);
|
|
143
|
-
}
|
|
144
|
-
export const WorkspaceForkRequestSchema = z
|
|
145
|
-
.strictObject({
|
|
146
|
-
checkpoint: WorkspaceCheckpointRefSchema,
|
|
147
|
-
name: z.string().min(1).optional(),
|
|
148
|
-
metadata: jsonRecordSchema.optional(),
|
|
149
|
-
idempotencyKey: idSchema,
|
|
150
|
-
requestDigest: sha256DigestSchema,
|
|
151
|
-
})
|
|
152
|
-
.superRefine((request, refinement) => {
|
|
153
|
-
if (request.requestDigest !==
|
|
154
|
-
workspaceForkRequestDigest({
|
|
155
|
-
checkpoint: request.checkpoint,
|
|
156
|
-
name: request.name,
|
|
157
|
-
metadata: request.metadata,
|
|
158
|
-
})) {
|
|
159
|
-
refinement.addIssue({
|
|
160
|
-
code: "custom",
|
|
161
|
-
path: ["requestDigest"],
|
|
162
|
-
message: "fork request digest does not match its material",
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
const PlacementInfoSchema = z.strictObject({
|
|
167
|
-
kind: z.enum(["local", "sandbox", "fleet", "provider"]),
|
|
168
|
-
sandboxId: idSchema.optional(),
|
|
169
|
-
fleetId: idSchema.optional(),
|
|
170
|
-
machineId: idSchema.optional(),
|
|
171
|
-
region: z.string().min(1).optional(),
|
|
172
|
-
providerMetadata: jsonRecordSchema.optional(),
|
|
173
|
-
});
|
|
174
|
-
export const ForkedEnvironmentRefSchema = z.strictObject({
|
|
175
|
-
provider: idSchema,
|
|
176
|
-
environmentId: idSchema,
|
|
177
|
-
sourceCheckpointId: idSchema,
|
|
178
|
-
idempotencyKey: idSchema,
|
|
179
|
-
requestDigest: sha256DigestSchema,
|
|
180
|
-
createdAt: z.iso.datetime(),
|
|
181
|
-
placement: PlacementInfoSchema.optional(),
|
|
182
|
-
confidential: z.boolean(),
|
|
183
|
-
metadata: jsonRecordSchema.optional(),
|
|
184
|
-
});
|
|
185
|
-
const forkOperationBase = {
|
|
186
|
-
idempotencyKey: idSchema,
|
|
187
|
-
requestDigest: sha256DigestSchema,
|
|
188
|
-
};
|
|
189
|
-
export const WorkspaceForkResultSchema = z.discriminatedUnion("status", [
|
|
190
|
-
z.strictObject({
|
|
191
|
-
status: z.enum(["created", "replayed"]),
|
|
192
|
-
...forkOperationBase,
|
|
193
|
-
environment: ForkedEnvironmentRefSchema,
|
|
194
|
-
}),
|
|
195
|
-
z.strictObject({
|
|
196
|
-
status: z.literal("conflict"),
|
|
197
|
-
...forkOperationBase,
|
|
198
|
-
existingRequestDigest: sha256DigestSchema,
|
|
199
|
-
}),
|
|
200
|
-
z.strictObject({
|
|
201
|
-
status: z.literal("unknown"),
|
|
202
|
-
...forkOperationBase,
|
|
203
|
-
message: z.string().min(1),
|
|
204
|
-
retryable: z.boolean(),
|
|
205
|
-
}),
|
|
206
|
-
]).superRefine((result, refinement) => {
|
|
207
|
-
if ((result.status === "created" || result.status === "replayed") &&
|
|
208
|
-
(result.environment.idempotencyKey !== result.idempotencyKey ||
|
|
209
|
-
result.environment.requestDigest !== result.requestDigest)) {
|
|
210
|
-
refinement.addIssue({
|
|
211
|
-
code: "custom",
|
|
212
|
-
path: ["environment"],
|
|
213
|
-
message: "forked environment identity must match its operation",
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
if (result.status === "conflict" &&
|
|
217
|
-
result.existingRequestDigest === result.requestDigest) {
|
|
218
|
-
refinement.addIssue({
|
|
219
|
-
code: "custom",
|
|
220
|
-
path: ["existingRequestDigest"],
|
|
221
|
-
message: "a conflict must identify a different existing request",
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
});
|
|
225
|
-
export const WorkspaceForkLookupResultSchema = z.discriminatedUnion("status", [
|
|
226
|
-
z.strictObject({
|
|
227
|
-
status: z.literal("found"),
|
|
228
|
-
...forkOperationBase,
|
|
229
|
-
environment: ForkedEnvironmentRefSchema,
|
|
230
|
-
}),
|
|
231
|
-
z.strictObject({ status: z.literal("not_found"), ...forkOperationBase }),
|
|
232
|
-
z.strictObject({
|
|
233
|
-
status: z.literal("conflict"),
|
|
234
|
-
...forkOperationBase,
|
|
235
|
-
existingRequestDigest: sha256DigestSchema,
|
|
236
|
-
}),
|
|
237
|
-
z.strictObject({
|
|
238
|
-
status: z.literal("unknown"),
|
|
239
|
-
...forkOperationBase,
|
|
240
|
-
message: z.string().min(1),
|
|
241
|
-
retryable: z.boolean(),
|
|
242
|
-
}),
|
|
243
|
-
]).superRefine((result, refinement) => {
|
|
244
|
-
if (result.status === "found" &&
|
|
245
|
-
(result.environment.idempotencyKey !== result.idempotencyKey ||
|
|
246
|
-
result.environment.requestDigest !== result.requestDigest)) {
|
|
247
|
-
refinement.addIssue({
|
|
248
|
-
code: "custom",
|
|
249
|
-
path: ["environment"],
|
|
250
|
-
message: "forked environment identity must match its lookup operation",
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
if (result.status === "conflict" &&
|
|
254
|
-
result.existingRequestDigest === result.requestDigest) {
|
|
255
|
-
refinement.addIssue({
|
|
256
|
-
code: "custom",
|
|
257
|
-
path: ["existingRequestDigest"],
|
|
258
|
-
message: "a conflict must identify a different existing request",
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
});
|
|
262
|
-
export const WorkspaceCleanupRequestSchema = z.strictObject({
|
|
263
|
-
operationId: idSchema,
|
|
264
|
-
targetId: idSchema,
|
|
265
|
-
provider: idSchema,
|
|
266
|
-
});
|
|
267
|
-
export const WorkspaceCleanupAcknowledgementSchema = z
|
|
268
|
-
.strictObject({
|
|
269
|
-
operationId: idSchema,
|
|
270
|
-
targetId: idSchema,
|
|
271
|
-
provider: idSchema,
|
|
272
|
-
status: z.enum([
|
|
273
|
-
"deleted",
|
|
274
|
-
"already_absent",
|
|
275
|
-
"unknown",
|
|
276
|
-
"in_use",
|
|
277
|
-
"conflict",
|
|
278
|
-
"transport_failure",
|
|
279
|
-
]),
|
|
280
|
-
message: z.string().min(1).optional(),
|
|
281
|
-
retryable: z.boolean().optional(),
|
|
282
|
-
/** Existing resources that must be removed before this target. */
|
|
283
|
-
blockingTargetIds: z.array(idSchema).min(1).optional(),
|
|
284
|
-
})
|
|
285
|
-
.superRefine((acknowledgement, refinement) => {
|
|
286
|
-
if (["unknown", "in_use", "conflict", "transport_failure"].includes(acknowledgement.status) &&
|
|
287
|
-
acknowledgement.message === undefined) {
|
|
288
|
-
refinement.addIssue({
|
|
289
|
-
code: "custom",
|
|
290
|
-
path: ["message"],
|
|
291
|
-
message: `${acknowledgement.status} cleanup must include a message`,
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
if (acknowledgement.status === "in_use" &&
|
|
295
|
-
acknowledgement.blockingTargetIds === undefined) {
|
|
296
|
-
refinement.addIssue({
|
|
297
|
-
code: "custom",
|
|
298
|
-
path: ["blockingTargetIds"],
|
|
299
|
-
message: "in_use cleanup must identify every known blocking target",
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
if (acknowledgement.status !== "in_use" &&
|
|
303
|
-
acknowledgement.blockingTargetIds !== undefined) {
|
|
304
|
-
refinement.addIssue({
|
|
305
|
-
code: "custom",
|
|
306
|
-
path: ["blockingTargetIds"],
|
|
307
|
-
message: "only in_use cleanup may identify blocking targets",
|
|
308
|
-
});
|
|
309
|
-
}
|
|
310
|
-
if (acknowledgement.blockingTargetIds &&
|
|
311
|
-
new Set(acknowledgement.blockingTargetIds).size !==
|
|
312
|
-
acknowledgement.blockingTargetIds.length) {
|
|
313
|
-
refinement.addIssue({
|
|
314
|
-
code: "custom",
|
|
315
|
-
path: ["blockingTargetIds"],
|
|
316
|
-
message: "blocking cleanup target ids must be unique",
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
if (["unknown", "transport_failure"].includes(acknowledgement.status) &&
|
|
320
|
-
acknowledgement.retryable === undefined) {
|
|
321
|
-
refinement.addIssue({
|
|
322
|
-
code: "custom",
|
|
323
|
-
path: ["retryable"],
|
|
324
|
-
message: `${acknowledgement.status} cleanup must state whether retry is safe`,
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
});
|
|
328
|
-
/** Bind a checkpoint result to the exact request before using the resource. */
|
|
329
|
-
export function workspaceCheckpointResultMatchesRequest(request, result) {
|
|
330
|
-
const parsedRequest = WorkspaceCheckpointRequestSchema.safeParse(request);
|
|
331
|
-
const parsedResult = WorkspaceCheckpointResultSchema.safeParse(result);
|
|
332
|
-
const parsedLookup = WorkspaceCheckpointLookupResultSchema.safeParse(result);
|
|
333
|
-
if (!parsedRequest.success)
|
|
334
|
-
return false;
|
|
335
|
-
const exactRequest = parsedRequest.data;
|
|
336
|
-
if (parsedResult.success &&
|
|
337
|
-
(parsedResult.data.status === "created" ||
|
|
338
|
-
parsedResult.data.status === "replayed")) {
|
|
339
|
-
return checkpointResultMatchesParsed(exactRequest, parsedResult.data);
|
|
340
|
-
}
|
|
341
|
-
if (parsedLookup.success && parsedLookup.data.status === "found") {
|
|
342
|
-
return checkpointResultMatchesParsed(exactRequest, parsedLookup.data);
|
|
343
|
-
}
|
|
344
|
-
return false;
|
|
345
|
-
}
|
|
346
|
-
function checkpointResultMatchesParsed(request, result) {
|
|
347
|
-
return (result.idempotencyKey === request.idempotencyKey &&
|
|
348
|
-
result.requestDigest === request.requestDigest &&
|
|
349
|
-
result.checkpoint.idempotencyKey === request.idempotencyKey &&
|
|
350
|
-
result.checkpoint.requestDigest === request.requestDigest &&
|
|
351
|
-
wireDigest(result.checkpoint.source) === wireDigest(request.source) &&
|
|
352
|
-
sameOptionalWireValue(result.checkpoint.metadata, request.metadata) &&
|
|
353
|
-
result.checkpoint.provider === request.source.provider);
|
|
354
|
-
}
|
|
355
|
-
/** Bind a fork result to the exact checkpoint request before using it. */
|
|
356
|
-
export function workspaceForkResultMatchesRequest(request, result) {
|
|
357
|
-
const parsedRequest = WorkspaceForkRequestSchema.safeParse(request);
|
|
358
|
-
const parsedResult = WorkspaceForkResultSchema.safeParse(result);
|
|
359
|
-
const parsedLookup = WorkspaceForkLookupResultSchema.safeParse(result);
|
|
360
|
-
if (!parsedRequest.success)
|
|
361
|
-
return false;
|
|
362
|
-
const exactRequest = parsedRequest.data;
|
|
363
|
-
if (parsedResult.success &&
|
|
364
|
-
(parsedResult.data.status === "created" ||
|
|
365
|
-
parsedResult.data.status === "replayed")) {
|
|
366
|
-
return forkResultMatchesParsed(exactRequest, parsedResult.data);
|
|
367
|
-
}
|
|
368
|
-
if (parsedLookup.success && parsedLookup.data.status === "found") {
|
|
369
|
-
return forkResultMatchesParsed(exactRequest, parsedLookup.data);
|
|
370
|
-
}
|
|
371
|
-
return false;
|
|
372
|
-
}
|
|
373
|
-
function forkResultMatchesParsed(request, result) {
|
|
374
|
-
return (result.idempotencyKey === request.idempotencyKey &&
|
|
375
|
-
result.requestDigest === request.requestDigest &&
|
|
376
|
-
result.environment.idempotencyKey === request.idempotencyKey &&
|
|
377
|
-
result.environment.requestDigest === request.requestDigest &&
|
|
378
|
-
result.environment.sourceCheckpointId === request.checkpoint.checkpointId &&
|
|
379
|
-
result.environment.provider === request.checkpoint.provider &&
|
|
380
|
-
sameOptionalWireValue(result.environment.metadata, request.metadata));
|
|
381
|
-
}
|
|
382
|
-
/** Bind cleanup confirmation to the exact provider resource and operation. */
|
|
383
|
-
export function workspaceCleanupAcknowledgementMatches(request, acknowledgement) {
|
|
384
|
-
const parsedRequest = WorkspaceCleanupRequestSchema.safeParse(request);
|
|
385
|
-
const parsedAcknowledgement = WorkspaceCleanupAcknowledgementSchema.safeParse(acknowledgement);
|
|
386
|
-
if (!parsedRequest.success || !parsedAcknowledgement.success)
|
|
387
|
-
return false;
|
|
388
|
-
const exactRequest = parsedRequest.data;
|
|
389
|
-
const exactAcknowledgement = parsedAcknowledgement.data;
|
|
390
|
-
return ((exactAcknowledgement.status === "deleted" ||
|
|
391
|
-
exactAcknowledgement.status === "already_absent") &&
|
|
392
|
-
exactAcknowledgement.operationId === exactRequest.operationId &&
|
|
393
|
-
exactAcknowledgement.targetId === exactRequest.targetId &&
|
|
394
|
-
exactAcknowledgement.provider === exactRequest.provider);
|
|
395
|
-
}
|
|
396
|
-
function sameOptionalWireValue(left, right) {
|
|
397
|
-
if (left === undefined || right === undefined)
|
|
398
|
-
return left === right;
|
|
399
|
-
return wireDigest(left) === wireDigest(right);
|
|
400
|
-
}
|
|
1
|
+
export * from "./workspace-confidentiality.js";
|
|
2
|
+
export * from "./workspace-checkpoint.js";
|
|
3
|
+
export * from "./workspace-fork.js";
|
|
4
|
+
export * from "./workspace-cleanup.js";
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { Sha256Digest } from "./agent-candidate.js";
|
|
3
|
+
import { type AgentExactRunControlRef } from "./runtime-control.js";
|
|
4
|
+
export interface WorkspaceCheckpointMaterial {
|
|
5
|
+
source: AgentExactRunControlRef;
|
|
6
|
+
name?: string;
|
|
7
|
+
metadata?: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
export interface WorkspaceCheckpointRequest extends WorkspaceCheckpointMaterial {
|
|
10
|
+
idempotencyKey: string;
|
|
11
|
+
requestDigest: Sha256Digest;
|
|
12
|
+
}
|
|
13
|
+
export declare function workspaceCheckpointRequestDigest(material: WorkspaceCheckpointMaterial): Sha256Digest;
|
|
14
|
+
export declare const WorkspaceCheckpointRequestSchema: z.ZodObject<{
|
|
15
|
+
source: z.ZodObject<{
|
|
16
|
+
runId: z.ZodString;
|
|
17
|
+
provider: z.ZodString;
|
|
18
|
+
environmentId: z.ZodString;
|
|
19
|
+
sessionId: z.ZodString;
|
|
20
|
+
executionId: z.ZodString;
|
|
21
|
+
requestDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
22
|
+
}, z.core.$strict>;
|
|
23
|
+
name: z.ZodOptional<z.ZodString>;
|
|
24
|
+
metadata: z.ZodOptional<z.ZodCustom<Record<string, unknown>, Record<string, unknown>>>;
|
|
25
|
+
idempotencyKey: z.ZodString;
|
|
26
|
+
requestDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
27
|
+
}, z.core.$strict>;
|
|
28
|
+
export interface WorkspaceCheckpointRef {
|
|
29
|
+
checkpointId: string;
|
|
30
|
+
provider: string;
|
|
31
|
+
source: AgentExactRunControlRef;
|
|
32
|
+
idempotencyKey: string;
|
|
33
|
+
requestDigest: Sha256Digest;
|
|
34
|
+
createdAt: string;
|
|
35
|
+
metadata?: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
export declare const WorkspaceCheckpointRefSchema: z.ZodObject<{
|
|
38
|
+
checkpointId: z.ZodString;
|
|
39
|
+
provider: z.ZodString;
|
|
40
|
+
source: z.ZodObject<{
|
|
41
|
+
runId: z.ZodString;
|
|
42
|
+
provider: z.ZodString;
|
|
43
|
+
environmentId: z.ZodString;
|
|
44
|
+
sessionId: z.ZodString;
|
|
45
|
+
executionId: z.ZodString;
|
|
46
|
+
requestDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
47
|
+
}, z.core.$strict>;
|
|
48
|
+
idempotencyKey: z.ZodString;
|
|
49
|
+
requestDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
50
|
+
createdAt: z.ZodISODateTime;
|
|
51
|
+
metadata: z.ZodOptional<z.ZodCustom<Record<string, unknown>, Record<string, unknown>>>;
|
|
52
|
+
}, z.core.$strict>;
|
|
53
|
+
export type WorkspaceCheckpointResult = {
|
|
54
|
+
status: "created" | "replayed";
|
|
55
|
+
idempotencyKey: string;
|
|
56
|
+
requestDigest: Sha256Digest;
|
|
57
|
+
checkpoint: WorkspaceCheckpointRef;
|
|
58
|
+
} | {
|
|
59
|
+
status: "conflict";
|
|
60
|
+
idempotencyKey: string;
|
|
61
|
+
requestDigest: Sha256Digest;
|
|
62
|
+
existingRequestDigest: Sha256Digest;
|
|
63
|
+
} | {
|
|
64
|
+
status: "unknown";
|
|
65
|
+
idempotencyKey: string;
|
|
66
|
+
requestDigest: Sha256Digest;
|
|
67
|
+
message: string;
|
|
68
|
+
retryable: boolean;
|
|
69
|
+
};
|
|
70
|
+
export declare const WorkspaceCheckpointResultSchema: z.ZodType<WorkspaceCheckpointResult>;
|
|
71
|
+
export declare const WorkspaceOperationLookupRequestSchema: z.ZodObject<{
|
|
72
|
+
idempotencyKey: z.ZodString;
|
|
73
|
+
requestDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
74
|
+
}, z.core.$strict>;
|
|
75
|
+
export type WorkspaceOperationLookupRequest = z.infer<typeof WorkspaceOperationLookupRequestSchema>;
|
|
76
|
+
export type WorkspaceCheckpointLookupResult = {
|
|
77
|
+
status: "found";
|
|
78
|
+
idempotencyKey: string;
|
|
79
|
+
requestDigest: Sha256Digest;
|
|
80
|
+
checkpoint: WorkspaceCheckpointRef;
|
|
81
|
+
} | {
|
|
82
|
+
status: "not_found";
|
|
83
|
+
idempotencyKey: string;
|
|
84
|
+
requestDigest: Sha256Digest;
|
|
85
|
+
} | {
|
|
86
|
+
status: "conflict";
|
|
87
|
+
idempotencyKey: string;
|
|
88
|
+
requestDigest: Sha256Digest;
|
|
89
|
+
existingRequestDigest: Sha256Digest;
|
|
90
|
+
} | {
|
|
91
|
+
status: "unknown";
|
|
92
|
+
idempotencyKey: string;
|
|
93
|
+
requestDigest: Sha256Digest;
|
|
94
|
+
message: string;
|
|
95
|
+
retryable: boolean;
|
|
96
|
+
};
|
|
97
|
+
export declare const WorkspaceCheckpointLookupResultSchema: z.ZodType<WorkspaceCheckpointLookupResult>;
|
|
98
|
+
/** Bind a checkpoint result to the exact request before using the resource. */
|
|
99
|
+
export declare function workspaceCheckpointResultMatchesRequest(request: WorkspaceCheckpointRequest, result: WorkspaceCheckpointResult | WorkspaceCheckpointLookupResult): boolean;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { AgentExactRunControlRefSchema } from "./runtime-control.js";
|
|
3
|
+
import { idSchema, jsonRecordSchema, sameOptionalWireValue, sha256DigestSchema, wireDigest } from "./workspace-branching-shared.js";
|
|
4
|
+
import { boundedStringSchema } from "./contract-limits.js";
|
|
5
|
+
const WorkspaceCheckpointMaterialSchema = z.strictObject({
|
|
6
|
+
source: AgentExactRunControlRefSchema,
|
|
7
|
+
name: idSchema.optional(),
|
|
8
|
+
metadata: jsonRecordSchema.optional(),
|
|
9
|
+
});
|
|
10
|
+
export function workspaceCheckpointRequestDigest(material) {
|
|
11
|
+
const parsed = WorkspaceCheckpointMaterialSchema.parse(material);
|
|
12
|
+
return wireDigest({
|
|
13
|
+
source: parsed.source,
|
|
14
|
+
...(parsed.name === undefined ? {} : { name: parsed.name }),
|
|
15
|
+
...(parsed.metadata === undefined ? {} : { metadata: parsed.metadata }),
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
export const WorkspaceCheckpointRequestSchema = z
|
|
19
|
+
.strictObject({
|
|
20
|
+
source: AgentExactRunControlRefSchema,
|
|
21
|
+
name: idSchema.optional(),
|
|
22
|
+
metadata: jsonRecordSchema.optional(),
|
|
23
|
+
idempotencyKey: idSchema,
|
|
24
|
+
requestDigest: sha256DigestSchema,
|
|
25
|
+
})
|
|
26
|
+
.superRefine((request, refinement) => {
|
|
27
|
+
if (request.requestDigest !==
|
|
28
|
+
workspaceCheckpointRequestDigest({
|
|
29
|
+
source: request.source,
|
|
30
|
+
name: request.name,
|
|
31
|
+
metadata: request.metadata,
|
|
32
|
+
})) {
|
|
33
|
+
refinement.addIssue({
|
|
34
|
+
code: "custom",
|
|
35
|
+
path: ["requestDigest"],
|
|
36
|
+
message: "checkpoint request digest does not match its material",
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
export const WorkspaceCheckpointRefSchema = z
|
|
41
|
+
.strictObject({
|
|
42
|
+
checkpointId: idSchema,
|
|
43
|
+
provider: idSchema,
|
|
44
|
+
source: AgentExactRunControlRefSchema,
|
|
45
|
+
idempotencyKey: idSchema,
|
|
46
|
+
requestDigest: sha256DigestSchema,
|
|
47
|
+
createdAt: z.iso.datetime().max(64),
|
|
48
|
+
metadata: jsonRecordSchema.optional(),
|
|
49
|
+
})
|
|
50
|
+
.superRefine((checkpoint, refinement) => {
|
|
51
|
+
if (checkpoint.provider !== checkpoint.source.provider) {
|
|
52
|
+
refinement.addIssue({
|
|
53
|
+
code: "custom",
|
|
54
|
+
path: ["provider"],
|
|
55
|
+
message: "checkpoint provider must match its source run",
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
const checkpointOperationBase = {
|
|
60
|
+
idempotencyKey: idSchema,
|
|
61
|
+
requestDigest: sha256DigestSchema,
|
|
62
|
+
};
|
|
63
|
+
export const WorkspaceCheckpointResultSchema = z.discriminatedUnion("status", [
|
|
64
|
+
z.strictObject({
|
|
65
|
+
status: z.enum(["created", "replayed"]),
|
|
66
|
+
...checkpointOperationBase,
|
|
67
|
+
checkpoint: WorkspaceCheckpointRefSchema,
|
|
68
|
+
}),
|
|
69
|
+
z.strictObject({
|
|
70
|
+
status: z.literal("conflict"),
|
|
71
|
+
...checkpointOperationBase,
|
|
72
|
+
existingRequestDigest: sha256DigestSchema,
|
|
73
|
+
}),
|
|
74
|
+
z.strictObject({
|
|
75
|
+
status: z.literal("unknown"),
|
|
76
|
+
...checkpointOperationBase,
|
|
77
|
+
message: boundedStringSchema.min(1),
|
|
78
|
+
retryable: z.boolean(),
|
|
79
|
+
}),
|
|
80
|
+
]).superRefine((result, refinement) => {
|
|
81
|
+
if ((result.status === "created" || result.status === "replayed") &&
|
|
82
|
+
(result.checkpoint.idempotencyKey !== result.idempotencyKey ||
|
|
83
|
+
result.checkpoint.requestDigest !== result.requestDigest)) {
|
|
84
|
+
refinement.addIssue({
|
|
85
|
+
code: "custom",
|
|
86
|
+
path: ["checkpoint"],
|
|
87
|
+
message: "checkpoint identity must match its operation",
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (result.status === "conflict" &&
|
|
91
|
+
result.existingRequestDigest === result.requestDigest) {
|
|
92
|
+
refinement.addIssue({
|
|
93
|
+
code: "custom",
|
|
94
|
+
path: ["existingRequestDigest"],
|
|
95
|
+
message: "a conflict must identify a different existing request",
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
export const WorkspaceOperationLookupRequestSchema = z.strictObject({
|
|
100
|
+
idempotencyKey: idSchema,
|
|
101
|
+
requestDigest: sha256DigestSchema,
|
|
102
|
+
});
|
|
103
|
+
export const WorkspaceCheckpointLookupResultSchema = z.discriminatedUnion("status", [
|
|
104
|
+
z.strictObject({
|
|
105
|
+
status: z.literal("found"),
|
|
106
|
+
...checkpointOperationBase,
|
|
107
|
+
checkpoint: WorkspaceCheckpointRefSchema,
|
|
108
|
+
}),
|
|
109
|
+
z.strictObject({
|
|
110
|
+
status: z.literal("not_found"),
|
|
111
|
+
...checkpointOperationBase,
|
|
112
|
+
}),
|
|
113
|
+
z.strictObject({
|
|
114
|
+
status: z.literal("conflict"),
|
|
115
|
+
...checkpointOperationBase,
|
|
116
|
+
existingRequestDigest: sha256DigestSchema,
|
|
117
|
+
}),
|
|
118
|
+
z.strictObject({
|
|
119
|
+
status: z.literal("unknown"),
|
|
120
|
+
...checkpointOperationBase,
|
|
121
|
+
message: boundedStringSchema.min(1),
|
|
122
|
+
retryable: z.boolean(),
|
|
123
|
+
}),
|
|
124
|
+
]).superRefine((result, refinement) => {
|
|
125
|
+
if (result.status === "found" &&
|
|
126
|
+
(result.checkpoint.idempotencyKey !== result.idempotencyKey ||
|
|
127
|
+
result.checkpoint.requestDigest !== result.requestDigest)) {
|
|
128
|
+
refinement.addIssue({
|
|
129
|
+
code: "custom",
|
|
130
|
+
path: ["checkpoint"],
|
|
131
|
+
message: "checkpoint identity must match its lookup operation",
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
if (result.status === "conflict" &&
|
|
135
|
+
result.existingRequestDigest === result.requestDigest) {
|
|
136
|
+
refinement.addIssue({
|
|
137
|
+
code: "custom",
|
|
138
|
+
path: ["existingRequestDigest"],
|
|
139
|
+
message: "a conflict must identify a different existing request",
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
/** Bind a checkpoint result to the exact request before using the resource. */
|
|
144
|
+
export function workspaceCheckpointResultMatchesRequest(request, result) {
|
|
145
|
+
const parsedRequest = WorkspaceCheckpointRequestSchema.safeParse(request);
|
|
146
|
+
const parsedResult = WorkspaceCheckpointResultSchema.safeParse(result);
|
|
147
|
+
const parsedLookup = WorkspaceCheckpointLookupResultSchema.safeParse(result);
|
|
148
|
+
if (!parsedRequest.success)
|
|
149
|
+
return false;
|
|
150
|
+
const exactRequest = parsedRequest.data;
|
|
151
|
+
if (parsedResult.success &&
|
|
152
|
+
(parsedResult.data.status === "created" ||
|
|
153
|
+
parsedResult.data.status === "replayed")) {
|
|
154
|
+
return checkpointResultMatchesParsed(exactRequest, parsedResult.data);
|
|
155
|
+
}
|
|
156
|
+
if (parsedLookup.success && parsedLookup.data.status === "found") {
|
|
157
|
+
return checkpointResultMatchesParsed(exactRequest, parsedLookup.data);
|
|
158
|
+
}
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
function checkpointResultMatchesParsed(request, result) {
|
|
162
|
+
return (result.idempotencyKey === request.idempotencyKey &&
|
|
163
|
+
result.requestDigest === request.requestDigest &&
|
|
164
|
+
result.checkpoint.idempotencyKey === request.idempotencyKey &&
|
|
165
|
+
result.checkpoint.requestDigest === request.requestDigest &&
|
|
166
|
+
wireDigest(result.checkpoint.source) === wireDigest(request.source) &&
|
|
167
|
+
sameOptionalWireValue(result.checkpoint.metadata, request.metadata) &&
|
|
168
|
+
result.checkpoint.provider === request.source.provider);
|
|
169
|
+
}
|