@holokai/neuron-sdk 0.4.0 → 0.5.1
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 +50 -44
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +38 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +38 -16
- package/dist/index.mjs.map +1 -1
- package/dist/ipc.d.mts +1 -1
- package/dist/ipc.d.ts +1 -1
- package/dist/{transport-Cs5tY2IO.d.mts → transport-Ckcwj-Do.d.mts} +4 -1
- package/dist/{transport-Cs5tY2IO.d.ts → transport-Ckcwj-Do.d.ts} +4 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -843,69 +843,75 @@ The `auth` callback isn't returning a valid token. If using a refresh flow, ensu
|
|
|
843
843
|
|
|
844
844
|
## Releasing (maintainers)
|
|
845
845
|
|
|
846
|
-
`@holokai/neuron-sdk` is published to public npm
|
|
847
|
-
|
|
848
|
-
|
|
846
|
+
`@holokai/neuron-sdk` is published to public npm by BigBrain's Release
|
|
847
|
+
workflow (`.github/workflows/release.yml`). There is no npm token on anyone's
|
|
848
|
+
laptop and none stored in the repo, and pushing a tag publishes nothing.
|
|
849
|
+
|
|
850
|
+
### Pick the version
|
|
851
|
+
|
|
852
|
+
Follow semver:
|
|
853
|
+
|
|
854
|
+
- Pilot phase, we are in **`0.x`**. Because the protocol is still absorbing
|
|
855
|
+
pilot-developer feedback, a **breaking** change bumps the **minor**
|
|
856
|
+
(`0.2.0` to `0.3.0`); a backward-compatible change or fix bumps the
|
|
857
|
+
**patch** (`0.2.0` to `0.2.1`). This is the standard `0.x` convention and
|
|
858
|
+
is what buys us room to break things on feedback without a major bump.
|
|
859
|
+
- Hold **`1.0.0`** until the public API has survived pilot feedback and we're
|
|
860
|
+
ready to commit to "breaking changes bump the major." Jumping to `1.0.0`
|
|
861
|
+
is a stability promise, not a milestone. Don't spend it early.
|
|
849
862
|
|
|
850
863
|
### Cut a release
|
|
851
864
|
|
|
852
|
-
1. **
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
The tag is prefixed `neuron-sdk-v` (the Python SDK uses
|
|
869
|
-
`neuron-sdk-python-v`) so the two never collide.
|
|
870
|
-
4. **`publish-neuron-sdk.yml`** fires on the tag: it asserts the tag version
|
|
871
|
-
matches `package.json`, runs the `prepublish` gate (`build` + `test`), and
|
|
872
|
-
publishes to npm. The `npm` GitHub Environment gates the publish behind a
|
|
873
|
-
**required-reviewer approval** — approve the run under Actions, and on success
|
|
874
|
-
the new version is live at
|
|
865
|
+
1. Open **Actions, Release, Run workflow** on branch `main`.
|
|
866
|
+
2. Fill **neuron-sdk** with the new version (`X.Y.Z`). Leave the other lines
|
|
867
|
+
(base, embedded, synapse) empty unless they are being released too; an
|
|
868
|
+
empty line is not touched. Tick **plan only** to read the plan without
|
|
869
|
+
cutting anything.
|
|
870
|
+
3. The plan job checks the version (shaped `X.Y.Z`, not older than
|
|
871
|
+
`packages/neuron-sdk/package.json`, tag `neuron-sdk-vX.Y.Z` not taken) and
|
|
872
|
+
writes the plan to the run summary.
|
|
873
|
+
4. A reviewer of the `release` environment approves the run. That is the only
|
|
874
|
+
approval.
|
|
875
|
+
5. The cut writes the version into `packages/neuron-sdk/package.json`,
|
|
876
|
+
commits it to `main`, tags `neuron-sdk-vX.Y.Z` and pushes both. If the file
|
|
877
|
+
already carries the version (a bump merged by pull request), it only tags.
|
|
878
|
+
6. From the commit the cut pushed, the run builds and tests the SDK (the
|
|
879
|
+
`prepublish` turbo task), packs it, and publishes the tarball to npm from a
|
|
880
|
+
GitHub-hosted runner. On success the new version is live at
|
|
875
881
|
[`@holokai/neuron-sdk`](https://www.npmjs.com/package/@holokai/neuron-sdk).
|
|
876
882
|
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
> unaffected. Add the flag back if bigbrain ever goes public.
|
|
883
|
+
The tag is prefixed `neuron-sdk-v` (the Python SDK uses `neuron-sdk-python-v`)
|
|
884
|
+
so the two never collide. The workflow file's header comments describe every
|
|
885
|
+
job and how to recover a failed run.
|
|
881
886
|
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
887
|
+
> No `--provenance`: bigbrain is a private repo, so npm's provenance
|
|
888
|
+
> attestation (a public transparency-log link back to the source) adds little
|
|
889
|
+
> and has historically errored from private repos. Trusted-publishing auth is
|
|
890
|
+
> unaffected. Add the flag back if bigbrain ever goes public.
|
|
885
891
|
|
|
886
892
|
### Publish auth: npm Trusted Publishing (one-time setup)
|
|
887
893
|
|
|
888
|
-
CI authenticates to npm via **OIDC trusted publishing
|
|
894
|
+
CI authenticates to npm via **OIDC trusted publishing**: GitHub Actions
|
|
889
895
|
exchanges a short-lived OIDC token for publish rights, so no long-lived
|
|
890
|
-
`NPM_TOKEN` exists to leak.
|
|
891
|
-
publishing. It requires two one-time setups:
|
|
896
|
+
`NPM_TOKEN` exists to leak. It requires two one-time setups:
|
|
892
897
|
|
|
893
898
|
1. **On npmjs.com** (a package admin, once): open the
|
|
894
899
|
[`@holokai/neuron-sdk`](https://www.npmjs.com/package/@holokai/neuron-sdk)
|
|
895
|
-
package
|
|
900
|
+
package, **Settings, Trusted Publisher, GitHub Actions**, and register:
|
|
896
901
|
- Organization / repository: `holok-ai/bigbrain`
|
|
897
|
-
- Workflow filename: `
|
|
902
|
+
- Workflow filename: `release.yml`
|
|
898
903
|
- Environment: `npm`
|
|
899
|
-
2. **In this repo** (once):
|
|
900
|
-
|
|
901
|
-
|
|
904
|
+
2. **In this repo** (once): the **`npm`** GitHub Environment (Settings,
|
|
905
|
+
Environments) with no required reviewer, because the Release run's one
|
|
906
|
+
approval is on its cut, and a deployment branch rule of `main` only, so a
|
|
907
|
+
copy of `release.yml` on another branch cannot publish to npm.
|
|
902
908
|
|
|
903
909
|
Until the trusted publisher is registered, the `npm publish` step fails with an
|
|
904
|
-
auth error
|
|
910
|
+
auth error. That is the expected "not set up yet" signal, not a code bug.
|
|
905
911
|
|
|
906
912
|
### Manual publish (fallback / first bootstrap)
|
|
907
913
|
|
|
908
|
-
The
|
|
914
|
+
The Release workflow is the norm. If you ever need to publish by hand (e.g. to bootstrap
|
|
909
915
|
the very first version before trusted publishing is configured):
|
|
910
916
|
|
|
911
917
|
```sh
|
|
@@ -915,6 +921,6 @@ pnpm run publish:npm # runs the prepublishOnly build+test gate, then publi
|
|
|
915
921
|
```
|
|
916
922
|
|
|
917
923
|
This uses your own `npm login` credentials and skips the CI approval gate —
|
|
918
|
-
prefer the
|
|
924
|
+
prefer the Release workflow for anything a developer will consume.
|
|
919
925
|
|
|
920
926
|
<!-- ci: force full build on the self-hosted runner (HOL-2028 verify); safe to remove -->
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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-
|
|
2
|
-
export { e as HandlerContext, f as HeartbeatInFlightEntry, L as LeasePayload, g as TaskPayload } from './transport-
|
|
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-Ckcwj-Do.mjs';
|
|
2
|
+
export { e as HandlerContext, f as HeartbeatInFlightEntry, L as LeasePayload, g as TaskPayload } from './transport-Ckcwj-Do.mjs';
|
|
3
3
|
import { EventEmitter } from 'eventemitter3';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { ErrorObject } from 'ajv';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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-
|
|
2
|
-
export { e as HandlerContext, f as HeartbeatInFlightEntry, L as LeasePayload, g as TaskPayload } from './transport-
|
|
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-Ckcwj-Do.js';
|
|
2
|
+
export { e as HandlerContext, f as HeartbeatInFlightEntry, L as LeasePayload, g as TaskPayload } from './transport-Ckcwj-Do.js';
|
|
3
3
|
import { EventEmitter } from 'eventemitter3';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { ErrorObject } from 'ajv';
|
package/dist/index.js
CHANGED
|
@@ -558,6 +558,7 @@ var TerminalFailure = class extends Error {
|
|
|
558
558
|
this.name = "TerminalFailure";
|
|
559
559
|
}
|
|
560
560
|
};
|
|
561
|
+
var DEFAULT_PROGRESS_TIMEOUT_MS = 5e3;
|
|
561
562
|
function validateInput(zod, validator, jsonSchema, data) {
|
|
562
563
|
if (zod) {
|
|
563
564
|
const result = zod.safeParse(data);
|
|
@@ -580,7 +581,8 @@ async function runLease(opts) {
|
|
|
580
581
|
transport,
|
|
581
582
|
validator,
|
|
582
583
|
logger,
|
|
583
|
-
signal
|
|
584
|
+
signal,
|
|
585
|
+
progressTimeoutMs = DEFAULT_PROGRESS_TIMEOUT_MS
|
|
584
586
|
} = opts;
|
|
585
587
|
const inputCheck = validateInput(zodInput, validator, inputSchema, lease.task.input);
|
|
586
588
|
if (!inputCheck.ok) {
|
|
@@ -595,13 +597,13 @@ async function runLease(opts) {
|
|
|
595
597
|
return;
|
|
596
598
|
}
|
|
597
599
|
const parsedInput = inputCheck.value;
|
|
598
|
-
const
|
|
600
|
+
const reporter = makeProgressReporter(transport, lease.leaseId, logger, signal, progressTimeoutMs);
|
|
599
601
|
const ctx = {
|
|
600
602
|
task: lease.task,
|
|
601
603
|
leaseId: lease.leaseId,
|
|
602
604
|
signal,
|
|
603
605
|
log: scopedLogger(logger, lease),
|
|
604
|
-
progress:
|
|
606
|
+
progress: reporter.progress,
|
|
605
607
|
fail: (reason, opts2) => {
|
|
606
608
|
throw new TerminalFailure(reason, opts2?.code);
|
|
607
609
|
}
|
|
@@ -610,7 +612,9 @@ async function runLease(opts) {
|
|
|
610
612
|
try {
|
|
611
613
|
output = await handler(parsedInput, ctx);
|
|
612
614
|
} catch (err) {
|
|
613
|
-
|
|
615
|
+
const cancelled = signal.aborted || err.name === "AbortError";
|
|
616
|
+
if (!cancelled) await reporter.drained();
|
|
617
|
+
if (cancelled) {
|
|
614
618
|
await sendNack(
|
|
615
619
|
transport,
|
|
616
620
|
lease.leaseId,
|
|
@@ -644,6 +648,7 @@ async function runLease(opts) {
|
|
|
644
648
|
);
|
|
645
649
|
return;
|
|
646
650
|
}
|
|
651
|
+
await reporter.drained();
|
|
647
652
|
const outputCheck = validateInput(zodOutput, validator, outputSchema, output);
|
|
648
653
|
if (!outputCheck.ok) {
|
|
649
654
|
await sendNack(
|
|
@@ -685,20 +690,37 @@ async function sendNack(transport, leaseId, kind, reason, extras = {}, logger) {
|
|
|
685
690
|
);
|
|
686
691
|
});
|
|
687
692
|
}
|
|
688
|
-
function
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
693
|
+
function makeProgressReporter(transport, leaseId, logger, signal, timeoutMs) {
|
|
694
|
+
let tail = Promise.resolve();
|
|
695
|
+
return {
|
|
696
|
+
progress: (update) => {
|
|
697
|
+
const frame = {
|
|
698
|
+
type: "progress",
|
|
699
|
+
leaseId,
|
|
700
|
+
percent: update.percent,
|
|
701
|
+
message: update.message,
|
|
702
|
+
data: update.data,
|
|
703
|
+
sentAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
704
|
+
};
|
|
705
|
+
tail = tail.then(async () => {
|
|
706
|
+
if (signal.aborted) return;
|
|
707
|
+
try {
|
|
708
|
+
await withTimeout(transport.post(POST_PATH.progress, frame), timeoutMs);
|
|
709
|
+
} catch (err) {
|
|
710
|
+
logger.warn({ err, leaseId }, "progress POST failed; continuing");
|
|
711
|
+
}
|
|
712
|
+
});
|
|
713
|
+
},
|
|
714
|
+
drained: () => tail
|
|
700
715
|
};
|
|
701
716
|
}
|
|
717
|
+
function withTimeout(work, ms) {
|
|
718
|
+
let timer;
|
|
719
|
+
const timeout = new Promise((_resolve, reject) => {
|
|
720
|
+
timer = setTimeout(() => reject(new Error(`timed out after ${ms}ms`)), ms);
|
|
721
|
+
});
|
|
722
|
+
return Promise.race([work, timeout]).finally(() => clearTimeout(timer));
|
|
723
|
+
}
|
|
702
724
|
function scopedLogger(logger, lease) {
|
|
703
725
|
const scope = { leaseId: lease.leaseId, taskId: lease.task.taskId };
|
|
704
726
|
return {
|