@holokai/neuron-sdk 0.5.1 → 0.7.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.mjs CHANGED
@@ -10,6 +10,11 @@ var CapabilityTypeSchema = z.string().min(1).regex(
10
10
  "capability type must be namespaced: {owner}/{package}[/{name}][.{variant}]"
11
11
  );
12
12
  var UserIdSchema = z.string().min(1);
13
+ var SKILL_CAPABILITY_PREFIX = "skill/";
14
+ function isSkillCapabilityType(type) {
15
+ return type.startsWith(SKILL_CAPABILITY_PREFIX);
16
+ }
17
+ var MAX_COMPOSED_CAPABILITIES = 64;
13
18
  var JsonSchemaSchema = z.unknown();
14
19
  var CapabilityScopeSchema = z.union([
15
20
  z.literal("any"),
@@ -62,8 +67,29 @@ var CapabilitySchema = z.object({
62
67
  * heartbeat budget should be the limiter, not a single
63
68
  * capability).
64
69
  */
65
- leaseTtlMs: z.number().int().min(1e3).max(60 * 60 * 1e3).optional()
66
- }).strict();
70
+ leaseTtlMs: z.number().int().min(1e3).max(60 * 60 * 1e3).optional(),
71
+ /**
72
+ * Capability types this `skill/*` capability composes (HOL-4326).
73
+ * Only valid on a `skill/*` type — enforced below, since a non-skill
74
+ * type carrying `composes` is a modeling error the gateway should
75
+ * reject rather than silently ignore.
76
+ */
77
+ composes: z.array(CapabilityTypeSchema).min(1).max(MAX_COMPOSED_CAPABILITIES).refine(
78
+ (types) => new Set(types).size === types.length,
79
+ "composes must not contain duplicate capability types"
80
+ ).refine(
81
+ (types) => types.every((t) => !isSkillCapabilityType(t)),
82
+ "composes must not contain skill/* capability types"
83
+ ).optional()
84
+ }).strict().superRefine((cap, ctx) => {
85
+ if (cap.composes !== void 0 && !isSkillCapabilityType(cap.type)) {
86
+ ctx.addIssue({
87
+ code: z.ZodIssueCode.custom,
88
+ message: "composes is only valid on a skill/* capability type",
89
+ path: ["composes"]
90
+ });
91
+ }
92
+ });
67
93
  var LeaseIdSchema = z.string().min(1);
68
94
  var TaskPayloadSchema = z.object({
69
95
  taskId: z.string().min(1),
@@ -202,7 +228,7 @@ z.discriminatedUnion("type", [
202
228
  ]);
203
229
 
204
230
  // ../neuron-protocol/src/transport.ts
205
- var PROTOCOL_VERSION = "1.1.0";
231
+ var PROTOCOL_VERSION = "1.2.0";
206
232
  var SSE_PATH = "/neuron/events";
207
233
  var SSE_EVENT = {
208
234
  registered: "registered",
@@ -228,6 +254,7 @@ function defineCapability(init) {
228
254
  scope: init.scope,
229
255
  concurrency: init.concurrency,
230
256
  leaseTtlMs: init.leaseTtlMs,
257
+ composes: init.composes,
231
258
  _zod: { input: init.input, output: init.output }
232
259
  };
233
260
  }
@@ -253,6 +280,7 @@ function toRegistrationCapability(def, opts) {
253
280
  );
254
281
  }
255
282
  const leaseTtlMs = opts?.leaseTtlMs ?? def.leaseTtlMs;
283
+ const composes = opts?.composes ?? def.composes;
256
284
  return {
257
285
  type: def.type,
258
286
  scope,
@@ -263,7 +291,8 @@ function toRegistrationCapability(def, opts) {
263
291
  description: opts?.description ?? def.description,
264
292
  inputSchema: def.inputSchema,
265
293
  outputSchema: def.outputSchema,
266
- ...typeof leaseTtlMs === "number" ? { leaseTtlMs } : {}
294
+ ...typeof leaseTtlMs === "number" ? { leaseTtlMs } : {},
295
+ ...composes !== void 0 ? { composes: [...composes] } : {}
267
296
  };
268
297
  }
269
298
 
@@ -543,13 +572,16 @@ var TransportError = class extends Error {
543
572
  };
544
573
 
545
574
  // src/lease-runner.ts
546
- var TerminalFailure = class extends Error {
547
- constructor(reason, code) {
575
+ var HandlerFailure = class extends Error {
576
+ constructor(reason, code, details, kind = "terminal") {
548
577
  super(reason);
549
578
  this.reason = reason;
550
579
  this.code = code;
551
- this.name = "TerminalFailure";
580
+ this.details = details;
581
+ this.name = "HandlerFailure";
582
+ this.kind = kind;
552
583
  }
584
+ kind;
553
585
  };
554
586
  var DEFAULT_PROGRESS_TIMEOUT_MS = 5e3;
555
587
  function validateInput(zod, validator, jsonSchema, data) {
@@ -557,10 +589,7 @@ function validateInput(zod, validator, jsonSchema, data) {
557
589
  const result = zod.safeParse(data);
558
590
  return result.success ? { ok: true, value: result.data } : { ok: false, errors: result.error.issues };
559
591
  }
560
- const errors = validator.validate(
561
- jsonSchema,
562
- data
563
- );
592
+ const errors = validator.validate(jsonSchema, data);
564
593
  return errors === null ? { ok: true, value: data } : { ok: false, errors };
565
594
  }
566
595
  async function runLease(opts) {
@@ -590,7 +619,13 @@ async function runLease(opts) {
590
619
  return;
591
620
  }
592
621
  const parsedInput = inputCheck.value;
593
- const reporter = makeProgressReporter(transport, lease.leaseId, logger, signal, progressTimeoutMs);
622
+ const reporter = makeProgressReporter(
623
+ transport,
624
+ lease.leaseId,
625
+ logger,
626
+ signal,
627
+ progressTimeoutMs
628
+ );
594
629
  const ctx = {
595
630
  task: lease.task,
596
631
  leaseId: lease.leaseId,
@@ -598,7 +633,7 @@ async function runLease(opts) {
598
633
  log: scopedLogger(logger, lease),
599
634
  progress: reporter.progress,
600
635
  fail: (reason, opts2) => {
601
- throw new TerminalFailure(reason, opts2?.code);
636
+ throw new HandlerFailure(reason, opts2?.code, opts2?.details, opts2?.kind);
602
637
  }
603
638
  };
604
639
  let output;
@@ -618,13 +653,16 @@ async function runLease(opts) {
618
653
  );
619
654
  return;
620
655
  }
621
- if (err instanceof TerminalFailure) {
656
+ if (err instanceof HandlerFailure) {
622
657
  await sendNack(
623
658
  transport,
624
659
  lease.leaseId,
625
- "terminal",
660
+ err.kind,
626
661
  err.reason,
627
- { code: err.code ?? "HANDLER_TERMINAL" },
662
+ {
663
+ code: err.code ?? (err.kind === "terminal" ? "HANDLER_TERMINAL" : "HANDLER_RETRYABLE"),
664
+ ...err.details !== void 0 ? { details: err.details } : {}
665
+ },
628
666
  logger
629
667
  );
630
668
  return;
@@ -972,7 +1010,8 @@ var Neuron = class extends EventEmitter {
972
1010
  ...reg.description !== void 0 ? { description: reg.description } : {},
973
1011
  ...reg.inputSchema !== void 0 ? { inputSchema: reg.inputSchema } : {},
974
1012
  ...reg.outputSchema !== void 0 ? { outputSchema: reg.outputSchema } : {},
975
- ...typeof reg.leaseTtlMs === "number" ? { leaseTtlMs: reg.leaseTtlMs } : {}
1013
+ ...typeof reg.leaseTtlMs === "number" ? { leaseTtlMs: reg.leaseTtlMs } : {},
1014
+ ...reg.composes !== void 0 ? { composes: reg.composes } : {}
976
1015
  };
977
1016
  inputSchema = reg.inputSchema;
978
1017
  outputSchema = reg.outputSchema;
@@ -1214,6 +1253,6 @@ var Neuron = class extends EventEmitter {
1214
1253
  };
1215
1254
  var SSE_EVENT_NAMES = SSE_EVENT;
1216
1255
 
1217
- export { HttpTransport, Neuron, SSE_EVENT_NAMES, SchemaValidator, ShutdownError, TransportError, WorkerPool, defineCapability, toPlanShape, toRegistrationCapability };
1256
+ export { HandlerFailure, HttpTransport, Neuron, SSE_EVENT_NAMES, SchemaValidator, ShutdownError, TransportError, WorkerPool, defineCapability, toPlanShape, toRegistrationCapability };
1218
1257
  //# sourceMappingURL=index.mjs.map
1219
1258
  //# sourceMappingURL=index.mjs.map