@tangle-network/agent-interface 0.55.0 → 0.56.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/dist/environment-interactive.d.ts +1603 -89
- package/dist/environment-interactive.js +415 -17
- package/dist/environment-runtime.d.ts +3 -0
- package/dist/environment-runtime.js +14 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { canonicalCandidateDigest, sha256DigestSchema, } from "./agent-candidate-schema-common.js";
|
|
3
|
-
import { canonicalAgentProfileDigest } from "./agent-execution-preparation.js";
|
|
3
|
+
import { agentExecutionPreparationReceiptSchema, canonicalAgentProfileDigest, } from "./agent-execution-preparation.js";
|
|
4
4
|
import { boundedIdentifierSchema, boundedStringSchema, } from "./contract-limits.js";
|
|
5
|
-
import { harnessTypeSchema } from "./harness.js";
|
|
6
5
|
import { agentProfileSchema } from "./profile-schema.js";
|
|
7
6
|
import { AgentExactRunControlRefSchema, } from "./runtime-control.js";
|
|
8
7
|
const INTERACTIVE_MAX_DIMENSION = 10_000;
|
|
@@ -20,21 +19,210 @@ const AgentInteractiveSessionRunCoordinatesSchema = z.strictObject({
|
|
|
20
19
|
/**
|
|
21
20
|
* Durable identity of one coding-agent TUI.
|
|
22
21
|
*
|
|
23
|
-
* This reference identifies the exact admitted run and
|
|
22
|
+
* This reference identifies the exact admitted run and preparation receipt.
|
|
24
23
|
* It is not a generic shell id and cannot be used to create another process.
|
|
25
24
|
*/
|
|
26
25
|
export const AgentInteractiveSessionRefSchema = z.strictObject({
|
|
27
26
|
run: AgentExactRunControlRefSchema,
|
|
28
|
-
/** Canonical
|
|
29
|
-
|
|
30
|
-
/** Canonical digest of the effective profile the provider admitted. */
|
|
31
|
-
admittedProfileDigest: sha256DigestSchema,
|
|
27
|
+
/** Canonical executor receipt containing the effective route and its proof. */
|
|
28
|
+
preparationReceipt: agentExecutionPreparationReceiptSchema,
|
|
32
29
|
/** Provider-issued identity of this exact process incarnation. */
|
|
33
30
|
incarnationId: boundedIdentifierSchema,
|
|
34
|
-
harness: harnessTypeSchema,
|
|
35
31
|
startedAt: z.iso.datetime().max(64),
|
|
36
32
|
});
|
|
37
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* Provider-issued write authority for one exact interactive process.
|
|
35
|
+
*
|
|
36
|
+
* Expiry blocks mutations but does not kill the coding process. A coordinator
|
|
37
|
+
* can issue a new compare-and-swap claim after expiry. The provider's PTY owner
|
|
38
|
+
* lease remains the separate process-cleanup authority.
|
|
39
|
+
*/
|
|
40
|
+
export const AgentInteractiveSessionControlClaimSchema = z.strictObject({
|
|
41
|
+
/** Canonical identity of the process ref this authority can mutate. */
|
|
42
|
+
refDigest: sha256DigestSchema,
|
|
43
|
+
/** Provider generation. A recovered coordinator must obtain a greater value. */
|
|
44
|
+
generation: z.number().int().positive().safe(),
|
|
45
|
+
/** Provider lease identity for this generation. */
|
|
46
|
+
leaseId: boundedIdentifierSchema,
|
|
47
|
+
/** Stable identity of the coordinator holding this lease. */
|
|
48
|
+
holderId: boundedIdentifierSchema,
|
|
49
|
+
expiresAt: z.iso.datetime().max(64),
|
|
50
|
+
});
|
|
51
|
+
const AgentInteractiveSessionControlClaimRequestMaterialSchema = z.strictObject({
|
|
52
|
+
operationId: boundedIdentifierSchema,
|
|
53
|
+
ref: AgentInteractiveSessionRefSchema,
|
|
54
|
+
holderId: boundedIdentifierSchema,
|
|
55
|
+
expectedGeneration: z.number().int().nonnegative().safe(),
|
|
56
|
+
});
|
|
57
|
+
export function agentInteractiveSessionControlClaimRequestDigest(value) {
|
|
58
|
+
const parsed = AgentInteractiveSessionControlClaimRequestMaterialSchema.parse(value);
|
|
59
|
+
return canonicalCandidateDigest({
|
|
60
|
+
kind: "agent-interactive-session-control-claim.v1",
|
|
61
|
+
operationId: parsed.operationId,
|
|
62
|
+
ref: parsed.ref,
|
|
63
|
+
holderId: parsed.holderId,
|
|
64
|
+
expectedGeneration: parsed.expectedGeneration,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
export const AgentInteractiveSessionControlClaimRequestSchema = z
|
|
68
|
+
.strictObject({
|
|
69
|
+
...AgentInteractiveSessionControlClaimRequestMaterialSchema.shape,
|
|
70
|
+
requestDigest: sha256DigestSchema,
|
|
71
|
+
})
|
|
72
|
+
.superRefine((request, refinement) => {
|
|
73
|
+
const { requestDigest: _requestDigest, ...material } = request;
|
|
74
|
+
if (request.requestDigest !==
|
|
75
|
+
agentInteractiveSessionControlClaimRequestDigest(material)) {
|
|
76
|
+
refinement.addIssue({
|
|
77
|
+
code: "custom",
|
|
78
|
+
path: ["requestDigest"],
|
|
79
|
+
message: "interactive session control claim request digest does not match its content",
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
export const AgentInteractiveSessionControlClaimAcknowledgementSchema = z
|
|
84
|
+
.strictObject({
|
|
85
|
+
operationId: boundedIdentifierSchema,
|
|
86
|
+
requestDigest: sha256DigestSchema,
|
|
87
|
+
ref: AgentInteractiveSessionRefSchema,
|
|
88
|
+
status: z.enum(["accepted", "replayed", "conflict", "unknown"]),
|
|
89
|
+
control: AgentInteractiveSessionControlClaimSchema.optional(),
|
|
90
|
+
conflictReason: z
|
|
91
|
+
.enum(["generation_mismatch", "operation_reuse"])
|
|
92
|
+
.optional(),
|
|
93
|
+
currentGeneration: z.number().int().nonnegative().safe().optional(),
|
|
94
|
+
existingRequestDigest: sha256DigestSchema.optional(),
|
|
95
|
+
message: boundedStringSchema.min(1).optional(),
|
|
96
|
+
retryable: z.boolean().optional(),
|
|
97
|
+
})
|
|
98
|
+
.superRefine((acknowledgement, refinement) => {
|
|
99
|
+
const hasControl = acknowledgement.control !== undefined;
|
|
100
|
+
if ((acknowledgement.status === "accepted" ||
|
|
101
|
+
acknowledgement.status === "replayed") &&
|
|
102
|
+
!hasControl) {
|
|
103
|
+
refinement.addIssue({
|
|
104
|
+
code: "custom",
|
|
105
|
+
path: ["control"],
|
|
106
|
+
message: "an accepted control claim must return its provider claim",
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
if (acknowledgement.status !== "accepted" &&
|
|
110
|
+
acknowledgement.status !== "replayed" &&
|
|
111
|
+
hasControl) {
|
|
112
|
+
refinement.addIssue({
|
|
113
|
+
code: "custom",
|
|
114
|
+
path: ["control"],
|
|
115
|
+
message: "only an accepted or replayed claim may return control",
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
if (acknowledgement.status === "conflict" &&
|
|
119
|
+
acknowledgement.conflictReason === undefined) {
|
|
120
|
+
refinement.addIssue({
|
|
121
|
+
code: "custom",
|
|
122
|
+
path: ["conflictReason"],
|
|
123
|
+
message: "a control claim conflict must distinguish generation mismatch from operation reuse",
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
if (acknowledgement.status !== "conflict" &&
|
|
127
|
+
acknowledgement.conflictReason !== undefined) {
|
|
128
|
+
refinement.addIssue({
|
|
129
|
+
code: "custom",
|
|
130
|
+
path: ["conflictReason"],
|
|
131
|
+
message: "only a control claim conflict may report a conflict reason",
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
if (hasControl &&
|
|
135
|
+
!agentInteractiveSessionControlClaimMatchesRef(acknowledgement.ref, acknowledgement.control)) {
|
|
136
|
+
refinement.addIssue({
|
|
137
|
+
code: "custom",
|
|
138
|
+
path: ["control", "refDigest"],
|
|
139
|
+
message: "interactive control claim acknowledgement does not match its process ref",
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
if (acknowledgement.status === "conflict" &&
|
|
143
|
+
acknowledgement.currentGeneration === undefined) {
|
|
144
|
+
refinement.addIssue({
|
|
145
|
+
code: "custom",
|
|
146
|
+
path: ["currentGeneration"],
|
|
147
|
+
message: "a control claim conflict must report the current generation",
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
if (acknowledgement.conflictReason === "generation_mismatch" &&
|
|
151
|
+
acknowledgement.existingRequestDigest !== undefined) {
|
|
152
|
+
refinement.addIssue({
|
|
153
|
+
code: "custom",
|
|
154
|
+
path: ["existingRequestDigest"],
|
|
155
|
+
message: "a generation mismatch must not be reported as operation reuse",
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
if (acknowledgement.conflictReason === "operation_reuse" &&
|
|
159
|
+
acknowledgement.existingRequestDigest === undefined) {
|
|
160
|
+
refinement.addIssue({
|
|
161
|
+
code: "custom",
|
|
162
|
+
path: ["existingRequestDigest"],
|
|
163
|
+
message: "operation reuse must report the digest already stored for this operation",
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
if (acknowledgement.status === "conflict" &&
|
|
167
|
+
acknowledgement.existingRequestDigest === acknowledgement.requestDigest) {
|
|
168
|
+
refinement.addIssue({
|
|
169
|
+
code: "custom",
|
|
170
|
+
path: ["existingRequestDigest"],
|
|
171
|
+
message: "a control claim conflict must identify different request material",
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
if (acknowledgement.status !== "conflict" &&
|
|
175
|
+
(acknowledgement.currentGeneration !== undefined ||
|
|
176
|
+
acknowledgement.existingRequestDigest !== undefined)) {
|
|
177
|
+
refinement.addIssue({
|
|
178
|
+
code: "custom",
|
|
179
|
+
path: ["currentGeneration"],
|
|
180
|
+
message: "only a control claim conflict may report existing generation state",
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
if (acknowledgement.status === "unknown" &&
|
|
184
|
+
(acknowledgement.message === undefined || acknowledgement.retryable !== true)) {
|
|
185
|
+
refinement.addIssue({
|
|
186
|
+
code: "custom",
|
|
187
|
+
path: ["retryable"],
|
|
188
|
+
message: "an unknown control claim outcome must explicitly permit safe same-operation retry",
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
export function agentInteractiveSessionControlClaimAcknowledgementMatchesRequest(request, acknowledgement) {
|
|
193
|
+
const exactRequest = AgentInteractiveSessionControlClaimRequestSchema.safeParse(request);
|
|
194
|
+
const exactAcknowledgement = AgentInteractiveSessionControlClaimAcknowledgementSchema.safeParse(acknowledgement);
|
|
195
|
+
if (!exactRequest.success || !exactAcknowledgement.success)
|
|
196
|
+
return false;
|
|
197
|
+
return (exactAcknowledgement.data.operationId === exactRequest.data.operationId &&
|
|
198
|
+
exactAcknowledgement.data.requestDigest === exactRequest.data.requestDigest &&
|
|
199
|
+
canonicalCandidateDigest(exactAcknowledgement.data.ref) ===
|
|
200
|
+
canonicalCandidateDigest(exactRequest.data.ref));
|
|
201
|
+
}
|
|
202
|
+
/** Bind a provider-issued control claim to the exact process it can mutate. */
|
|
203
|
+
export function agentInteractiveSessionControlClaimMatchesRef(ref, claim) {
|
|
204
|
+
const parsedRef = AgentInteractiveSessionRefSchema.safeParse(ref);
|
|
205
|
+
const parsedClaim = AgentInteractiveSessionControlClaimSchema.safeParse(claim);
|
|
206
|
+
return (parsedRef.success &&
|
|
207
|
+
parsedClaim.success &&
|
|
208
|
+
parsedClaim.data.refDigest === canonicalCandidateDigest(parsedRef.data));
|
|
209
|
+
}
|
|
210
|
+
/** Compare two claims for one process without making a provider state claim. */
|
|
211
|
+
export function agentInteractiveSessionControlClaimIsNewer(candidate, current) {
|
|
212
|
+
const parsedCandidate = AgentInteractiveSessionControlClaimSchema.safeParse(candidate);
|
|
213
|
+
const parsedCurrent = AgentInteractiveSessionControlClaimSchema.safeParse(current);
|
|
214
|
+
return (parsedCandidate.success &&
|
|
215
|
+
parsedCurrent.success &&
|
|
216
|
+
parsedCandidate.data.refDigest === parsedCurrent.data.refDigest &&
|
|
217
|
+
parsedCandidate.data.generation > parsedCurrent.data.generation);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Start one native coding-agent TUI from caller-owned request material.
|
|
221
|
+
*
|
|
222
|
+
* The provider owns profile materialization and returns its preparation receipt
|
|
223
|
+
* in the resulting reference. Replaying the same exact request/run returns the
|
|
224
|
+
* same reference, even after the process exits; changed material cannot reuse it.
|
|
225
|
+
*/
|
|
38
226
|
export const AgentInteractiveSessionStartSchema = z.strictObject({
|
|
39
227
|
run: AgentExactRunControlRefSchema,
|
|
40
228
|
profile: agentProfileSchema,
|
|
@@ -72,6 +260,8 @@ export function agentInteractiveSessionRunRef(coordinates, input) {
|
|
|
72
260
|
}
|
|
73
261
|
/** Geometry for one attachment to the existing coding-agent TUI. */
|
|
74
262
|
export const AgentInteractiveSessionAttachSchema = z.strictObject({
|
|
263
|
+
/** Required because the returned terminal permits input and resize. */
|
|
264
|
+
control: AgentInteractiveSessionControlClaimSchema,
|
|
75
265
|
cols: interactiveDimensionSchema.optional(),
|
|
76
266
|
rows: interactiveDimensionSchema.optional(),
|
|
77
267
|
});
|
|
@@ -96,6 +286,215 @@ export const AgentInteractiveSessionStatusSchema = z.discriminatedUnion("state",
|
|
|
96
286
|
retryable: z.boolean(),
|
|
97
287
|
}),
|
|
98
288
|
]);
|
|
289
|
+
const AgentInteractiveSessionStopCommandMaterialSchema = z
|
|
290
|
+
.strictObject({
|
|
291
|
+
operationId: boundedIdentifierSchema,
|
|
292
|
+
ref: AgentInteractiveSessionRefSchema,
|
|
293
|
+
control: AgentInteractiveSessionControlClaimSchema,
|
|
294
|
+
})
|
|
295
|
+
.superRefine((command, refinement) => {
|
|
296
|
+
if (!agentInteractiveSessionControlClaimMatchesRef(command.ref, command.control)) {
|
|
297
|
+
refinement.addIssue({
|
|
298
|
+
code: "custom",
|
|
299
|
+
path: ["control", "refDigest"],
|
|
300
|
+
message: "interactive stop control claim does not match its process ref",
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
export function agentInteractiveSessionStopRequestDigest(value) {
|
|
305
|
+
const parsed = AgentInteractiveSessionStopCommandMaterialSchema.parse(value);
|
|
306
|
+
return canonicalCandidateDigest({
|
|
307
|
+
kind: "agent-interactive-session-stop.v1",
|
|
308
|
+
operationId: parsed.operationId,
|
|
309
|
+
ref: parsed.ref,
|
|
310
|
+
control: parsed.control,
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
export const AgentInteractiveSessionStopCommandSchema = z
|
|
314
|
+
.strictObject({
|
|
315
|
+
...AgentInteractiveSessionStopCommandMaterialSchema.shape,
|
|
316
|
+
requestDigest: sha256DigestSchema,
|
|
317
|
+
})
|
|
318
|
+
.superRefine((command, refinement) => {
|
|
319
|
+
const { requestDigest: _requestDigest, ...material } = command;
|
|
320
|
+
if (command.requestDigest !==
|
|
321
|
+
agentInteractiveSessionStopRequestDigest(material)) {
|
|
322
|
+
refinement.addIssue({
|
|
323
|
+
code: "custom",
|
|
324
|
+
path: ["requestDigest"],
|
|
325
|
+
message: "interactive stop request digest does not match its content",
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
export const AgentInteractiveSessionStopAcknowledgementSchema = z
|
|
330
|
+
.strictObject({
|
|
331
|
+
operationId: boundedIdentifierSchema,
|
|
332
|
+
requestDigest: sha256DigestSchema,
|
|
333
|
+
ref: AgentInteractiveSessionRefSchema,
|
|
334
|
+
control: AgentInteractiveSessionControlClaimSchema,
|
|
335
|
+
status: z.enum(["accepted", "replayed", "conflict", "unknown"]),
|
|
336
|
+
effect: z.enum(["stop_requested", "stopped", "not_live", "unknown"]),
|
|
337
|
+
message: boundedStringSchema.min(1).optional(),
|
|
338
|
+
retryable: z.boolean().optional(),
|
|
339
|
+
existingRequestDigest: sha256DigestSchema.optional(),
|
|
340
|
+
})
|
|
341
|
+
.superRefine((acknowledgement, refinement) => {
|
|
342
|
+
if (!agentInteractiveSessionControlClaimMatchesRef(acknowledgement.ref, acknowledgement.control)) {
|
|
343
|
+
refinement.addIssue({
|
|
344
|
+
code: "custom",
|
|
345
|
+
path: ["control", "refDigest"],
|
|
346
|
+
message: "interactive stop acknowledgement control does not match its process ref",
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
const known = acknowledgement.effect !== "unknown";
|
|
350
|
+
if (((acknowledgement.status === "accepted" ||
|
|
351
|
+
acknowledgement.status === "replayed") &&
|
|
352
|
+
!known) ||
|
|
353
|
+
((acknowledgement.status === "conflict" ||
|
|
354
|
+
acknowledgement.status === "unknown") &&
|
|
355
|
+
known)) {
|
|
356
|
+
refinement.addIssue({
|
|
357
|
+
code: "custom",
|
|
358
|
+
path: ["effect"],
|
|
359
|
+
message: "interactive stop status and effect certainty do not agree",
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
if (acknowledgement.status === "conflict" &&
|
|
363
|
+
(acknowledgement.existingRequestDigest === undefined ||
|
|
364
|
+
acknowledgement.existingRequestDigest === acknowledgement.requestDigest)) {
|
|
365
|
+
refinement.addIssue({
|
|
366
|
+
code: "custom",
|
|
367
|
+
path: ["existingRequestDigest"],
|
|
368
|
+
message: "an interactive stop conflict must identify a different existing request",
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
if (acknowledgement.status !== "conflict" &&
|
|
372
|
+
acknowledgement.existingRequestDigest !== undefined) {
|
|
373
|
+
refinement.addIssue({
|
|
374
|
+
code: "custom",
|
|
375
|
+
path: ["existingRequestDigest"],
|
|
376
|
+
message: "only an interactive stop conflict may include an existing digest",
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
if (acknowledgement.status === "unknown" &&
|
|
380
|
+
(acknowledgement.message === undefined || acknowledgement.retryable !== true)) {
|
|
381
|
+
refinement.addIssue({
|
|
382
|
+
code: "custom",
|
|
383
|
+
path: ["retryable"],
|
|
384
|
+
message: "an unknown interactive stop outcome must explicitly permit safe same-operation retry",
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
export function agentInteractiveSessionStopAcknowledgementMatchesCommand(command, acknowledgement) {
|
|
389
|
+
const exactCommand = AgentInteractiveSessionStopCommandSchema.safeParse(command);
|
|
390
|
+
const exactAcknowledgement = AgentInteractiveSessionStopAcknowledgementSchema.safeParse(acknowledgement);
|
|
391
|
+
if (!exactCommand.success || !exactAcknowledgement.success)
|
|
392
|
+
return false;
|
|
393
|
+
return (exactAcknowledgement.data.operationId === exactCommand.data.operationId &&
|
|
394
|
+
exactAcknowledgement.data.requestDigest === exactCommand.data.requestDigest &&
|
|
395
|
+
canonicalCandidateDigest(exactAcknowledgement.data.ref) ===
|
|
396
|
+
canonicalCandidateDigest(exactCommand.data.ref) &&
|
|
397
|
+
canonicalCandidateDigest(exactAcknowledgement.data.control) ===
|
|
398
|
+
canonicalCandidateDigest(exactCommand.data.control));
|
|
399
|
+
}
|
|
400
|
+
const AgentInteractiveSessionPromptCommandMaterialSchema = z
|
|
401
|
+
.strictObject({
|
|
402
|
+
operationId: boundedIdentifierSchema,
|
|
403
|
+
ref: AgentInteractiveSessionRefSchema,
|
|
404
|
+
control: AgentInteractiveSessionControlClaimSchema,
|
|
405
|
+
prompt: boundedStringSchema.min(1),
|
|
406
|
+
})
|
|
407
|
+
.superRefine((command, refinement) => {
|
|
408
|
+
if (!agentInteractiveSessionControlClaimMatchesRef(command.ref, command.control)) {
|
|
409
|
+
refinement.addIssue({
|
|
410
|
+
code: "custom",
|
|
411
|
+
path: ["control", "refDigest"],
|
|
412
|
+
message: "interactive prompt control claim does not match its process ref",
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
export function agentInteractiveSessionPromptRequestDigest(value) {
|
|
417
|
+
const parsed = AgentInteractiveSessionPromptCommandMaterialSchema.parse(value);
|
|
418
|
+
return canonicalCandidateDigest({
|
|
419
|
+
kind: "agent-interactive-session-prompt.v1",
|
|
420
|
+
operationId: parsed.operationId,
|
|
421
|
+
ref: parsed.ref,
|
|
422
|
+
control: parsed.control,
|
|
423
|
+
prompt: parsed.prompt,
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
export const AgentInteractiveSessionPromptCommandSchema = z
|
|
427
|
+
.strictObject({
|
|
428
|
+
...AgentInteractiveSessionPromptCommandMaterialSchema.shape,
|
|
429
|
+
requestDigest: sha256DigestSchema,
|
|
430
|
+
})
|
|
431
|
+
.superRefine((command, refinement) => {
|
|
432
|
+
const { requestDigest: _requestDigest, ...material } = command;
|
|
433
|
+
if (command.requestDigest !== agentInteractiveSessionPromptRequestDigest(material)) {
|
|
434
|
+
refinement.addIssue({
|
|
435
|
+
code: "custom",
|
|
436
|
+
path: ["requestDigest"],
|
|
437
|
+
message: "interactive session prompt request digest does not match its content",
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
export const AgentInteractiveSessionPromptAcknowledgementSchema = z
|
|
442
|
+
.strictObject({
|
|
443
|
+
operationId: boundedIdentifierSchema,
|
|
444
|
+
requestDigest: sha256DigestSchema,
|
|
445
|
+
ref: AgentInteractiveSessionRefSchema,
|
|
446
|
+
control: AgentInteractiveSessionControlClaimSchema,
|
|
447
|
+
status: z.enum(["accepted", "replayed", "conflict", "unknown"]),
|
|
448
|
+
message: boundedStringSchema.min(1).optional(),
|
|
449
|
+
retryable: z.boolean().optional(),
|
|
450
|
+
existingRequestDigest: sha256DigestSchema.optional(),
|
|
451
|
+
})
|
|
452
|
+
.superRefine((acknowledgement, refinement) => {
|
|
453
|
+
if (!agentInteractiveSessionControlClaimMatchesRef(acknowledgement.ref, acknowledgement.control)) {
|
|
454
|
+
refinement.addIssue({
|
|
455
|
+
code: "custom",
|
|
456
|
+
path: ["control", "refDigest"],
|
|
457
|
+
message: "interactive prompt acknowledgement control claim does not match its process ref",
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
if (acknowledgement.status === "conflict" &&
|
|
461
|
+
(acknowledgement.existingRequestDigest === undefined ||
|
|
462
|
+
acknowledgement.existingRequestDigest === acknowledgement.requestDigest)) {
|
|
463
|
+
refinement.addIssue({
|
|
464
|
+
code: "custom",
|
|
465
|
+
path: ["existingRequestDigest"],
|
|
466
|
+
message: "an interactive prompt conflict must identify a different existing request",
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
if (acknowledgement.status !== "conflict" &&
|
|
470
|
+
acknowledgement.existingRequestDigest !== undefined) {
|
|
471
|
+
refinement.addIssue({
|
|
472
|
+
code: "custom",
|
|
473
|
+
path: ["existingRequestDigest"],
|
|
474
|
+
message: "only an interactive prompt conflict may include an existing digest",
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
if (acknowledgement.status === "unknown" &&
|
|
478
|
+
(acknowledgement.message === undefined || acknowledgement.retryable !== true)) {
|
|
479
|
+
refinement.addIssue({
|
|
480
|
+
code: "custom",
|
|
481
|
+
path: ["retryable"],
|
|
482
|
+
message: "an unknown interactive prompt outcome must explicitly permit safe same-operation retry",
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
export function agentInteractiveSessionPromptAcknowledgementMatchesCommand(command, acknowledgement) {
|
|
487
|
+
const exactCommand = AgentInteractiveSessionPromptCommandSchema.safeParse(command);
|
|
488
|
+
const exactAcknowledgement = AgentInteractiveSessionPromptAcknowledgementSchema.safeParse(acknowledgement);
|
|
489
|
+
if (!exactCommand.success || !exactAcknowledgement.success)
|
|
490
|
+
return false;
|
|
491
|
+
return (exactAcknowledgement.data.operationId === exactCommand.data.operationId &&
|
|
492
|
+
exactAcknowledgement.data.requestDigest === exactCommand.data.requestDigest &&
|
|
493
|
+
canonicalCandidateDigest(exactAcknowledgement.data.ref) ===
|
|
494
|
+
canonicalCandidateDigest(exactCommand.data.ref) &&
|
|
495
|
+
canonicalCandidateDigest(exactAcknowledgement.data.control) ===
|
|
496
|
+
canonicalCandidateDigest(exactCommand.data.control));
|
|
497
|
+
}
|
|
99
498
|
/** Parse a start request and prove its profile identity before provider work. */
|
|
100
499
|
export function exactAgentInteractiveSessionStart(value) {
|
|
101
500
|
const parsed = AgentInteractiveSessionStartSchema.parse(value);
|
|
@@ -113,18 +512,18 @@ export function exactAgentInteractiveSessionStart(value) {
|
|
|
113
512
|
}
|
|
114
513
|
return parsed;
|
|
115
514
|
}
|
|
116
|
-
/** Prove that a provider returned the exact run
|
|
515
|
+
/** Prove that a provider returned the exact run and preparation receipt requested. */
|
|
117
516
|
export function agentInteractiveSessionRefMatchesStart(request, ref) {
|
|
118
517
|
const parsedRequest = AgentInteractiveSessionStartSchema.safeParse(request);
|
|
119
518
|
const parsedRef = AgentInteractiveSessionRefSchema.safeParse(ref);
|
|
120
519
|
if (!parsedRequest.success || !parsedRef.success)
|
|
121
520
|
return false;
|
|
122
|
-
const
|
|
123
|
-
if (
|
|
521
|
+
const requestedHarness = parsedRequest.data.profile.harness;
|
|
522
|
+
if (requestedHarness === undefined)
|
|
124
523
|
return false;
|
|
125
|
-
return (parsedRef.data.
|
|
524
|
+
return (parsedRef.data.preparationReceipt.authoredProfileDigest ===
|
|
126
525
|
parsedRequest.data.requestedProfileDigest &&
|
|
127
|
-
parsedRef.data.harness ===
|
|
526
|
+
parsedRef.data.preparationReceipt.harness === requestedHarness &&
|
|
128
527
|
sameExactRun(parsedRef.data.run, parsedRequest.data.run));
|
|
129
528
|
}
|
|
130
529
|
/** Prove that a status belongs to the handle that requested it. */
|
|
@@ -134,10 +533,9 @@ export function agentInteractiveSessionStatusMatchesRef(ref, status) {
|
|
|
134
533
|
if (!parsedRef.success || !parsedStatus.success)
|
|
135
534
|
return false;
|
|
136
535
|
const observed = parsedStatus.data.ref;
|
|
137
|
-
return (observed.
|
|
138
|
-
|
|
536
|
+
return (observed.preparationReceipt.digest ===
|
|
537
|
+
parsedRef.data.preparationReceipt.digest &&
|
|
139
538
|
observed.incarnationId === parsedRef.data.incarnationId &&
|
|
140
|
-
observed.harness === parsedRef.data.harness &&
|
|
141
539
|
observed.startedAt === parsedRef.data.startedAt &&
|
|
142
540
|
sameExactRun(observed.run, parsedRef.data.run));
|
|
143
541
|
}
|
|
@@ -776,6 +776,8 @@ export interface AgentEnvironmentCapabilities {
|
|
|
776
776
|
/** Present only when the provider can start and rediscover exact agent TUIs. */
|
|
777
777
|
interactiveAgent?: {
|
|
778
778
|
start: boolean;
|
|
779
|
+
/** Provider-issued generation claims fence recovered coordinators. */
|
|
780
|
+
control: boolean;
|
|
779
781
|
status: boolean;
|
|
780
782
|
attach: boolean;
|
|
781
783
|
reattach: boolean;
|
|
@@ -895,6 +897,7 @@ export declare const AgentEnvironmentCapabilitiesSchema: z.ZodObject<{
|
|
|
895
897
|
}, z.core.$strict>>;
|
|
896
898
|
interactiveAgent: z.ZodOptional<z.ZodObject<{
|
|
897
899
|
start: z.ZodBoolean;
|
|
900
|
+
control: z.ZodBoolean;
|
|
898
901
|
status: z.ZodBoolean;
|
|
899
902
|
attach: z.ZodBoolean;
|
|
900
903
|
reattach: z.ZodBoolean;
|
|
@@ -192,6 +192,7 @@ export const AgentEnvironmentCapabilitiesSchema = z
|
|
|
192
192
|
interactiveAgent: z
|
|
193
193
|
.strictObject({
|
|
194
194
|
start: z.boolean(),
|
|
195
|
+
control: z.boolean(),
|
|
195
196
|
status: z.boolean(),
|
|
196
197
|
attach: z.boolean(),
|
|
197
198
|
reattach: z.boolean(),
|
|
@@ -277,6 +278,19 @@ export const AgentEnvironmentCapabilitiesSchema = z
|
|
|
277
278
|
message: "interactive agent status, attach, reattach, sendPrompt, input, resize, and stop each require start",
|
|
278
279
|
});
|
|
279
280
|
}
|
|
281
|
+
if (interactiveAgent !== undefined &&
|
|
282
|
+
(interactiveAgent.attach ||
|
|
283
|
+
interactiveAgent.sendPrompt ||
|
|
284
|
+
interactiveAgent.input ||
|
|
285
|
+
interactiveAgent.resize ||
|
|
286
|
+
interactiveAgent.stop) &&
|
|
287
|
+
!interactiveAgent.control) {
|
|
288
|
+
refinement.addIssue({
|
|
289
|
+
code: "custom",
|
|
290
|
+
path: ["interactiveAgent", "control"],
|
|
291
|
+
message: "interactive agent mutation requires provider-issued control claims",
|
|
292
|
+
});
|
|
293
|
+
}
|
|
280
294
|
if (interactiveAgent !== undefined &&
|
|
281
295
|
(interactiveAgent.reattach || interactiveAgent.input || interactiveAgent.resize) &&
|
|
282
296
|
!interactiveAgent.attach) {
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export * from "./host-services.js";
|
|
|
8
8
|
export * from "./mcp.js";
|
|
9
9
|
export * from "./provider-adapter.js";
|
|
10
10
|
export type * from "./environment-provider.js";
|
|
11
|
-
export { AgentEnvironmentCapabilitiesSchema, AgentNativeContextContinuationResultSchema, AgentTurnInputSchema, AgentTurnResultSchema, agentNativeContextContinuationResultMatchesRequest, AccountUsageSchema, AgentEnvironmentObservationSchema, AgentEnvironmentStatusSchema, ComputeBillingSchema, EnvironmentLifecycleSchema, ModelUsageSchema, ObservationProvenanceSchema, ObservationStateSchema, PlacementDescriptorSchema, ProviderIdentitySchema, ResourceProfileSchema, ResourceUseSampleSchema, SafeEndpointSchema, agentEnvironmentObservationIdentityMatches, assertObservationCredentialFree, observationContainsCredential, observationOf, AgentInteractiveSessionAttachSchema, AgentInteractiveSessionRefSchema, AgentInteractiveSessionStartSchema, AgentInteractiveSessionStatusSchema, agentInteractiveSessionRequestDigest, agentInteractiveSessionRefMatchesStart, agentInteractiveSessionRunRef, agentInteractiveSessionStatusMatchesRef, exactAgentInteractiveSessionStart, TerminalAttachRequestSchema, TerminalAttachResultSchema, TerminalDetachAckSchema, TerminalInputSchema, TerminalOutputEventSchema, TerminalReplayWindowSchema, TerminalResizeSchema, TerminalSessionRefSchema, terminalAttachResultMatchesRequest, terminalSessionUsable, } from "./environment-provider.js";
|
|
11
|
+
export { AgentEnvironmentCapabilitiesSchema, AgentNativeContextContinuationResultSchema, AgentTurnInputSchema, AgentTurnResultSchema, agentNativeContextContinuationResultMatchesRequest, AccountUsageSchema, AgentEnvironmentObservationSchema, AgentEnvironmentStatusSchema, ComputeBillingSchema, EnvironmentLifecycleSchema, ModelUsageSchema, ObservationProvenanceSchema, ObservationStateSchema, PlacementDescriptorSchema, ProviderIdentitySchema, ResourceProfileSchema, ResourceUseSampleSchema, SafeEndpointSchema, agentEnvironmentObservationIdentityMatches, assertObservationCredentialFree, observationContainsCredential, observationOf, AgentInteractiveSessionAttachSchema, AgentInteractiveSessionControlClaimAcknowledgementSchema, AgentInteractiveSessionControlClaimRequestSchema, AgentInteractiveSessionControlClaimSchema, AgentInteractiveSessionPromptAcknowledgementSchema, AgentInteractiveSessionPromptCommandSchema, AgentInteractiveSessionRefSchema, AgentInteractiveSessionStartSchema, AgentInteractiveSessionStopAcknowledgementSchema, AgentInteractiveSessionStopCommandSchema, AgentInteractiveSessionStatusSchema, agentInteractiveSessionControlClaimAcknowledgementMatchesRequest, agentInteractiveSessionControlClaimRequestDigest, agentInteractiveSessionControlClaimMatchesRef, agentInteractiveSessionControlClaimIsNewer, agentInteractiveSessionPromptAcknowledgementMatchesCommand, agentInteractiveSessionPromptRequestDigest, agentInteractiveSessionStopAcknowledgementMatchesCommand, agentInteractiveSessionStopRequestDigest, agentInteractiveSessionRequestDigest, agentInteractiveSessionRefMatchesStart, agentInteractiveSessionRunRef, agentInteractiveSessionStatusMatchesRef, exactAgentInteractiveSessionStart, TerminalAttachRequestSchema, TerminalAttachResultSchema, TerminalDetachAckSchema, TerminalInputSchema, TerminalOutputEventSchema, TerminalReplayWindowSchema, TerminalResizeSchema, TerminalSessionRefSchema, terminalAttachResultMatchesRequest, terminalSessionUsable, } from "./environment-provider.js";
|
|
12
12
|
export * from "./plan.js";
|
|
13
13
|
export * from "./runtime-control.js";
|
|
14
14
|
export * from "./portable-context.js";
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ export * from "./provider-config.js";
|
|
|
7
7
|
export * from "./host-services.js";
|
|
8
8
|
export * from "./mcp.js";
|
|
9
9
|
export * from "./provider-adapter.js";
|
|
10
|
-
export { AgentEnvironmentCapabilitiesSchema, AgentNativeContextContinuationResultSchema, AgentTurnInputSchema, AgentTurnResultSchema, agentNativeContextContinuationResultMatchesRequest, AccountUsageSchema, AgentEnvironmentObservationSchema, AgentEnvironmentStatusSchema, ComputeBillingSchema, EnvironmentLifecycleSchema, ModelUsageSchema, ObservationProvenanceSchema, ObservationStateSchema, PlacementDescriptorSchema, ProviderIdentitySchema, ResourceProfileSchema, ResourceUseSampleSchema, SafeEndpointSchema, agentEnvironmentObservationIdentityMatches, assertObservationCredentialFree, observationContainsCredential, observationOf, AgentInteractiveSessionAttachSchema, AgentInteractiveSessionRefSchema, AgentInteractiveSessionStartSchema, AgentInteractiveSessionStatusSchema, agentInteractiveSessionRequestDigest, agentInteractiveSessionRefMatchesStart, agentInteractiveSessionRunRef, agentInteractiveSessionStatusMatchesRef, exactAgentInteractiveSessionStart, TerminalAttachRequestSchema, TerminalAttachResultSchema, TerminalDetachAckSchema, TerminalInputSchema, TerminalOutputEventSchema, TerminalReplayWindowSchema, TerminalResizeSchema, TerminalSessionRefSchema, terminalAttachResultMatchesRequest, terminalSessionUsable, } from "./environment-provider.js";
|
|
10
|
+
export { AgentEnvironmentCapabilitiesSchema, AgentNativeContextContinuationResultSchema, AgentTurnInputSchema, AgentTurnResultSchema, agentNativeContextContinuationResultMatchesRequest, AccountUsageSchema, AgentEnvironmentObservationSchema, AgentEnvironmentStatusSchema, ComputeBillingSchema, EnvironmentLifecycleSchema, ModelUsageSchema, ObservationProvenanceSchema, ObservationStateSchema, PlacementDescriptorSchema, ProviderIdentitySchema, ResourceProfileSchema, ResourceUseSampleSchema, SafeEndpointSchema, agentEnvironmentObservationIdentityMatches, assertObservationCredentialFree, observationContainsCredential, observationOf, AgentInteractiveSessionAttachSchema, AgentInteractiveSessionControlClaimAcknowledgementSchema, AgentInteractiveSessionControlClaimRequestSchema, AgentInteractiveSessionControlClaimSchema, AgentInteractiveSessionPromptAcknowledgementSchema, AgentInteractiveSessionPromptCommandSchema, AgentInteractiveSessionRefSchema, AgentInteractiveSessionStartSchema, AgentInteractiveSessionStopAcknowledgementSchema, AgentInteractiveSessionStopCommandSchema, AgentInteractiveSessionStatusSchema, agentInteractiveSessionControlClaimAcknowledgementMatchesRequest, agentInteractiveSessionControlClaimRequestDigest, agentInteractiveSessionControlClaimMatchesRef, agentInteractiveSessionControlClaimIsNewer, agentInteractiveSessionPromptAcknowledgementMatchesCommand, agentInteractiveSessionPromptRequestDigest, agentInteractiveSessionStopAcknowledgementMatchesCommand, agentInteractiveSessionStopRequestDigest, agentInteractiveSessionRequestDigest, agentInteractiveSessionRefMatchesStart, agentInteractiveSessionRunRef, agentInteractiveSessionStatusMatchesRef, exactAgentInteractiveSessionStart, TerminalAttachRequestSchema, TerminalAttachResultSchema, TerminalDetachAckSchema, TerminalInputSchema, TerminalOutputEventSchema, TerminalReplayWindowSchema, TerminalResizeSchema, TerminalSessionRefSchema, terminalAttachResultMatchesRequest, terminalSessionUsable, } from "./environment-provider.js";
|
|
11
11
|
export * from "./plan.js";
|
|
12
12
|
export * from "./runtime-control.js";
|
|
13
13
|
export * from "./portable-context.js";
|