@holokai/neuron-sdk 0.1.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 +628 -0
- package/dist/index.d.mts +1022 -0
- package/dist/index.d.ts +1022 -0
- package/dist/index.js +1124 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1108 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +71 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1022 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { EventEmitter } from 'eventemitter3';
|
|
3
|
+
import { ErrorObject } from 'ajv';
|
|
4
|
+
|
|
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
|
+
/**
|
|
634
|
+
* `defineCapability` — single source of truth for a capability's contract.
|
|
635
|
+
*
|
|
636
|
+
* One object carries everything a neuron and a planner need to know about a
|
|
637
|
+
* capability: namespaced type, human-readable description, typed input and
|
|
638
|
+
* output schemas, and (optionally) deployment defaults like scope and
|
|
639
|
+
* concurrency. The SDK serializes only the fields each endpoint cares
|
|
640
|
+
* about — plan-time gets the contract, registration gets the deployment.
|
|
641
|
+
*
|
|
642
|
+
* Why one object: users don't have to juggle a "plan-time def" vs a
|
|
643
|
+
* "registration-time def". Defaults set on the def can still be overridden
|
|
644
|
+
* at `neuron.handle(...)` time per deployment (e.g., desktop vs server).
|
|
645
|
+
*/
|
|
646
|
+
|
|
647
|
+
interface CapabilityDefInit<TIn extends z.ZodTypeAny, TOut extends z.ZodTypeAny> {
|
|
648
|
+
/** Namespaced capability type, e.g. `core/script.python`. */
|
|
649
|
+
type: string;
|
|
650
|
+
/**
|
|
651
|
+
* Plain-language description shown to the planner LLM. Required at
|
|
652
|
+
* plan-time so the model can choose this capability appropriately.
|
|
653
|
+
*/
|
|
654
|
+
description: string;
|
|
655
|
+
/** Zod schema for the capability's input payload. */
|
|
656
|
+
input: TIn;
|
|
657
|
+
/** Zod schema for the capability's output payload. */
|
|
658
|
+
output: TOut;
|
|
659
|
+
/**
|
|
660
|
+
* Optional deployment defaults. Both can be overridden at
|
|
661
|
+
* `neuron.handle(def, opts, fn)` time.
|
|
662
|
+
*/
|
|
663
|
+
scope?: Capability['scope'];
|
|
664
|
+
concurrency?: number;
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* A typed capability definition. The phantom `_input` / `_output` fields
|
|
668
|
+
* carry the inferred TS types so `neuron.handle(def, fn)` can constrain
|
|
669
|
+
* `fn`'s argument and return type.
|
|
670
|
+
*
|
|
671
|
+
* Internal serializers (`toPlanShape`, `toRegistrationCapability`) keep the
|
|
672
|
+
* "send only what the endpoint needs" rule in one place — endpoints get
|
|
673
|
+
* the right subset and never accidentally see the wrong fields.
|
|
674
|
+
*/
|
|
675
|
+
interface CapabilityDef<TIn = unknown, TOut = unknown> {
|
|
676
|
+
readonly type: string;
|
|
677
|
+
readonly description: string;
|
|
678
|
+
/** Compiled JSON Schema — derived once at definition time. */
|
|
679
|
+
readonly inputSchema: JsonSchema;
|
|
680
|
+
readonly outputSchema: JsonSchema;
|
|
681
|
+
readonly scope?: Capability['scope'];
|
|
682
|
+
readonly concurrency?: number;
|
|
683
|
+
/** Original zod schemas — kept for runtime validation in handlers if needed. */
|
|
684
|
+
readonly _zod: {
|
|
685
|
+
input: z.ZodType<TIn>;
|
|
686
|
+
output: z.ZodType<TOut>;
|
|
687
|
+
};
|
|
688
|
+
/** Phantom type carriers — never read at runtime. */
|
|
689
|
+
readonly _input?: TIn;
|
|
690
|
+
readonly _output?: TOut;
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Plan-request shape: `{ type, description, input, output }`. Scope and
|
|
694
|
+
* concurrency are intentionally dropped — they're per-deployment and
|
|
695
|
+
* don't belong in the planner's catalog.
|
|
696
|
+
*/
|
|
697
|
+
interface CapabilityPlanShape {
|
|
698
|
+
type: string;
|
|
699
|
+
description: string;
|
|
700
|
+
input: JsonSchema;
|
|
701
|
+
output: JsonSchema;
|
|
702
|
+
}
|
|
703
|
+
declare function defineCapability<TIn extends z.ZodTypeAny, TOut extends z.ZodTypeAny>(init: CapabilityDefInit<TIn, TOut>): CapabilityDef<z.infer<TIn>, z.infer<TOut>>;
|
|
704
|
+
/** Render the def for inclusion in a `POST /plan` catalog. */
|
|
705
|
+
declare function toPlanShape(def: CapabilityDef): CapabilityPlanShape;
|
|
706
|
+
/**
|
|
707
|
+
* Render the registration `Capability` frame for the gateway. `opts`
|
|
708
|
+
* overrides any defaults set on the def. `scope` and `concurrency` are
|
|
709
|
+
* required at registration time — if neither the def nor `opts` provides
|
|
710
|
+
* them, this throws so the misconfiguration surfaces at start time
|
|
711
|
+
* rather than as a confusing wire-validation error.
|
|
712
|
+
*/
|
|
713
|
+
declare function toRegistrationCapability(def: CapabilityDef, opts?: CapabilityHandleOptions): Capability;
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Public event surface. The `Neuron` class extends `EventEmitter<NeuronEvents>`
|
|
717
|
+
* from `eventemitter3` so consumers can subscribe with the familiar
|
|
718
|
+
* `.on() / .once() / .off()` API:
|
|
719
|
+
*
|
|
720
|
+
* neuron.on('frame', (frame) => log.append(frame));
|
|
721
|
+
* neuron.once('connection:registered', ({ sessionId }) => mountUI(sessionId));
|
|
722
|
+
* const off = neuron.on('error', captureError);
|
|
723
|
+
* off();
|
|
724
|
+
*
|
|
725
|
+
* Two flavors:
|
|
726
|
+
*
|
|
727
|
+
* - `frame` — a pass-through of the gateway's `/neuron/events` SSE stream.
|
|
728
|
+
* Fires for every parsed `ServerToNeuronFrame`, including ones for
|
|
729
|
+
* which no handler is registered. Useful for live event logs,
|
|
730
|
+
* observability, and the neuron-tester debug UI.
|
|
731
|
+
*
|
|
732
|
+
* - `connection:*` and `error` — synthetic, SDK-generated. Mirror the
|
|
733
|
+
* transport's lifecycle (SSE handshake, register acceptance, close,
|
|
734
|
+
* reconnect scheduling).
|
|
735
|
+
*
|
|
736
|
+
* Adding new events is intentionally cheap — extend `NeuronEvents` and emit
|
|
737
|
+
* from inside the class. Future entries (e.g. `'workflow:task-completed'`
|
|
738
|
+
* for sibling-neuron notifications) slot in without breaking subscribers.
|
|
739
|
+
*/
|
|
740
|
+
interface NeuronEvents {
|
|
741
|
+
/** Fired after the SSE handshake succeeds, before register is posted. */
|
|
742
|
+
'connection:open': () => void;
|
|
743
|
+
/** Fired after the gateway accepts the register frame. */
|
|
744
|
+
'connection:registered': (info: {
|
|
745
|
+
sessionId: string;
|
|
746
|
+
capabilities: number;
|
|
747
|
+
}) => void;
|
|
748
|
+
/** Fired when the SSE stream closes — clean shutdown or transient error. */
|
|
749
|
+
'connection:close': (reason: string) => void;
|
|
750
|
+
/** Fired when a reconnect is scheduled, before the backoff delay elapses. */
|
|
751
|
+
'connection:reconnecting': (info: {
|
|
752
|
+
attempt: number;
|
|
753
|
+
delayMs: number;
|
|
754
|
+
reason: string;
|
|
755
|
+
}) => void;
|
|
756
|
+
/** Fired on transport / parse errors. Reconnect handling is automatic. */
|
|
757
|
+
error: (err: Error) => void;
|
|
758
|
+
/** Pass-through of every parsed inbound SSE frame. */
|
|
759
|
+
frame: (frame: ServerToNeuronFrame) => void;
|
|
760
|
+
}
|
|
761
|
+
interface NeuronOptions {
|
|
762
|
+
/** Base URL of the gateway, e.g. `https://api.holokai.dev`. */
|
|
763
|
+
gatewayUrl: string;
|
|
764
|
+
/**
|
|
765
|
+
* Stable per-process identifier. Reused across reconnects so the
|
|
766
|
+
* gateway can correlate the new session with the same neuron. SDK does
|
|
767
|
+
* NOT generate one for you — pick something stable per device/process
|
|
768
|
+
* (UUID stored on disk for desktop, hostname+pid for server).
|
|
769
|
+
*/
|
|
770
|
+
neuronId: string;
|
|
771
|
+
/** Token provider — see `AuthCallback` for refresh semantics. */
|
|
772
|
+
auth: AuthCallback;
|
|
773
|
+
/** Logger; defaults to a silent no-op. */
|
|
774
|
+
logger?: NeuronLogger;
|
|
775
|
+
/** Heartbeat interval (ms). Default 10s. */
|
|
776
|
+
heartbeatIntervalMs?: number;
|
|
777
|
+
/** Initial reconnect delay (ms). Default 500ms. */
|
|
778
|
+
initialReconnectDelayMs?: number;
|
|
779
|
+
/** Max reconnect delay (ms). Default 30s. */
|
|
780
|
+
maxReconnectDelayMs?: number;
|
|
781
|
+
/** Override `fetch`; mainly for tests. */
|
|
782
|
+
fetch?: typeof fetch;
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Public SDK class. Compose:
|
|
786
|
+
*
|
|
787
|
+
* const neuron = new Neuron({ gatewayUrl, neuronId, auth: () => token });
|
|
788
|
+
* neuron.handle({ type: 'core/script.python', scope: 'any', concurrency: 4 }, handler);
|
|
789
|
+
* neuron.on('connection:registered', ({ sessionId }) => log(sessionId));
|
|
790
|
+
* await neuron.start();
|
|
791
|
+
* ...
|
|
792
|
+
* await neuron.stop({ drain: true, timeoutMs: 30_000 });
|
|
793
|
+
*
|
|
794
|
+
* See `NeuronEvents` for the full set of subscribable events.
|
|
795
|
+
*/
|
|
796
|
+
declare class Neuron extends EventEmitter<NeuronEvents> {
|
|
797
|
+
private readonly transport;
|
|
798
|
+
private readonly handlers;
|
|
799
|
+
private readonly inFlightLeases;
|
|
800
|
+
/**
|
|
801
|
+
* Leases admitted by `dispatchLease` but still waiting for a worker-pool
|
|
802
|
+
* slot. Tracked separately from `inFlightLeases` so the heartbeat snapshot
|
|
803
|
+
* doesn't lie — only running leases extend the gateway's lease TTL.
|
|
804
|
+
*/
|
|
805
|
+
private readonly queuedLeases;
|
|
806
|
+
private readonly heartbeat;
|
|
807
|
+
private readonly validator;
|
|
808
|
+
private readonly logger;
|
|
809
|
+
private readonly opts;
|
|
810
|
+
private started;
|
|
811
|
+
private stopping;
|
|
812
|
+
private hasOpenedOnce;
|
|
813
|
+
constructor(opts: NeuronOptions);
|
|
814
|
+
/**
|
|
815
|
+
* Register a handler for a capability. Must be called before `start()`;
|
|
816
|
+
* the gateway expects the full capability list in the register frame.
|
|
817
|
+
*
|
|
818
|
+
* Three call shapes:
|
|
819
|
+
*
|
|
820
|
+
* neuron.handle(capDef, fn) // typed via defineCapability defaults
|
|
821
|
+
* neuron.handle(capDef, opts, fn) // typed; override scope/concurrency
|
|
822
|
+
* neuron.handle(capabilityRegistration, fn) // legacy/low-level: explicit JSON Schemas
|
|
823
|
+
*
|
|
824
|
+
* If called twice for the same capability before start, the second call
|
|
825
|
+
* replaces the first. After start, use `updateCapability` to adjust
|
|
826
|
+
* concurrency at runtime.
|
|
827
|
+
*/
|
|
828
|
+
handle<TIn, TOut>(def: CapabilityDef<TIn, TOut>, handler: Handler<TIn, TOut>): void;
|
|
829
|
+
handle<TIn, TOut>(def: CapabilityDef<TIn, TOut>, opts: CapabilityHandleOptions, handler: Handler<TIn, TOut>): void;
|
|
830
|
+
handle(reg: CapabilityRegistration, handler: Handler): void;
|
|
831
|
+
/**
|
|
832
|
+
* Adjust an already-registered capability's concurrency at runtime and
|
|
833
|
+
* notify the gateway via an `update-capability` frame so prefetch can be
|
|
834
|
+
* tuned. Schema and handler are not replaced — re-register before start
|
|
835
|
+
* if those need to change.
|
|
836
|
+
*/
|
|
837
|
+
updateCapability(reg: Pick<CapabilityRegistration, 'type' | 'concurrency'>): Promise<void>;
|
|
838
|
+
/**
|
|
839
|
+
* Open the SSE stream, post register with all advertised capabilities,
|
|
840
|
+
* and start the heartbeat loop. Resolves once the gateway accepts the
|
|
841
|
+
* register frame.
|
|
842
|
+
*/
|
|
843
|
+
start(): Promise<void>;
|
|
844
|
+
/**
|
|
845
|
+
* Refuse new leases, drain in-flight handlers up to `timeoutMs`, then
|
|
846
|
+
* tear down the connection. Pending leases (queued but not started)
|
|
847
|
+
* are abandoned — the gateway's lease TTL will reclaim them.
|
|
848
|
+
*/
|
|
849
|
+
stop(opts?: {
|
|
850
|
+
drain?: boolean;
|
|
851
|
+
timeoutMs?: number;
|
|
852
|
+
}): Promise<void>;
|
|
853
|
+
private snapshotInFlight;
|
|
854
|
+
private handleConnectionOpen;
|
|
855
|
+
private handleConnectionClose;
|
|
856
|
+
private postRegister;
|
|
857
|
+
private handleFrame;
|
|
858
|
+
private dispatchLease;
|
|
859
|
+
private handleCancel;
|
|
860
|
+
}
|
|
861
|
+
/** SSE event names re-exported for tests / consumers that want to match
|
|
862
|
+
* by name without importing the protocol package. */
|
|
863
|
+
declare const SSE_EVENT_NAMES: {
|
|
864
|
+
readonly registered: "registered";
|
|
865
|
+
readonly lease: "lease";
|
|
866
|
+
readonly cancel: "cancel";
|
|
867
|
+
readonly capabilityRevoked: "capability-revoked";
|
|
868
|
+
readonly disconnect: "disconnect";
|
|
869
|
+
};
|
|
870
|
+
|
|
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 {
|
|
894
|
+
/** Base URL of the gateway (e.g. `https://api.holokai.dev`). */
|
|
895
|
+
gatewayUrl: string;
|
|
896
|
+
/** Stable per-process identifier sent as `?neuronId=` on the SSE GET. */
|
|
897
|
+
neuronId: string;
|
|
898
|
+
/** Token provider — called on every POST and SSE open; called again on 401 retry. */
|
|
899
|
+
auth: AuthCallback;
|
|
900
|
+
/** Logger; defaults to a silent no-op. */
|
|
901
|
+
logger?: NeuronLogger;
|
|
902
|
+
/**
|
|
903
|
+
* Initial reconnect delay in ms. Doubles on each consecutive failure
|
|
904
|
+
* up to `maxReconnectDelayMs`. Defaults: 500ms initial, 30s ceiling.
|
|
905
|
+
*/
|
|
906
|
+
initialReconnectDelayMs?: number;
|
|
907
|
+
maxReconnectDelayMs?: number;
|
|
908
|
+
/** Override `fetch`. Defaults to global fetch (Node 20+ undici). */
|
|
909
|
+
fetch?: typeof fetch;
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* Wire-level transport. Holds a single SSE stream open against the
|
|
913
|
+
* gateway, parses inbound frames, exposes a typed `post(...)` for
|
|
914
|
+
* outbound frames, and reconnects on disconnect with exponential backoff.
|
|
915
|
+
*
|
|
916
|
+
* Lifecycle:
|
|
917
|
+
* - `start()` opens the SSE stream and resolves once the connection is
|
|
918
|
+
* established. Reconnect logic kicks in if the stream drops.
|
|
919
|
+
* - `post(path, frame)` sends an outbound frame; refreshes the token via
|
|
920
|
+
* the auth callback on 401 and retries once.
|
|
921
|
+
* - `stop()` aborts the SSE stream and prevents further reconnects.
|
|
922
|
+
*
|
|
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).
|
|
927
|
+
*/
|
|
928
|
+
declare class Transport {
|
|
929
|
+
private readonly opts;
|
|
930
|
+
private readonly callbacks;
|
|
931
|
+
private abortController;
|
|
932
|
+
private stopped;
|
|
933
|
+
private connected;
|
|
934
|
+
private reconnectAttempts;
|
|
935
|
+
private reconnectTimer;
|
|
936
|
+
constructor(opts: TransportOptions);
|
|
937
|
+
isConnected(): boolean;
|
|
938
|
+
/** Open the SSE stream. Resolves after the connection is established. */
|
|
939
|
+
start(): Promise<void>;
|
|
940
|
+
/** Tear down the SSE stream and prevent further reconnect attempts. */
|
|
941
|
+
stop(): Promise<void>;
|
|
942
|
+
/**
|
|
943
|
+
* POST a client frame to the gateway. Refreshes the token via the auth
|
|
944
|
+
* callback and retries once on 401 — that's the contract: callers
|
|
945
|
+
* implement refresh inside their callback.
|
|
946
|
+
*/
|
|
947
|
+
post<T extends ClientFrame>(path: PostPath, frame: T): Promise<unknown>;
|
|
948
|
+
private postRaw;
|
|
949
|
+
private openStream;
|
|
950
|
+
private consumeStream;
|
|
951
|
+
private handleStreamEnd;
|
|
952
|
+
private scheduleReconnect;
|
|
953
|
+
}
|
|
954
|
+
declare class TransportError extends Error {
|
|
955
|
+
readonly statusCode: number;
|
|
956
|
+
constructor(message: string, statusCode: number);
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
/**
|
|
960
|
+
* Per-capability concurrency limiter. Bounds the number of in-flight
|
|
961
|
+
* handler invocations locally even if the gateway overshoots prefetch — a
|
|
962
|
+
* misbehaving gateway should never push past the contract.
|
|
963
|
+
*
|
|
964
|
+
* Pools are created per (neuron, capability) and live for the duration of
|
|
965
|
+
* the SDK's session. Drain support (used by `neuron.stop({ drain: true })`)
|
|
966
|
+
* resolves once all in-flight tasks have completed; new submissions during
|
|
967
|
+
* drain are rejected with `ShutdownError`.
|
|
968
|
+
*/
|
|
969
|
+
declare class WorkerPool {
|
|
970
|
+
private maxConcurrency;
|
|
971
|
+
private inFlight;
|
|
972
|
+
private queue;
|
|
973
|
+
private draining;
|
|
974
|
+
private drained;
|
|
975
|
+
constructor(maxConcurrency: number);
|
|
976
|
+
/** Currently-running task count. */
|
|
977
|
+
size(): number;
|
|
978
|
+
/** Tasks waiting for a slot. */
|
|
979
|
+
pending(): number;
|
|
980
|
+
/**
|
|
981
|
+
* Run `fn` once a concurrency slot is available. Resolves with the
|
|
982
|
+
* function's return value (or rejects with its error). Throws
|
|
983
|
+
* ShutdownError if the pool is already draining.
|
|
984
|
+
*/
|
|
985
|
+
run<T>(fn: () => Promise<T>): Promise<T>;
|
|
986
|
+
/**
|
|
987
|
+
* Update the max concurrency. Lowering doesn't kill in-flight tasks —
|
|
988
|
+
* they finish naturally — but it does prevent new ones from starting
|
|
989
|
+
* until the in-flight count drops below the new limit.
|
|
990
|
+
*/
|
|
991
|
+
setConcurrency(newMax: number): void;
|
|
992
|
+
/**
|
|
993
|
+
* Stop accepting new submissions. Returns a promise that resolves once
|
|
994
|
+
* every in-flight AND queued task has finished — queued waiters from
|
|
995
|
+
* before drain are released as in-flight slots free, run normally, and
|
|
996
|
+
* are awaited as part of drain. Only fresh `run()` calls received after
|
|
997
|
+
* `drain()` reject with ShutdownError. Callers that need a hard stop
|
|
998
|
+
* should race this promise against a timeout and abort handlers.
|
|
999
|
+
*/
|
|
1000
|
+
drain(): Promise<void>;
|
|
1001
|
+
}
|
|
1002
|
+
declare class ShutdownError extends Error {
|
|
1003
|
+
constructor(message: string);
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
/**
|
|
1007
|
+
* Compiles JSON Schemas once and caches by reference. Mirror of the
|
|
1008
|
+
* gateway-side OutputValidator — both ends of the wire validate against
|
|
1009
|
+
* the same schemas so a misbehaving party can't sneak by either side.
|
|
1010
|
+
*/
|
|
1011
|
+
declare class SchemaValidator {
|
|
1012
|
+
private readonly ajv;
|
|
1013
|
+
private readonly cache;
|
|
1014
|
+
constructor();
|
|
1015
|
+
/**
|
|
1016
|
+
* Returns null if the value matches the schema (or no schema given);
|
|
1017
|
+
* otherwise an array of structured errors.
|
|
1018
|
+
*/
|
|
1019
|
+
validate(schema: JsonSchema | undefined, data: unknown): ErrorObject[] | null;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
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 };
|