norns-sdk 0.2.0 → 0.3.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/CHANGELOG.md +10 -0
- package/README.md +6 -0
- package/dist/index.cjs +26 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -2
- package/dist/index.d.ts +16 -2
- package/dist/index.js +24 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `norns-sdk` are documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.3.0] - 2026-10-22
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- A worker holding a scoped key (`nrnw_...`, issued for one gard's worker)
|
|
9
|
+
skips the agent registration on `start()`, since the key cannot reach the
|
|
10
|
+
REST API; the definitions are registered with a tenant key instead.
|
|
11
|
+
`isScopedKey()` is exported.
|
|
12
|
+
- `KeyRevokedError`: `worker.stopped` rejects with it when Norns revokes the
|
|
13
|
+
key the worker joined on.
|
|
14
|
+
|
|
5
15
|
## [0.2.0] - 2026-10-16
|
|
6
16
|
|
|
7
17
|
### Added
|
package/README.md
CHANGED
|
@@ -90,6 +90,12 @@ execute: async ({ port }, ctx) => {
|
|
|
90
90
|
|
|
91
91
|
A fatally rejected claim (bad token, destroyed gard) rejects `start()` with `JoinError` instead of reconnect-looping. If the gard is destroyed while the worker is connected, `worker.stopped` rejects with `GardDestroyedError`.
|
|
92
92
|
|
|
93
|
+
A worker inside a gard should hold a [scoped key](https://github.com/nornscode/norns/blob/main/docs/gards.md#scoped-worker-keys) (`nrnw_...`) rather than the tenant key: it can join the worker socket, claim its gard and serve tasks, and nothing else. With one, `start()` skips the agent registration, since the key cannot reach the REST API; register the definitions with a tenant key instead. Pass `capabilities: ["tools"]` for a worker with no LLM access, matching what the key allows. If the key is revoked while the worker is connected, `worker.stopped` rejects with `KeyRevokedError`.
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
const worker = new NornsWorker({ agents: [coder], gard: 3, claimToken: "tok_...", capabilities: ["tools"] });
|
|
97
|
+
```
|
|
98
|
+
|
|
93
99
|
### Shutdown
|
|
94
100
|
|
|
95
101
|
On SIGTERM or SIGINT the worker drains instead of dying mid-task: it tells Norns to stop sending it work, finishes the tasks it holds, reports their results, leaves the channel, and the process exits. Tasks still running after `shutdownTimeoutMs` (default 30 seconds, or `NORNS_SHUTDOWN_TIMEOUT` in seconds) are dropped and Norns re-dispatches them. A second signal exits at once.
|
package/dist/index.cjs
CHANGED
|
@@ -23,6 +23,7 @@ __export(index_exports, {
|
|
|
23
23
|
DEFAULT_MODEL: () => DEFAULT_MODEL,
|
|
24
24
|
GardDestroyedError: () => GardDestroyedError,
|
|
25
25
|
JoinError: () => JoinError,
|
|
26
|
+
KeyRevokedError: () => KeyRevokedError,
|
|
26
27
|
NornsApiError: () => NornsApiError,
|
|
27
28
|
NornsClient: () => NornsClient,
|
|
28
29
|
NornsError: () => NornsError,
|
|
@@ -33,6 +34,7 @@ __export(index_exports, {
|
|
|
33
34
|
consoleLogger: () => consoleLogger,
|
|
34
35
|
defineAgent: () => defineAgent,
|
|
35
36
|
inferProvider: () => inferProvider,
|
|
37
|
+
isScopedKey: () => isScopedKey,
|
|
36
38
|
jsonSchema: () => import_ai4.jsonSchema,
|
|
37
39
|
silentLogger: () => silentLogger,
|
|
38
40
|
tool: () => tool
|
|
@@ -245,6 +247,12 @@ var GardDestroyedError = class extends NornsError {
|
|
|
245
247
|
this.name = "GardDestroyedError";
|
|
246
248
|
}
|
|
247
249
|
};
|
|
250
|
+
var KeyRevokedError = class extends NornsError {
|
|
251
|
+
constructor() {
|
|
252
|
+
super("the worker's scoped key was revoked");
|
|
253
|
+
this.name = "KeyRevokedError";
|
|
254
|
+
}
|
|
255
|
+
};
|
|
248
256
|
var StreamClosedError = class extends NornsError {
|
|
249
257
|
reason;
|
|
250
258
|
constructor(reason) {
|
|
@@ -573,6 +581,9 @@ function resolveApiKey(apiKey) {
|
|
|
573
581
|
if (!value) throw new NornsError("Norns API key missing: pass `apiKey` or set NORNS_API_KEY");
|
|
574
582
|
return value;
|
|
575
583
|
}
|
|
584
|
+
function isScopedKey(apiKey) {
|
|
585
|
+
return apiKey.startsWith("nrnw_");
|
|
586
|
+
}
|
|
576
587
|
function wsBase(url) {
|
|
577
588
|
return url.replace(/^http:\/\//, "ws://").replace(/^https:\/\//, "wss://");
|
|
578
589
|
}
|
|
@@ -1283,9 +1294,15 @@ var NornsWorker = class {
|
|
|
1283
1294
|
return this.#starting;
|
|
1284
1295
|
}
|
|
1285
1296
|
async #start() {
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1297
|
+
if (isScopedKey(this.#apiKey)) {
|
|
1298
|
+
this.#logger.info(
|
|
1299
|
+
"Worker key is scoped (nrnw_): skipping agent registration. Register the agent definitions with a tenant key."
|
|
1300
|
+
);
|
|
1301
|
+
} else {
|
|
1302
|
+
for (const agent of this.#agents) {
|
|
1303
|
+
const info = await this.#client.agents.ensure(agent);
|
|
1304
|
+
this.#logger.info(`Registered agent '${agent.name}' (id=${info.id})`);
|
|
1305
|
+
}
|
|
1289
1306
|
}
|
|
1290
1307
|
if (this.#capabilities.includes("llm")) {
|
|
1291
1308
|
for (const model of new Set(this.#agents.map((a) => a.model))) {
|
|
@@ -1336,6 +1353,10 @@ var NornsWorker = class {
|
|
|
1336
1353
|
this.#logger.error("This worker's gard was destroyed; shutting down");
|
|
1337
1354
|
this.#fail(new GardDestroyedError(this.gard));
|
|
1338
1355
|
});
|
|
1356
|
+
channel.on("key_revoked", () => {
|
|
1357
|
+
this.#logger.error("This worker's key was revoked; shutting down");
|
|
1358
|
+
this.#fail(new KeyRevokedError());
|
|
1359
|
+
});
|
|
1339
1360
|
channel.onError((reason) => {
|
|
1340
1361
|
if (this.#state === "running")
|
|
1341
1362
|
this.#logger.warn(`Channel error (${errorMessage(reason)}); rejoining`);
|
|
@@ -1649,6 +1670,7 @@ var NornsWorker = class {
|
|
|
1649
1670
|
DEFAULT_MODEL,
|
|
1650
1671
|
GardDestroyedError,
|
|
1651
1672
|
JoinError,
|
|
1673
|
+
KeyRevokedError,
|
|
1652
1674
|
NornsApiError,
|
|
1653
1675
|
NornsClient,
|
|
1654
1676
|
NornsError,
|
|
@@ -1659,6 +1681,7 @@ var NornsWorker = class {
|
|
|
1659
1681
|
consoleLogger,
|
|
1660
1682
|
defineAgent,
|
|
1661
1683
|
inferProvider,
|
|
1684
|
+
isScopedKey,
|
|
1662
1685
|
jsonSchema,
|
|
1663
1686
|
silentLogger,
|
|
1664
1687
|
tool
|