norns-sdk 0.2.0 → 0.4.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.cts CHANGED
@@ -264,6 +264,12 @@ declare class NornsClient {
264
264
  delete: (agent: AgentRef, key: string) => Promise<void>;
265
265
  };
266
266
  }
267
+ /**
268
+ * A key issued by `POST /api/v1/api_keys` with a worker scope (`nrnw_...`).
269
+ * It opens the worker socket and nothing else, so a worker holding one must
270
+ * not try the REST API.
271
+ */
272
+ declare function isScopedKey(apiKey: string): boolean;
267
273
 
268
274
  /**
269
275
  * Where the SDK writes what it is doing. Anything with these four methods
@@ -301,7 +307,11 @@ interface NornsWorkerOptions {
301
307
  agents: AgentDefinition | AgentDefinition[];
302
308
  /** The Norns base URL. Defaults to `NORNS_URL`. */
303
309
  url?: string;
304
- /** The tenant's bearer token. Defaults to `NORNS_API_KEY`. */
310
+ /**
311
+ * The bearer token. Defaults to `NORNS_API_KEY`. A scoped worker key
312
+ * (`nrnw_...`) joins without registering the agents, since it cannot reach
313
+ * the REST API; register the definitions with a tenant key.
314
+ */
305
315
  apiKey?: string;
306
316
  /**
307
317
  * How a model name on an LLM task becomes a model to call: a function, a
@@ -470,6 +480,7 @@ interface ToolDefinition<I = unknown> {
470
480
  */
471
481
  declare function tool<S extends ToolInputSchema>(options: ToolOptions<S>): ToolDefinition<InferToolInput<S>>;
472
482
 
483
+ /** @deprecated Norns never read it; a conversation starts from a `conversationKey` on the message. */
473
484
  type AgentMode = "task" | "conversation";
474
485
  type CheckpointPolicy = "every_step" | "on_tool_call" | "manual";
475
486
  type ContextStrategy = "sliding_window" | "none";
@@ -500,6 +511,7 @@ interface AgentOptions {
500
511
  systemPrompt?: string;
501
512
  /** What this worker serves for the agent (see `allowedTools` for what it is offered). */
502
513
  tools?: ToolDefinition[];
514
+ /** @deprecated Ignored. Norns never read it; send a message with a `conversationKey` instead. */
503
515
  mode?: AgentMode;
504
516
  checkpointPolicy?: CheckpointPolicy;
505
517
  contextStrategy?: ContextStrategy;
@@ -530,7 +542,6 @@ interface AgentDefinition {
530
542
  readonly model: string;
531
543
  readonly systemPrompt: string;
532
544
  readonly tools: readonly ToolDefinition[];
533
- readonly mode: AgentMode;
534
545
  readonly checkpointPolicy: CheckpointPolicy;
535
546
  readonly contextStrategy: ContextStrategy;
536
547
  readonly contextWindow: number;
@@ -582,6 +593,10 @@ declare class JoinError extends NornsError {
582
593
  declare class GardDestroyedError extends NornsError {
583
594
  constructor(gard: string | number | undefined);
584
595
  }
596
+ /** The scoped key this worker joined on was revoked while it was connected. */
597
+ declare class KeyRevokedError extends NornsError {
598
+ constructor();
599
+ }
585
600
  /** A stream's socket closed before the run reached a terminal event. */
586
601
  declare class StreamClosedError extends NornsError {
587
602
  readonly reason: unknown;
@@ -675,5 +690,5 @@ type ToolResult = {
675
690
  error: string;
676
691
  };
677
692
 
678
- export { DEFAULT_MODEL, GardDestroyedError, JoinError, NornsApiError, NornsClient, NornsError, NornsTimeoutError, NornsWorker, NotFoundError, StreamClosedError, consoleLogger, defineAgent, inferProvider, silentLogger, tool };
693
+ export { DEFAULT_MODEL, GardDestroyedError, JoinError, KeyRevokedError, NornsApiError, NornsClient, NornsError, NornsTimeoutError, NornsWorker, NotFoundError, StreamClosedError, consoleLogger, defineAgent, inferProvider, isScopedKey, silentLogger, tool };
679
694
  export type { AgentDefinition, AgentInfo, AgentMode, AgentOptions, AgentRef, Capability, CheckpointPolicy, ContextPolicy, ContextStrategy, Conversation, InferToolInput, ListRunsOptions, LlmResult, LlmTask, Logger, MessageResult, ModelResolver, ModelSource, ModelsOption, NeutralMessage, NeutralToolCall, NornsClientOptions, NornsWorkerOptions, OnFailure, RegisterPortOptions, RegisteredPort, Run, RunEvent, RunStatus, SendMessageOptions, StreamEvent, StreamOptions, SubagentConversation, SubagentPolicy, ToolContext, ToolDefinition, ToolInputSchema, ToolOptions, ToolResult, ToolTask, WaitingFor, WebSocketConstructor };
package/dist/index.d.ts CHANGED
@@ -264,6 +264,12 @@ declare class NornsClient {
264
264
  delete: (agent: AgentRef, key: string) => Promise<void>;
265
265
  };
266
266
  }
267
+ /**
268
+ * A key issued by `POST /api/v1/api_keys` with a worker scope (`nrnw_...`).
269
+ * It opens the worker socket and nothing else, so a worker holding one must
270
+ * not try the REST API.
271
+ */
272
+ declare function isScopedKey(apiKey: string): boolean;
267
273
 
268
274
  /**
269
275
  * Where the SDK writes what it is doing. Anything with these four methods
@@ -301,7 +307,11 @@ interface NornsWorkerOptions {
301
307
  agents: AgentDefinition | AgentDefinition[];
302
308
  /** The Norns base URL. Defaults to `NORNS_URL`. */
303
309
  url?: string;
304
- /** The tenant's bearer token. Defaults to `NORNS_API_KEY`. */
310
+ /**
311
+ * The bearer token. Defaults to `NORNS_API_KEY`. A scoped worker key
312
+ * (`nrnw_...`) joins without registering the agents, since it cannot reach
313
+ * the REST API; register the definitions with a tenant key.
314
+ */
305
315
  apiKey?: string;
306
316
  /**
307
317
  * How a model name on an LLM task becomes a model to call: a function, a
@@ -470,6 +480,7 @@ interface ToolDefinition<I = unknown> {
470
480
  */
471
481
  declare function tool<S extends ToolInputSchema>(options: ToolOptions<S>): ToolDefinition<InferToolInput<S>>;
472
482
 
483
+ /** @deprecated Norns never read it; a conversation starts from a `conversationKey` on the message. */
473
484
  type AgentMode = "task" | "conversation";
474
485
  type CheckpointPolicy = "every_step" | "on_tool_call" | "manual";
475
486
  type ContextStrategy = "sliding_window" | "none";
@@ -500,6 +511,7 @@ interface AgentOptions {
500
511
  systemPrompt?: string;
501
512
  /** What this worker serves for the agent (see `allowedTools` for what it is offered). */
502
513
  tools?: ToolDefinition[];
514
+ /** @deprecated Ignored. Norns never read it; send a message with a `conversationKey` instead. */
503
515
  mode?: AgentMode;
504
516
  checkpointPolicy?: CheckpointPolicy;
505
517
  contextStrategy?: ContextStrategy;
@@ -530,7 +542,6 @@ interface AgentDefinition {
530
542
  readonly model: string;
531
543
  readonly systemPrompt: string;
532
544
  readonly tools: readonly ToolDefinition[];
533
- readonly mode: AgentMode;
534
545
  readonly checkpointPolicy: CheckpointPolicy;
535
546
  readonly contextStrategy: ContextStrategy;
536
547
  readonly contextWindow: number;
@@ -582,6 +593,10 @@ declare class JoinError extends NornsError {
582
593
  declare class GardDestroyedError extends NornsError {
583
594
  constructor(gard: string | number | undefined);
584
595
  }
596
+ /** The scoped key this worker joined on was revoked while it was connected. */
597
+ declare class KeyRevokedError extends NornsError {
598
+ constructor();
599
+ }
585
600
  /** A stream's socket closed before the run reached a terminal event. */
586
601
  declare class StreamClosedError extends NornsError {
587
602
  readonly reason: unknown;
@@ -675,5 +690,5 @@ type ToolResult = {
675
690
  error: string;
676
691
  };
677
692
 
678
- export { DEFAULT_MODEL, GardDestroyedError, JoinError, NornsApiError, NornsClient, NornsError, NornsTimeoutError, NornsWorker, NotFoundError, StreamClosedError, consoleLogger, defineAgent, inferProvider, silentLogger, tool };
693
+ export { DEFAULT_MODEL, GardDestroyedError, JoinError, KeyRevokedError, NornsApiError, NornsClient, NornsError, NornsTimeoutError, NornsWorker, NotFoundError, StreamClosedError, consoleLogger, defineAgent, inferProvider, isScopedKey, silentLogger, tool };
679
694
  export type { AgentDefinition, AgentInfo, AgentMode, AgentOptions, AgentRef, Capability, CheckpointPolicy, ContextPolicy, ContextStrategy, Conversation, InferToolInput, ListRunsOptions, LlmResult, LlmTask, Logger, MessageResult, ModelResolver, ModelSource, ModelsOption, NeutralMessage, NeutralToolCall, NornsClientOptions, NornsWorkerOptions, OnFailure, RegisterPortOptions, RegisteredPort, Run, RunEvent, RunStatus, SendMessageOptions, StreamEvent, StreamOptions, SubagentConversation, SubagentPolicy, ToolContext, ToolDefinition, ToolInputSchema, ToolOptions, ToolResult, ToolTask, WaitingFor, WebSocketConstructor };
package/dist/index.js CHANGED
@@ -34,7 +34,6 @@ function defineAgent(options) {
34
34
  model: options.model ?? DEFAULT_MODEL,
35
35
  systemPrompt: options.systemPrompt ?? "",
36
36
  tools: Object.freeze([...tools]),
37
- mode: options.mode ?? "task",
38
37
  checkpointPolicy: options.checkpointPolicy ?? "on_tool_call",
39
38
  contextStrategy: options.contextStrategy ?? "sliding_window",
40
39
  contextWindow: options.contextWindow ?? 20,
@@ -49,7 +48,6 @@ function defineAgent(options) {
49
48
  }
50
49
  function agentBody(agent) {
51
50
  const modelConfig = {
52
- mode: agent.mode,
53
51
  checkpoint_policy: agent.checkpointPolicy,
54
52
  context_strategy: agent.contextStrategy,
55
53
  context_window: agent.contextWindow,
@@ -206,6 +204,12 @@ var GardDestroyedError = class extends NornsError {
206
204
  this.name = "GardDestroyedError";
207
205
  }
208
206
  };
207
+ var KeyRevokedError = class extends NornsError {
208
+ constructor() {
209
+ super("the worker's scoped key was revoked");
210
+ this.name = "KeyRevokedError";
211
+ }
212
+ };
209
213
  var StreamClosedError = class extends NornsError {
210
214
  reason;
211
215
  constructor(reason) {
@@ -534,6 +538,9 @@ function resolveApiKey(apiKey) {
534
538
  if (!value) throw new NornsError("Norns API key missing: pass `apiKey` or set NORNS_API_KEY");
535
539
  return value;
536
540
  }
541
+ function isScopedKey(apiKey) {
542
+ return apiKey.startsWith("nrnw_");
543
+ }
537
544
  function wsBase(url) {
538
545
  return url.replace(/^http:\/\//, "ws://").replace(/^https:\/\//, "wss://");
539
546
  }
@@ -1247,9 +1254,15 @@ var NornsWorker = class {
1247
1254
  return this.#starting;
1248
1255
  }
1249
1256
  async #start() {
1250
- for (const agent of this.#agents) {
1251
- const info = await this.#client.agents.ensure(agent);
1252
- this.#logger.info(`Registered agent '${agent.name}' (id=${info.id})`);
1257
+ if (isScopedKey(this.#apiKey)) {
1258
+ this.#logger.info(
1259
+ "Worker key is scoped (nrnw_): skipping agent registration. Register the agent definitions with a tenant key."
1260
+ );
1261
+ } else {
1262
+ for (const agent of this.#agents) {
1263
+ const info = await this.#client.agents.ensure(agent);
1264
+ this.#logger.info(`Registered agent '${agent.name}' (id=${info.id})`);
1265
+ }
1253
1266
  }
1254
1267
  if (this.#capabilities.includes("llm")) {
1255
1268
  for (const model of new Set(this.#agents.map((a) => a.model))) {
@@ -1300,6 +1313,10 @@ var NornsWorker = class {
1300
1313
  this.#logger.error("This worker's gard was destroyed; shutting down");
1301
1314
  this.#fail(new GardDestroyedError(this.gard));
1302
1315
  });
1316
+ channel.on("key_revoked", () => {
1317
+ this.#logger.error("This worker's key was revoked; shutting down");
1318
+ this.#fail(new KeyRevokedError());
1319
+ });
1303
1320
  channel.onError((reason) => {
1304
1321
  if (this.#state === "running")
1305
1322
  this.#logger.warn(`Channel error (${errorMessage(reason)}); rejoining`);
@@ -1612,6 +1629,7 @@ export {
1612
1629
  DEFAULT_MODEL,
1613
1630
  GardDestroyedError,
1614
1631
  JoinError,
1632
+ KeyRevokedError,
1615
1633
  NornsApiError,
1616
1634
  NornsClient,
1617
1635
  NornsError,
@@ -1622,6 +1640,7 @@ export {
1622
1640
  consoleLogger,
1623
1641
  defineAgent,
1624
1642
  inferProvider,
1643
+ isScopedKey,
1625
1644
  jsonSchema3 as jsonSchema,
1626
1645
  silentLogger,
1627
1646
  tool