@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.
package/dist/index.d.ts CHANGED
@@ -1,635 +1,9 @@
1
- import { z } from 'zod';
1
+ import { J as JsonSchema, C as Capability, a as CapabilityHandleOptions, S as ServerToNeuronFrame, N as NeuronLogger, T as Transport, A as AuthCallback, H as Handler, b as CapabilityRegistration, c as TransportCallbacks, d as ClientFrame, P as PostPath } from './transport-QqkooS7K.js';
2
+ export { e as HandlerContext, f as HeartbeatInFlightEntry, L as LeasePayload, g as TaskPayload } from './transport-QqkooS7K.js';
2
3
  import { EventEmitter } from 'eventemitter3';
4
+ import { z } from 'zod';
3
5
  import { ErrorObject } from 'ajv';
4
6
 
5
- /** Opaque JSON Schema; runtime structure handled by ajv at the gateway. */
6
- type JsonSchema = unknown;
7
-
8
- declare const CapabilitySchema: z.ZodObject<{
9
- type: z.ZodString;
10
- scope: z.ZodUnion<[z.ZodLiteral<"any">, z.ZodObject<{
11
- onBehalfOf: z.ZodString;
12
- }, "strict", z.ZodTypeAny, {
13
- onBehalfOf: string;
14
- }, {
15
- onBehalfOf: string;
16
- }>]>;
17
- concurrency: z.ZodNumber;
18
- }, "strict", z.ZodTypeAny, {
19
- type: string;
20
- scope: "any" | {
21
- onBehalfOf: string;
22
- };
23
- concurrency: number;
24
- }, {
25
- type: string;
26
- scope: "any" | {
27
- onBehalfOf: string;
28
- };
29
- concurrency: number;
30
- }>;
31
- type Capability = z.infer<typeof CapabilitySchema>;
32
-
33
- declare const TaskPayloadSchema: z.ZodObject<{
34
- taskId: z.ZodString;
35
- workflowId: z.ZodString;
36
- capability: z.ZodString;
37
- onBehalfOf: z.ZodOptional<z.ZodString>;
38
- input: z.ZodUnknown;
39
- attempt: z.ZodNumber;
40
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
41
- }, "strict", z.ZodTypeAny, {
42
- taskId: string;
43
- workflowId: string;
44
- capability: string;
45
- attempt: number;
46
- onBehalfOf?: string | undefined;
47
- input?: unknown;
48
- metadata?: Record<string, unknown> | undefined;
49
- }, {
50
- taskId: string;
51
- workflowId: string;
52
- capability: string;
53
- attempt: number;
54
- onBehalfOf?: string | undefined;
55
- input?: unknown;
56
- metadata?: Record<string, unknown> | undefined;
57
- }>;
58
- type TaskPayload = z.infer<typeof TaskPayloadSchema>;
59
- declare const LeasePayloadSchema: z.ZodObject<{
60
- leaseId: z.ZodString;
61
- expiresAt: z.ZodString;
62
- task: z.ZodObject<{
63
- taskId: z.ZodString;
64
- workflowId: z.ZodString;
65
- capability: z.ZodString;
66
- onBehalfOf: z.ZodOptional<z.ZodString>;
67
- input: z.ZodUnknown;
68
- attempt: z.ZodNumber;
69
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
70
- }, "strict", z.ZodTypeAny, {
71
- taskId: string;
72
- workflowId: string;
73
- capability: string;
74
- attempt: number;
75
- onBehalfOf?: string | undefined;
76
- input?: unknown;
77
- metadata?: Record<string, unknown> | undefined;
78
- }, {
79
- taskId: string;
80
- workflowId: string;
81
- capability: string;
82
- attempt: number;
83
- onBehalfOf?: string | undefined;
84
- input?: unknown;
85
- metadata?: Record<string, unknown> | undefined;
86
- }>;
87
- inputSchema: z.ZodUnknown;
88
- outputSchema: z.ZodUnknown;
89
- }, "strict", z.ZodTypeAny, {
90
- leaseId: string;
91
- expiresAt: string;
92
- task: {
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?: unknown;
102
- outputSchema?: unknown;
103
- }, {
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
- type LeasePayload = z.infer<typeof LeasePayloadSchema>;
119
-
120
- declare const RegisterFrameSchema: z.ZodObject<{
121
- type: z.ZodLiteral<"register">;
122
- neuronId: z.ZodString;
123
- protocolVersion: z.ZodString;
124
- capabilities: z.ZodEffects<z.ZodArray<z.ZodObject<{
125
- type: z.ZodString;
126
- scope: z.ZodUnion<[z.ZodLiteral<"any">, z.ZodObject<{
127
- onBehalfOf: z.ZodString;
128
- }, "strict", z.ZodTypeAny, {
129
- onBehalfOf: string;
130
- }, {
131
- onBehalfOf: string;
132
- }>]>;
133
- concurrency: z.ZodNumber;
134
- }, "strict", z.ZodTypeAny, {
135
- type: string;
136
- scope: "any" | {
137
- onBehalfOf: string;
138
- };
139
- concurrency: number;
140
- }, {
141
- type: string;
142
- scope: "any" | {
143
- onBehalfOf: string;
144
- };
145
- concurrency: number;
146
- }>, "many">, {
147
- type: string;
148
- scope: "any" | {
149
- onBehalfOf: string;
150
- };
151
- concurrency: number;
152
- }[], {
153
- type: string;
154
- scope: "any" | {
155
- onBehalfOf: string;
156
- };
157
- concurrency: number;
158
- }[]>;
159
- }, "strict", z.ZodTypeAny, {
160
- type: "register";
161
- neuronId: string;
162
- protocolVersion: string;
163
- capabilities: {
164
- type: string;
165
- scope: "any" | {
166
- onBehalfOf: string;
167
- };
168
- concurrency: number;
169
- }[];
170
- }, {
171
- type: "register";
172
- neuronId: string;
173
- protocolVersion: string;
174
- capabilities: {
175
- type: string;
176
- scope: "any" | {
177
- onBehalfOf: string;
178
- };
179
- concurrency: number;
180
- }[];
181
- }>;
182
- type RegisterFrame = z.infer<typeof RegisterFrameSchema>;
183
- declare const UpdateCapabilityFrameSchema: z.ZodObject<{
184
- type: z.ZodLiteral<"update-capability">;
185
- neuronId: z.ZodString;
186
- capability: z.ZodObject<{
187
- type: z.ZodString;
188
- scope: z.ZodUnion<[z.ZodLiteral<"any">, z.ZodObject<{
189
- onBehalfOf: z.ZodString;
190
- }, "strict", z.ZodTypeAny, {
191
- onBehalfOf: string;
192
- }, {
193
- onBehalfOf: string;
194
- }>]>;
195
- concurrency: z.ZodNumber;
196
- }, "strict", z.ZodTypeAny, {
197
- type: string;
198
- scope: "any" | {
199
- onBehalfOf: string;
200
- };
201
- concurrency: number;
202
- }, {
203
- type: string;
204
- scope: "any" | {
205
- onBehalfOf: string;
206
- };
207
- concurrency: number;
208
- }>;
209
- }, "strict", z.ZodTypeAny, {
210
- type: "update-capability";
211
- capability: {
212
- type: string;
213
- scope: "any" | {
214
- onBehalfOf: string;
215
- };
216
- concurrency: number;
217
- };
218
- neuronId: string;
219
- }, {
220
- type: "update-capability";
221
- capability: {
222
- type: string;
223
- scope: "any" | {
224
- onBehalfOf: string;
225
- };
226
- concurrency: number;
227
- };
228
- neuronId: string;
229
- }>;
230
- type UpdateCapabilityFrame = z.infer<typeof UpdateCapabilityFrameSchema>;
231
- declare const HeartbeatInFlightEntrySchema: z.ZodObject<{
232
- leaseId: z.ZodString;
233
- taskId: z.ZodString;
234
- startedAt: z.ZodString;
235
- }, "strict", z.ZodTypeAny, {
236
- taskId: string;
237
- leaseId: string;
238
- startedAt: string;
239
- }, {
240
- taskId: string;
241
- leaseId: string;
242
- startedAt: string;
243
- }>;
244
- type HeartbeatInFlightEntry = z.infer<typeof HeartbeatInFlightEntrySchema>;
245
- declare const HeartbeatFrameSchema: z.ZodObject<{
246
- type: z.ZodLiteral<"heartbeat">;
247
- neuronId: z.ZodString;
248
- inFlight: z.ZodArray<z.ZodObject<{
249
- leaseId: z.ZodString;
250
- taskId: z.ZodString;
251
- startedAt: z.ZodString;
252
- }, "strict", z.ZodTypeAny, {
253
- taskId: string;
254
- leaseId: string;
255
- startedAt: string;
256
- }, {
257
- taskId: string;
258
- leaseId: string;
259
- startedAt: string;
260
- }>, "many">;
261
- sentAt: z.ZodString;
262
- }, "strict", z.ZodTypeAny, {
263
- type: "heartbeat";
264
- neuronId: string;
265
- inFlight: {
266
- taskId: string;
267
- leaseId: string;
268
- startedAt: string;
269
- }[];
270
- sentAt: string;
271
- }, {
272
- type: "heartbeat";
273
- neuronId: string;
274
- inFlight: {
275
- taskId: string;
276
- leaseId: string;
277
- startedAt: string;
278
- }[];
279
- sentAt: string;
280
- }>;
281
- type HeartbeatFrame = z.infer<typeof HeartbeatFrameSchema>;
282
- declare const AckFrameSchema: z.ZodObject<{
283
- type: z.ZodLiteral<"ack">;
284
- leaseId: z.ZodString;
285
- output: z.ZodUnknown;
286
- completedAt: z.ZodString;
287
- }, "strict", z.ZodTypeAny, {
288
- type: "ack";
289
- leaseId: string;
290
- completedAt: string;
291
- output?: unknown;
292
- }, {
293
- type: "ack";
294
- leaseId: string;
295
- completedAt: string;
296
- output?: unknown;
297
- }>;
298
- type AckFrame = z.infer<typeof AckFrameSchema>;
299
- declare const NackFrameSchema: z.ZodObject<{
300
- type: z.ZodLiteral<"nack">;
301
- leaseId: z.ZodString;
302
- kind: z.ZodEnum<["retryable", "terminal", "schema-mismatch", "cancelled"]>;
303
- reason: z.ZodString;
304
- code: z.ZodOptional<z.ZodString>;
305
- details: z.ZodOptional<z.ZodUnknown>;
306
- failedAt: z.ZodString;
307
- }, "strict", z.ZodTypeAny, {
308
- type: "nack";
309
- leaseId: string;
310
- kind: "retryable" | "terminal" | "schema-mismatch" | "cancelled";
311
- reason: string;
312
- failedAt: string;
313
- code?: string | undefined;
314
- details?: unknown;
315
- }, {
316
- type: "nack";
317
- leaseId: string;
318
- kind: "retryable" | "terminal" | "schema-mismatch" | "cancelled";
319
- reason: string;
320
- failedAt: string;
321
- code?: string | undefined;
322
- details?: unknown;
323
- }>;
324
- type NackFrame = z.infer<typeof NackFrameSchema>;
325
- declare const ProgressFrameSchema: z.ZodObject<{
326
- type: z.ZodLiteral<"progress">;
327
- leaseId: z.ZodString;
328
- percent: z.ZodOptional<z.ZodNumber>;
329
- message: z.ZodOptional<z.ZodString>;
330
- data: z.ZodOptional<z.ZodUnknown>;
331
- sentAt: z.ZodString;
332
- }, "strict", z.ZodTypeAny, {
333
- type: "progress";
334
- leaseId: string;
335
- sentAt: string;
336
- message?: string | undefined;
337
- percent?: number | undefined;
338
- data?: unknown;
339
- }, {
340
- type: "progress";
341
- leaseId: string;
342
- sentAt: string;
343
- message?: string | undefined;
344
- percent?: number | undefined;
345
- data?: unknown;
346
- }>;
347
- type ProgressFrame = z.infer<typeof ProgressFrameSchema>;
348
- declare const ServerToNeuronFrameSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
349
- type: z.ZodLiteral<"registered">;
350
- sessionId: z.ZodString;
351
- capabilities: z.ZodArray<z.ZodObject<{
352
- type: z.ZodString;
353
- scope: z.ZodUnion<[z.ZodLiteral<"any">, z.ZodObject<{
354
- onBehalfOf: z.ZodString;
355
- }, "strict", z.ZodTypeAny, {
356
- onBehalfOf: string;
357
- }, {
358
- onBehalfOf: string;
359
- }>]>;
360
- concurrency: z.ZodNumber;
361
- }, "strict", z.ZodTypeAny, {
362
- type: string;
363
- scope: "any" | {
364
- onBehalfOf: string;
365
- };
366
- concurrency: number;
367
- }, {
368
- type: string;
369
- scope: "any" | {
370
- onBehalfOf: string;
371
- };
372
- concurrency: number;
373
- }>, "many">;
374
- acceptedAt: z.ZodString;
375
- }, "strict", z.ZodTypeAny, {
376
- type: "registered";
377
- capabilities: {
378
- type: string;
379
- scope: "any" | {
380
- onBehalfOf: string;
381
- };
382
- concurrency: number;
383
- }[];
384
- sessionId: string;
385
- acceptedAt: string;
386
- }, {
387
- type: "registered";
388
- capabilities: {
389
- type: string;
390
- scope: "any" | {
391
- onBehalfOf: string;
392
- };
393
- concurrency: number;
394
- }[];
395
- sessionId: string;
396
- acceptedAt: string;
397
- }>, z.ZodObject<{
398
- type: z.ZodLiteral<"lease">;
399
- lease: z.ZodObject<{
400
- leaseId: z.ZodString;
401
- expiresAt: z.ZodString;
402
- task: z.ZodObject<{
403
- taskId: z.ZodString;
404
- workflowId: z.ZodString;
405
- capability: z.ZodString;
406
- onBehalfOf: z.ZodOptional<z.ZodString>;
407
- input: z.ZodUnknown;
408
- attempt: z.ZodNumber;
409
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
410
- }, "strict", z.ZodTypeAny, {
411
- taskId: string;
412
- workflowId: string;
413
- capability: string;
414
- attempt: number;
415
- onBehalfOf?: string | undefined;
416
- input?: unknown;
417
- metadata?: Record<string, unknown> | undefined;
418
- }, {
419
- taskId: string;
420
- workflowId: string;
421
- capability: string;
422
- attempt: number;
423
- onBehalfOf?: string | undefined;
424
- input?: unknown;
425
- metadata?: Record<string, unknown> | undefined;
426
- }>;
427
- inputSchema: z.ZodUnknown;
428
- outputSchema: z.ZodUnknown;
429
- }, "strict", z.ZodTypeAny, {
430
- leaseId: string;
431
- expiresAt: string;
432
- task: {
433
- taskId: string;
434
- workflowId: string;
435
- capability: string;
436
- attempt: number;
437
- onBehalfOf?: string | undefined;
438
- input?: unknown;
439
- metadata?: Record<string, unknown> | undefined;
440
- };
441
- inputSchema?: unknown;
442
- outputSchema?: unknown;
443
- }, {
444
- leaseId: string;
445
- expiresAt: string;
446
- task: {
447
- taskId: string;
448
- workflowId: string;
449
- capability: string;
450
- attempt: number;
451
- onBehalfOf?: string | undefined;
452
- input?: unknown;
453
- metadata?: Record<string, unknown> | undefined;
454
- };
455
- inputSchema?: unknown;
456
- outputSchema?: unknown;
457
- }>;
458
- sentAt: z.ZodString;
459
- }, "strict", z.ZodTypeAny, {
460
- type: "lease";
461
- sentAt: string;
462
- lease: {
463
- leaseId: string;
464
- expiresAt: string;
465
- task: {
466
- taskId: string;
467
- workflowId: string;
468
- capability: string;
469
- attempt: number;
470
- onBehalfOf?: string | undefined;
471
- input?: unknown;
472
- metadata?: Record<string, unknown> | undefined;
473
- };
474
- inputSchema?: unknown;
475
- outputSchema?: unknown;
476
- };
477
- }, {
478
- type: "lease";
479
- sentAt: string;
480
- lease: {
481
- leaseId: string;
482
- expiresAt: string;
483
- task: {
484
- taskId: string;
485
- workflowId: string;
486
- capability: string;
487
- attempt: number;
488
- onBehalfOf?: string | undefined;
489
- input?: unknown;
490
- metadata?: Record<string, unknown> | undefined;
491
- };
492
- inputSchema?: unknown;
493
- outputSchema?: unknown;
494
- };
495
- }>, z.ZodObject<{
496
- type: z.ZodLiteral<"cancel">;
497
- leaseId: z.ZodString;
498
- reason: z.ZodString;
499
- cancelledAt: z.ZodString;
500
- }, "strict", z.ZodTypeAny, {
501
- type: "cancel";
502
- leaseId: string;
503
- reason: string;
504
- cancelledAt: string;
505
- }, {
506
- type: "cancel";
507
- leaseId: string;
508
- reason: string;
509
- cancelledAt: string;
510
- }>, z.ZodObject<{
511
- type: z.ZodLiteral<"capability-revoked">;
512
- capability: z.ZodString;
513
- reason: z.ZodString;
514
- revokedAt: z.ZodString;
515
- }, "strict", z.ZodTypeAny, {
516
- type: "capability-revoked";
517
- capability: string;
518
- reason: string;
519
- revokedAt: string;
520
- }, {
521
- type: "capability-revoked";
522
- capability: string;
523
- reason: string;
524
- revokedAt: string;
525
- }>, z.ZodObject<{
526
- type: z.ZodLiteral<"disconnect">;
527
- reason: z.ZodString;
528
- code: z.ZodOptional<z.ZodString>;
529
- reconnectable: z.ZodBoolean;
530
- sentAt: z.ZodString;
531
- }, "strict", z.ZodTypeAny, {
532
- type: "disconnect";
533
- sentAt: string;
534
- reason: string;
535
- reconnectable: boolean;
536
- code?: string | undefined;
537
- }, {
538
- type: "disconnect";
539
- sentAt: string;
540
- reason: string;
541
- reconnectable: boolean;
542
- code?: string | undefined;
543
- }>]>;
544
- type ServerToNeuronFrame = z.infer<typeof ServerToNeuronFrameSchema>;
545
-
546
- declare const POST_PATH: {
547
- readonly register: "/neuron/register";
548
- readonly updateCapability: "/neuron/update-capability";
549
- readonly heartbeat: "/neuron/heartbeat";
550
- readonly ack: "/neuron/ack";
551
- readonly nack: "/neuron/nack";
552
- readonly progress: "/neuron/progress";
553
- };
554
- type PostPath = (typeof POST_PATH)[keyof typeof POST_PATH];
555
-
556
- /** Function returning the current bearer JWT. Called on each POST and SSE
557
- * open; can refresh tokens internally. The SDK retries once on 401, so
558
- * refreshing on 401 inside the callback is the right place to do it. */
559
- type AuthCallback = () => Promise<string> | string;
560
- /** Logger surface — minimal shape so consumers can plug in pino, console,
561
- * etc. without an interface mismatch. */
562
- interface NeuronLogger {
563
- debug(meta: Record<string, unknown>, msg?: string): void;
564
- info(meta: Record<string, unknown>, msg?: string): void;
565
- warn(meta: Record<string, unknown>, msg?: string): void;
566
- error(meta: Record<string, unknown>, msg?: string): void;
567
- }
568
- /** Per-handler context passed to `neuron.handle(...)` callbacks. */
569
- interface HandlerContext {
570
- /** Lease metadata for this delivery. */
571
- task: TaskPayload;
572
- /** UUID identifying the lease the gateway holds for this task. */
573
- leaseId: string;
574
- /**
575
- * AbortSignal that fires when the gateway sends a `cancel` frame for
576
- * this lease (workflow cancellation) or the SDK is shutting down.
577
- * Handlers that wrap fetch/HTTP calls should pass this signal through.
578
- */
579
- signal: AbortSignal;
580
- /** Logger scoped to this lease. */
581
- log: NeuronLogger;
582
- /**
583
- * Send a `progress` frame to the gateway. Non-blocking; safe to call
584
- * many times during a long-running handler.
585
- */
586
- progress(update: {
587
- percent?: number;
588
- message?: string;
589
- data?: unknown;
590
- }): void;
591
- /**
592
- * Terminal failure — short-circuits the handler with a non-retryable
593
- * nack containing the given reason. Throws an internal error to bail
594
- * out of the handler; do not catch it.
595
- */
596
- fail(reason: string, opts?: {
597
- code?: string;
598
- }): never;
599
- }
600
- /**
601
- * Low-level capability registration: type + scope + concurrency + optional
602
- * schemas. Most users go through `defineCapability` + `neuron.handle(def,
603
- * fn)` instead, but this shape is still accepted by `neuron.handle` for
604
- * cases where a zod schema isn't on hand (or for the legacy worker path).
605
- */
606
- interface CapabilityRegistration extends Capability {
607
- /** JSON Schema validated against the lease input before invoking the
608
- * handler. Mismatch produces a `schema-mismatch` nack and the handler
609
- * is never called. */
610
- inputSchema?: JsonSchema;
611
- /** JSON Schema validated against the handler's return value. Mismatch
612
- * produces a `schema-mismatch` nack and the gateway publishes a failed
613
- * TaskResult. */
614
- outputSchema?: JsonSchema;
615
- }
616
- /**
617
- * Per-deployment options when registering a `CapabilityDef` with a neuron.
618
- * Both fields override the corresponding defaults on the def. If neither
619
- * the def nor these options provide `scope`/`concurrency`, registration
620
- * throws at start time (intentional fail-fast).
621
- */
622
- interface CapabilityHandleOptions {
623
- scope?: Capability['scope'];
624
- concurrency?: number;
625
- }
626
- /** Handler signature: receives the resolved input and a context, returns
627
- * the output. Throwing nacks the lease (retryable by default; ctx.fail
628
- * for terminal). */
629
- type Handler<TInput = unknown, TOutput = unknown> = (input: TInput, ctx: HandlerContext) => Promise<TOutput> | TOutput;
630
- /** Internal: the wire frames the SDK emits. */
631
- type ClientFrame = RegisterFrame | UpdateCapabilityFrame | HeartbeatFrame | AckFrame | NackFrame | ProgressFrame;
632
-
633
7
  /**
634
8
  * `defineCapability` — single source of truth for a capability's contract.
635
9
  *
@@ -657,11 +31,23 @@ interface CapabilityDefInit<TIn extends z.ZodTypeAny, TOut extends z.ZodTypeAny>
657
31
  /** Zod schema for the capability's output payload. */
658
32
  output: TOut;
659
33
  /**
660
- * Optional deployment defaults. Both can be overridden at
34
+ * Optional deployment defaults. All can be overridden at
661
35
  * `neuron.handle(def, opts, fn)` time.
662
36
  */
663
37
  scope?: Capability['scope'];
664
38
  concurrency?: number;
39
+ /**
40
+ * Per-capability lease TTL override in milliseconds (HOL-356).
41
+ * Flows through the register frame to the gateway, which uses it
42
+ * when minting a lease's `expiresAt` for this capability instead of
43
+ * its own default. Useful when one capability runs much longer than
44
+ * the rest of a neuron's repertoire (e.g. a sandboxed Python script
45
+ * with a 10-minute deadline) — set this rather than tuning the
46
+ * gateway-wide default for everyone.
47
+ *
48
+ * Bounded `[1_000, 3_600_000]` (1s..1h) by `CapabilitySchema`.
49
+ */
50
+ leaseTtlMs?: number;
665
51
  }
666
52
  /**
667
53
  * A typed capability definition. The phantom `_input` / `_output` fields
@@ -680,6 +66,8 @@ interface CapabilityDef<TIn = unknown, TOut = unknown> {
680
66
  readonly outputSchema: JsonSchema;
681
67
  readonly scope?: Capability['scope'];
682
68
  readonly concurrency?: number;
69
+ /** See {@link CapabilityDefInit.leaseTtlMs}. */
70
+ readonly leaseTtlMs?: number;
683
71
  /** Original zod schemas — kept for runtime validation in handlers if needed. */
684
72
  readonly _zod: {
685
73
  input: z.ZodType<TIn>;
@@ -758,9 +146,10 @@ interface NeuronEvents {
758
146
  /** Pass-through of every parsed inbound SSE frame. */
759
147
  frame: (frame: ServerToNeuronFrame) => void;
760
148
  }
761
- interface NeuronOptions {
762
- /** Base URL of the gateway, e.g. `https://api.holokai.dev`. */
763
- gatewayUrl: string;
149
+ /**
150
+ * Options shared by both `NeuronOptions` shapes.
151
+ */
152
+ interface NeuronCommonOptions {
764
153
  /**
765
154
  * Stable per-process identifier. Reused across reconnects so the
766
155
  * gateway can correlate the new session with the same neuron. SDK does
@@ -768,12 +157,29 @@ interface NeuronOptions {
768
157
  * (UUID stored on disk for desktop, hostname+pid for server).
769
158
  */
770
159
  neuronId: string;
771
- /** Token provider — see `AuthCallback` for refresh semantics. */
772
- auth: AuthCallback;
773
160
  /** Logger; defaults to a silent no-op. */
774
161
  logger?: NeuronLogger;
775
162
  /** Heartbeat interval (ms). Default 10s. */
776
163
  heartbeatIntervalMs?: number;
164
+ }
165
+ /**
166
+ * Power-user shape — bring your own `Transport`. Used when the default
167
+ * HTTP+SSE transport doesn't fit, e.g. a renderer-process neuron in
168
+ * Electron embedding BigBrain in main, where leases arrive over IPC.
169
+ */
170
+ interface NeuronOptionsWithTransport extends NeuronCommonOptions {
171
+ transport: Transport;
172
+ }
173
+ /**
174
+ * Convenience shape — provide gateway URL + auth, the SDK builds an
175
+ * `HttpTransport` for you. The most common path; matches the v1 SDK
176
+ * surface so existing call sites keep compiling unchanged.
177
+ */
178
+ interface NeuronOptionsWithHttp extends NeuronCommonOptions {
179
+ /** Base URL of the gateway, e.g. `https://api.holokai.dev`. */
180
+ gatewayUrl: string;
181
+ /** Token provider — see `AuthCallback` for refresh semantics. */
182
+ auth: AuthCallback;
777
183
  /** Initial reconnect delay (ms). Default 500ms. */
778
184
  initialReconnectDelayMs?: number;
779
185
  /** Max reconnect delay (ms). Default 30s. */
@@ -781,6 +187,7 @@ interface NeuronOptions {
781
187
  /** Override `fetch`; mainly for tests. */
782
188
  fetch?: typeof fetch;
783
189
  }
190
+ type NeuronOptions = NeuronOptionsWithTransport | NeuronOptionsWithHttp;
784
191
  /**
785
192
  * Public SDK class. Compose:
786
193
  *
@@ -806,7 +213,7 @@ declare class Neuron extends EventEmitter<NeuronEvents> {
806
213
  private readonly heartbeat;
807
214
  private readonly validator;
808
215
  private readonly logger;
809
- private readonly opts;
216
+ private readonly neuronId;
810
217
  private started;
811
218
  private stopping;
812
219
  private hasOpenedOnce;
@@ -868,29 +275,7 @@ declare const SSE_EVENT_NAMES: {
868
275
  readonly disconnect: "disconnect";
869
276
  };
870
277
 
871
- /**
872
- * Internal callback surface — the `Neuron` that owns a `Transport` is the
873
- * single subscriber. There's no broadcast or late-subscription use case
874
- * here, so a callbacks-on-options shape is simpler than an emitter and
875
- * keeps the transport free of any event-library dependency.
876
- */
877
- interface TransportCallbacks {
878
- /** Fired after the SSE handshake succeeds. */
879
- onOpen?: () => void;
880
- /** Fired when the SSE stream ends — clean close or error. */
881
- onClose?: (reason: string) => void;
882
- /** Fired on every parsed server frame. */
883
- onFrame?: (frame: ServerToNeuronFrame) => void;
884
- /** Fired on connection or parse error; transport will reconnect unless stopped. */
885
- onError?: (err: Error) => void;
886
- /** Fired when a reconnect is scheduled, before the backoff delay elapses. */
887
- onReconnecting?: (info: {
888
- attempt: number;
889
- delayMs: number;
890
- reason: string;
891
- }) => void;
892
- }
893
- interface TransportOptions extends TransportCallbacks {
278
+ interface HttpTransportOptions {
894
279
  /** Base URL of the gateway (e.g. `https://api.holokai.dev`). */
895
280
  gatewayUrl: string;
896
281
  /** Stable per-process identifier sent as `?neuronId=` on the SSE GET. */
@@ -909,7 +294,7 @@ interface TransportOptions extends TransportCallbacks {
909
294
  fetch?: typeof fetch;
910
295
  }
911
296
  /**
912
- * Wire-level transport. Holds a single SSE stream open against the
297
+ * HTTP+SSE transport. Holds a single SSE stream open against the
913
298
  * gateway, parses inbound frames, exposes a typed `post(...)` for
914
299
  * outbound frames, and reconnects on disconnect with exponential backoff.
915
300
  *
@@ -920,20 +305,21 @@ interface TransportOptions extends TransportCallbacks {
920
305
  * the auth callback on 401 and retries once.
921
306
  * - `stop()` aborts the SSE stream and prevents further reconnects.
922
307
  *
923
- * Note: `Transport` does NOT call `register` itself — that's the Neuron
924
- * class's job, since register requires the SSE stream to already exist
925
- * (the gateway matches identity+neuronId between SSE pending stream and
926
- * register POST).
308
+ * Note: `HttpTransport` does NOT call `register` itself — that's the
309
+ * Neuron class's job, since register requires the SSE stream to already
310
+ * exist (the gateway matches identity+neuronId between SSE pending stream
311
+ * and register POST).
927
312
  */
928
- declare class Transport {
313
+ declare class HttpTransport implements Transport {
929
314
  private readonly opts;
930
- private readonly callbacks;
315
+ private callbacks;
931
316
  private abortController;
932
317
  private stopped;
933
318
  private connected;
934
319
  private reconnectAttempts;
935
320
  private reconnectTimer;
936
- constructor(opts: TransportOptions);
321
+ constructor(opts: HttpTransportOptions);
322
+ subscribe(callbacks: TransportCallbacks): void;
937
323
  isConnected(): boolean;
938
324
  /** Open the SSE stream. Resolves after the connection is established. */
939
325
  start(): Promise<void>;
@@ -1019,4 +405,4 @@ declare class SchemaValidator {
1019
405
  validate(schema: JsonSchema | undefined, data: unknown): ErrorObject[] | null;
1020
406
  }
1021
407
 
1022
- export { type AuthCallback, type Capability, type CapabilityDef, type CapabilityDefInit, type CapabilityHandleOptions, type CapabilityPlanShape, type CapabilityRegistration, type Handler, type HandlerContext, type HeartbeatInFlightEntry, type LeasePayload, Neuron, type NeuronEvents, type NeuronLogger, type NeuronOptions, SSE_EVENT_NAMES, SchemaValidator, type ServerToNeuronFrame, ShutdownError, type TaskPayload, Transport, type TransportCallbacks, TransportError, type TransportOptions, WorkerPool, defineCapability, toPlanShape, toRegistrationCapability };
408
+ export { AuthCallback, Capability, type CapabilityDef, type CapabilityDefInit, CapabilityHandleOptions, type CapabilityPlanShape, CapabilityRegistration, Handler, HttpTransport, type HttpTransportOptions, Neuron, type NeuronEvents, NeuronLogger, type NeuronOptions, SSE_EVENT_NAMES, SchemaValidator, ServerToNeuronFrame, ShutdownError, Transport, TransportCallbacks, TransportError, WorkerPool, defineCapability, toPlanShape, toRegistrationCapability };