@tangle-network/agent-interface 1.3.0 → 1.4.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 +6 -0
- package/dist/environment-observation.d.ts +3 -3
- package/dist/environment-runtime.d.ts +41 -1
- package/dist/environment-runtime.js +27 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/runtime-control.js +66 -0
- package/dist/stream-events.d.ts +59 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,9 +33,15 @@ The public `AgentInstanceRecord` contains a credential-free profile identity, no
|
|
|
33
33
|
|
|
34
34
|
`AgentRunControlRef` identifies a retained run without depending on a live JavaScript object and may carry the provider's admission digest so reconstruction can reject changed-input reuse.
|
|
35
35
|
`RuntimeEventEnvelope` adds stable run, event, sequence, cursor, and timestamp fields around the existing `StreamEvent` union, and its runtime schema validates every canonical event variant.
|
|
36
|
+
The `child-task` event reports one update of a provider-native child task (a subagent, worker, or delegated task) with a stable `childId`, an optional `parentChildId`, a lifecycle status, start and update times, and the runner, model, usage, and terminal reason when the provider reports them.
|
|
37
|
+
Its `sourceEventId` identifies the exact update, so a consumer applies the first event with a given `sourceEventId` and ignores later copies during replay or reconnect.
|
|
38
|
+
Identity never depends on the bounded `raw` payload, and a provider that cannot report a stable `childId` emits no `child-task` event.
|
|
36
39
|
The canonical `cancelled` status identifies caller cancellation and remains distinct from `failed`.
|
|
37
40
|
Providers advertise `retainedControl` only when exact run, result, event, cancellation, replay, detach, turn, and session identity are all implemented together.
|
|
38
41
|
`AgentEnvironment.metadata` is the detached snapshot returned by create or get, so recovery can check persisted annotations without listing environments.
|
|
42
|
+
`AgentEnvironment.creation` reports what the create call that returned the object did: `created` when the call provisioned the environment, `replayed` when an existing environment matched the idempotency key.
|
|
43
|
+
It is a per-call fact, so a same-key replay returns a view of the same environment with `creation: "replayed"`, and the value is absent when the provider cannot prove either outcome.
|
|
44
|
+
A consumer never destroys an environment whose creation it cannot prove, because another caller can hold it.
|
|
39
45
|
Metadata can include caller-authored values and does not prove authorization or authorship.
|
|
40
46
|
`AgentSession.cancelRun()` accepts a canonical request digest bound to one operation and `AgentExactRunControlRef`, so a caller can safely repeat the same cancellation after losing the first acknowledgement.
|
|
41
47
|
Its acknowledgement repeats the operation, digest, and run coordinates and distinguishes a known cancellation effect from conflict or unknown state.
|
|
@@ -135,8 +135,8 @@ export declare const EnvironmentLifecycleSchema: z.ZodObject<{
|
|
|
135
135
|
resumable: z.ZodBoolean;
|
|
136
136
|
mode: z.ZodOptional<z.ZodEnum<{
|
|
137
137
|
none: "none";
|
|
138
|
-
replayed: "replayed";
|
|
139
138
|
native: "native";
|
|
139
|
+
replayed: "replayed";
|
|
140
140
|
}>>;
|
|
141
141
|
}, z.core.$strict>>;
|
|
142
142
|
persistence: z.ZodOptional<z.ZodObject<{
|
|
@@ -460,8 +460,8 @@ export declare const AgentEnvironmentObservationSchema: z.ZodObject<{
|
|
|
460
460
|
resumable: z.ZodBoolean;
|
|
461
461
|
mode: z.ZodOptional<z.ZodEnum<{
|
|
462
462
|
none: "none";
|
|
463
|
-
replayed: "replayed";
|
|
464
463
|
native: "native";
|
|
464
|
+
replayed: "replayed";
|
|
465
465
|
}>>;
|
|
466
466
|
}, z.core.$strict>>;
|
|
467
467
|
persistence: z.ZodOptional<z.ZodObject<{
|
|
@@ -508,8 +508,8 @@ export declare const AgentEnvironmentObservationSchema: z.ZodObject<{
|
|
|
508
508
|
resumable: z.ZodBoolean;
|
|
509
509
|
mode: z.ZodOptional<z.ZodEnum<{
|
|
510
510
|
none: "none";
|
|
511
|
-
replayed: "replayed";
|
|
512
511
|
native: "native";
|
|
512
|
+
replayed: "replayed";
|
|
513
513
|
}>>;
|
|
514
514
|
}, z.core.$strict>>;
|
|
515
515
|
persistence: z.ZodOptional<z.ZodObject<{
|
|
@@ -624,10 +624,34 @@ export interface AgentSession {
|
|
|
624
624
|
signal?: AbortSignal;
|
|
625
625
|
}): Promise<void>;
|
|
626
626
|
}
|
|
627
|
+
/**
|
|
628
|
+
* What one {@link AgentEnvironmentProvider.create} call did for the
|
|
629
|
+
* environment it returned.
|
|
630
|
+
*
|
|
631
|
+
* - `created`: this call provisioned the environment.
|
|
632
|
+
* - `replayed`: an existing environment that matched the idempotency key was
|
|
633
|
+
* returned. This call provisioned nothing.
|
|
634
|
+
*
|
|
635
|
+
* Absent when the provider cannot distinguish the two. A consumer treats an
|
|
636
|
+
* absent value as unknown and fails closed: it never destroys an environment
|
|
637
|
+
* whose creation it cannot prove, because another caller can hold it.
|
|
638
|
+
*/
|
|
639
|
+
export type AgentEnvironmentCreation = "created" | "replayed";
|
|
640
|
+
export declare const AgentEnvironmentCreationSchema: z.ZodEnum<{
|
|
641
|
+
replayed: "replayed";
|
|
642
|
+
created: "created";
|
|
643
|
+
}>;
|
|
627
644
|
export interface AgentEnvironment {
|
|
628
645
|
readonly id: string;
|
|
629
646
|
readonly provider: string;
|
|
630
647
|
readonly name?: string;
|
|
648
|
+
/**
|
|
649
|
+
* The verdict of the create call that returned this object. It is a
|
|
650
|
+
* per-call fact: a same-key replay returns a view of the same environment
|
|
651
|
+
* with `creation: "replayed"`. Absent on `get()` results and when the
|
|
652
|
+
* provider cannot prove which outcome happened.
|
|
653
|
+
*/
|
|
654
|
+
readonly creation?: AgentEnvironmentCreation;
|
|
631
655
|
/**
|
|
632
656
|
* Detached metadata returned by the provider.
|
|
633
657
|
* It can contain caller-authored annotations and is not authorization evidence.
|
|
@@ -945,15 +969,31 @@ export interface AgentEnvironmentCreateIdempotencyRecord<T> {
|
|
|
945
969
|
readonly pending: Promise<T>;
|
|
946
970
|
environment?: T;
|
|
947
971
|
}
|
|
972
|
+
/**
|
|
973
|
+
* Return the per-call view of an environment that a same-key create replayed.
|
|
974
|
+
*
|
|
975
|
+
* The view shares every member of the environment, so operations act on the
|
|
976
|
+
* one environment, and it states `creation: "replayed"` because this call
|
|
977
|
+
* provisioned nothing. The copy is shallow, so the environment must be a plain
|
|
978
|
+
* object whose members do not read `this`; a class instance loses its
|
|
979
|
+
* prototype members in a copy and is rejected.
|
|
980
|
+
* @internal
|
|
981
|
+
*/
|
|
982
|
+
export declare function replayedAgentEnvironmentView<T extends object>(environment: T): T;
|
|
948
983
|
/**
|
|
949
984
|
* Apply the generic create contract to one provider adapter's keyed requests.
|
|
950
985
|
*
|
|
951
986
|
* The provider's backing service remains responsible for retaining the key
|
|
952
987
|
* across adapter reconstruction. This helper coalesces concurrent retries and
|
|
953
988
|
* rejects collisions before the provider performs another create effect.
|
|
989
|
+
*
|
|
990
|
+
* The call that runs `create` receives the environment the provider built,
|
|
991
|
+
* with the creation verdict the provider could prove. Every same-key call
|
|
992
|
+
* after it, including one that awaited the same pending create, receives
|
|
993
|
+
* {@link replayedAgentEnvironmentView} of that environment.
|
|
954
994
|
* @internal
|
|
955
995
|
*/
|
|
956
|
-
export declare function createAgentEnvironmentWithIdempotency<T>(records: Map<string, AgentEnvironmentCreateIdempotencyRecord<T>>, input: CreateAgentEnvironmentInput, create: () => Promise<T>): Promise<T>;
|
|
996
|
+
export declare function createAgentEnvironmentWithIdempotency<T extends object>(records: Map<string, AgentEnvironmentCreateIdempotencyRecord<T>>, input: CreateAgentEnvironmentInput, create: () => Promise<T>): Promise<T>;
|
|
957
997
|
export interface AgentEnvironmentProvider {
|
|
958
998
|
readonly name: string;
|
|
959
999
|
readonly exactProcess?: AgentExactProcessProvider;
|
|
@@ -113,6 +113,10 @@ export function agentNativeContextContinuationResultMatchesRequest(request, outc
|
|
|
113
113
|
(exactOutcome.result.sessionId === undefined ||
|
|
114
114
|
exactOutcome.result.sessionId === current.sessionId));
|
|
115
115
|
}
|
|
116
|
+
export const AgentEnvironmentCreationSchema = z.enum([
|
|
117
|
+
"created",
|
|
118
|
+
"replayed",
|
|
119
|
+
]);
|
|
116
120
|
/** Strict runtime validator for provider capability negotiation. */
|
|
117
121
|
export const AgentEnvironmentCapabilitiesSchema = z
|
|
118
122
|
.strictObject({
|
|
@@ -325,12 +329,34 @@ export function agentEnvironmentCreateInputDigest(input) {
|
|
|
325
329
|
input: material,
|
|
326
330
|
});
|
|
327
331
|
}
|
|
332
|
+
/**
|
|
333
|
+
* Return the per-call view of an environment that a same-key create replayed.
|
|
334
|
+
*
|
|
335
|
+
* The view shares every member of the environment, so operations act on the
|
|
336
|
+
* one environment, and it states `creation: "replayed"` because this call
|
|
337
|
+
* provisioned nothing. The copy is shallow, so the environment must be a plain
|
|
338
|
+
* object whose members do not read `this`; a class instance loses its
|
|
339
|
+
* prototype members in a copy and is rejected.
|
|
340
|
+
* @internal
|
|
341
|
+
*/
|
|
342
|
+
export function replayedAgentEnvironmentView(environment) {
|
|
343
|
+
const prototype = Object.getPrototypeOf(environment);
|
|
344
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
345
|
+
throw new Error("a replayed agent environment view requires a plain object environment");
|
|
346
|
+
}
|
|
347
|
+
return { ...environment, creation: "replayed" };
|
|
348
|
+
}
|
|
328
349
|
/**
|
|
329
350
|
* Apply the generic create contract to one provider adapter's keyed requests.
|
|
330
351
|
*
|
|
331
352
|
* The provider's backing service remains responsible for retaining the key
|
|
332
353
|
* across adapter reconstruction. This helper coalesces concurrent retries and
|
|
333
354
|
* rejects collisions before the provider performs another create effect.
|
|
355
|
+
*
|
|
356
|
+
* The call that runs `create` receives the environment the provider built,
|
|
357
|
+
* with the creation verdict the provider could prove. Every same-key call
|
|
358
|
+
* after it, including one that awaited the same pending create, receives
|
|
359
|
+
* {@link replayedAgentEnvironmentView} of that environment.
|
|
334
360
|
* @internal
|
|
335
361
|
*/
|
|
336
362
|
export async function createAgentEnvironmentWithIdempotency(records, input, create) {
|
|
@@ -344,7 +370,7 @@ export async function createAgentEnvironmentWithIdempotency(records, input, crea
|
|
|
344
370
|
if (existing.digest !== digest) {
|
|
345
371
|
throw new Error("agent environment create idempotency key conflicts with a different create input");
|
|
346
372
|
}
|
|
347
|
-
return existing.environment ?? existing.pending;
|
|
373
|
+
return replayedAgentEnvironmentView(existing.environment ?? (await existing.pending));
|
|
348
374
|
}
|
|
349
375
|
const pending = Promise.resolve().then(create);
|
|
350
376
|
const record = {
|
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, agentEnvironmentCreateInputDigest, 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, createAgentEnvironmentWithIdempotency, TerminalAttachRequestSchema, TerminalAttachResultSchema, TerminalDetachAckSchema, TerminalInputSchema, TerminalOutputEventSchema, TerminalReplayWindowSchema, TerminalResizeSchema, TerminalSessionRefSchema, terminalAttachResultMatchesRequest, terminalSessionUsable, } from "./environment-provider.js";
|
|
11
|
+
export { AgentEnvironmentCapabilitiesSchema, AgentNativeContextContinuationResultSchema, AgentTurnInputSchema, AgentTurnResultSchema, agentEnvironmentCreateInputDigest, 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, AgentEnvironmentCreationSchema, createAgentEnvironmentWithIdempotency, replayedAgentEnvironmentView, 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, agentEnvironmentCreateInputDigest, 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, createAgentEnvironmentWithIdempotency, TerminalAttachRequestSchema, TerminalAttachResultSchema, TerminalDetachAckSchema, TerminalInputSchema, TerminalOutputEventSchema, TerminalReplayWindowSchema, TerminalResizeSchema, TerminalSessionRefSchema, terminalAttachResultMatchesRequest, terminalSessionUsable, } from "./environment-provider.js";
|
|
10
|
+
export { AgentEnvironmentCapabilitiesSchema, AgentNativeContextContinuationResultSchema, AgentTurnInputSchema, AgentTurnResultSchema, agentEnvironmentCreateInputDigest, 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, AgentEnvironmentCreationSchema, createAgentEnvironmentWithIdempotency, replayedAgentEnvironmentView, 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";
|
package/dist/runtime-control.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { canonicalCandidateDigest, sha256DigestSchema, } from "./agent-candidate-schema-common.js";
|
|
3
3
|
import { boundedIdentifierSchema, boundedJsonRecordSchema, boundedJsonSchema, boundedStringSchema, } from "./contract-limits.js";
|
|
4
|
+
import { ModelUsageSchema } from "./environment-observation.js";
|
|
4
5
|
import { InteractionRequestSchema } from "./interaction.js";
|
|
5
6
|
import { DurablePlanSchema } from "./plan.js";
|
|
6
7
|
const stableIdSchema = boundedIdentifierSchema;
|
|
@@ -263,6 +264,70 @@ const partSchema = z.discriminatedUnion("type", [
|
|
|
263
264
|
agent: stableIdSchema,
|
|
264
265
|
}),
|
|
265
266
|
]);
|
|
267
|
+
const TERMINAL_CHILD_TASK_STATUSES = new Set(["completed", "failed", "cancelled"]);
|
|
268
|
+
const epochMillisecondsSchema = z.number().finite().nonnegative();
|
|
269
|
+
/**
|
|
270
|
+
* Provider-native child task lifecycle. Identity comes only from `childId`,
|
|
271
|
+
* `parentChildId`, and `sourceEventId`; `raw` is opaque and bounded. A provider
|
|
272
|
+
* without a stable `childId` emits no `child-task` event.
|
|
273
|
+
*/
|
|
274
|
+
const ChildTaskEventSchema = z
|
|
275
|
+
.strictObject({
|
|
276
|
+
type: z.literal("child-task"),
|
|
277
|
+
childId: stableIdSchema,
|
|
278
|
+
parentChildId: stableIdSchema.optional(),
|
|
279
|
+
status: z.enum(["started", "running", "completed", "failed", "cancelled"]),
|
|
280
|
+
title: boundedStringSchema.optional(),
|
|
281
|
+
time: z.strictObject({
|
|
282
|
+
started: epochMillisecondsSchema,
|
|
283
|
+
updated: epochMillisecondsSchema,
|
|
284
|
+
ended: epochMillisecondsSchema.optional(),
|
|
285
|
+
}),
|
|
286
|
+
runner: stableIdSchema.optional(),
|
|
287
|
+
model: stableIdSchema.optional(),
|
|
288
|
+
usage: ModelUsageSchema.optional(),
|
|
289
|
+
terminalReason: boundedStringSchema.optional(),
|
|
290
|
+
sourceEventId: stableIdSchema,
|
|
291
|
+
raw: boundedJsonRecordSchema.optional(),
|
|
292
|
+
})
|
|
293
|
+
.superRefine((event, refinement) => {
|
|
294
|
+
const terminal = TERMINAL_CHILD_TASK_STATUSES.has(event.status);
|
|
295
|
+
if (!terminal && event.time.ended !== undefined) {
|
|
296
|
+
refinement.addIssue({
|
|
297
|
+
code: "custom",
|
|
298
|
+
path: ["time", "ended"],
|
|
299
|
+
message: "only a terminal child task status may carry an end time",
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
if (!terminal && event.terminalReason !== undefined) {
|
|
303
|
+
refinement.addIssue({
|
|
304
|
+
code: "custom",
|
|
305
|
+
path: ["terminalReason"],
|
|
306
|
+
message: "only a terminal child task status may carry a terminal reason",
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
if (event.time.updated < event.time.started) {
|
|
310
|
+
refinement.addIssue({
|
|
311
|
+
code: "custom",
|
|
312
|
+
path: ["time", "updated"],
|
|
313
|
+
message: "a child task update time cannot precede its start time",
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
if (event.time.ended !== undefined && event.time.ended < event.time.started) {
|
|
317
|
+
refinement.addIssue({
|
|
318
|
+
code: "custom",
|
|
319
|
+
path: ["time", "ended"],
|
|
320
|
+
message: "a child task end time cannot precede its start time",
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
if (event.parentChildId === event.childId) {
|
|
324
|
+
refinement.addIssue({
|
|
325
|
+
code: "custom",
|
|
326
|
+
path: ["parentChildId"],
|
|
327
|
+
message: "a child task cannot be its own parent",
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
});
|
|
266
331
|
/** Runtime validator for every member of the existing canonical event union. */
|
|
267
332
|
export const CanonicalStreamEventSchema = z.discriminatedUnion("type", [
|
|
268
333
|
z.strictObject({
|
|
@@ -332,6 +397,7 @@ export const CanonicalStreamEventSchema = z.discriminatedUnion("type", [
|
|
|
332
397
|
type: z.literal("plan.submitted"),
|
|
333
398
|
plan: DurablePlanSchema,
|
|
334
399
|
}),
|
|
400
|
+
ChildTaskEventSchema,
|
|
335
401
|
]);
|
|
336
402
|
export const RuntimeEventEnvelopeSchema = z.strictObject({
|
|
337
403
|
runId: stableIdSchema,
|
package/dist/stream-events.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TokenUsage } from "./execution-types.js";
|
|
1
2
|
import type { InteractionRequest } from "./interaction.js";
|
|
2
3
|
import type { DurablePlan } from "./plan.js";
|
|
3
4
|
import type { Part } from "./parts.js";
|
|
@@ -7,6 +8,63 @@ export type MessagePartUpdatedEvent = {
|
|
|
7
8
|
delta?: string;
|
|
8
9
|
};
|
|
9
10
|
export type StreamStatus = "started" | "processing" | "completed" | "failed" | "cancelled";
|
|
11
|
+
export type ChildTaskStatus = "started" | "running" | "completed" | "failed" | "cancelled";
|
|
12
|
+
/**
|
|
13
|
+
* One observed update of a provider-native child task: a subagent, worker, or
|
|
14
|
+
* delegated task that the runner started inside the same run.
|
|
15
|
+
*
|
|
16
|
+
* Identity rules:
|
|
17
|
+
* - `childId` is the provider's stable identifier for the child task. Every
|
|
18
|
+
* update of one child repeats the same `childId`. A provider that cannot
|
|
19
|
+
* report a stable `childId` emits no `child-task` event.
|
|
20
|
+
* - `parentChildId` names the parent child task. It is absent when the parent
|
|
21
|
+
* is the run itself.
|
|
22
|
+
* - `sourceEventId` is the provider's identifier for this exact update. Two
|
|
23
|
+
* events with the same `sourceEventId` are the same update, so a consumer
|
|
24
|
+
* applies the first and ignores the rest during replay or reconnect.
|
|
25
|
+
* - Identity never depends on `raw`. `raw` is an opaque, bounded copy of
|
|
26
|
+
* provider fields that have no canonical position.
|
|
27
|
+
*
|
|
28
|
+
* Certainty rules:
|
|
29
|
+
* - `time.ended` and `terminalReason` are present only with a terminal status
|
|
30
|
+
* (`completed`, `failed`, `cancelled`).
|
|
31
|
+
* - `time.updated` and `time.ended` are never earlier than `time.started`.
|
|
32
|
+
*
|
|
33
|
+
* Dedupe example for a consumer that rebuilds the child tree from a replayed
|
|
34
|
+
* stream. Live and replayed streams produce the same tree because identity
|
|
35
|
+
* comes only from `childId`, `parentChildId`, and `sourceEventId`:
|
|
36
|
+
*
|
|
37
|
+
* ```ts
|
|
38
|
+
* const applied = new Set<string>();
|
|
39
|
+
* const children = new Map<string, ChildTaskEvent>();
|
|
40
|
+
* for (const event of events) {
|
|
41
|
+
* if (event.type !== "child-task") continue;
|
|
42
|
+
* if (applied.has(event.sourceEventId)) continue;
|
|
43
|
+
* applied.add(event.sourceEventId);
|
|
44
|
+
* children.set(event.childId, event);
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export type ChildTaskEvent = {
|
|
49
|
+
type: "child-task";
|
|
50
|
+
childId: string;
|
|
51
|
+
parentChildId?: string;
|
|
52
|
+
status: ChildTaskStatus;
|
|
53
|
+
title?: string;
|
|
54
|
+
/** Epoch milliseconds reported by the provider. */
|
|
55
|
+
time: {
|
|
56
|
+
started: number;
|
|
57
|
+
updated: number;
|
|
58
|
+
ended?: number;
|
|
59
|
+
};
|
|
60
|
+
/** Runner that executes the child, for example `claude-code`. */
|
|
61
|
+
runner?: string;
|
|
62
|
+
model?: string;
|
|
63
|
+
usage?: TokenUsage;
|
|
64
|
+
terminalReason?: string;
|
|
65
|
+
sourceEventId: string;
|
|
66
|
+
raw?: Record<string, unknown>;
|
|
67
|
+
};
|
|
10
68
|
export type StreamEvent = MessagePartUpdatedEvent | {
|
|
11
69
|
type: "tool-heartbeat";
|
|
12
70
|
toolName: string;
|
|
@@ -53,4 +111,4 @@ export type StreamEvent = MessagePartUpdatedEvent | {
|
|
|
53
111
|
} | {
|
|
54
112
|
type: "plan.submitted";
|
|
55
113
|
plan: DurablePlan;
|
|
56
|
-
};
|
|
114
|
+
} | ChildTaskEvent;
|