@holokai/neuron-sdk 0.1.0 → 0.2.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.
@@ -0,0 +1,742 @@
1
+ import { z } from 'zod';
2
+
3
+ /** Opaque JSON Schema; runtime structure handled by ajv at the gateway. */
4
+ type JsonSchema = unknown;
5
+
6
+ declare const CapabilitySchema: z.ZodObject<{
7
+ type: z.ZodString;
8
+ scope: z.ZodUnion<[z.ZodLiteral<"any">, z.ZodObject<{
9
+ onBehalfOf: z.ZodString;
10
+ }, "strict", z.ZodTypeAny, {
11
+ onBehalfOf: string;
12
+ }, {
13
+ onBehalfOf: string;
14
+ }>]>;
15
+ concurrency: z.ZodNumber;
16
+ /**
17
+ * Per-capability lease TTL override in milliseconds (HOL-356).
18
+ * The gateway uses this when minting a lease's `expiresAt`; absent
19
+ * → falls back to the gateway's default (`leaseTtlMs` on the
20
+ * dispatcher). Lets a slow capability (e.g. a scripted run with a
21
+ * 10-minute deadline) declare a longer TTL without tuning the
22
+ * whole gateway.
23
+ *
24
+ * Bounded by reasonable extremes: at least 1s (anything shorter
25
+ * than a heartbeat is meaningless) and at most 1h (the reaper +
26
+ * heartbeat budget should be the limiter, not a single
27
+ * capability).
28
+ */
29
+ leaseTtlMs: z.ZodOptional<z.ZodNumber>;
30
+ }, "strict", z.ZodTypeAny, {
31
+ type: string;
32
+ scope: "any" | {
33
+ onBehalfOf: string;
34
+ };
35
+ concurrency: number;
36
+ leaseTtlMs?: number | undefined;
37
+ }, {
38
+ type: string;
39
+ scope: "any" | {
40
+ onBehalfOf: string;
41
+ };
42
+ concurrency: number;
43
+ leaseTtlMs?: number | undefined;
44
+ }>;
45
+ type Capability = z.infer<typeof CapabilitySchema>;
46
+
47
+ declare const TaskPayloadSchema: z.ZodObject<{
48
+ taskId: z.ZodString;
49
+ workflowId: z.ZodString;
50
+ capability: z.ZodString;
51
+ onBehalfOf: z.ZodOptional<z.ZodString>;
52
+ input: z.ZodUnknown;
53
+ attempt: z.ZodNumber;
54
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
55
+ }, "strict", z.ZodTypeAny, {
56
+ taskId: string;
57
+ workflowId: string;
58
+ capability: string;
59
+ attempt: number;
60
+ onBehalfOf?: string | undefined;
61
+ input?: unknown;
62
+ metadata?: Record<string, unknown> | undefined;
63
+ }, {
64
+ taskId: string;
65
+ workflowId: string;
66
+ capability: string;
67
+ attempt: number;
68
+ onBehalfOf?: string | undefined;
69
+ input?: unknown;
70
+ metadata?: Record<string, unknown> | undefined;
71
+ }>;
72
+ type TaskPayload = z.infer<typeof TaskPayloadSchema>;
73
+ declare const LeasePayloadSchema: z.ZodObject<{
74
+ leaseId: z.ZodString;
75
+ expiresAt: z.ZodString;
76
+ task: z.ZodObject<{
77
+ taskId: z.ZodString;
78
+ workflowId: z.ZodString;
79
+ capability: z.ZodString;
80
+ onBehalfOf: z.ZodOptional<z.ZodString>;
81
+ input: z.ZodUnknown;
82
+ attempt: z.ZodNumber;
83
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
84
+ }, "strict", z.ZodTypeAny, {
85
+ taskId: string;
86
+ workflowId: string;
87
+ capability: string;
88
+ attempt: number;
89
+ onBehalfOf?: string | undefined;
90
+ input?: unknown;
91
+ metadata?: Record<string, unknown> | undefined;
92
+ }, {
93
+ taskId: string;
94
+ workflowId: string;
95
+ capability: string;
96
+ attempt: number;
97
+ onBehalfOf?: string | undefined;
98
+ input?: unknown;
99
+ metadata?: Record<string, unknown> | undefined;
100
+ }>;
101
+ inputSchema: z.ZodUnknown;
102
+ outputSchema: z.ZodUnknown;
103
+ }, "strict", z.ZodTypeAny, {
104
+ leaseId: string;
105
+ expiresAt: string;
106
+ task: {
107
+ taskId: string;
108
+ workflowId: string;
109
+ capability: string;
110
+ attempt: number;
111
+ onBehalfOf?: string | undefined;
112
+ input?: unknown;
113
+ metadata?: Record<string, unknown> | undefined;
114
+ };
115
+ inputSchema?: unknown;
116
+ outputSchema?: unknown;
117
+ }, {
118
+ leaseId: string;
119
+ expiresAt: string;
120
+ task: {
121
+ taskId: string;
122
+ workflowId: string;
123
+ capability: string;
124
+ attempt: number;
125
+ onBehalfOf?: string | undefined;
126
+ input?: unknown;
127
+ metadata?: Record<string, unknown> | undefined;
128
+ };
129
+ inputSchema?: unknown;
130
+ outputSchema?: unknown;
131
+ }>;
132
+ type LeasePayload = z.infer<typeof LeasePayloadSchema>;
133
+
134
+ declare const RegisterFrameSchema: z.ZodObject<{
135
+ type: z.ZodLiteral<"register">;
136
+ neuronId: z.ZodString;
137
+ protocolVersion: z.ZodString;
138
+ capabilities: z.ZodEffects<z.ZodArray<z.ZodObject<{
139
+ type: z.ZodString;
140
+ scope: z.ZodUnion<[z.ZodLiteral<"any">, z.ZodObject<{
141
+ onBehalfOf: z.ZodString;
142
+ }, "strict", z.ZodTypeAny, {
143
+ onBehalfOf: string;
144
+ }, {
145
+ onBehalfOf: string;
146
+ }>]>;
147
+ concurrency: z.ZodNumber;
148
+ leaseTtlMs: z.ZodOptional<z.ZodNumber>;
149
+ }, "strict", z.ZodTypeAny, {
150
+ type: string;
151
+ scope: "any" | {
152
+ onBehalfOf: string;
153
+ };
154
+ concurrency: number;
155
+ leaseTtlMs?: number | undefined;
156
+ }, {
157
+ type: string;
158
+ scope: "any" | {
159
+ onBehalfOf: string;
160
+ };
161
+ concurrency: number;
162
+ leaseTtlMs?: number | undefined;
163
+ }>, "many">, {
164
+ type: string;
165
+ scope: "any" | {
166
+ onBehalfOf: string;
167
+ };
168
+ concurrency: number;
169
+ leaseTtlMs?: number | undefined;
170
+ }[], {
171
+ type: string;
172
+ scope: "any" | {
173
+ onBehalfOf: string;
174
+ };
175
+ concurrency: number;
176
+ leaseTtlMs?: number | undefined;
177
+ }[]>;
178
+ }, "strict", z.ZodTypeAny, {
179
+ type: "register";
180
+ neuronId: string;
181
+ protocolVersion: string;
182
+ capabilities: {
183
+ type: string;
184
+ scope: "any" | {
185
+ onBehalfOf: string;
186
+ };
187
+ concurrency: number;
188
+ leaseTtlMs?: number | undefined;
189
+ }[];
190
+ }, {
191
+ type: "register";
192
+ neuronId: string;
193
+ protocolVersion: string;
194
+ capabilities: {
195
+ type: string;
196
+ scope: "any" | {
197
+ onBehalfOf: string;
198
+ };
199
+ concurrency: number;
200
+ leaseTtlMs?: number | undefined;
201
+ }[];
202
+ }>;
203
+ type RegisterFrame = z.infer<typeof RegisterFrameSchema>;
204
+ declare const UpdateCapabilityFrameSchema: z.ZodObject<{
205
+ type: z.ZodLiteral<"update-capability">;
206
+ neuronId: z.ZodString;
207
+ capability: z.ZodObject<{
208
+ type: z.ZodString;
209
+ scope: z.ZodUnion<[z.ZodLiteral<"any">, z.ZodObject<{
210
+ onBehalfOf: z.ZodString;
211
+ }, "strict", z.ZodTypeAny, {
212
+ onBehalfOf: string;
213
+ }, {
214
+ onBehalfOf: string;
215
+ }>]>;
216
+ concurrency: z.ZodNumber;
217
+ leaseTtlMs: z.ZodOptional<z.ZodNumber>;
218
+ }, "strict", z.ZodTypeAny, {
219
+ type: string;
220
+ scope: "any" | {
221
+ onBehalfOf: string;
222
+ };
223
+ concurrency: number;
224
+ leaseTtlMs?: number | undefined;
225
+ }, {
226
+ type: string;
227
+ scope: "any" | {
228
+ onBehalfOf: string;
229
+ };
230
+ concurrency: number;
231
+ leaseTtlMs?: number | undefined;
232
+ }>;
233
+ }, "strict", z.ZodTypeAny, {
234
+ type: "update-capability";
235
+ capability: {
236
+ type: string;
237
+ scope: "any" | {
238
+ onBehalfOf: string;
239
+ };
240
+ concurrency: number;
241
+ leaseTtlMs?: number | undefined;
242
+ };
243
+ neuronId: string;
244
+ }, {
245
+ type: "update-capability";
246
+ capability: {
247
+ type: string;
248
+ scope: "any" | {
249
+ onBehalfOf: string;
250
+ };
251
+ concurrency: number;
252
+ leaseTtlMs?: number | undefined;
253
+ };
254
+ neuronId: string;
255
+ }>;
256
+ type UpdateCapabilityFrame = z.infer<typeof UpdateCapabilityFrameSchema>;
257
+ declare const HeartbeatInFlightEntrySchema: z.ZodObject<{
258
+ leaseId: z.ZodString;
259
+ taskId: z.ZodString;
260
+ startedAt: z.ZodString;
261
+ }, "strict", z.ZodTypeAny, {
262
+ taskId: string;
263
+ leaseId: string;
264
+ startedAt: string;
265
+ }, {
266
+ taskId: string;
267
+ leaseId: string;
268
+ startedAt: string;
269
+ }>;
270
+ type HeartbeatInFlightEntry = z.infer<typeof HeartbeatInFlightEntrySchema>;
271
+ declare const HeartbeatFrameSchema: z.ZodObject<{
272
+ type: z.ZodLiteral<"heartbeat">;
273
+ neuronId: z.ZodString;
274
+ inFlight: z.ZodArray<z.ZodObject<{
275
+ leaseId: z.ZodString;
276
+ taskId: z.ZodString;
277
+ startedAt: z.ZodString;
278
+ }, "strict", z.ZodTypeAny, {
279
+ taskId: string;
280
+ leaseId: string;
281
+ startedAt: string;
282
+ }, {
283
+ taskId: string;
284
+ leaseId: string;
285
+ startedAt: string;
286
+ }>, "many">;
287
+ sentAt: z.ZodString;
288
+ }, "strict", z.ZodTypeAny, {
289
+ type: "heartbeat";
290
+ neuronId: string;
291
+ inFlight: {
292
+ taskId: string;
293
+ leaseId: string;
294
+ startedAt: string;
295
+ }[];
296
+ sentAt: string;
297
+ }, {
298
+ type: "heartbeat";
299
+ neuronId: string;
300
+ inFlight: {
301
+ taskId: string;
302
+ leaseId: string;
303
+ startedAt: string;
304
+ }[];
305
+ sentAt: string;
306
+ }>;
307
+ type HeartbeatFrame = z.infer<typeof HeartbeatFrameSchema>;
308
+ declare const AckFrameSchema: z.ZodObject<{
309
+ type: z.ZodLiteral<"ack">;
310
+ leaseId: z.ZodString;
311
+ output: z.ZodUnknown;
312
+ completedAt: z.ZodString;
313
+ }, "strict", z.ZodTypeAny, {
314
+ type: "ack";
315
+ leaseId: string;
316
+ completedAt: string;
317
+ output?: unknown;
318
+ }, {
319
+ type: "ack";
320
+ leaseId: string;
321
+ completedAt: string;
322
+ output?: unknown;
323
+ }>;
324
+ type AckFrame = z.infer<typeof AckFrameSchema>;
325
+ declare const NackFrameSchema: z.ZodObject<{
326
+ type: z.ZodLiteral<"nack">;
327
+ leaseId: z.ZodString;
328
+ kind: z.ZodEnum<["retryable", "terminal", "schema-mismatch", "cancelled"]>;
329
+ reason: z.ZodString;
330
+ code: z.ZodOptional<z.ZodString>;
331
+ details: z.ZodOptional<z.ZodUnknown>;
332
+ failedAt: z.ZodString;
333
+ }, "strict", z.ZodTypeAny, {
334
+ type: "nack";
335
+ leaseId: string;
336
+ kind: "retryable" | "terminal" | "schema-mismatch" | "cancelled";
337
+ reason: string;
338
+ failedAt: string;
339
+ code?: string | undefined;
340
+ details?: unknown;
341
+ }, {
342
+ type: "nack";
343
+ leaseId: string;
344
+ kind: "retryable" | "terminal" | "schema-mismatch" | "cancelled";
345
+ reason: string;
346
+ failedAt: string;
347
+ code?: string | undefined;
348
+ details?: unknown;
349
+ }>;
350
+ type NackFrame = z.infer<typeof NackFrameSchema>;
351
+ declare const ProgressFrameSchema: z.ZodObject<{
352
+ type: z.ZodLiteral<"progress">;
353
+ leaseId: z.ZodString;
354
+ percent: z.ZodOptional<z.ZodNumber>;
355
+ message: z.ZodOptional<z.ZodString>;
356
+ data: z.ZodOptional<z.ZodUnknown>;
357
+ sentAt: z.ZodString;
358
+ }, "strict", z.ZodTypeAny, {
359
+ type: "progress";
360
+ leaseId: string;
361
+ sentAt: string;
362
+ message?: string | undefined;
363
+ percent?: number | undefined;
364
+ data?: unknown;
365
+ }, {
366
+ type: "progress";
367
+ leaseId: string;
368
+ sentAt: string;
369
+ message?: string | undefined;
370
+ percent?: number | undefined;
371
+ data?: unknown;
372
+ }>;
373
+ type ProgressFrame = z.infer<typeof ProgressFrameSchema>;
374
+ declare const ServerToNeuronFrameSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
375
+ type: z.ZodLiteral<"registered">;
376
+ sessionId: z.ZodString;
377
+ capabilities: z.ZodArray<z.ZodObject<{
378
+ type: z.ZodString;
379
+ scope: z.ZodUnion<[z.ZodLiteral<"any">, z.ZodObject<{
380
+ onBehalfOf: z.ZodString;
381
+ }, "strict", z.ZodTypeAny, {
382
+ onBehalfOf: string;
383
+ }, {
384
+ onBehalfOf: string;
385
+ }>]>;
386
+ concurrency: z.ZodNumber;
387
+ leaseTtlMs: z.ZodOptional<z.ZodNumber>;
388
+ }, "strict", z.ZodTypeAny, {
389
+ type: string;
390
+ scope: "any" | {
391
+ onBehalfOf: string;
392
+ };
393
+ concurrency: number;
394
+ leaseTtlMs?: number | undefined;
395
+ }, {
396
+ type: string;
397
+ scope: "any" | {
398
+ onBehalfOf: string;
399
+ };
400
+ concurrency: number;
401
+ leaseTtlMs?: number | undefined;
402
+ }>, "many">;
403
+ acceptedAt: z.ZodString;
404
+ }, "strict", z.ZodTypeAny, {
405
+ type: "registered";
406
+ capabilities: {
407
+ type: string;
408
+ scope: "any" | {
409
+ onBehalfOf: string;
410
+ };
411
+ concurrency: number;
412
+ leaseTtlMs?: number | undefined;
413
+ }[];
414
+ sessionId: string;
415
+ acceptedAt: string;
416
+ }, {
417
+ type: "registered";
418
+ capabilities: {
419
+ type: string;
420
+ scope: "any" | {
421
+ onBehalfOf: string;
422
+ };
423
+ concurrency: number;
424
+ leaseTtlMs?: number | undefined;
425
+ }[];
426
+ sessionId: string;
427
+ acceptedAt: string;
428
+ }>, z.ZodObject<{
429
+ type: z.ZodLiteral<"lease">;
430
+ lease: z.ZodObject<{
431
+ leaseId: z.ZodString;
432
+ expiresAt: z.ZodString;
433
+ task: z.ZodObject<{
434
+ taskId: z.ZodString;
435
+ workflowId: z.ZodString;
436
+ capability: z.ZodString;
437
+ onBehalfOf: z.ZodOptional<z.ZodString>;
438
+ input: z.ZodUnknown;
439
+ attempt: z.ZodNumber;
440
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
441
+ }, "strict", z.ZodTypeAny, {
442
+ taskId: string;
443
+ workflowId: string;
444
+ capability: string;
445
+ attempt: number;
446
+ onBehalfOf?: string | undefined;
447
+ input?: unknown;
448
+ metadata?: Record<string, unknown> | undefined;
449
+ }, {
450
+ taskId: string;
451
+ workflowId: string;
452
+ capability: string;
453
+ attempt: number;
454
+ onBehalfOf?: string | undefined;
455
+ input?: unknown;
456
+ metadata?: Record<string, unknown> | undefined;
457
+ }>;
458
+ inputSchema: z.ZodUnknown;
459
+ outputSchema: z.ZodUnknown;
460
+ }, "strict", z.ZodTypeAny, {
461
+ leaseId: string;
462
+ expiresAt: string;
463
+ task: {
464
+ taskId: string;
465
+ workflowId: string;
466
+ capability: string;
467
+ attempt: number;
468
+ onBehalfOf?: string | undefined;
469
+ input?: unknown;
470
+ metadata?: Record<string, unknown> | undefined;
471
+ };
472
+ inputSchema?: unknown;
473
+ outputSchema?: unknown;
474
+ }, {
475
+ leaseId: string;
476
+ expiresAt: string;
477
+ task: {
478
+ taskId: string;
479
+ workflowId: string;
480
+ capability: string;
481
+ attempt: number;
482
+ onBehalfOf?: string | undefined;
483
+ input?: unknown;
484
+ metadata?: Record<string, unknown> | undefined;
485
+ };
486
+ inputSchema?: unknown;
487
+ outputSchema?: unknown;
488
+ }>;
489
+ sentAt: z.ZodString;
490
+ }, "strict", z.ZodTypeAny, {
491
+ type: "lease";
492
+ sentAt: string;
493
+ lease: {
494
+ leaseId: string;
495
+ expiresAt: string;
496
+ task: {
497
+ taskId: string;
498
+ workflowId: string;
499
+ capability: string;
500
+ attempt: number;
501
+ onBehalfOf?: string | undefined;
502
+ input?: unknown;
503
+ metadata?: Record<string, unknown> | undefined;
504
+ };
505
+ inputSchema?: unknown;
506
+ outputSchema?: unknown;
507
+ };
508
+ }, {
509
+ type: "lease";
510
+ sentAt: string;
511
+ lease: {
512
+ leaseId: string;
513
+ expiresAt: string;
514
+ task: {
515
+ taskId: string;
516
+ workflowId: string;
517
+ capability: string;
518
+ attempt: number;
519
+ onBehalfOf?: string | undefined;
520
+ input?: unknown;
521
+ metadata?: Record<string, unknown> | undefined;
522
+ };
523
+ inputSchema?: unknown;
524
+ outputSchema?: unknown;
525
+ };
526
+ }>, z.ZodObject<{
527
+ type: z.ZodLiteral<"cancel">;
528
+ leaseId: z.ZodString;
529
+ reason: z.ZodString;
530
+ cancelledAt: z.ZodString;
531
+ }, "strict", z.ZodTypeAny, {
532
+ type: "cancel";
533
+ leaseId: string;
534
+ reason: string;
535
+ cancelledAt: string;
536
+ }, {
537
+ type: "cancel";
538
+ leaseId: string;
539
+ reason: string;
540
+ cancelledAt: string;
541
+ }>, z.ZodObject<{
542
+ type: z.ZodLiteral<"capability-revoked">;
543
+ capability: z.ZodString;
544
+ reason: z.ZodString;
545
+ revokedAt: z.ZodString;
546
+ }, "strict", z.ZodTypeAny, {
547
+ type: "capability-revoked";
548
+ capability: string;
549
+ reason: string;
550
+ revokedAt: string;
551
+ }, {
552
+ type: "capability-revoked";
553
+ capability: string;
554
+ reason: string;
555
+ revokedAt: string;
556
+ }>, z.ZodObject<{
557
+ type: z.ZodLiteral<"disconnect">;
558
+ reason: z.ZodString;
559
+ code: z.ZodOptional<z.ZodString>;
560
+ reconnectable: z.ZodBoolean;
561
+ sentAt: z.ZodString;
562
+ }, "strict", z.ZodTypeAny, {
563
+ type: "disconnect";
564
+ sentAt: string;
565
+ reason: string;
566
+ reconnectable: boolean;
567
+ code?: string | undefined;
568
+ }, {
569
+ type: "disconnect";
570
+ sentAt: string;
571
+ reason: string;
572
+ reconnectable: boolean;
573
+ code?: string | undefined;
574
+ }>]>;
575
+ type ServerToNeuronFrame = z.infer<typeof ServerToNeuronFrameSchema>;
576
+
577
+ declare const POST_PATH: {
578
+ readonly register: "/neuron/register";
579
+ readonly updateCapability: "/neuron/update-capability";
580
+ readonly heartbeat: "/neuron/heartbeat";
581
+ readonly ack: "/neuron/ack";
582
+ readonly nack: "/neuron/nack";
583
+ readonly progress: "/neuron/progress";
584
+ };
585
+ type PostPath = (typeof POST_PATH)[keyof typeof POST_PATH];
586
+
587
+ /** Function returning the current bearer JWT. Called on each POST and SSE
588
+ * open; can refresh tokens internally. The SDK retries once on 401, so
589
+ * refreshing on 401 inside the callback is the right place to do it. */
590
+ type AuthCallback = () => Promise<string> | string;
591
+ /** Logger surface — minimal shape so consumers can plug in pino, console,
592
+ * etc. without an interface mismatch. */
593
+ interface NeuronLogger {
594
+ debug(meta: Record<string, unknown>, msg?: string): void;
595
+ info(meta: Record<string, unknown>, msg?: string): void;
596
+ warn(meta: Record<string, unknown>, msg?: string): void;
597
+ error(meta: Record<string, unknown>, msg?: string): void;
598
+ }
599
+ /** Per-handler context passed to `neuron.handle(...)` callbacks. */
600
+ interface HandlerContext {
601
+ /** Lease metadata for this delivery. */
602
+ task: TaskPayload;
603
+ /** UUID identifying the lease the gateway holds for this task. */
604
+ leaseId: string;
605
+ /**
606
+ * AbortSignal that fires when the gateway sends a `cancel` frame for
607
+ * this lease (workflow cancellation) or the SDK is shutting down.
608
+ * Handlers that wrap fetch/HTTP calls should pass this signal through.
609
+ */
610
+ signal: AbortSignal;
611
+ /** Logger scoped to this lease. */
612
+ log: NeuronLogger;
613
+ /**
614
+ * Send a `progress` frame to the gateway. Non-blocking; safe to call
615
+ * many times during a long-running handler.
616
+ */
617
+ progress(update: {
618
+ percent?: number;
619
+ message?: string;
620
+ data?: unknown;
621
+ }): void;
622
+ /**
623
+ * Terminal failure — short-circuits the handler with a non-retryable
624
+ * nack containing the given reason. Throws an internal error to bail
625
+ * out of the handler; do not catch it.
626
+ */
627
+ fail(reason: string, opts?: {
628
+ code?: string;
629
+ }): never;
630
+ }
631
+ /**
632
+ * Low-level capability registration: type + scope + concurrency + optional
633
+ * schemas. Most users go through `defineCapability` + `neuron.handle(def,
634
+ * fn)` instead, but this shape is still accepted by `neuron.handle` for
635
+ * cases where a zod schema isn't on hand (or for the legacy worker path).
636
+ */
637
+ interface CapabilityRegistration extends Capability {
638
+ /** JSON Schema validated against the lease input before invoking the
639
+ * handler. Mismatch produces a `schema-mismatch` nack and the handler
640
+ * is never called. */
641
+ inputSchema?: JsonSchema;
642
+ /** JSON Schema validated against the handler's return value. Mismatch
643
+ * produces a `schema-mismatch` nack and the gateway publishes a failed
644
+ * TaskResult. */
645
+ outputSchema?: JsonSchema;
646
+ }
647
+ /**
648
+ * Per-deployment options when registering a `CapabilityDef` with a neuron.
649
+ * Both fields override the corresponding defaults on the def. If neither
650
+ * the def nor these options provide `scope`/`concurrency`, registration
651
+ * throws at start time (intentional fail-fast).
652
+ */
653
+ interface CapabilityHandleOptions {
654
+ scope?: Capability['scope'];
655
+ concurrency?: number;
656
+ /**
657
+ * Per-capability lease TTL override (HOL-356). Wins over the same
658
+ * field on the def. See `CapabilityDefInit.leaseTtlMs` for shape;
659
+ * bounded `[1_000, 3_600_000]` (1s..1h) by `CapabilitySchema`.
660
+ */
661
+ leaseTtlMs?: number;
662
+ }
663
+ /** Handler signature: receives the resolved input and a context, returns
664
+ * the output. Throwing nacks the lease (retryable by default; ctx.fail
665
+ * for terminal). */
666
+ type Handler<TInput = unknown, TOutput = unknown> = (input: TInput, ctx: HandlerContext) => Promise<TOutput> | TOutput;
667
+ /** Internal: the wire frames the SDK emits. */
668
+ type ClientFrame = RegisterFrame | UpdateCapabilityFrame | HeartbeatFrame | AckFrame | NackFrame | ProgressFrame;
669
+
670
+ /**
671
+ * The wire-level abstraction the rest of the SDK builds on. A `Transport`
672
+ * is whatever can carry typed frames in both directions:
673
+ *
674
+ * - outbound: typed POSTs of `ClientFrame`s (register, heartbeat, ack,
675
+ * nack, progress, update-capability),
676
+ * - inbound: a stream of `ServerToNeuronFrame`s delivered via the
677
+ * callback shape on the constructor / factory of the implementation.
678
+ *
679
+ * The default implementation is `HttpTransport` (SSE + HTTPS POST). An
680
+ * `IpcTransport` exists for renderer-process neurons running inside an
681
+ * Electron app that hosts BigBrain in main.
682
+ *
683
+ * Implementations are responsible for:
684
+ *
685
+ * - establishing the inbound channel during `start()` and tearing it
686
+ * down during `stop()`,
687
+ * - delivering parsed inbound frames via the callbacks supplied at
688
+ * construction (see `TransportCallbacks`),
689
+ * - reporting connection state via `isConnected()`,
690
+ * - any reconnect / retry strategy that makes sense for the underlying
691
+ * wire (HTTP reconnects with backoff; IPC has no transient socket).
692
+ *
693
+ * The SDK never reaches past these four methods — `Neuron`,
694
+ * `HeartbeatLoop`, `runLease`, etc. all treat `Transport` as a black box.
695
+ * Adding a new transport means implementing this interface, nothing else.
696
+ */
697
+ interface Transport {
698
+ /**
699
+ * Bind the lifecycle callbacks. Single-subscriber model — calling this
700
+ * a second time replaces any prior subscription. Must be called before
701
+ * `start()`; the owning `Neuron` does this in its constructor so the
702
+ * transport can deliver inbound frames as soon as the channel opens.
703
+ */
704
+ subscribe(callbacks: TransportCallbacks): void;
705
+ /** Open the inbound channel. Resolves once the connection is established. */
706
+ start(): Promise<void>;
707
+ /** Close the inbound channel and prevent any further reconnect attempts. */
708
+ stop(): Promise<void>;
709
+ /** Send a typed client frame outbound. Resolves with the parsed body. */
710
+ post<T extends ClientFrame>(path: PostPath, frame: T): Promise<unknown>;
711
+ /** Whether the inbound channel is currently live. */
712
+ isConnected(): boolean;
713
+ }
714
+ /**
715
+ * Lifecycle callbacks fired by a `Transport` implementation. Single
716
+ * subscriber (the owning `Neuron`); a callbacks-on-options shape is
717
+ * simpler than an emitter and keeps transport implementations free of
718
+ * any event-library dependency.
719
+ */
720
+ interface TransportCallbacks {
721
+ /** Fired once the inbound channel is established. */
722
+ onOpen?: () => void;
723
+ /** Fired when the inbound channel ends — clean close or error. */
724
+ onClose?: (reason: string) => void;
725
+ /** Fired on every parsed server frame. */
726
+ onFrame?: (frame: ServerToNeuronFrame) => void;
727
+ /** Fired on transport-level errors (connect, parse, IPC dispatch). */
728
+ onError?: (err: Error) => void;
729
+ /**
730
+ * Fired when an implementation has decided to reconnect, before the
731
+ * delay elapses. HTTP transport schedules these on disconnect with
732
+ * exponential backoff; IPC transport never fires this (no transient
733
+ * socket).
734
+ */
735
+ onReconnecting?: (info: {
736
+ attempt: number;
737
+ delayMs: number;
738
+ reason: string;
739
+ }) => void;
740
+ }
741
+
742
+ export type { AuthCallback as A, Capability as C, Handler as H, JsonSchema as J, LeasePayload as L, NeuronLogger as N, PostPath as P, ServerToNeuronFrame as S, Transport as T, CapabilityHandleOptions as a, CapabilityRegistration as b, TransportCallbacks as c, ClientFrame as d, HandlerContext as e, HeartbeatInFlightEntry as f, TaskPayload as g };