@adea-ai/runtime-sdk 1.22.0 → 1.24.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
@@ -1,13 +1,11 @@
1
1
  # @control-plane/runtime-sdk
2
2
 
3
3
  SDK for building runtimes that plug into the Control Plane: implement the
4
- adapter interface, declare capabilities, pass conformance, and speak the
5
- gateway protocol — without touching Control Plane internals.
4
+ adapter interface, declare capabilities, and pass conformance — without
5
+ touching Control Plane internals.
6
6
 
7
7
  Depends only on [`@adea-ai/contracts`](https://www.npmjs.com/package/@adea-ai/contracts)
8
- and Zod. Pair it with
9
- [`@adea-ai/runtime-gateway-protocol`](https://www.npmjs.com/package/@adea-ai/runtime-gateway-protocol)
10
- for the wire protocol and [`@adea-ai/contracts`](https://www.npmjs.com/package/@adea-ai/contracts)
8
+ and Zod. Pair it with [`@adea-ai/contracts`](https://www.npmjs.com/package/@adea-ai/contracts)
11
9
  for the service boundary.
12
10
 
13
11
  ## What's inside
@@ -20,8 +18,8 @@ for the service boundary.
20
18
  - **Conformance & compatibility** — versioned conformance suites and
21
19
  compatibility checks for runtime implementations.
22
20
  - **Sessions & routing** — external session types and routing decisions.
23
- - **Transport** — transport ports with deterministic in-memory doubles
24
- (`mock.ts`, `fixtures.ts`) for testing adapters without a live gateway.
21
+ - **Transport** — the co-located transport port with deterministic in-memory
22
+ doubles (`mock.ts`, `fixtures.ts`) for testing adapters.
25
23
 
26
24
  Runtime usage accounting distinguishes HQ-funded API usage (`hq_managed`),
27
25
  user-funded API usage (`byo_api`), and external subscriptions
package/dist/adapter.d.ts CHANGED
@@ -12,7 +12,6 @@ export declare const RuntimeAdapterMetadataSchema: z.ZodObject<{
12
12
  harnessVersion: z.ZodString;
13
13
  transportKind: z.ZodOptional<z.ZodEnum<{
14
14
  "direct-local": "direct-local";
15
- "remote-gateway": "remote-gateway";
16
15
  }>>;
17
16
  }, z.core.$strict>;
18
17
  export declare const RuntimeAdapterInspectionSchema: z.ZodObject<{
@@ -28,7 +27,6 @@ export declare const RuntimeAdapterInspectionSchema: z.ZodObject<{
28
27
  harnessVersion: z.ZodString;
29
28
  transportKind: z.ZodOptional<z.ZodEnum<{
30
29
  "direct-local": "direct-local";
31
- "remote-gateway": "remote-gateway";
32
30
  }>>;
33
31
  }, z.core.$strict>;
34
32
  health: z.ZodEnum<{
package/dist/adapter.js CHANGED
@@ -23,7 +23,7 @@ export const RuntimeAdapterMetadataSchema = z
23
23
  .regex(/^[a-z][a-z0-9-]*$/),
24
24
  driverVersion: SemanticVersionSchema,
25
25
  harnessVersion: SemanticVersionSchema,
26
- transportKind: z.enum(['direct-local', 'remote-gateway']).optional(),
26
+ transportKind: z.enum(['direct-local']).optional(),
27
27
  })
28
28
  .strict();
29
29
  const CapabilityEvaluationSchema = z
@@ -13,10 +13,6 @@ export declare const RuntimeChannelOwnershipSchema: z.ZodObject<{
13
13
  lastHeartbeatAt: z.ZodISODateTime;
14
14
  }, z.core.$strict>;
15
15
  export type RuntimeChannelOwnership = z.output<typeof RuntimeChannelOwnershipSchema>;
16
- export interface RuntimeChannelOwnershipCredentialFence {
17
- readonly credentialId: string;
18
- readonly revocationVersion: number;
19
- }
20
16
  export declare const RuntimeChannelSequenceRequestSchema: z.ZodObject<{
21
17
  channel: z.ZodObject<{
22
18
  nodeId: z.ZodString;
@@ -38,12 +34,3 @@ export type RuntimeChannelSequenceRequest = z.output<typeof RuntimeChannelSequen
38
34
  export interface RuntimeChannelSequenceRepository {
39
35
  reserve(request: RuntimeChannelSequenceRequest): Promise<number>;
40
36
  }
41
- export interface RuntimeChannelOwnershipRepository {
42
- claim(record: RuntimeChannelOwnership, credentialFence?: RuntimeChannelOwnershipCredentialFence): Promise<{
43
- accepted: boolean;
44
- previous?: RuntimeChannelOwnership;
45
- }>;
46
- lookup(nodeId: string): Promise<RuntimeChannelOwnership | undefined>;
47
- heartbeat(record: RuntimeChannelOwnership, credentialFence?: RuntimeChannelOwnershipCredentialFence): Promise<boolean>;
48
- release(record: RuntimeChannelOwnership): Promise<boolean>;
49
- }
@@ -78,7 +78,6 @@ export declare const RuntimeCertificationSchema: z.ZodObject<{
78
78
  "direct-local-transport-integration": "direct-local-transport-integration";
79
79
  "hosted-runtime-integration": "hosted-runtime-integration";
80
80
  "runtime-adapter-conformance": "runtime-adapter-conformance";
81
- "runtime-gateway-integration": "runtime-gateway-integration";
82
81
  }>;
83
82
  source: z.ZodString;
84
83
  command: z.ZodString;
@@ -166,7 +165,6 @@ export declare const RuntimeCompatibilityMatrixSchema: z.ZodObject<{
166
165
  "direct-local-transport-integration": "direct-local-transport-integration";
167
166
  "hosted-runtime-integration": "hosted-runtime-integration";
168
167
  "runtime-adapter-conformance": "runtime-adapter-conformance";
169
- "runtime-gateway-integration": "runtime-gateway-integration";
170
168
  }>;
171
169
  source: z.ZodString;
172
170
  command: z.ZodString;
@@ -54,7 +54,6 @@ export const RuntimeCertificationSchema = z
54
54
  suite: z.enum([
55
55
  'runtime-adapter-conformance',
56
56
  'direct-local-transport-integration',
57
- 'runtime-gateway-integration',
58
57
  'hosted-runtime-integration',
59
58
  ]),
60
59
  source: z
@@ -73,7 +72,8 @@ export const RuntimeCertificationSchema = z
73
72
  .superRefine((certification, context) => {
74
73
  if (certification.classification === 'supported' &&
75
74
  (!certification.evidence.some((entry) => entry.suite === 'runtime-adapter-conformance') ||
76
- !certification.evidence.some((entry) => ['direct-local-transport-integration', 'runtime-gateway-integration'].includes(entry.suite) || entry.suite === 'hosted-runtime-integration'))) {
75
+ !certification.evidence.some((entry) => entry.suite === 'direct-local-transport-integration' ||
76
+ entry.suite === 'hosted-runtime-integration'))) {
77
77
  context.addIssue({
78
78
  code: 'custom',
79
79
  path: ['evidence'],
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export * from './adapter.js';
2
2
  export * from './pi-durable-lead.js';
3
+ export * from './pi-durable-questions.js';
4
+ export * from './pi-durable-approvals.js';
3
5
  export * from './agent-plugins.js';
4
6
  export * from './channel-ownership.js';
5
7
  export * from './capabilities.js';
package/dist/index.js CHANGED
@@ -1,5 +1,7 @@
1
1
  export * from './adapter.js';
2
2
  export * from './pi-durable-lead.js';
3
+ export * from './pi-durable-questions.js';
4
+ export * from './pi-durable-approvals.js';
3
5
  export * from './agent-plugins.js';
4
6
  export * from './channel-ownership.js';
5
7
  export * from './capabilities.js';
@@ -0,0 +1,47 @@
1
+ import { z } from 'zod';
2
+ import { IdentifierSchemas } from '@adea-ai/contracts';
3
+ export declare const PiDurableApprovalEffectDigestSchema: z.ZodString;
4
+ export declare const PiDurableApprovalDecisionIdSchema: z.ZodString;
5
+ export declare const PiDurableApprovalAnswerSchema: z.ZodObject<{
6
+ dispatchId: z.ZodString;
7
+ approvalId: typeof IdentifierSchemas.interactionId;
8
+ effectDigest: z.ZodString;
9
+ decision: z.ZodEnum<{
10
+ approve: "approve";
11
+ deny: "deny";
12
+ }>;
13
+ decisionId: z.ZodString;
14
+ }, z.core.$strict>;
15
+ export declare const PiDurableApprovalAttestationSchema: z.ZodObject<{
16
+ decidedBy: z.ZodString;
17
+ senderKeyId: z.ZodString;
18
+ keyringRevision: z.ZodNumber;
19
+ }, z.core.$strict>;
20
+ export declare const PiDurableApprovalDecisionSchema: z.ZodObject<{
21
+ decidedBy: z.ZodString;
22
+ senderKeyId: z.ZodString;
23
+ keyringRevision: z.ZodNumber;
24
+ schemaVersion: z.ZodLiteral<"pi-lead-approval-decision/v1">;
25
+ workspaceId: typeof IdentifierSchemas.workspaceId;
26
+ dispatchId: z.ZodString;
27
+ executionId: typeof IdentifierSchemas.executionId;
28
+ attemptId: typeof IdentifierSchemas.attemptId;
29
+ approvalId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"interaction ID">, string>>;
30
+ effectDigest: z.ZodString;
31
+ decision: z.ZodEnum<{
32
+ approve: "approve";
33
+ deny: "deny";
34
+ }>;
35
+ decisionId: z.ZodString;
36
+ decidedAt: z.ZodISODateTime;
37
+ deadlineAt: z.ZodISODateTime;
38
+ }, z.core.$strict>;
39
+ export type PiDurableApprovalAnswer = z.output<typeof PiDurableApprovalAnswerSchema>;
40
+ export type PiDurableApprovalAttestation = z.output<typeof PiDurableApprovalAttestationSchema>;
41
+ export type PiDurableApprovalDecision = z.output<typeof PiDurableApprovalDecisionSchema>;
42
+ export interface PiDurableApprovalDecisionAuthority {
43
+ readonly principalId: string;
44
+ authorize(decision: PiDurableApprovalDecision): Promise<boolean>;
45
+ publish?(decision: PiDurableApprovalDecision): Promise<void>;
46
+ }
47
+ export declare function samePiDurableApprovalDecision(left: PiDurableApprovalDecision, right: PiDurableApprovalDecision): boolean;
@@ -0,0 +1,40 @@
1
+ import { z } from 'zod';
2
+ import { canonicalJsonStringify, IdentifierSchemas } from '@adea-ai/contracts';
3
+ export const PiDurableApprovalEffectDigestSchema = z.string().regex(/^sha256:[a-f0-9]{64}$/);
4
+ export const PiDurableApprovalDecisionIdSchema = z.string().regex(/^pi-decision:[a-f0-9]{32}$/);
5
+ const Reference = z
6
+ .string()
7
+ .min(1)
8
+ .max(256)
9
+ .regex(/^[A-Za-z0-9._:-]+$/);
10
+ export const PiDurableApprovalAnswerSchema = z.strictObject({
11
+ dispatchId: z.string().regex(/^dispatch_[a-f0-9]{32}$/),
12
+ approvalId: IdentifierSchemas.interactionId,
13
+ effectDigest: PiDurableApprovalEffectDigestSchema,
14
+ decision: z.enum(['approve', 'deny']),
15
+ decisionId: PiDurableApprovalDecisionIdSchema,
16
+ });
17
+ export const PiDurableApprovalAttestationSchema = z.strictObject({
18
+ decidedBy: Reference,
19
+ senderKeyId: Reference,
20
+ keyringRevision: z.number().int().min(1),
21
+ });
22
+ export const PiDurableApprovalDecisionSchema = z.strictObject({
23
+ schemaVersion: z.literal('pi-lead-approval-decision/v1'),
24
+ workspaceId: IdentifierSchemas.workspaceId,
25
+ dispatchId: PiDurableApprovalAnswerSchema.shape.dispatchId,
26
+ executionId: IdentifierSchemas.executionId,
27
+ attemptId: IdentifierSchemas.attemptId,
28
+ approvalId: PiDurableApprovalAnswerSchema.shape.approvalId,
29
+ effectDigest: PiDurableApprovalEffectDigestSchema,
30
+ decision: PiDurableApprovalAnswerSchema.shape.decision,
31
+ decisionId: PiDurableApprovalDecisionIdSchema,
32
+ ...PiDurableApprovalAttestationSchema.shape,
33
+ decidedAt: z.iso.datetime(),
34
+ deadlineAt: z.iso.datetime(),
35
+ });
36
+ export function samePiDurableApprovalDecision(left, right) {
37
+ const { decidedAt: _left, ...a } = left;
38
+ const { decidedAt: _right, ...b } = right;
39
+ return canonicalJsonStringify(a) === canonicalJsonStringify(b);
40
+ }
@@ -1,4 +1,6 @@
1
1
  import { z } from 'zod';
2
+ import { PiDurableQuestionAnswersSchema, PiDurableQuestionRequestIdSchema } from './pi-durable-questions.js';
3
+ import { PiDurableApprovalAnswerSchema, PiDurableApprovalAttestationSchema } from './pi-durable-approvals.js';
2
4
  import { IdentifierSchemas, ModelSelectionRefSchema } from '@adea-ai/contracts';
3
5
  import { RuntimeExecutionProgressSchema, RuntimeExecutionStatusSchema, RuntimeExecutionStateSchema, RuntimeObservedGenerationSchema } from './adapter.js';
4
6
  declare const IntentId: z.ZodUUID;
@@ -155,6 +157,56 @@ export declare const PiDurableLeadProgressRequestSchema: z.ZodObject<{
155
157
  afterSequence: z.ZodOptional<z.ZodNumber>;
156
158
  }, z.core.$strict>;
157
159
  }, z.core.$strict>;
160
+ export declare const PI_DURABLE_LEAD_EVENTS_CONTRACT_VERSION = 1;
161
+ export declare const PI_DURABLE_LEAD_EVENTS_MAX_PAGE = 256;
162
+ export declare const PI_DURABLE_LEAD_EVENTS_MAX_WAIT_MS = 8000;
163
+ export declare const PiDurableSessionIdSchema: z.ZodString;
164
+ export declare const PiDurableLeadEventsRequestSchema: z.ZodObject<{
165
+ contractVersion: z.ZodObject<{
166
+ major: z.ZodNumber;
167
+ minor: z.ZodNumber;
168
+ }, z.core.$strict>;
169
+ requestId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"request ID">, string>>;
170
+ workspaceId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"workspace ID">, string>>;
171
+ projectId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"project ID">, string>>>;
172
+ requestedAt: z.ZodISODateTime;
173
+ caller: typeof Caller;
174
+ correlation: typeof Correlation;
175
+ operation: z.ZodLiteral<"pi-durable.lead.events">;
176
+ parameters: z.ZodObject<{
177
+ dispatchId: typeof DispatchId;
178
+ messageId: z.ZodString;
179
+ afterSeq: z.ZodNumber;
180
+ waitMs: z.ZodNumber;
181
+ limit: z.ZodOptional<z.ZodNumber>;
182
+ }, z.core.$strict>;
183
+ }, z.core.$strict>;
184
+ export declare const PiDurableLeadTurnEventSchema: z.ZodObject<{
185
+ schemaVersion: z.ZodLiteral<1>;
186
+ eventId: z.ZodString;
187
+ runtimeSessionId: typeof PiDurableSessionIdSchema;
188
+ harnessRunId: z.ZodString;
189
+ generation: z.ZodLiteral<1>;
190
+ seq: z.ZodString;
191
+ occurredAt: z.ZodISODateTime;
192
+ receivedAt: z.ZodISODateTime;
193
+ source: z.ZodLiteral<"native">;
194
+ sourceEventId: z.ZodString;
195
+ confidence: z.ZodLiteral<"authoritative">;
196
+ classification: z.ZodEnum<{
197
+ restricted_local: "restricted_local";
198
+ workspace_private: "workspace_private";
199
+ }>;
200
+ kind: z.ZodString;
201
+ payload: z.ZodRecord<z.ZodString, z.ZodUnknown>;
202
+ }, z.core.$strict>;
203
+ export declare const PiDurableLeadEventsDataSchema: z.ZodObject<{
204
+ contractVersion: z.ZodLiteral<1>;
205
+ dispatchId: typeof DispatchId;
206
+ events: z.ZodArray<typeof PiDurableLeadTurnEventSchema>;
207
+ nextSeq: z.ZodNumber;
208
+ complete: z.ZodBoolean;
209
+ }, z.core.$strict>;
158
210
  export declare const PiDurableLeadChildrenCursorSchema: z.ZodReadonly<z.ZodObject<{
159
211
  acceptedAt: z.ZodISODateTime;
160
212
  delegationId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"delegation ID">, string>>;
@@ -179,6 +231,44 @@ export declare const PiDurableLeadChildrenRequestSchema: z.ZodObject<{
179
231
  limit: z.ZodOptional<z.ZodNumber>;
180
232
  }, z.core.$strict>;
181
233
  }, z.core.$strict>;
234
+ export declare const PI_DURABLE_SESSIONS_MAX_PAGE = 256;
235
+ export declare const PiDurableSessionsRequestSchema: z.ZodObject<{
236
+ contractVersion: z.ZodObject<{
237
+ major: z.ZodNumber;
238
+ minor: z.ZodNumber;
239
+ }, z.core.$strict>;
240
+ requestId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"request ID">, string>>;
241
+ workspaceId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"workspace ID">, string>>;
242
+ projectId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"project ID">, string>>>;
243
+ requestedAt: z.ZodISODateTime;
244
+ caller: typeof Caller;
245
+ correlation: typeof Correlation;
246
+ operation: z.ZodLiteral<"pi-durable.lead.sessions">;
247
+ parameters: z.ZodObject<{
248
+ runtimeSessionId: z.ZodOptional<typeof PiDurableSessionIdSchema>;
249
+ after: z.ZodOptional<typeof PiDurableSessionIdSchema>;
250
+ limit: z.ZodOptional<z.ZodNumber>;
251
+ }, z.core.$strict>;
252
+ }, z.core.$strict>;
253
+ export declare const PiDurableSessionEventsRequestSchema: z.ZodObject<{
254
+ contractVersion: z.ZodObject<{
255
+ major: z.ZodNumber;
256
+ minor: z.ZodNumber;
257
+ }, z.core.$strict>;
258
+ requestId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"request ID">, string>>;
259
+ workspaceId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"workspace ID">, string>>;
260
+ projectId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"project ID">, string>>>;
261
+ requestedAt: z.ZodISODateTime;
262
+ caller: typeof Caller;
263
+ correlation: typeof Correlation;
264
+ operation: z.ZodLiteral<"pi-durable.lead.session-events">;
265
+ parameters: z.ZodObject<{
266
+ runtimeSessionId: typeof PiDurableSessionIdSchema;
267
+ afterSeq: z.ZodNumber;
268
+ waitMs: z.ZodNumber;
269
+ limit: z.ZodOptional<z.ZodNumber>;
270
+ }, z.core.$strict>;
271
+ }, z.core.$strict>;
182
272
  export declare const PiDurableLeadChildTargetRequestSchema: z.ZodObject<{
183
273
  contractVersion: z.ZodObject<{
184
274
  major: z.ZodNumber;
@@ -215,6 +305,44 @@ export declare const PiDurableLeadCancelRequestSchema: z.ZodObject<{
215
305
  dispatchId: z.ZodString;
216
306
  }, z.core.$strict>;
217
307
  }, z.core.$strict>;
308
+ export declare const PiDurableLeadQuestionAnswerRequestSchema: z.ZodObject<{
309
+ contractVersion: z.ZodObject<{
310
+ major: z.ZodNumber;
311
+ minor: z.ZodNumber;
312
+ }, z.core.$strict>;
313
+ requestId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"request ID">, string>>;
314
+ workspaceId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"workspace ID">, string>>;
315
+ projectId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"project ID">, string>>>;
316
+ commandId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"command ID">, string>>;
317
+ idempotencyKey: z.ZodString;
318
+ payloadHash: z.ZodString;
319
+ issuedAt: z.ZodISODateTime;
320
+ caller: typeof Caller;
321
+ correlation: typeof Correlation;
322
+ operation: z.ZodLiteral<"pi-durable.lead.question-answer">;
323
+ payload: z.ZodObject<{
324
+ dispatchId: typeof DispatchId;
325
+ requestId: typeof PiDurableQuestionRequestIdSchema;
326
+ answers: typeof PiDurableQuestionAnswersSchema;
327
+ }, z.core.$strict>;
328
+ }, z.core.$strict>;
329
+ export declare const PiDurableLeadApprovalAnswerRequestSchema: z.ZodObject<{
330
+ contractVersion: z.ZodObject<{
331
+ major: z.ZodNumber;
332
+ minor: z.ZodNumber;
333
+ }, z.core.$strict>;
334
+ requestId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"request ID">, string>>;
335
+ workspaceId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"workspace ID">, string>>;
336
+ projectId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"project ID">, string>>>;
337
+ commandId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"command ID">, string>>;
338
+ idempotencyKey: z.ZodString;
339
+ payloadHash: z.ZodString;
340
+ issuedAt: z.ZodISODateTime;
341
+ caller: typeof Caller;
342
+ correlation: typeof Correlation;
343
+ operation: z.ZodLiteral<"pi-durable.lead.approval-answer">;
344
+ payload: z.ZodObject<typeof PiDurableApprovalAnswerSchema.shape & typeof PiDurableApprovalAttestationSchema.shape, z.core.$strict>;
345
+ }, z.core.$strict>;
218
346
  export declare const PiDurableLeadChildCancelRequestSchema: z.ZodObject<{
219
347
  contractVersion: z.ZodObject<{
220
348
  major: z.ZodNumber;
@@ -457,6 +585,137 @@ export declare const PiDurableLeadCancelResponseSchema: z.ZodObject<{
457
585
  status: typeof RuntimeExecutionStatusSchema;
458
586
  }, z.core.$strict>;
459
587
  }, z.core.$strict>;
588
+ export declare const PiDurableLeadQuestionAnswerResponseSchema: z.ZodObject<{
589
+ contractVersion: z.ZodObject<{
590
+ major: z.ZodNumber;
591
+ minor: z.ZodNumber;
592
+ }, z.core.$strict>;
593
+ requestId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"request ID">, string>>;
594
+ correlation: z.ZodObject<{
595
+ traceId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"trace ID">, string>>;
596
+ causationCommandId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"command ID">, string>>>;
597
+ parentEventId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"event ID">, string>>>;
598
+ }, z.core.$strict>;
599
+ data: z.ZodObject<{
600
+ schemaVersion: z.ZodLiteral<"pi-lead-dispatch/v1">;
601
+ dispatchId: typeof DispatchId;
602
+ intentId: typeof IntentId;
603
+ executionId: typeof IdentifierSchemas.executionId;
604
+ attemptId: typeof IdentifierSchemas.attemptId;
605
+ runtimeSessionId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"external-session ID">, string>>;
606
+ requestedTarget: z.ZodOptional<typeof PiDurableLeadRequestedTargetSchema>;
607
+ observedTarget: z.ZodOptional<typeof PiDurableLeadObservedTargetSchema>;
608
+ questionSchemaVersion: z.ZodLiteral<"pi-lead-question-answer/v1">;
609
+ requestId: typeof PiDurableQuestionRequestIdSchema;
610
+ requestEventId: z.ZodString;
611
+ outcome: z.ZodEnum<{
612
+ already_answered: "already_answered";
613
+ answered: "answered";
614
+ expired: "expired";
615
+ }>;
616
+ state: typeof RuntimeExecutionStateSchema;
617
+ status: typeof RuntimeExecutionStatusSchema;
618
+ }, z.core.$strict>;
619
+ }, z.core.$strict>;
620
+ export declare const PiDurableLeadApprovalAnswerResponseSchema: z.ZodObject<{
621
+ contractVersion: z.ZodObject<{
622
+ major: z.ZodNumber;
623
+ minor: z.ZodNumber;
624
+ }, z.core.$strict>;
625
+ requestId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"request ID">, string>>;
626
+ correlation: z.ZodObject<{
627
+ traceId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"trace ID">, string>>;
628
+ causationCommandId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"command ID">, string>>>;
629
+ parentEventId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"event ID">, string>>>;
630
+ }, z.core.$strict>;
631
+ data: z.ZodObject<{
632
+ schemaVersion: z.ZodLiteral<"pi-lead-dispatch/v1">;
633
+ dispatchId: typeof DispatchId;
634
+ intentId: typeof IntentId;
635
+ executionId: typeof IdentifierSchemas.executionId;
636
+ attemptId: typeof IdentifierSchemas.attemptId;
637
+ runtimeSessionId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"external-session ID">, string>>;
638
+ requestedTarget: z.ZodOptional<typeof PiDurableLeadRequestedTargetSchema>;
639
+ observedTarget: z.ZodOptional<typeof PiDurableLeadObservedTargetSchema>;
640
+ approvalSchemaVersion: z.ZodLiteral<"pi-lead-approval-answer/v1">;
641
+ approvalId: typeof IdentifierSchemas.interactionId;
642
+ decisionId: z.ZodString;
643
+ requestEventId: z.ZodString;
644
+ decision: z.ZodEnum<{
645
+ approve: "approve";
646
+ deny: "deny";
647
+ }>;
648
+ outcome: z.ZodEnum<{
649
+ already_decided: "already_decided";
650
+ decided: "decided";
651
+ }>;
652
+ state: typeof RuntimeExecutionStateSchema;
653
+ status: typeof RuntimeExecutionStatusSchema;
654
+ }, z.core.$strict>;
655
+ }, z.core.$strict>;
656
+ export declare const PiDurableLeadEventsResponseSchema: z.ZodObject<{
657
+ contractVersion: z.ZodObject<{
658
+ major: z.ZodNumber;
659
+ minor: z.ZodNumber;
660
+ }, z.core.$strict>;
661
+ requestId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"request ID">, string>>;
662
+ correlation: z.ZodObject<{
663
+ traceId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"trace ID">, string>>;
664
+ causationCommandId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"command ID">, string>>>;
665
+ parentEventId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"event ID">, string>>>;
666
+ }, z.core.$strict>;
667
+ data: typeof PiDurableLeadEventsDataSchema;
668
+ }, z.core.$strict>;
669
+ export declare const PiDurableSessionSchema: z.ZodObject<{
670
+ runtimeSessionId: typeof PiDurableSessionIdSchema;
671
+ role: z.ZodEnum<{
672
+ child: "child";
673
+ lead: "lead";
674
+ }>;
675
+ dispatchId: typeof DispatchId;
676
+ intentId: typeof IntentId;
677
+ delegationId: z.ZodOptional<typeof IdentifierSchemas.delegationId>;
678
+ executionId: typeof IdentifierSchemas.executionId;
679
+ attemptId: typeof IdentifierSchemas.attemptId;
680
+ state: typeof RuntimeExecutionStateSchema;
681
+ startedAt: z.ZodISODateTime;
682
+ updatedAt: z.ZodISODateTime;
683
+ }, z.core.$strict>;
684
+ export declare const PiDurableSessionsResponseSchema: z.ZodObject<{
685
+ contractVersion: z.ZodObject<{
686
+ major: z.ZodNumber;
687
+ minor: z.ZodNumber;
688
+ }, z.core.$strict>;
689
+ requestId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"request ID">, string>>;
690
+ correlation: z.ZodObject<{
691
+ traceId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"trace ID">, string>>;
692
+ causationCommandId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"command ID">, string>>>;
693
+ parentEventId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"event ID">, string>>>;
694
+ }, z.core.$strict>;
695
+ data: z.ZodObject<{
696
+ sessions: z.ZodArray<typeof PiDurableSessionSchema>;
697
+ next: z.ZodOptional<typeof PiDurableSessionIdSchema>;
698
+ }, z.core.$strict>;
699
+ }, z.core.$strict>;
700
+ export declare const PiDurableSessionEventsResponseSchema: z.ZodObject<{
701
+ contractVersion: z.ZodObject<{
702
+ major: z.ZodNumber;
703
+ minor: z.ZodNumber;
704
+ }, z.core.$strict>;
705
+ requestId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"request ID">, string>>;
706
+ correlation: z.ZodObject<{
707
+ traceId: z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"trace ID">, string>>;
708
+ causationCommandId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"command ID">, string>>>;
709
+ parentEventId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("@adea-ai/contracts").OpaqueIdentifier<"event ID">, string>>>;
710
+ }, z.core.$strict>;
711
+ data: z.ZodObject<{
712
+ contractVersion: z.ZodLiteral<1>;
713
+ runtimeSessionId: typeof PiDurableSessionIdSchema;
714
+ events: z.ZodArray<typeof PiDurableLeadTurnEventSchema>;
715
+ nextSeq: z.ZodNumber;
716
+ complete: z.ZodBoolean;
717
+ }, z.core.$strict>;
718
+ }, z.core.$strict>;
460
719
  declare const ChildReference: z.ZodString;
461
720
  export declare const PiDurableLeadChildOutcomeSchema: z.ZodObject<{
462
721
  state: z.ZodEnum<{
@@ -482,6 +741,7 @@ export declare const PiDurableLeadChildSchema: z.ZodObject<{
482
741
  delegationId: typeof IdentifierSchemas.delegationId;
483
742
  childExecutionId: typeof IdentifierSchemas.executionId;
484
743
  childAttemptId: z.ZodOptional<typeof IdentifierSchemas.attemptId>;
744
+ runtimeSessionId: z.ZodOptional<typeof IdentifierSchemas.externalSessionId>;
485
745
  role: typeof ChildReference;
486
746
  state: z.ZodEnum<{
487
747
  awaiting_input: "awaiting_input";
@@ -673,6 +933,13 @@ export declare const PiDurableLeadHttpContract: Readonly<{
673
933
  requestSchema: typeof PiDurableLeadProgressRequestSchema;
674
934
  responseSchema: typeof PiDurableLeadProgressResponseSchema;
675
935
  }>;
936
+ events: Readonly<{
937
+ route: "events";
938
+ operation: "pi-durable.lead.events";
939
+ scope: "execution:read";
940
+ requestSchema: typeof PiDurableLeadEventsRequestSchema;
941
+ responseSchema: typeof PiDurableLeadEventsResponseSchema;
942
+ }>;
676
943
  children: Readonly<{
677
944
  route: "children";
678
945
  operation: "pi-durable.lead.children";
@@ -687,6 +954,20 @@ export declare const PiDurableLeadHttpContract: Readonly<{
687
954
  requestSchema: typeof PiDurableLeadChildTargetRequestSchema;
688
955
  responseSchema: typeof PiDurableLeadChildTargetResponseSchema;
689
956
  }>;
957
+ sessions: Readonly<{
958
+ route: "sessions";
959
+ operation: "pi-durable.lead.sessions";
960
+ scope: "execution:read";
961
+ requestSchema: typeof PiDurableSessionsRequestSchema;
962
+ responseSchema: typeof PiDurableSessionsResponseSchema;
963
+ }>;
964
+ sessionEvents: Readonly<{
965
+ route: "session-events";
966
+ operation: "pi-durable.lead.session-events";
967
+ scope: "execution:read";
968
+ requestSchema: typeof PiDurableSessionEventsRequestSchema;
969
+ responseSchema: typeof PiDurableSessionEventsResponseSchema;
970
+ }>;
690
971
  cancel: Readonly<{
691
972
  route: "cancel";
692
973
  operation: "pi-durable.lead.cancel";
@@ -694,6 +975,20 @@ export declare const PiDurableLeadHttpContract: Readonly<{
694
975
  requestSchema: typeof PiDurableLeadCancelRequestSchema;
695
976
  responseSchema: typeof PiDurableLeadCancelResponseSchema;
696
977
  }>;
978
+ questionAnswer: Readonly<{
979
+ route: "questions/answer";
980
+ operation: "pi-durable.lead.question-answer";
981
+ scope: "execution:write";
982
+ requestSchema: typeof PiDurableLeadQuestionAnswerRequestSchema;
983
+ responseSchema: typeof PiDurableLeadQuestionAnswerResponseSchema;
984
+ }>;
985
+ approvalAnswer: Readonly<{
986
+ route: "approvals/answer";
987
+ operation: "pi-durable.lead.approval-answer";
988
+ scope: "execution:write";
989
+ requestSchema: typeof PiDurableLeadApprovalAnswerRequestSchema;
990
+ responseSchema: typeof PiDurableLeadApprovalAnswerResponseSchema;
991
+ }>;
697
992
  childCancel: Readonly<{
698
993
  route: "child-cancel";
699
994
  operation: "pi-durable.lead.child-cancel";
@@ -714,11 +1009,23 @@ export type PiDurableLeadStatusRequest = z.output<typeof PiDurableLeadStatusRequ
714
1009
  export type PiDurableLeadStatusResponse = z.output<typeof PiDurableLeadStatusResponseSchema>;
715
1010
  export type PiDurableLeadProgressRequest = z.output<typeof PiDurableLeadProgressRequestSchema>;
716
1011
  export type PiDurableLeadProgressResponse = z.output<typeof PiDurableLeadProgressResponseSchema>;
1012
+ export type PiDurableLeadEventsRequest = z.output<typeof PiDurableLeadEventsRequestSchema>;
1013
+ export type PiDurableLeadEventsResponse = z.output<typeof PiDurableLeadEventsResponseSchema>;
1014
+ export type PiDurableLeadTurnEvent = z.output<typeof PiDurableLeadTurnEventSchema>;
717
1015
  export type PiDurableLeadChildrenRequest = z.output<typeof PiDurableLeadChildrenRequestSchema>;
1016
+ export type PiDurableSession = z.output<typeof PiDurableSessionSchema>;
1017
+ export type PiDurableSessionsRequest = z.output<typeof PiDurableSessionsRequestSchema>;
1018
+ export type PiDurableSessionsResponse = z.output<typeof PiDurableSessionsResponseSchema>;
1019
+ export type PiDurableSessionEventsRequest = z.output<typeof PiDurableSessionEventsRequestSchema>;
1020
+ export type PiDurableSessionEventsResponse = z.output<typeof PiDurableSessionEventsResponseSchema>;
718
1021
  export type PiDurableLeadChildrenResponse = z.output<typeof PiDurableLeadChildrenResponseSchema>;
719
1022
  export type PiDurableLeadChild = z.output<typeof PiDurableLeadChildSchema>;
720
1023
  export type PiDurableLeadCancelRequest = z.output<typeof PiDurableLeadCancelRequestSchema>;
721
1024
  export type PiDurableLeadCancelResponse = z.output<typeof PiDurableLeadCancelResponseSchema>;
1025
+ export type PiDurableLeadQuestionAnswerRequest = z.output<typeof PiDurableLeadQuestionAnswerRequestSchema>;
1026
+ export type PiDurableLeadQuestionAnswerResponse = z.output<typeof PiDurableLeadQuestionAnswerResponseSchema>;
1027
+ export type PiDurableLeadApprovalAnswerRequest = z.output<typeof PiDurableLeadApprovalAnswerRequestSchema>;
1028
+ export type PiDurableLeadApprovalAnswerResponse = z.output<typeof PiDurableLeadApprovalAnswerResponseSchema>;
722
1029
  export type PiDurableLeadChildCancelRequest = z.output<typeof PiDurableLeadChildCancelRequestSchema>;
723
1030
  export type PiDurableLeadChildCancelResponse = z.output<typeof PiDurableLeadChildCancelResponseSchema>;
724
1031
  export type PiDurableLeadChildTargetRequest = z.output<typeof PiDurableLeadChildTargetRequestSchema>;
@@ -1,4 +1,6 @@
1
1
  import { z } from 'zod';
2
+ import { PiDurableQuestionAnswersSchema, PiDurableQuestionRequestIdSchema, } from './pi-durable-questions.js';
3
+ import { PiDurableApprovalAnswerSchema, PiDurableApprovalAttestationSchema, PiDurableApprovalDecisionIdSchema, } from './pi-durable-approvals.js';
2
4
  import { ContractVersionSchema, IdentifierSchemas, ModelSelectionFundingViewSchema, ModelSelectionRefSchema, PublicContractManifest, ReadRequestEnvelopeSchema, StateChangingCommandEnvelopeSchema, SuccessResponseEnvelopeSchema, negotiateContractVersion, } from '@adea-ai/contracts';
3
5
  import { RuntimeExecutionHandleSchema, RuntimeExecutionProgressSchema, RuntimeExecutionStatusSchema, RuntimeExecutionStateSchema, RuntimeObservedGenerationSchema, } from './adapter.js';
4
6
  const IntentId = z.uuid();
@@ -101,6 +103,72 @@ export const PiDurableLeadProgressRequestSchema = PiDurableLeadReadEnvelopeSchem
101
103
  })
102
104
  .strict(),
103
105
  });
106
+ export const PI_DURABLE_LEAD_EVENTS_CONTRACT_VERSION = 1;
107
+ export const PI_DURABLE_LEAD_EVENTS_MAX_PAGE = 256;
108
+ export const PI_DURABLE_LEAD_EVENTS_MAX_WAIT_MS = 8000;
109
+ const LeadEventSeq = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
110
+ export const PiDurableSessionIdSchema = z
111
+ .string()
112
+ .regex(/^(?:pi-lead:dispatch_[a-f0-9]{32}|ses_[0-9A-HJKMNP-TV-Z]{26})$/);
113
+ export const PiDurableLeadEventsRequestSchema = PiDurableLeadReadEnvelopeSchema.extend({
114
+ operation: z.literal('pi-durable.lead.events'),
115
+ parameters: z
116
+ .object({
117
+ dispatchId: DispatchId,
118
+ messageId: z
119
+ .string()
120
+ .min(1)
121
+ .max(128)
122
+ .regex(/^[A-Za-z0-9._:-]+$/),
123
+ afterSeq: LeadEventSeq,
124
+ waitMs: z.number().int().min(0).max(PI_DURABLE_LEAD_EVENTS_MAX_WAIT_MS),
125
+ limit: z.number().int().min(1).max(PI_DURABLE_LEAD_EVENTS_MAX_PAGE).optional(),
126
+ })
127
+ .strict(),
128
+ });
129
+ export const PiDurableLeadTurnEventSchema = z
130
+ .object({
131
+ schemaVersion: z.literal(1),
132
+ eventId: z.string().min(1).max(256),
133
+ runtimeSessionId: PiDurableSessionIdSchema,
134
+ harnessRunId: z.string().min(1).max(256),
135
+ generation: z.literal(1),
136
+ seq: z.string().regex(/^[1-9]\d*$/),
137
+ occurredAt: z.iso.datetime(),
138
+ receivedAt: z.iso.datetime(),
139
+ source: z.literal('native'),
140
+ sourceEventId: z.string().min(1).max(256),
141
+ confidence: z.literal('authoritative'),
142
+ classification: z.enum(['workspace_private', 'restricted_local']),
143
+ kind: z.string().min(1).max(64),
144
+ payload: z.record(z.string(), z.unknown()),
145
+ })
146
+ .strict();
147
+ export const PiDurableLeadEventsDataSchema = z
148
+ .object({
149
+ contractVersion: z.literal(PI_DURABLE_LEAD_EVENTS_CONTRACT_VERSION),
150
+ dispatchId: DispatchId,
151
+ events: z
152
+ .array(PiDurableLeadTurnEventSchema)
153
+ .max(PI_DURABLE_LEAD_EVENTS_MAX_PAGE),
154
+ nextSeq: LeadEventSeq,
155
+ complete: z.boolean(),
156
+ })
157
+ .strict()
158
+ .superRefine((value, context) => {
159
+ const first = value.nextSeq - value.events.length + 1;
160
+ value.events.forEach((event, index) => {
161
+ if (event.seq !== String(first + index) ||
162
+ event.runtimeSessionId !== `pi-lead:${value.dispatchId}`)
163
+ context.addIssue({
164
+ code: 'custom',
165
+ path: ['events', index],
166
+ message: 'Events must be the contiguous seqs of this dispatch ending at nextSeq',
167
+ });
168
+ });
169
+ if (first < 1)
170
+ context.addIssue({ code: 'custom', path: ['nextSeq'], message: 'nextSeq precedes the page' });
171
+ });
104
172
  export const PiDurableLeadChildrenCursorSchema = z
105
173
  .object({ acceptedAt: z.iso.datetime(), delegationId: IdentifierSchemas.delegationId })
106
174
  .strict()
@@ -116,6 +184,28 @@ export const PiDurableLeadChildrenRequestSchema = PiDurableLeadReadEnvelopeSchem
116
184
  })
117
185
  .strict(),
118
186
  });
187
+ export const PI_DURABLE_SESSIONS_MAX_PAGE = 256;
188
+ export const PiDurableSessionsRequestSchema = PiDurableLeadReadEnvelopeSchema.extend({
189
+ operation: z.literal('pi-durable.lead.sessions'),
190
+ parameters: z
191
+ .object({
192
+ runtimeSessionId: PiDurableSessionIdSchema.optional(),
193
+ after: PiDurableSessionIdSchema.optional(),
194
+ limit: z.number().int().min(1).max(PI_DURABLE_SESSIONS_MAX_PAGE).optional(),
195
+ })
196
+ .strict(),
197
+ });
198
+ export const PiDurableSessionEventsRequestSchema = PiDurableLeadReadEnvelopeSchema.extend({
199
+ operation: z.literal('pi-durable.lead.session-events'),
200
+ parameters: z
201
+ .object({
202
+ runtimeSessionId: PiDurableSessionIdSchema,
203
+ afterSeq: LeadEventSeq,
204
+ waitMs: z.number().int().min(0).max(PI_DURABLE_LEAD_EVENTS_MAX_WAIT_MS),
205
+ limit: z.number().int().min(1).max(PI_DURABLE_LEAD_EVENTS_MAX_PAGE).optional(),
206
+ })
207
+ .strict(),
208
+ });
119
209
  export const PiDurableLeadChildTargetRequestSchema = PiDurableLeadReadEnvelopeSchema.extend({
120
210
  operation: z.literal('pi-durable.lead.child-target'),
121
211
  parameters: z
@@ -129,6 +219,20 @@ export const PiDurableLeadCancelRequestSchema = PiDurableLeadCommandEnvelopeSche
129
219
  operation: z.literal('pi-durable.lead.cancel'),
130
220
  payload: z.object({ dispatchId: DispatchId }).strict(),
131
221
  });
222
+ export const PiDurableLeadQuestionAnswerRequestSchema = PiDurableLeadCommandEnvelopeSchema.extend({
223
+ operation: z.literal('pi-durable.lead.question-answer'),
224
+ payload: z
225
+ .object({
226
+ dispatchId: DispatchId,
227
+ requestId: PiDurableQuestionRequestIdSchema,
228
+ answers: PiDurableQuestionAnswersSchema,
229
+ })
230
+ .strict(),
231
+ });
232
+ export const PiDurableLeadApprovalAnswerRequestSchema = PiDurableLeadCommandEnvelopeSchema.extend({
233
+ operation: z.literal('pi-durable.lead.approval-answer'),
234
+ payload: PiDurableApprovalAnswerSchema.extend(PiDurableApprovalAttestationSchema.shape),
235
+ });
132
236
  export const PiDurableLeadChildCancelRequestSchema = PiDurableLeadCommandEnvelopeSchema.extend({
133
237
  operation: z.literal('pi-durable.lead.child-cancel'),
134
238
  payload: z
@@ -256,6 +360,106 @@ export const PiDurableLeadProgressResponseSchema = response.extend({
256
360
  }),
257
361
  });
258
362
  export const PiDurableLeadCancelResponseSchema = PiDurableLeadStatusResponseSchema;
363
+ export const PiDurableLeadQuestionAnswerResponseSchema = response.extend({
364
+ data: PiDurableLeadReceiptResponseSchema.extend({
365
+ questionSchemaVersion: z.literal('pi-lead-question-answer/v1'),
366
+ requestId: PiDurableQuestionRequestIdSchema,
367
+ requestEventId: z.string().min(1).max(256),
368
+ outcome: z.enum(['answered', 'already_answered', 'expired']),
369
+ state: RuntimeExecutionStateSchema,
370
+ status: RuntimeExecutionStatusSchema,
371
+ }),
372
+ });
373
+ export const PiDurableLeadApprovalAnswerResponseSchema = response.extend({
374
+ data: PiDurableLeadReceiptResponseSchema.extend({
375
+ approvalSchemaVersion: z.literal('pi-lead-approval-answer/v1'),
376
+ approvalId: IdentifierSchemas.interactionId,
377
+ decisionId: PiDurableApprovalDecisionIdSchema,
378
+ requestEventId: z.string().min(1).max(256),
379
+ decision: z.enum(['approve', 'deny']),
380
+ outcome: z.enum(['decided', 'already_decided']),
381
+ state: RuntimeExecutionStateSchema,
382
+ status: RuntimeExecutionStatusSchema,
383
+ }),
384
+ });
385
+ export const PiDurableLeadEventsResponseSchema = response.extend({
386
+ data: PiDurableLeadEventsDataSchema,
387
+ });
388
+ export const PiDurableSessionSchema = z
389
+ .object({
390
+ runtimeSessionId: PiDurableSessionIdSchema,
391
+ role: z.enum(['lead', 'child']),
392
+ dispatchId: DispatchId,
393
+ intentId: IntentId,
394
+ delegationId: IdentifierSchemas.delegationId.optional(),
395
+ executionId: IdentifierSchemas.executionId,
396
+ attemptId: IdentifierSchemas.attemptId,
397
+ state: RuntimeExecutionStateSchema,
398
+ startedAt: z.iso.datetime(),
399
+ updatedAt: z.iso.datetime(),
400
+ })
401
+ .strict()
402
+ .superRefine((value, context) => {
403
+ const lead = value.runtimeSessionId === `pi-lead:${value.dispatchId}`;
404
+ if ((value.role === 'lead') !== lead ||
405
+ (value.role === 'lead') !== (value.delegationId === undefined))
406
+ context.addIssue({
407
+ code: 'custom',
408
+ message: 'A lead session is its dispatch; a child session names its delegation',
409
+ });
410
+ });
411
+ export const PiDurableSessionsResponseSchema = response.extend({
412
+ data: z
413
+ .object({
414
+ sessions: z.array(PiDurableSessionSchema).max(PI_DURABLE_SESSIONS_MAX_PAGE),
415
+ next: PiDurableSessionIdSchema.optional(),
416
+ })
417
+ .strict()
418
+ .superRefine((value, context) => {
419
+ value.sessions.forEach((session, index) => {
420
+ const previous = value.sessions[index - 1];
421
+ if (previous && previous.runtimeSessionId >= session.runtimeSessionId)
422
+ context.addIssue({
423
+ code: 'custom',
424
+ path: ['sessions', index],
425
+ message: 'Sessions are unique and sorted by runtimeSessionId',
426
+ });
427
+ });
428
+ if (value.next !== undefined && value.next !== value.sessions.at(-1)?.runtimeSessionId)
429
+ context.addIssue({ code: 'custom', path: ['next'], message: 'next is the last session' });
430
+ }),
431
+ });
432
+ export const PiDurableSessionEventsResponseSchema = response.extend({
433
+ data: z
434
+ .object({
435
+ contractVersion: z.literal(PI_DURABLE_LEAD_EVENTS_CONTRACT_VERSION),
436
+ runtimeSessionId: PiDurableSessionIdSchema,
437
+ events: z
438
+ .array(PiDurableLeadTurnEventSchema)
439
+ .max(PI_DURABLE_LEAD_EVENTS_MAX_PAGE),
440
+ nextSeq: LeadEventSeq,
441
+ complete: z.boolean(),
442
+ })
443
+ .strict()
444
+ .superRefine((value, context) => {
445
+ const first = value.nextSeq - value.events.length + 1;
446
+ value.events.forEach((event, index) => {
447
+ if (event.seq !== String(first + index) ||
448
+ event.runtimeSessionId !== value.runtimeSessionId)
449
+ context.addIssue({
450
+ code: 'custom',
451
+ path: ['events', index],
452
+ message: 'Events must be the contiguous seqs of this session ending at nextSeq',
453
+ });
454
+ });
455
+ if (first < 1)
456
+ context.addIssue({
457
+ code: 'custom',
458
+ path: ['nextSeq'],
459
+ message: 'nextSeq precedes the page',
460
+ });
461
+ }),
462
+ });
259
463
  const ChildReference = z
260
464
  .string()
261
465
  .trim()
@@ -280,6 +484,7 @@ export const PiDurableLeadChildSchema = z
280
484
  delegationId: IdentifierSchemas.delegationId,
281
485
  childExecutionId: IdentifierSchemas.executionId,
282
486
  childAttemptId: IdentifierSchemas.attemptId.optional(),
487
+ runtimeSessionId: IdentifierSchemas.externalSessionId.optional(),
283
488
  role: ChildReference,
284
489
  state: z.enum([
285
490
  'requested',
@@ -458,6 +663,13 @@ export const PiDurableLeadHttpContract = Object.freeze({
458
663
  requestSchema: PiDurableLeadProgressRequestSchema,
459
664
  responseSchema: PiDurableLeadProgressResponseSchema,
460
665
  }),
666
+ events: Object.freeze({
667
+ route: 'events',
668
+ operation: 'pi-durable.lead.events',
669
+ scope: 'execution:read',
670
+ requestSchema: PiDurableLeadEventsRequestSchema,
671
+ responseSchema: PiDurableLeadEventsResponseSchema,
672
+ }),
461
673
  children: Object.freeze({
462
674
  route: 'children',
463
675
  operation: 'pi-durable.lead.children',
@@ -472,6 +684,20 @@ export const PiDurableLeadHttpContract = Object.freeze({
472
684
  requestSchema: PiDurableLeadChildTargetRequestSchema,
473
685
  responseSchema: PiDurableLeadChildTargetResponseSchema,
474
686
  }),
687
+ sessions: Object.freeze({
688
+ route: 'sessions',
689
+ operation: 'pi-durable.lead.sessions',
690
+ scope: 'execution:read',
691
+ requestSchema: PiDurableSessionsRequestSchema,
692
+ responseSchema: PiDurableSessionsResponseSchema,
693
+ }),
694
+ sessionEvents: Object.freeze({
695
+ route: 'session-events',
696
+ operation: 'pi-durable.lead.session-events',
697
+ scope: 'execution:read',
698
+ requestSchema: PiDurableSessionEventsRequestSchema,
699
+ responseSchema: PiDurableSessionEventsResponseSchema,
700
+ }),
475
701
  cancel: Object.freeze({
476
702
  route: 'cancel',
477
703
  operation: 'pi-durable.lead.cancel',
@@ -479,6 +705,20 @@ export const PiDurableLeadHttpContract = Object.freeze({
479
705
  requestSchema: PiDurableLeadCancelRequestSchema,
480
706
  responseSchema: PiDurableLeadCancelResponseSchema,
481
707
  }),
708
+ questionAnswer: Object.freeze({
709
+ route: 'questions/answer',
710
+ operation: 'pi-durable.lead.question-answer',
711
+ scope: 'execution:write',
712
+ requestSchema: PiDurableLeadQuestionAnswerRequestSchema,
713
+ responseSchema: PiDurableLeadQuestionAnswerResponseSchema,
714
+ }),
715
+ approvalAnswer: Object.freeze({
716
+ route: 'approvals/answer',
717
+ operation: 'pi-durable.lead.approval-answer',
718
+ scope: 'execution:write',
719
+ requestSchema: PiDurableLeadApprovalAnswerRequestSchema,
720
+ responseSchema: PiDurableLeadApprovalAnswerResponseSchema,
721
+ }),
482
722
  childCancel: Object.freeze({
483
723
  route: 'child-cancel',
484
724
  operation: 'pi-durable.lead.child-cancel',
@@ -0,0 +1,106 @@
1
+ import { z } from 'zod';
2
+ export declare const PI_QUESTION_TIMEOUT_DEFAULT_SECONDS: number;
3
+ export declare const PI_QUESTION_TIMEOUT_MIN_SECONDS = 60;
4
+ export declare const PI_QUESTION_TIMEOUT_MAX_SECONDS: number;
5
+ export declare const PI_QUESTIONS_MAX = 8;
6
+ export declare const PI_QUESTION_OPTIONS_MAX = 16;
7
+ export declare const PI_QUESTION_CONTENT_BYTES_MAX: number;
8
+ export declare const PiDurableQuestionRequestIdSchema: z.ZodString;
9
+ export declare const PiDurableQuestionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
10
+ id: z.ZodString;
11
+ prompt: z.ZodString;
12
+ required: z.ZodBoolean;
13
+ kind: z.ZodLiteral<"text">;
14
+ }, z.core.$strict>, z.ZodObject<{
15
+ id: z.ZodString;
16
+ prompt: z.ZodString;
17
+ required: z.ZodBoolean;
18
+ kind: z.ZodLiteral<"choice">;
19
+ multiple: z.ZodBoolean;
20
+ options: z.ZodArray<z.ZodObject<{
21
+ id: z.ZodString;
22
+ label: z.ZodString;
23
+ description: z.ZodOptional<z.ZodString>;
24
+ }, z.core.$strict>>;
25
+ }, z.core.$strict>], "kind">;
26
+ export type PiDurableQuestion = z.output<typeof PiDurableQuestionSchema>;
27
+ export declare const PiDurableQuestionsSchema: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
28
+ id: z.ZodString;
29
+ prompt: z.ZodString;
30
+ required: z.ZodBoolean;
31
+ kind: z.ZodLiteral<"text">;
32
+ }, z.core.$strict>, z.ZodObject<{
33
+ id: z.ZodString;
34
+ prompt: z.ZodString;
35
+ required: z.ZodBoolean;
36
+ kind: z.ZodLiteral<"choice">;
37
+ multiple: z.ZodBoolean;
38
+ options: z.ZodArray<z.ZodObject<{
39
+ id: z.ZodString;
40
+ label: z.ZodString;
41
+ description: z.ZodOptional<z.ZodString>;
42
+ }, z.core.$strict>>;
43
+ }, z.core.$strict>], "kind">>;
44
+ export declare const PiDurableQuestionAnswerSchema: z.ZodUnion<readonly [z.ZodObject<{
45
+ questionId: z.ZodString;
46
+ text: z.ZodString;
47
+ }, z.core.$strict>, z.ZodObject<{
48
+ questionId: z.ZodString;
49
+ optionIds: z.ZodArray<z.ZodString>;
50
+ }, z.core.$strict>, z.ZodObject<{
51
+ questionId: z.ZodString;
52
+ skipped: z.ZodLiteral<true>;
53
+ }, z.core.$strict>]>;
54
+ export type PiDurableQuestionAnswer = z.output<typeof PiDurableQuestionAnswerSchema>;
55
+ export declare const PiDurableQuestionAnswersSchema: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
56
+ questionId: z.ZodString;
57
+ text: z.ZodString;
58
+ }, z.core.$strict>, z.ZodObject<{
59
+ questionId: z.ZodString;
60
+ optionIds: z.ZodArray<z.ZodString>;
61
+ }, z.core.$strict>, z.ZodObject<{
62
+ questionId: z.ZodString;
63
+ skipped: z.ZodLiteral<true>;
64
+ }, z.core.$strict>]>>;
65
+ export declare const PiDurableQuestionRequestSchema: z.ZodObject<{
66
+ requestId: z.ZodString;
67
+ callId: z.ZodString;
68
+ questions: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
69
+ id: z.ZodString;
70
+ prompt: z.ZodString;
71
+ required: z.ZodBoolean;
72
+ kind: z.ZodLiteral<"text">;
73
+ }, z.core.$strict>, z.ZodObject<{
74
+ id: z.ZodString;
75
+ prompt: z.ZodString;
76
+ required: z.ZodBoolean;
77
+ kind: z.ZodLiteral<"choice">;
78
+ multiple: z.ZodBoolean;
79
+ options: z.ZodArray<z.ZodObject<{
80
+ id: z.ZodString;
81
+ label: z.ZodString;
82
+ description: z.ZodOptional<z.ZodString>;
83
+ }, z.core.$strict>>;
84
+ }, z.core.$strict>], "kind">>;
85
+ expiresAt: z.ZodISODateTime;
86
+ }, z.core.$strict>;
87
+ export type PiDurableQuestionRequest = z.output<typeof PiDurableQuestionRequestSchema>;
88
+ export declare const PiDurableQuestionOutcomeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
89
+ decision: z.ZodLiteral<"answered">;
90
+ answers: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
91
+ questionId: z.ZodString;
92
+ text: z.ZodString;
93
+ }, z.core.$strict>, z.ZodObject<{
94
+ questionId: z.ZodString;
95
+ optionIds: z.ZodArray<z.ZodString>;
96
+ }, z.core.$strict>, z.ZodObject<{
97
+ questionId: z.ZodString;
98
+ skipped: z.ZodLiteral<true>;
99
+ }, z.core.$strict>]>>;
100
+ decidedAt: z.ZodISODateTime;
101
+ }, z.core.$strict>, z.ZodObject<{
102
+ decision: z.ZodLiteral<"expired">;
103
+ decidedAt: z.ZodISODateTime;
104
+ }, z.core.$strict>], "decision">;
105
+ export type PiDurableQuestionOutcome = z.output<typeof PiDurableQuestionOutcomeSchema>;
106
+ export declare function questionAnswersProblem(questions: readonly PiDurableQuestion[], input: unknown): string | undefined;
@@ -0,0 +1,109 @@
1
+ import { z } from 'zod';
2
+ export const PI_QUESTION_TIMEOUT_DEFAULT_SECONDS = 60 * 60;
3
+ export const PI_QUESTION_TIMEOUT_MIN_SECONDS = 60;
4
+ export const PI_QUESTION_TIMEOUT_MAX_SECONDS = 24 * 60 * 60;
5
+ export const PI_QUESTIONS_MAX = 8;
6
+ export const PI_QUESTION_OPTIONS_MAX = 16;
7
+ export const PI_QUESTION_CONTENT_BYTES_MAX = 32 * 1024;
8
+ const Id = z
9
+ .string()
10
+ .min(1)
11
+ .max(64)
12
+ .regex(/^[A-Za-z0-9][A-Za-z0-9._:-]*$/);
13
+ export const PiDurableQuestionRequestIdSchema = z.string().regex(/^pi-question:[a-f0-9]{32}$/);
14
+ const OptionSchema = z.strictObject({
15
+ id: Id,
16
+ label: z.string().trim().min(1).max(512),
17
+ description: z.string().trim().min(1).max(2048).optional(),
18
+ });
19
+ export const PiDurableQuestionSchema = z.discriminatedUnion('kind', [
20
+ z.strictObject({
21
+ id: Id,
22
+ prompt: z.string().trim().min(1).max(4096),
23
+ required: z.boolean(),
24
+ kind: z.literal('text'),
25
+ }),
26
+ z.strictObject({
27
+ id: Id,
28
+ prompt: z.string().trim().min(1).max(4096),
29
+ required: z.boolean(),
30
+ kind: z.literal('choice'),
31
+ multiple: z.boolean(),
32
+ options: z
33
+ .array(OptionSchema)
34
+ .min(1)
35
+ .max(PI_QUESTION_OPTIONS_MAX)
36
+ .refine((options) => unique(options.map((option) => option.id)), 'duplicate option id'),
37
+ }),
38
+ ]);
39
+ export const PiDurableQuestionsSchema = z
40
+ .array(PiDurableQuestionSchema)
41
+ .min(1)
42
+ .max(PI_QUESTIONS_MAX)
43
+ .refine((questions) => unique(questions.map((question) => question.id)), 'duplicate question id')
44
+ .refine((questions) => fits(questions), 'questions too large');
45
+ export const PiDurableQuestionAnswerSchema = z.union([
46
+ z.strictObject({ questionId: Id, text: z.string().min(1).max(16_384) }),
47
+ z.strictObject({
48
+ questionId: Id,
49
+ optionIds: z
50
+ .array(Id)
51
+ .min(1)
52
+ .max(PI_QUESTION_OPTIONS_MAX)
53
+ .refine((ids) => unique(ids), 'duplicate option id'),
54
+ }),
55
+ z.strictObject({ questionId: Id, skipped: z.literal(true) }),
56
+ ]);
57
+ export const PiDurableQuestionAnswersSchema = z
58
+ .array(PiDurableQuestionAnswerSchema)
59
+ .max(PI_QUESTIONS_MAX)
60
+ .refine((answers) => unique(answers.map((answer) => answer.questionId)), 'duplicate question id')
61
+ .refine((answers) => fits(answers), 'answers too large');
62
+ export const PiDurableQuestionRequestSchema = z.strictObject({
63
+ requestId: PiDurableQuestionRequestIdSchema,
64
+ callId: z.string().min(1).max(256),
65
+ questions: PiDurableQuestionsSchema,
66
+ expiresAt: z.iso.datetime(),
67
+ });
68
+ export const PiDurableQuestionOutcomeSchema = z.discriminatedUnion('decision', [
69
+ z.strictObject({
70
+ decision: z.literal('answered'),
71
+ answers: PiDurableQuestionAnswersSchema,
72
+ decidedAt: z.iso.datetime(),
73
+ }),
74
+ z.strictObject({ decision: z.literal('expired'), decidedAt: z.iso.datetime() }),
75
+ ]);
76
+ export function questionAnswersProblem(questions, input) {
77
+ const parsed = PiDurableQuestionAnswersSchema.safeParse(input);
78
+ if (!parsed.success)
79
+ return 'answers are malformed';
80
+ const answers = new Map(parsed.data.map((answer) => [answer.questionId, answer]));
81
+ for (const question of questions) {
82
+ const answer = answers.get(question.id);
83
+ answers.delete(question.id);
84
+ if (!answer || 'skipped' in answer) {
85
+ if (question.required)
86
+ return 'a required question is unanswered';
87
+ }
88
+ else if (question.kind === 'text') {
89
+ if (!('text' in answer))
90
+ return 'a text question needs a text answer';
91
+ }
92
+ else {
93
+ if (!('optionIds' in answer))
94
+ return 'a choice question needs option ids';
95
+ if (!question.multiple && answer.optionIds.length !== 1)
96
+ return 'expected a single choice';
97
+ const known = new Set(question.options.map((option) => option.id));
98
+ if (answer.optionIds.some((id) => !known.has(id)))
99
+ return 'unknown option id';
100
+ }
101
+ }
102
+ return answers.size ? 'unknown question id' : undefined;
103
+ }
104
+ function unique(values) {
105
+ return new Set(values).size === values.length;
106
+ }
107
+ function fits(value) {
108
+ return Buffer.byteLength(JSON.stringify(value), 'utf8') <= PI_QUESTION_CONTENT_BYTES_MAX;
109
+ }
@@ -1,5 +1,5 @@
1
1
  import type { RuntimeAdapter, RuntimeAdapterInspection, RuntimeApprovalRequest, RuntimeCancelRequest, RuntimeExecutionHandle, RuntimeExecutionProgress, RuntimeExecutionStatus, RuntimeInputRequest, RuntimeProgressOptions, RuntimeSessionOperation, RuntimeSessionResult, RuntimeStartRequest } from './adapter.js';
2
- export type RuntimeTransportKind = 'direct-local' | 'remote-gateway';
2
+ export type RuntimeTransportKind = 'direct-local';
3
3
  export type RuntimeDriver = RuntimeAdapter;
4
4
  export interface RuntimeTransport extends RuntimeAdapter {
5
5
  readonly kind: RuntimeTransportKind;
@@ -34,7 +34,4 @@ export declare class TransportedRuntimeAdapter extends DelegatingRuntimeAdapter
34
34
  export declare class DirectLocalRuntimeTransport extends DelegatingRuntimeTransport {
35
35
  readonly kind: 'direct-local';
36
36
  }
37
- export declare class RemoteRuntimeGatewayTransport extends DelegatingRuntimeTransport {
38
- readonly kind: 'remote-gateway';
39
- }
40
37
  export {};
package/dist/transport.js CHANGED
@@ -61,6 +61,3 @@ export class TransportedRuntimeAdapter extends DelegatingRuntimeAdapter {
61
61
  export class DirectLocalRuntimeTransport extends DelegatingRuntimeTransport {
62
62
  kind = 'direct-local';
63
63
  }
64
- export class RemoteRuntimeGatewayTransport extends DelegatingRuntimeTransport {
65
- kind = 'remote-gateway';
66
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adea-ai/runtime-sdk",
3
- "version": "1.22.0",
3
+ "version": "1.24.0",
4
4
  "description": "SDK for building Control Plane runtimes: adapters, capabilities, conformance, discovery, eligibility, health, sessions, transport, and routing.",
5
5
  "keywords": [
6
6
  "adapter",
@@ -31,8 +31,7 @@
31
31
  }
32
32
  },
33
33
  "publishConfig": {
34
- "access": "public",
35
- "provenance": true
34
+ "access": "public"
36
35
  },
37
36
  "scripts": {
38
37
  "build": "tsc -p tsconfig.json",
@@ -43,7 +42,7 @@
43
42
  "test": "bun test src"
44
43
  },
45
44
  "dependencies": {
46
- "@adea-ai/contracts": "^1.26.1",
45
+ "@adea-ai/contracts": "^3.1.0",
47
46
  "zod": "4.6.6"
48
47
  },
49
48
  "engines": {