@tangle-network/agent-interface 0.41.0 → 0.42.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 CHANGED
@@ -30,7 +30,11 @@ Partial input or output always requires explicit user or policy acceptance, even
30
30
  `contextTransferResultMatchesRequest()` checks the operation identifier and request digest for every outcome before a caller accepts, retries, or reports it.
31
31
  Its successful receipt repeats the exact destination and carries the provider's session-creation operation and timestamp, identifying the one fresh provider session that admitted the context.
32
32
  `NativeContextBoundaryProof` is the separate path for same-session continuation and includes the exact run identity.
33
- Continuation is valid only when the provider proves the recorded token, revision, digest, or message boundary, sends zero copied history, and applies retry or changed-input conflict semantics.
33
+ `NativeContextContinuationRequest.turnDigest` binds the operation to the exact new JSON-stable user turn; timeout and abort controls live outside that turn under `AgentNativeContextContinuationOptions`.
34
+ Continuation is valid only when the provider atomically proves the recorded token, revision, digest, or message boundary, sends zero copied history, and applies retry or changed-input conflict semantics.
35
+ Providers advertise `nativeContinuation` only when both guarantees are implemented and expose `AgentSession.continueNative()` as the single durable operation.
36
+ An accepted or replayed operation returns its original turn result and exact current control reference; `AgentNativeContextContinuationResultSchema` validates that shape and `agentNativeContextContinuationResultMatchesRequest()` checks its request and retained-session bindings.
37
+ A changed request with the same operation identifier conflicts without dispatch.
34
38
 
35
39
  Providers that support recoverable workspace copies expose `workspaceBranching` and set `branching.retrySafe`, `branching.lookup`, and `branching.cleanup` together.
36
40
  Checkpoint and fork requests bind an idempotency key to a canonical request digest.
@@ -39,7 +43,7 @@ A checkpoint with dependent forks returns `in_use` plus the blocking environment
39
43
  The older `checkpoint()` and `fork()` methods remain source-compatible for providers that have not yet implemented recovery semantics, but clients must not present them as durable workspace branching.
40
44
 
41
45
  All new wire values have exported Zod schemas on the package root.
42
- Omitting `interactions` or leaving the three durable branching flags false is the compatible declaration for existing providers.
46
+ Omitting `interactions` and `nativeContinuation`, or leaving the three durable branching flags false, is the compatible declaration for existing providers.
43
47
 
44
48
  ## Install
45
49
 
@@ -3,8 +3,8 @@ import type { AgentProfile, AgentProfileCapabilities, AgentProfileValidationResu
3
3
  import type { AgentCandidateTermination } from "./agent-candidate.js";
4
4
  import type { InputPart, StreamEvent, TokenUsage } from "./index.js";
5
5
  import { type InteractionAcknowledgement, type InteractionCapabilities, type InteractionResponseCommand } from "./interaction.js";
6
- import type { ContextTransferReceipt, ContextTransferRequest, NativeContextBoundaryProof, NativeContextContinuationRequest } from "./portable-context.js";
7
- import type { AgentRunControlRef } from "./runtime-control.js";
6
+ import { type ContextTransferReceipt, type ContextTransferRequest, type NativeContextBoundaryProof, type NativeContextContinuationRequest, type NativeContextContinuationTurn } from "./portable-context.js";
7
+ import { type AgentRunControlRef } from "./runtime-control.js";
8
8
  import type { AgentWorkspaceBranching } from "./workspace-branching.js";
9
9
  /** Portable profile reference: inline profile or provider catalog id. */
10
10
  export type AgentProfileRef = AgentProfile | string;
@@ -227,6 +227,262 @@ export interface AgentTurnResult {
227
227
  events?: AgentEnvironmentEvent[];
228
228
  contextTransferReceipt?: ContextTransferReceipt;
229
229
  }
230
+ /** Runtime validator for a provider turn returned from durable continuation. */
231
+ export declare const AgentTurnResultSchema: z.ZodObject<{
232
+ text: z.ZodString;
233
+ success: z.ZodBoolean;
234
+ error: z.ZodOptional<z.ZodString>;
235
+ sessionId: z.ZodOptional<z.ZodString>;
236
+ usage: z.ZodOptional<z.ZodObject<{
237
+ inputTokens: z.ZodNumber;
238
+ outputTokens: z.ZodNumber;
239
+ totalTokens: z.ZodOptional<z.ZodNumber>;
240
+ cacheReadInputTokens: z.ZodOptional<z.ZodNumber>;
241
+ cacheCreationInputTokens: z.ZodOptional<z.ZodNumber>;
242
+ reasoningTokens: z.ZodOptional<z.ZodNumber>;
243
+ cost: z.ZodOptional<z.ZodNumber>;
244
+ }, z.core.$strict>>;
245
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
246
+ events: z.ZodOptional<z.ZodArray<z.ZodObject<{
247
+ type: z.ZodString;
248
+ data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
249
+ id: z.ZodOptional<z.ZodString>;
250
+ normalized: z.ZodOptional<z.ZodType<StreamEvent, unknown, z.core.$ZodTypeInternals<StreamEvent, unknown>>>;
251
+ usage: z.ZodOptional<z.ZodObject<{
252
+ inputTokens: z.ZodNumber;
253
+ outputTokens: z.ZodNumber;
254
+ totalTokens: z.ZodOptional<z.ZodNumber>;
255
+ cacheReadInputTokens: z.ZodOptional<z.ZodNumber>;
256
+ cacheCreationInputTokens: z.ZodOptional<z.ZodNumber>;
257
+ reasoningTokens: z.ZodOptional<z.ZodNumber>;
258
+ cost: z.ZodOptional<z.ZodNumber>;
259
+ }, z.core.$strict>>;
260
+ providerEvent: z.ZodOptional<z.ZodUnknown>;
261
+ }, z.core.$strict>>>;
262
+ contextTransferReceipt: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
263
+ status: z.ZodLiteral<"accepted" | "replayed">;
264
+ operationId: z.ZodString;
265
+ requestDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
266
+ planDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
267
+ contextDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
268
+ destination: z.ZodObject<{
269
+ runner: z.ZodString;
270
+ provider: z.ZodOptional<z.ZodString>;
271
+ model: z.ZodOptional<z.ZodString>;
272
+ profileDigest: z.ZodOptional<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
273
+ }, z.core.$strict>;
274
+ provider: z.ZodString;
275
+ environmentId: z.ZodString;
276
+ sessionId: z.ZodString;
277
+ sessionCreatedForOperationId: z.ZodString;
278
+ sessionCreatedAt: z.ZodISODateTime;
279
+ transferredMessageIds: z.ZodArray<z.ZodString>;
280
+ omittedMessageIds: z.ZodArray<z.ZodString>;
281
+ admittedAt: z.ZodISODateTime;
282
+ }, z.core.$strict>, z.ZodObject<{
283
+ status: z.ZodLiteral<"accepted" | "replayed">;
284
+ operationId: z.ZodString;
285
+ requestDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
286
+ planDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
287
+ contextDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
288
+ destination: z.ZodObject<{
289
+ runner: z.ZodString;
290
+ provider: z.ZodOptional<z.ZodString>;
291
+ model: z.ZodOptional<z.ZodString>;
292
+ profileDigest: z.ZodOptional<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
293
+ }, z.core.$strict>;
294
+ provider: z.ZodString;
295
+ environmentId: z.ZodString;
296
+ sessionId: z.ZodString;
297
+ sessionCreatedForOperationId: z.ZodString;
298
+ sessionCreatedAt: z.ZodISODateTime;
299
+ transferredMessageIds: z.ZodArray<z.ZodString>;
300
+ omittedMessageIds: z.ZodArray<z.ZodString>;
301
+ admittedAt: z.ZodISODateTime;
302
+ }, z.core.$strict>], "status">>;
303
+ }, z.core.$strict>;
304
+ /** Durable provider result for one digest-bound native continuation operation. */
305
+ export declare const AgentNativeContextContinuationResultSchema: z.ZodUnion<readonly [z.ZodObject<{
306
+ acknowledgement: z.ZodIntersection<z.ZodObject<{
307
+ operationId: z.ZodString;
308
+ requestDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
309
+ status: z.ZodEnum<{
310
+ conflict: "conflict";
311
+ accepted: "accepted";
312
+ transport_failure: "transport_failure";
313
+ replayed: "replayed";
314
+ boundary_mismatch: "boundary_mismatch";
315
+ unverified: "unverified";
316
+ unknown_session: "unknown_session";
317
+ }>;
318
+ historyMessagesSent: z.ZodNumber;
319
+ existingRequestDigest: z.ZodOptional<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
320
+ actualBoundary: z.ZodOptional<z.ZodObject<{
321
+ runId: z.ZodString;
322
+ provider: z.ZodString;
323
+ environmentId: z.ZodString;
324
+ sessionId: z.ZodString;
325
+ boundary: z.ZodDiscriminatedUnion<[z.ZodObject<{
326
+ kind: z.ZodLiteral<"token">;
327
+ token: z.ZodString;
328
+ }, z.core.$strict>, z.ZodObject<{
329
+ kind: z.ZodLiteral<"revision">;
330
+ revision: z.ZodString;
331
+ }, z.core.$strict>, z.ZodObject<{
332
+ kind: z.ZodLiteral<"digest">;
333
+ digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
334
+ }, z.core.$strict>, z.ZodObject<{
335
+ kind: z.ZodLiteral<"messages">;
336
+ messageIds: z.ZodArray<z.ZodString>;
337
+ digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
338
+ }, z.core.$strict>], "kind">;
339
+ observedAt: z.ZodISODateTime;
340
+ }, z.core.$strict>>;
341
+ message: z.ZodOptional<z.ZodString>;
342
+ retryable: z.ZodOptional<z.ZodBoolean>;
343
+ }, z.core.$strict>, z.ZodObject<{
344
+ status: z.ZodEnum<{
345
+ accepted: "accepted";
346
+ replayed: "replayed";
347
+ }>;
348
+ }, z.core.$strip>>;
349
+ result: z.ZodObject<{
350
+ text: z.ZodString;
351
+ success: z.ZodBoolean;
352
+ error: z.ZodOptional<z.ZodString>;
353
+ sessionId: z.ZodOptional<z.ZodString>;
354
+ usage: z.ZodOptional<z.ZodObject<{
355
+ inputTokens: z.ZodNumber;
356
+ outputTokens: z.ZodNumber;
357
+ totalTokens: z.ZodOptional<z.ZodNumber>;
358
+ cacheReadInputTokens: z.ZodOptional<z.ZodNumber>;
359
+ cacheCreationInputTokens: z.ZodOptional<z.ZodNumber>;
360
+ reasoningTokens: z.ZodOptional<z.ZodNumber>;
361
+ cost: z.ZodOptional<z.ZodNumber>;
362
+ }, z.core.$strict>>;
363
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
364
+ events: z.ZodOptional<z.ZodArray<z.ZodObject<{
365
+ type: z.ZodString;
366
+ data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
367
+ id: z.ZodOptional<z.ZodString>;
368
+ normalized: z.ZodOptional<z.ZodType<StreamEvent, unknown, z.core.$ZodTypeInternals<StreamEvent, unknown>>>;
369
+ usage: z.ZodOptional<z.ZodObject<{
370
+ inputTokens: z.ZodNumber;
371
+ outputTokens: z.ZodNumber;
372
+ totalTokens: z.ZodOptional<z.ZodNumber>;
373
+ cacheReadInputTokens: z.ZodOptional<z.ZodNumber>;
374
+ cacheCreationInputTokens: z.ZodOptional<z.ZodNumber>;
375
+ reasoningTokens: z.ZodOptional<z.ZodNumber>;
376
+ cost: z.ZodOptional<z.ZodNumber>;
377
+ }, z.core.$strict>>;
378
+ providerEvent: z.ZodOptional<z.ZodUnknown>;
379
+ }, z.core.$strict>>>;
380
+ contextTransferReceipt: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
381
+ status: z.ZodLiteral<"accepted" | "replayed">;
382
+ operationId: z.ZodString;
383
+ requestDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
384
+ planDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
385
+ contextDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
386
+ destination: z.ZodObject<{
387
+ runner: z.ZodString;
388
+ provider: z.ZodOptional<z.ZodString>;
389
+ model: z.ZodOptional<z.ZodString>;
390
+ profileDigest: z.ZodOptional<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
391
+ }, z.core.$strict>;
392
+ provider: z.ZodString;
393
+ environmentId: z.ZodString;
394
+ sessionId: z.ZodString;
395
+ sessionCreatedForOperationId: z.ZodString;
396
+ sessionCreatedAt: z.ZodISODateTime;
397
+ transferredMessageIds: z.ZodArray<z.ZodString>;
398
+ omittedMessageIds: z.ZodArray<z.ZodString>;
399
+ admittedAt: z.ZodISODateTime;
400
+ }, z.core.$strict>, z.ZodObject<{
401
+ status: z.ZodLiteral<"accepted" | "replayed">;
402
+ operationId: z.ZodString;
403
+ requestDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
404
+ planDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
405
+ contextDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
406
+ destination: z.ZodObject<{
407
+ runner: z.ZodString;
408
+ provider: z.ZodOptional<z.ZodString>;
409
+ model: z.ZodOptional<z.ZodString>;
410
+ profileDigest: z.ZodOptional<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
411
+ }, z.core.$strict>;
412
+ provider: z.ZodString;
413
+ environmentId: z.ZodString;
414
+ sessionId: z.ZodString;
415
+ sessionCreatedForOperationId: z.ZodString;
416
+ sessionCreatedAt: z.ZodISODateTime;
417
+ transferredMessageIds: z.ZodArray<z.ZodString>;
418
+ omittedMessageIds: z.ZodArray<z.ZodString>;
419
+ admittedAt: z.ZodISODateTime;
420
+ }, z.core.$strict>], "status">>;
421
+ }, z.core.$strict>;
422
+ controlRef: z.ZodObject<{
423
+ runId: z.ZodString;
424
+ provider: z.ZodString;
425
+ environmentId: z.ZodString;
426
+ sessionId: z.ZodOptional<z.ZodString>;
427
+ executionId: z.ZodOptional<z.ZodString>;
428
+ }, z.core.$strict>;
429
+ }, z.core.$strict>, z.ZodObject<{
430
+ acknowledgement: z.ZodIntersection<z.ZodObject<{
431
+ operationId: z.ZodString;
432
+ requestDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
433
+ status: z.ZodEnum<{
434
+ conflict: "conflict";
435
+ accepted: "accepted";
436
+ transport_failure: "transport_failure";
437
+ replayed: "replayed";
438
+ boundary_mismatch: "boundary_mismatch";
439
+ unverified: "unverified";
440
+ unknown_session: "unknown_session";
441
+ }>;
442
+ historyMessagesSent: z.ZodNumber;
443
+ existingRequestDigest: z.ZodOptional<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
444
+ actualBoundary: z.ZodOptional<z.ZodObject<{
445
+ runId: z.ZodString;
446
+ provider: z.ZodString;
447
+ environmentId: z.ZodString;
448
+ sessionId: z.ZodString;
449
+ boundary: z.ZodDiscriminatedUnion<[z.ZodObject<{
450
+ kind: z.ZodLiteral<"token">;
451
+ token: z.ZodString;
452
+ }, z.core.$strict>, z.ZodObject<{
453
+ kind: z.ZodLiteral<"revision">;
454
+ revision: z.ZodString;
455
+ }, z.core.$strict>, z.ZodObject<{
456
+ kind: z.ZodLiteral<"digest">;
457
+ digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
458
+ }, z.core.$strict>, z.ZodObject<{
459
+ kind: z.ZodLiteral<"messages">;
460
+ messageIds: z.ZodArray<z.ZodString>;
461
+ digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
462
+ }, z.core.$strict>], "kind">;
463
+ observedAt: z.ZodISODateTime;
464
+ }, z.core.$strict>>;
465
+ message: z.ZodOptional<z.ZodString>;
466
+ retryable: z.ZodOptional<z.ZodBoolean>;
467
+ }, z.core.$strict>, z.ZodObject<{
468
+ status: z.ZodEnum<{
469
+ conflict: "conflict";
470
+ transport_failure: "transport_failure";
471
+ boundary_mismatch: "boundary_mismatch";
472
+ unverified: "unverified";
473
+ unknown_session: "unknown_session";
474
+ }>;
475
+ }, z.core.$strip>>;
476
+ }, z.core.$strict>]>;
477
+ export type AgentNativeContextContinuationResult = z.infer<typeof AgentNativeContextContinuationResultSchema>;
478
+ /** Runtime-only controls kept outside the digest-bound user turn. */
479
+ export interface AgentNativeContextContinuationOptions {
480
+ turn: NativeContextContinuationTurn;
481
+ timeoutMs?: number;
482
+ signal?: AbortSignal;
483
+ }
484
+ /** Cross-check a successful result against its exact request and retained session. */
485
+ export declare function agentNativeContextContinuationResultMatchesRequest(request: NativeContextContinuationRequest, outcome: AgentNativeContextContinuationResult): boolean;
230
486
  export interface AgentSessionRef {
231
487
  id: string;
232
488
  provider?: string;
@@ -261,6 +517,12 @@ export interface AgentSession {
261
517
  contextBoundary?(options?: {
262
518
  signal?: AbortSignal;
263
519
  }): Promise<NativeContextBoundaryProof | null>;
520
+ /**
521
+ * Atomically verify the boundary and admit one digest-bound continuation.
522
+ * Repeating an operation id with the same request returns the original result;
523
+ * repeating it with a different request returns a conflict without dispatch.
524
+ */
525
+ continueNative?(request: NativeContextContinuationRequest, options: AgentNativeContextContinuationOptions): Promise<AgentNativeContextContinuationResult>;
264
526
  cancel(): Promise<void>;
265
527
  }
266
528
  export interface AgentEnvironment {
@@ -304,6 +566,13 @@ export interface AgentEnvironmentCapabilities {
304
566
  list: boolean;
305
567
  messages: boolean;
306
568
  };
569
+ /** Absent when verified, retry-safe same-session continuation is unsupported. */
570
+ nativeContinuation?: {
571
+ /** Boundary comparison and operation admission are one atomic provider action. */
572
+ atomicBoundary: boolean;
573
+ /** Operation id + request digest recover retries and reject changed input. */
574
+ requestIdempotency: boolean;
575
+ };
307
576
  /** Absent when the provider cannot originate or answer interactions. */
308
577
  interactions?: InteractionCapabilities;
309
578
  workspace: {
@@ -367,6 +636,10 @@ export declare const AgentEnvironmentCapabilitiesSchema: z.ZodObject<{
367
636
  list: z.ZodBoolean;
368
637
  messages: z.ZodBoolean;
369
638
  }, z.core.$strict>;
639
+ nativeContinuation: z.ZodOptional<z.ZodObject<{
640
+ atomicBoundary: z.ZodBoolean;
641
+ requestIdempotency: z.ZodBoolean;
642
+ }, z.core.$strict>>;
370
643
  interactions: z.ZodOptional<z.ZodObject<{
371
644
  kinds: z.ZodArray<z.ZodString>;
372
645
  answerFieldTypes: z.ZodArray<z.ZodEnum<{
@@ -27,6 +27,102 @@ const AgentProfileCapabilitiesSchema = z.strictObject({
27
27
  validation: z.boolean(),
28
28
  extensions: z.array(z.string().min(1)).optional(),
29
29
  });
30
+ import { ContextTransferReceiptSchema, NativeContextContinuationAcknowledgementSchema, NativeContextContinuationRequestSchema, nativeContextContinuationAcknowledgementMatches, } from "./portable-context.js";
31
+ import { AgentRunControlRefSchema, CanonicalStreamEventSchema, } from "./runtime-control.js";
32
+ const TokenUsageSchema = z.strictObject({
33
+ inputTokens: z.number().int().nonnegative(),
34
+ outputTokens: z.number().int().nonnegative(),
35
+ totalTokens: z.number().int().nonnegative().optional(),
36
+ cacheReadInputTokens: z.number().int().nonnegative().optional(),
37
+ cacheCreationInputTokens: z.number().int().nonnegative().optional(),
38
+ reasoningTokens: z.number().int().nonnegative().optional(),
39
+ cost: z.number().finite().nonnegative().optional(),
40
+ });
41
+ const AgentEnvironmentEventSchema = z.strictObject({
42
+ type: z.string().min(1),
43
+ data: z.record(z.string(), z.unknown()),
44
+ id: z.string().min(1).optional(),
45
+ normalized: CanonicalStreamEventSchema.optional(),
46
+ usage: TokenUsageSchema.optional(),
47
+ providerEvent: z.unknown().optional(),
48
+ });
49
+ /** Runtime validator for a provider turn returned from durable continuation. */
50
+ export const AgentTurnResultSchema = z.strictObject({
51
+ text: z.string(),
52
+ success: z.boolean(),
53
+ error: z.string().optional(),
54
+ sessionId: z.string().min(1).optional(),
55
+ usage: TokenUsageSchema.optional(),
56
+ metadata: z.record(z.string(), z.unknown()).optional(),
57
+ events: z.array(AgentEnvironmentEventSchema).optional(),
58
+ contextTransferReceipt: ContextTransferReceiptSchema.optional(),
59
+ });
60
+ /** Durable provider result for one digest-bound native continuation operation. */
61
+ export const AgentNativeContextContinuationResultSchema = z.union([
62
+ z
63
+ .strictObject({
64
+ acknowledgement: NativeContextContinuationAcknowledgementSchema.and(z.object({ status: z.enum(["accepted", "replayed"]) })),
65
+ result: AgentTurnResultSchema,
66
+ /** Exact provider coordinates after the continuation completed. */
67
+ controlRef: AgentRunControlRefSchema,
68
+ })
69
+ .superRefine((outcome, refinement) => {
70
+ if (outcome.result.contextTransferReceipt !== undefined) {
71
+ refinement.addIssue({
72
+ code: "custom",
73
+ path: ["result", "contextTransferReceipt"],
74
+ message: "native continuation cannot return a context transfer receipt",
75
+ });
76
+ }
77
+ }),
78
+ z
79
+ .strictObject({
80
+ acknowledgement: NativeContextContinuationAcknowledgementSchema.and(z.object({
81
+ status: z.enum([
82
+ "conflict",
83
+ "boundary_mismatch",
84
+ "unverified",
85
+ "unknown_session",
86
+ "transport_failure",
87
+ ]),
88
+ })),
89
+ })
90
+ .superRefine((outcome, refinement) => {
91
+ if (outcome.acknowledgement.status === "transport_failure" &&
92
+ outcome.acknowledgement.retryable !== true) {
93
+ refinement.addIssue({
94
+ code: "custom",
95
+ path: ["acknowledgement", "retryable"],
96
+ message: "a durable native continuation transport failure must be retryable",
97
+ });
98
+ }
99
+ }),
100
+ ]);
101
+ /** Cross-check a successful result against its exact request and retained session. */
102
+ export function agentNativeContextContinuationResultMatchesRequest(request, outcome) {
103
+ const parsedRequest = NativeContextContinuationRequestSchema.safeParse(request);
104
+ const parsedOutcome = AgentNativeContextContinuationResultSchema.safeParse(outcome);
105
+ if (!parsedRequest.success || !parsedOutcome.success)
106
+ return false;
107
+ const exactOutcome = parsedOutcome.data;
108
+ if (exactOutcome.acknowledgement.status !== "accepted" &&
109
+ exactOutcome.acknowledgement.status !== "replayed") {
110
+ return false;
111
+ }
112
+ if (!("result" in exactOutcome) || !("controlRef" in exactOutcome)) {
113
+ return false;
114
+ }
115
+ if (!nativeContextContinuationAcknowledgementMatches(parsedRequest.data, exactOutcome.acknowledgement)) {
116
+ return false;
117
+ }
118
+ const source = parsedRequest.data.run;
119
+ const current = exactOutcome.controlRef;
120
+ return (current.provider === source.provider &&
121
+ current.environmentId === source.environmentId &&
122
+ current.sessionId === source.sessionId &&
123
+ (exactOutcome.result.sessionId === undefined ||
124
+ exactOutcome.result.sessionId === current.sessionId));
125
+ }
30
126
  /** Strict runtime validator for provider capability negotiation. */
31
127
  export const AgentEnvironmentCapabilitiesSchema = z
32
128
  .strictObject({
@@ -42,6 +138,12 @@ export const AgentEnvironmentCapabilitiesSchema = z
42
138
  list: z.boolean(),
43
139
  messages: z.boolean(),
44
140
  }),
141
+ nativeContinuation: z
142
+ .strictObject({
143
+ atomicBoundary: z.boolean(),
144
+ requestIdempotency: z.boolean(),
145
+ })
146
+ .optional(),
45
147
  interactions: InteractionCapabilitiesSchema.optional(),
46
148
  workspace: z.strictObject({
47
149
  read: z.boolean(),
@@ -68,6 +170,16 @@ export const AgentEnvironmentCapabilitiesSchema = z
68
170
  .optional(),
69
171
  })
70
172
  .superRefine((capabilities, refinement) => {
173
+ if (capabilities.nativeContinuation !== undefined &&
174
+ (!capabilities.nativeContinuation.atomicBoundary ||
175
+ !capabilities.nativeContinuation.requestIdempotency ||
176
+ !capabilities.sessions.continue)) {
177
+ refinement.addIssue({
178
+ code: "custom",
179
+ path: ["nativeContinuation"],
180
+ message: "native continuation requires session continuation, atomic boundary admission, and request idempotency together",
181
+ });
182
+ }
71
183
  const durableBranching = [
72
184
  capabilities.branching.retrySafe ?? false,
73
185
  capabilities.branching.lookup ?? false,
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  import type { InteractionAcknowledgement, InteractionRequest, InteractionResponse, InteractionResponseCommand } from "./interaction.js";
8
8
  import type { AgentExecutionOutcome, DurablePlan, PlanContinuation, SdkPlanHost } from "./plan.js";
9
9
  export type * from "./environment-provider.js";
10
- export { AgentEnvironmentCapabilitiesSchema } from "./environment-provider.js";
10
+ export { AgentEnvironmentCapabilitiesSchema, AgentNativeContextContinuationResultSchema, AgentTurnResultSchema, agentNativeContextContinuationResultMatchesRequest, } from "./environment-provider.js";
11
11
  export * from "./plan.js";
12
12
  export * from "./runtime-control.js";
13
13
  export * from "./portable-context.js";
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * Shared types and interfaces for SDK provider adapters.
5
5
  * This package defines the contract between the sidecar and provider implementations.
6
6
  */
7
- export { AgentEnvironmentCapabilitiesSchema } from "./environment-provider.js";
7
+ export { AgentEnvironmentCapabilitiesSchema, AgentNativeContextContinuationResultSchema, AgentTurnResultSchema, agentNativeContextContinuationResultMatchesRequest, } from "./environment-provider.js";
8
8
  export * from "./plan.js";
9
9
  export * from "./runtime-control.js";
10
10
  export * from "./portable-context.js";
@@ -630,17 +630,53 @@ export type NativeContextBoundaryProof = z.infer<typeof NativeContextBoundaryPro
630
630
  export interface NativeContextContinuationRequest {
631
631
  operationId: string;
632
632
  requestDigest: Sha256Digest;
633
+ turnDigest: Sha256Digest;
633
634
  run: AgentRunControlRef;
634
635
  expectedBoundary: NativeContextBoundaryProof;
635
636
  }
636
637
  export interface NativeContextContinuationRequestMaterial {
638
+ turnDigest: Sha256Digest;
637
639
  run: AgentRunControlRef;
638
640
  expectedBoundary: NativeContextBoundaryProof;
639
641
  }
642
+ /** JSON-stable user turn admitted by a native same-session continuation. */
643
+ export interface NativeContextContinuationTurn {
644
+ prompt?: string;
645
+ parts?: InputPart[];
646
+ model?: string;
647
+ context?: Record<string, unknown>;
648
+ providerOptions?: Record<string, unknown>;
649
+ }
650
+ export declare const NativeContextContinuationTurnSchema: z.ZodObject<{
651
+ prompt: z.ZodOptional<z.ZodString>;
652
+ parts: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
653
+ type: z.ZodLiteral<"text">;
654
+ text: z.ZodString;
655
+ }, z.core.$strict>, z.ZodObject<{
656
+ type: z.ZodLiteral<"file">;
657
+ filename: z.ZodOptional<z.ZodString>;
658
+ mediaType: z.ZodOptional<z.ZodString>;
659
+ url: z.ZodOptional<z.ZodString>;
660
+ path: z.ZodOptional<z.ZodString>;
661
+ content: z.ZodOptional<z.ZodString>;
662
+ }, z.core.$strict>, z.ZodObject<{
663
+ type: z.ZodLiteral<"image">;
664
+ filename: z.ZodOptional<z.ZodString>;
665
+ mediaType: z.ZodOptional<z.ZodString>;
666
+ url: z.ZodOptional<z.ZodString>;
667
+ path: z.ZodOptional<z.ZodString>;
668
+ }, z.core.$strict>], "type">>>;
669
+ model: z.ZodOptional<z.ZodString>;
670
+ context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
671
+ providerOptions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>;
672
+ }, z.core.$strict>;
673
+ /** Bind retry identity to the exact new user turn, excluding timeout and abort controls. */
674
+ export declare function nativeContextContinuationTurnDigest(turn: NativeContextContinuationTurn): Sha256Digest;
640
675
  export declare function nativeContextContinuationRequestDigest(request: NativeContextContinuationRequestMaterial): Sha256Digest;
641
676
  export declare const NativeContextContinuationRequestSchema: z.ZodObject<{
642
677
  operationId: z.ZodString;
643
678
  requestDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
679
+ turnDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
644
680
  run: z.ZodObject<{
645
681
  runId: z.ZodString;
646
682
  provider: z.ZodString;
@@ -559,8 +559,20 @@ export const NativeContextBoundaryProofSchema = z.strictObject({
559
559
  boundary: NativeContextBoundarySchema,
560
560
  observedAt: z.iso.datetime(),
561
561
  });
562
+ export const NativeContextContinuationTurnSchema = z.strictObject({
563
+ prompt: z.string().optional(),
564
+ parts: z.array(InputPartSchema).optional(),
565
+ model: z.string().min(1).optional(),
566
+ context: jsonRecordSchema.optional(),
567
+ providerOptions: jsonRecordSchema.optional(),
568
+ });
569
+ /** Bind retry identity to the exact new user turn, excluding timeout and abort controls. */
570
+ export function nativeContextContinuationTurnDigest(turn) {
571
+ return wireDigest(NativeContextContinuationTurnSchema.parse(turn));
572
+ }
562
573
  export function nativeContextContinuationRequestDigest(request) {
563
574
  return wireDigest({
575
+ turnDigest: request.turnDigest,
564
576
  run: request.run,
565
577
  expectedBoundary: request.expectedBoundary,
566
578
  });
@@ -569,6 +581,7 @@ export const NativeContextContinuationRequestSchema = z
569
581
  .strictObject({
570
582
  operationId: idSchema,
571
583
  requestDigest: sha256DigestSchema,
584
+ turnDigest: sha256DigestSchema,
572
585
  run: AgentRunControlRefSchema,
573
586
  expectedBoundary: NativeContextBoundaryProofSchema,
574
587
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-interface",
3
- "version": "0.41.0",
3
+ "version": "0.42.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",