@canonmsg/agent-sdk 12.3.2 → 12.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.
@@ -0,0 +1,25 @@
1
+ import type { MlsEnvironmentId } from '../internal/backend-contracts/index.js';
2
+ /**
3
+ * Each environment's Cloud KMS issuer and feed-receipt key versions (public keys, raw Ed25519 in base64url). During an
4
+ * issuer rotation `issuerKeys` holds both versions (docs/mls-dev-activation.md, "Planned issuer rotation"), and an SDK
5
+ * release carrying the new one ships before issuance switches.
6
+ */
7
+ export declare const MLS_ENVIRONMENT_PINS: Readonly<Record<MlsEnvironmentId, {
8
+ issuerKeys: ReadonlyArray<{
9
+ keyVersion: string;
10
+ signaturePublicKey: string;
11
+ }>;
12
+ receiptKeys: ReadonlyArray<{
13
+ keyVersion: string;
14
+ signaturePublicKey: string;
15
+ }>;
16
+ }>>;
17
+ /**
18
+ * The custody helper this package ships for this host (`dist/mls/<platform>/canon-mls-custody`), checked against its
19
+ * pin, or undefined where it ships none: an Intel Mac, musl, Windows, or a build of this package without helpers. A
20
+ * file that is there but differs from its pin is refused.
21
+ */
22
+ export declare function bundledMlsCustodyHelper(): {
23
+ path: string;
24
+ sha256: string;
25
+ } | undefined;
@@ -0,0 +1,36 @@
1
+ import { type MlsDevDeviceContext, type MlsEnvironmentId } from '../internal/backend-contracts/index.js';
2
+ import type { RunnerMlsOptions } from './mls.js';
3
+ export interface ManagedMlsDeviceOptions {
4
+ /** The runner's home (CANON_HOME, or a relay installation's home). */
5
+ home: string;
6
+ environmentId: MlsEnvironmentId;
7
+ /** Another helper than this package's for the host, such as one built from mls/native. */
8
+ helper?: {
9
+ path: string;
10
+ sha256: string;
11
+ };
12
+ /** Other public pins than this package's for the environment. */
13
+ pins?: {
14
+ issuerKeys: ReadonlyArray<{
15
+ keyVersion: string;
16
+ signaturePublicKey: string;
17
+ }>;
18
+ receiptKeys: ReadonlyArray<{
19
+ keyVersion: string;
20
+ signaturePublicKey: string;
21
+ }>;
22
+ };
23
+ timeoutMs?: number;
24
+ }
25
+ export type ManagedMlsDevice = RunnerMlsOptions & {
26
+ provision(context: MlsDevDeviceContext): Promise<void>;
27
+ /** Whether this context's vault exists: its device was provisioned here. */
28
+ provisioned(context: MlsDevDeviceContext): boolean;
29
+ close(): Promise<void>;
30
+ };
31
+ /**
32
+ * A runner's device where it is given none (`createRunner` and the CLI alike): managed custody with this package's helper
33
+ * for the host, or undefined where it ships none or the environment has no MLS.
34
+ */
35
+ export declare function defaultMlsDevice(home: string, environmentId: string): ManagedMlsDevice | undefined;
36
+ export declare function managedMlsDevice(options: ManagedMlsDeviceOptions): ManagedMlsDevice;
@@ -1,9 +1,14 @@
1
1
  import { type CanonEndpoint, type CanonMlsDevOptions, type MlsDevCurrentAudience } from '../internal/core/index.js';
2
2
  import { type MlsDevDeviceContext } from '../internal/backend-contracts/index.js';
3
3
  import type { ToolDefinition } from './types.js';
4
- /** What `createRunner({ mls })` takes: issuer pins and custody, plus the custody's own shutdown. */
4
+ /**
5
+ * What `createRunner({ mls })` takes: issuer pins and custody, plus the custody's own shutdown. With `provisioned`
6
+ * (managed custody, `managedMlsDevice`) the runner sets the device up itself at start.
7
+ */
5
8
  export type RunnerMlsOptions = CanonMlsDevOptions & {
6
9
  close?(): Promise<void>;
10
+ provision?(context: MlsDevDeviceContext): Promise<void>;
11
+ provisioned?(context: MlsDevDeviceContext): boolean;
7
12
  };
8
13
  /** A closed copy of the public audience (no provider input or key material), in a fixed field order. */
9
14
  export declare function snapshotMlsAudience(value: unknown): MlsDevCurrentAudience;
@@ -70,7 +75,7 @@ export declare function loadMlsDevConfiguration(filePath: string, input: {
70
75
  provision?: (context: MlsDevDeviceContext) => Promise<void>;
71
76
  close(): Promise<void>;
72
77
  }>;
73
- export declare const MLS_SETUP_ACTIONS: readonly ["status", "provision", "enroll", "renew", "publish", "refresh"];
78
+ export declare const MLS_SETUP_ACTIONS: readonly ["status", "setup", "provision", "enroll", "renew", "publish", "refresh"];
74
79
  export type MlsSetupAction = typeof MLS_SETUP_ACTIONS[number];
75
80
  /** The KeyPackage an agent publishes for one room: stable for its installation, so a repeated publish is the same intent. */
76
81
  export declare function mlsDevRoomPackageId(identity: {
@@ -79,15 +84,23 @@ export declare function mlsDevRoomPackageId(identity: {
79
84
  installationId: string;
80
85
  ownershipVersion?: number;
81
86
  }, room: string): string;
87
+ /**
88
+ * Managed custody opens only the vaults it made in its home. A device the engine store holds with no vault there (set up
89
+ * with an operator's configuration, or its vault lost) is refused once, here, rather than failing in every room.
90
+ */
91
+ export declare function assertMlsVaultInHome(endpoint: CanonEndpoint, provisioned: (context: MlsDevDeviceContext) => boolean): Promise<void>;
82
92
  /**
83
93
  * One operator step for the agent's device (`canon-agent mls`), on the same engine store the runner uses. It never
84
- * starts a model, and prints only public device state: no credentials, proofs, envelopes or history.
94
+ * starts a model, and prints only public device state: no credentials, proofs, envelopes or history. `setup` does what
95
+ * is left of provision then enroll, so it also finishes a setup that stopped part way; it never replaces a vault, and
96
+ * with `provisioned` (managed custody) it provisions only where this installation has none, and refuses a device whose
97
+ * vault is elsewhere.
85
98
  */
86
- export declare function runMlsDevSetup(endpoint: CanonEndpoint, action: MlsSetupAction, room?: string, provision?: (context: MlsDevDeviceContext) => Promise<void>): Promise<{
99
+ export declare function runMlsDevSetup(endpoint: CanonEndpoint, action: MlsSetupAction, room?: string, provision?: (context: MlsDevDeviceContext) => Promise<void>, provisioned?: (context: MlsDevDeviceContext) => boolean): Promise<{
87
100
  conversationId?: string | undefined;
88
101
  version: number;
89
- action: "status" | "publish" | "enroll" | "renew" | "provision" | "refresh";
90
- environmentId: "canon-dev-v1" | "canon-prod-v1";
102
+ action: "status" | "publish" | "enroll" | "renew" | "provision" | "setup" | "refresh";
103
+ environmentId: string;
91
104
  principalId: string;
92
105
  installationId: string;
93
106
  ownershipVersion: number | undefined;
@@ -1,9 +1,9 @@
1
1
  import { type ConnectorRelayCredentialDelivery } from '../internal/backend-contracts/index.js';
2
2
  import type { ConnectorInbox } from '../drivers/connector.js';
3
3
  import type { Runner } from './runner.js';
4
- /** What the channel serves: the relay's runner (history and sends) and its connector driver's inbox (pickup). */
4
+ /** What the channel serves: the relay's runner (history, sends and starts) and its connector driver's inbox (pickup). */
5
5
  export interface RelayTarget {
6
- runner: Pick<Runner, 'relayRead' | 'relaySend'>;
6
+ runner: Pick<Runner, 'relayRead' | 'relaySend' | 'relayStart'>;
7
7
  inbox: ConnectorInbox;
8
8
  }
9
9
  /** Canon's credential for this relay, as delivered: the connection it serves is the delivering request's. */
@@ -12,7 +12,7 @@ export type RelayCredentialDelivery = ConnectorRelayCredentialDelivery & {
12
12
  };
13
13
  export interface RelayChannelOptions {
14
14
  /** The runner and inbox to serve from the start; `serve` sets or replaces them. Until then only `credential` is answered. */
15
- runner?: Pick<Runner, 'relayRead' | 'relaySend'>;
15
+ runner?: Pick<Runner, 'relayRead' | 'relaySend' | 'relayStart'>;
16
16
  inbox?: ConnectorInbox;
17
17
  /** The relayed agent: requests naming another agent are refused. */
18
18
  agentId: string;
@@ -1,5 +1,5 @@
1
1
  import type { AgentWakeConfiguration } from '../internal/backend-contracts/index.js';
2
- import { type ConnectorRelayPage, type ConnectorRelaySent } from '../internal/backend-contracts/index.js';
2
+ import { type ConnectorRelayPage, type ConnectorRelaySent, type ConnectorRelayStarted, type DirectConversationSelection } from '../internal/backend-contracts/index.js';
3
3
  import { type CanonEndpoint, type CanonRuntimeDescriptor, type CommunicateInput, type CommunicateResult } from '../internal/core/index.js';
4
4
  import { type RunnerMlsOptions } from './mls.js';
5
5
  import { type RuntimeDriver } from './types.js';
@@ -26,16 +26,18 @@ export interface RunnerOptions {
26
26
  baseUrl?: string;
27
27
  streamUrl?: string;
28
28
  /**
29
- * The agent's MLS device (Dev only, spec §6): issuer pins and custody, from `loadMlsDevConfiguration`. With it the
30
- * runner takes part in encrypted rooms; without it each encrypted room is refused, once, in the log. An injected
31
- * `endpoint` that already has an MLS device counts as configured. `close` runs last on shutdown.
29
+ * The agent's MLS device (spec §6): issuer pins and custody, from `loadMlsDevConfiguration` or `managedMlsDevice`. Left
30
+ * out, it is managed custody in `home` where this package ships a custody helper for the host, as the CLI's; `false` is
31
+ * none. With a device the runner takes part in encrypted rooms; without one each encrypted room is refused, once, in the
32
+ * log. An injected `endpoint` brings its own device, if any. `close` runs last on shutdown.
32
33
  */
33
- mls?: RunnerMlsOptions;
34
+ mls?: RunnerMlsOptions | false;
34
35
  /**
35
36
  * Relay mode, the class-C relay (spec §11.4): only encrypted rooms are served, which is what lets a `remote` driver
36
37
  * (the connector) into them. Plaintext input is cancelled with no turn (the connector's own installation serves it),
37
- * control hints are read only for encrypted rooms, no runtime descriptor is published, and `relayRead` and `relaySend`
38
- * serve the relay channel. It needs the agent's MLS device.
38
+ * control hints are read only for encrypted rooms, and `relayRead` and `relaySend` serve the relay channel. It publishes
39
+ * the runtime descriptor and heartbeat, so the apps show a relayed turn working and offer Stop. It needs the agent's MLS
40
+ * device.
39
41
  */
40
42
  relay?: boolean;
41
43
  /** The engine's installation: the relay's reserved one, from its configuration. A store opened under another refuses to start. */
@@ -95,6 +97,15 @@ export interface Runner {
95
97
  relaySend(conversationId: string, messageId: string, text: string, options?: {
96
98
  deadline?: number;
97
99
  }): Promise<ConnectorRelaySent>;
100
+ /**
101
+ * Relay mode (§11.5): a conversation started with a person or agent, its opening line withheld from Canon and kept
102
+ * here first; this device founds (or finds) the encrypted room and sends the line. The same `messageId` is the same
103
+ * start. It answers by `deadline`: `starting` means unresolved, even if recording has not finished; retry the same
104
+ * identity until another answer arrives. Only a persisted start resumes automatically after a restart.
105
+ */
106
+ relayStart(targetUserId: string, messageId: string, text: string, selection?: DirectConversationSelection, options?: {
107
+ deadline?: number;
108
+ }): Promise<ConnectorRelayStarted>;
98
109
  }
99
110
  /** RUN-27: generated once from the driver's declarations; no static capability table. */
100
111
  export declare function runtimeDescriptor(driver: RuntimeDriver): CanonRuntimeDescriptor;
@@ -36,8 +36,9 @@ export interface DriverTurn {
36
36
  tools: TurnTools;
37
37
  /**
38
38
  * For a `remote` runtime, before its input first leaves this host (the connector's claim): the runner reads the
39
- * agent's membership, and an encrypted room's audience, from Canon now and counts the pickup as progress (RUN-12).
40
- * It rejects, and ends the turn, when the agent may no longer act on this input; a transient failure only rejects.
39
+ * agent's membership, and an encrypted room's audience, from Canon now, submits the input on the first confirmed
40
+ * pickup (until then it is only offered, with no deadline) and counts each pickup as progress (RUN-12). It rejects,
41
+ * and ends the turn, when the agent may no longer act on this input; a transient failure only rejects.
41
42
  */
42
43
  confirmPickup(): Promise<void>;
43
44
  }
@@ -65,7 +66,9 @@ export interface DriverCapabilities {
65
66
  /**
66
67
  * The runtime runs off the runner's host (the class-C connector, spec §11.3): it gets no local files (inbound
67
68
  * attachments are named in the prompt, never materialized), and since its plaintext leaves this host, the runner
68
- * takes it into encrypted rooms only in relay mode, whose installation discloses that.
69
+ * takes it into encrypted rooms only in relay mode, whose installation discloses that. Its input is offered first and
70
+ * submitted only when the runtime picks it up (`confirmPickup`); newer messages in the room join an input not yet
71
+ * picked up.
69
72
  */
70
73
  remote?: boolean;
71
74
  /** Across rooms; runner default 8. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonmsg/agent-sdk",
3
- "version": "12.3.2",
3
+ "version": "12.5.1",
4
4
  "description": "Canon Agent SDK — build AI agents that participate in Canon conversations",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -24,7 +24,7 @@
24
24
  "scripts": {
25
25
  "build": "node ../../scripts/build-agent-sdk.mjs",
26
26
  "dev": "tsc --watch --noEmit",
27
- "prepack": "npm run build"
27
+ "prepack": "node ../../scripts/build-agent-sdk.mjs --pack"
28
28
  },
29
29
  "engines": {
30
30
  "node": ">=22.23.4 <23 || >=24.22.1 <25 || >=26.12.1 <27"