@canonmsg/agent-sdk 12.2.1 → 12.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/README.md CHANGED
@@ -12,7 +12,7 @@ npm install @canonmsg/agent-sdk
12
12
 
13
13
  This is the only Canon package an agent installs. It bundles the Canon client code it uses and ships its own type declarations, so it depends on no other `@canonmsg/*` package; its dependencies are `@modelcontextprotocol/sdk`, `@noble/curves` and `chess.js`. The other `@canonmsg/*` packages on npm (`core`, `endpoint`, `backend-contracts`, `agent-tools`, `rich-cards` and the old hosts) are no longer published; remove them from an agent's dependencies. The `claude` driver also needs `@anthropic-ai/claude-agent-sdk` (an optional peer, see [Claude Code](#claude-code)); the `codex` driver needs the Codex CLI.
14
14
 
15
- Node.js 22.22.3 or later is required. You need an approved agent's API key; see [Registration](#registration).
15
+ Use a supported, patched Node.js release: 22.23.4+, 24.22.1+, or 26.12.1+ within those major lines. You need an approved agent's API key; see [Registration](#registration).
16
16
 
17
17
  ## Quick start
18
18
 
@@ -232,7 +232,7 @@ In an encrypted room:
232
232
  - A reply is journaled before it is encrypted. A retry or a restart sends the same ciphertext, and only while the room's audience is unchanged.
233
233
  - The ids Canon sees for what the runner sends there (each message's id, and a card's request id) are keyed with a secret the runner creates once in `$CANON_HOME/runner/<environment>/<agent>/mls-ids/` (0600; it belongs with the rest of the home). They reveal nothing about the text or what was asked, and every message's id has the same shape, whether it is a reply, a notice or a `communicate` send.
234
234
 
235
- Without `--mls-dev-config` (or `mls`), the runner refuses each encrypted room, logs it once, and runs nothing for it.
235
+ Without `--mls-dev-config` (or `mls`), the runner refuses each encrypted room, logs it once, and runs nothing for it. Where Canon encrypts every new conversation (its capabilities say `roomMode: 'default'`), such a runner does not start: it could take part in none of them.
236
236
 
237
237
  ### The class-C relay (Dev, Canon-operated)
238
238
 
@@ -4159,6 +4159,7 @@ var ENDPOINT_CONTENT_FUNCTION_QUERIES = [
4159
4159
  ];
4160
4160
  var ENDPOINT_CONTENT_QUERIES = [...ENDPOINT_CONTENT_FUNCTION_QUERIES, "admit_messages"];
4161
4161
  var ENDPOINT_CONTENT_EPHEMERALS = [
4162
+ "prewarm_agents",
4162
4163
  "create_memo_stream",
4163
4164
  "publish_presence",
4164
4165
  "publish_typing",
@@ -4364,6 +4365,7 @@ var turnPresence = {
4364
4365
  var transientRouting = {
4365
4366
  create_memo_stream: ["conversationId", "streamId"],
4366
4367
  append_memo_chunk: ["streamId"],
4368
+ prewarm_agents: ["conversationId"],
4367
4369
  publish_presence: [],
4368
4370
  publish_typing: ["conversationId"],
4369
4371
  publish_streaming: ["conversationId"],
@@ -109,7 +109,7 @@ import {
109
109
  readMembershipChangeMetadata,
110
110
  resolveAllowedUploadMimeType,
111
111
  sanitizeDownloadFileName
112
- } from "./chunk-J63YVAKA.js";
112
+ } from "./chunk-5MI6Q3VS.js";
113
113
 
114
114
  // src/media.ts
115
115
  import { createWriteStream as createWriteStream2 } from "node:fs";
@@ -194,6 +194,7 @@ function createEndpointEventHub(input) {
194
194
  let attempt = 0;
195
195
  while (!signal.aborted && observers.size) {
196
196
  let retryAfterMs = 0;
197
+ let handling = false;
197
198
  try {
198
199
  if (!input.transport.events) return;
199
200
  for await (const event of input.transport.events({ lastEventId, signal, families: families(), principalScopes: principalScopes(), onConnected: /* @__PURE__ */ __name(() => {
@@ -204,8 +205,10 @@ function createEndpointEventHub(input) {
204
205
  if (signal.aborted) break;
205
206
  validateEndpointContentBoundary("event", event.kind, event.data);
206
207
  if (event.kind === "error") throw decodeEndpointError(event.data, { stream: true });
207
- attempt = 0;
208
+ handling = true;
208
209
  await input.onEvent?.(event);
210
+ handling = false;
211
+ attempt = 0;
209
212
  if (event.kind === "replay.expired") lastEventId = void 0;
210
213
  else if (event.id) lastEventId = event.id;
211
214
  for (const observer of observers) safe(() => observer.listener(event));
@@ -213,7 +216,7 @@ function createEndpointEventHub(input) {
213
216
  }
214
217
  } catch (error) {
215
218
  if (!signal.aborted) {
216
- terminalError = error instanceof EndpointError && !error.retryable;
219
+ terminalError = !handling && error instanceof EndpointError && !error.retryable;
217
220
  if (error instanceof EndpointError && typeof error.retryAfterMs === "number" && Number.isFinite(error.retryAfterMs)) retryAfterMs = Math.max(0, Math.min(3e5, error.retryAfterMs));
218
221
  for (const { hooks } of observers) safe(() => hooks?.onError?.(error instanceof Error ? error : new EndpointError("Stream connection failed")));
219
222
  }
@@ -8834,7 +8837,8 @@ function createEndpoint(options) {
8834
8837
  await refreshMlsRoom(conversationId, true);
8835
8838
  } catch (error) {
8836
8839
  if (isMlsDevGroupRoomRecoveryFailure(error)) return;
8837
- throw error;
8840
+ if (error instanceof EndpointError && ["ENDPOINT_CLOSED", "PREPARATION_INSTALLATION_FENCED"].includes(error.code)) throw error;
8841
+ if (!(error instanceof EndpointError) || error.retryable) scheduleAdmission(conversationId, admissionRetry.initial, true);
8838
8842
  }
8839
8843
  }
8840
8844
  __name(refreshMlsRoomFromHint, "refreshMlsRoomFromHint");
@@ -9047,6 +9051,8 @@ function createEndpoint(options) {
9047
9051
  queryObserver.invalidate((query, parameters) => queryAffectedByOperation(updated, query, parameters));
9048
9052
  if (terminal(updated.status)) scheduleRetry(0);
9049
9053
  if (!terminal(updated.status) && updated.status !== "uncertain") scheduleRetry(Math.max(1e3, (updated.nextAttemptAt ?? clock()) - clock()));
9054
+ const made = updated.status === "succeeded" && ["start_conversation", "create_conversation"].includes(updated.action) ? updated.receipt?.result?.conversationId : void 0;
9055
+ if (mlsDevGroups && typeof made === "string" && ENDPOINT_ID_PATTERN.test(made)) void refreshMlsRoom(made, true).catch(() => void 0);
9050
9056
  }
9051
9057
  __name(afterReceipt, "afterReceipt");
9052
9058
  async function persistReceipt(operation, receipt) {
@@ -10032,7 +10038,7 @@ async function acquireAgentEndpoint(input) {
10032
10038
  }
10033
10039
  const requestedMls = input.options.mlsDev;
10034
10040
  const mls = requestedMls ? await (async () => {
10035
- const crypto2 = await import("./mls-crypto-ITVGUEP7.js");
10041
+ const crypto2 = await import("./mls-crypto-D5YAGYJ3.js");
10036
10042
  const configuration = crypto2.parseMlsDevClientConfiguration(requestedMls.configuration);
10037
10043
  if (configuration.environmentId !== environmentId || baseUrl !== CANON_RUNTIME_ENDPOINT_DEFAULTS[configuration.environmentId]?.apiBaseUrl || configuration.principalIds && !configuration.principalIds.includes(input.principalId) || !Number.isSafeInteger(input.ownershipVersion) || input.ownershipVersion < 0) throw new Error("MLS_DEV_AGENT_CONFIGURATION_BINDING_MISMATCH");
10038
10044
  const custody = requestedMls.custody;
@@ -10326,6 +10332,17 @@ var CanonClient = class {
10326
10332
  if (!res.ok) throw new CanonApiError(res.status, await res.text());
10327
10333
  return res.json();
10328
10334
  }
10335
+ /** Register (or explicitly remove) this installed agent's signed readiness callback. */
10336
+ async configureWake(configuration) {
10337
+ const response = await this.http(`${this.baseUrl}/agents/me/wake`, {
10338
+ method: configuration ? "POST" : "DELETE",
10339
+ headers: this.authHeaders(),
10340
+ signal: AbortSignal.timeout(15e3),
10341
+ ...configuration ? { body: JSON.stringify(configuration) } : {}
10342
+ });
10343
+ if (!response.ok) throw new CanonApiError(response.status, "Wake callback registration failed");
10344
+ return response.json();
10345
+ }
10329
10346
  async discoverAgents(input = {}) {
10330
10347
  const result = await this.endpointQuery("discover_agents", { ...input });
10331
10348
  if (!isDiscoverAgentsResult(result)) {
@@ -29,7 +29,7 @@ import {
29
29
  sendMessageWithRetryChunked,
30
30
  splitTextByUtf8Bytes,
31
31
  verifyCanonRuntimeConnection
32
- } from "./chunk-FCG2Z57F.js";
32
+ } from "./chunk-GJO7KULY.js";
33
33
  import {
34
34
  CONNECTOR_RELAY_ANSWER_WITHIN_MS,
35
35
  CONNECTOR_RELAY_INSTALLATION_PATTERN,
@@ -58,7 +58,7 @@ import {
58
58
  parseMlsDevGroupHead,
59
59
  parseMlsDevGroupRoster,
60
60
  resolveAllowedUploadMimeType
61
- } from "./chunk-J63YVAKA.js";
61
+ } from "./chunk-5MI6Q3VS.js";
62
62
 
63
63
  // src/runner/types.ts
64
64
  var DriverSessionError = class extends Error {
@@ -4701,7 +4701,11 @@ ${JSON.stringify(result, null, 2)}`);
4701
4701
  }
4702
4702
  agentId = identity.principalId;
4703
4703
  ownershipVersion = identity.ownershipVersion;
4704
+ if (options.wake !== void 0) await client.configureWake(options.wake);
4704
4705
  mlsOn = !!(endpoint.mlsDevDevice && endpoint.mlsDevGroups);
4706
+ if (!mlsOn && (await endpoint.capabilities().catch(() => null))?.mls?.roomMode === "default") {
4707
+ throw new Error("Canon encrypts every new conversation here, and this runner has no MLS device: run it with --mls-dev-config <path> (set one up with canon-agent mls).");
4708
+ }
4705
4709
  if (mlsOn) await endpoint.mlsDevDevice.ensureReady().catch(warn("MLS device not ready; encrypted rooms wait for it"));
4706
4710
  const keepPool = /* @__PURE__ */ __name(() => endpoint.mlsDevDevice.read().then(async (view) => {
4707
4711
  if (view.registration && view.status !== "revoked") {
@@ -2,7 +2,7 @@ import {
2
2
  createMlsDevCredentialVerifier,
3
3
  mlsDevDeviceHttpConfiguration,
4
4
  parseMlsDevClientConfiguration
5
- } from "./chunk-J63YVAKA.js";
5
+ } from "./chunk-5MI6Q3VS.js";
6
6
  export {
7
7
  createMlsDevCredentialVerifier,
8
8
  mlsDevDeviceHttpConfiguration,
package/dist/cli.js CHANGED
@@ -22,7 +22,7 @@ import {
22
22
  runnerLockName,
23
23
  startRelayChannel,
24
24
  writeRelayCredential
25
- } from "./chunks/chunk-LFTYXZUY.js";
25
+ } from "./chunks/chunk-HHODEJNL.js";
26
26
  import {
27
27
  CanonApiError,
28
28
  CanonClient,
@@ -33,11 +33,11 @@ import {
33
33
  resolveCanonRuntimeConnection,
34
34
  runCli,
35
35
  verifyCanonRuntimeConnection
36
- } from "./chunks/chunk-FCG2Z57F.js";
36
+ } from "./chunks/chunk-GJO7KULY.js";
37
37
  import {
38
38
  __name,
39
39
  isCanonClientVersion
40
- } from "./chunks/chunk-J63YVAKA.js";
40
+ } from "./chunks/chunk-5MI6Q3VS.js";
41
41
 
42
42
  // src/cli.ts
43
43
  import { realpathSync } from "node:fs";
@@ -80,9 +80,10 @@ Usage:
80
80
  canon-agent errands [--follow] [--cancel <errand id>] (--agent <id> | --profile <name>)
81
81
  [--environment <id>]
82
82
 
83
- Every run command also takes --mls-dev-config <path> (Dev only), which gives the agent
84
- its MLS device so it can take part in encrypted rooms. Without it, the agent refuses
85
- encrypted rooms and logs each one once.
83
+ Every run command also takes --mls-dev-config <path>, which gives the agent its MLS
84
+ device so it can take part in encrypted rooms. Without it, the agent refuses encrypted
85
+ rooms and logs each one once; where Canon encrypts every new conversation, it does not
86
+ start.
86
87
 
87
88
  Team rooms (an owner's agents working together): claude and codex also take
88
89
  [--instructions <file>] [--trust-agent <agentId>]...; every run command takes
@@ -155,8 +156,8 @@ Flags:
155
156
  which are then not end-to-end encrypted to that agent. With
156
157
  "mls", it sets up the relay's device with that credential.
157
158
  --mls-dev-config <p> The operator's MLS configuration: an absolute path to a private
158
- JSON file with the Dev issuer pins and the custody helper (no
159
- keys or credentials). Dev only.
159
+ JSON file with the environment's issuer pins and the custody
160
+ helper (no keys or credentials).
160
161
  --action <action> mls: status (public device state), provision (create the
161
162
  portable vault, once), enroll, renew, publish (this device's
162
163
  KeyPackage for --room) or refresh (catch up --room). It never
package/dist/index.d.ts CHANGED
@@ -20,3 +20,4 @@ export { CanonApiError, clearPendingRegistration, ensureAgentProfile, resumeRegi
20
20
  export type { CommunicateInput, CommunicateResult, EnsureAgentProfileOptions, MediaAttachment, RegistrationCredentials, RegistrationProgress, RegistrationSession, RegistrationStatus, RegistrationStore, ResumableMediaUploadResult, ResumeRegistrationOptions, VideoProcessingErrorCode, VideoProcessingStatus, } from './internal/core/index.js';
21
21
  export { DEFAULT_ANTHROPIC_REQUEST_HEADROOM_BYTES, DEFAULT_MEDIA_CACHE_DIR, DEFAULT_MEDIA_MATERIALIZATION_BYTES, MAX_ANTHROPIC_IMAGE_RAW_BYTES, MAX_ANTHROPIC_REQUEST_BYTES, MAX_CANON_MEDIA_BYTES, getCodexImagePath, getMessageAttachments, inferUploadMimeType, isAnthropicImageAttachment, conversationMediaCacheDir, materializeAttachment, materializeMessageMedia, materializeReplyContextMedia, resolveAttachmentMimeType, sendMediaFileMessage, toAnthropicImageBlock, toAnthropicImageBlocksWithinBudget, uploadMediaFile, } from './media.js';
22
22
  export type { AnthropicImageBlock, AnthropicImageBudgetOptions, AnthropicImageMimeType, MaterializeMediaOptions, MaterializedCanonAttachment, MaterializedCanonReplyContext, ReplyWithFileOptions, UploadMediaFileOptions, } from './media.js';
23
+ export type { AgentWakeConfiguration } from './internal/backend-contracts/index.js';
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  runMlsDevSetup,
19
19
  runtimeDescriptor,
20
20
  startRelayChannel
21
- } from "./chunks/chunk-LFTYXZUY.js";
21
+ } from "./chunks/chunk-HHODEJNL.js";
22
22
  import {
23
23
  CanonApiError,
24
24
  DEFAULT_ANTHROPIC_REQUEST_HEADROOM_BYTES,
@@ -43,8 +43,8 @@ import {
43
43
  toAnthropicImageBlock,
44
44
  toAnthropicImageBlocksWithinBudget,
45
45
  uploadMediaFile
46
- } from "./chunks/chunk-FCG2Z57F.js";
47
- import "./chunks/chunk-J63YVAKA.js";
46
+ } from "./chunks/chunk-GJO7KULY.js";
47
+ import "./chunks/chunk-5MI6Q3VS.js";
48
48
  export {
49
49
  CanonApiError,
50
50
  ConnectorRelayError,
@@ -0,0 +1,11 @@
1
+ /** Operator-installed plugin callback. Signing material is restricted secret
2
+ * configuration and never part of conversations, catalogs or event payloads. */
3
+ export interface AgentWakeConfiguration {
4
+ callbackUrl: string;
5
+ secret: string;
6
+ conversationIds: string[];
7
+ }
8
+ export interface AgentWakeHint {
9
+ type: 'wake';
10
+ reason: 'typing' | 'event';
11
+ }
@@ -11,7 +11,7 @@ export declare const MLS_DEV_UNSUPPORTED_CONTENT_ACTIONS: readonly ["forward_mes
11
11
  export declare const ENDPOINT_CONTENT_ACTIONS: readonly ["mls_application", "mls_group_control", "initialize_endpoint", "append_artifact_command", "retain_artifact_asset", "sync_phone_contacts", "update_agent_behavior_policy", "update_conversation_agent_behavior_policy", "send_message", "delete_message", "forward_message", "react", "verb_execute", "send_contextual_message", "create_interaction", "consume_interaction", "start_conversation", "create_conversation", "add_member", "remove_member", "leave_conversation", "update_member_role", "update_conversation", "rename_conversation", "update_topic", "update_group_avatar", "mark_read", "cancel_queued_message", "set_conversation_preferences", "set_block", "save_contact", "remove_contact", "respond_interaction", "session_control", "approve_contact_request", "reject_contact_request", "cancel_direct_request", "update_message_disposition", "create_upload", "finalize_upload", "delete_upload", "retry_video_processing", "stage_media_message", "cancel_media_message", "renew_media_message_upload", "finalize_memo_stream", "abort_memo_stream", "create_voice_session", "join_voice_session", "decline_voice_session", "end_voice_session", "consume_runtime_signal", "consume_runtime_primitive", "generate_image"];
12
12
  export declare const ENDPOINT_CONTENT_FUNCTION_QUERIES: readonly ["mls_group_feed", "mls_group_controls", "mls_group_admissions", "mls_interactions", "list_artifacts", "get_artifact_log", "get_artifact_asset", "discover_agents", "get_unread_summary", "peek_runtime_signal", "list_runtime_primitives", "get_agent_behavior_policy", "get_conversation_agent_behavior_policy", "get_ephemeral", "list_voice_sessions", "list_contact_requests", "list_conversations", "list_messages", "get_messages", "admission_fences", "list_contacts", "get_contact", "get_members", "resolve_admission", "resolve_group_admission", "get_runtime_card_state", "conversation", "conversation_changes", "get_upload", "get_media_message", "get_voice_session", "get_image_generation", "get_image_generation_status", "same_owner_agents"];
13
13
  export declare const ENDPOINT_CONTENT_QUERIES: readonly ["mls_group_feed", "mls_group_controls", "mls_group_admissions", "mls_interactions", "list_artifacts", "get_artifact_log", "get_artifact_asset", "discover_agents", "get_unread_summary", "peek_runtime_signal", "list_runtime_primitives", "get_agent_behavior_policy", "get_conversation_agent_behavior_policy", "get_ephemeral", "list_voice_sessions", "list_contact_requests", "list_conversations", "list_messages", "get_messages", "admission_fences", "list_contacts", "get_contact", "get_members", "resolve_admission", "resolve_group_admission", "get_runtime_card_state", "conversation", "conversation_changes", "get_upload", "get_media_message", "get_voice_session", "get_image_generation", "get_image_generation_status", "same_owner_agents", "admit_messages"];
14
- export declare const ENDPOINT_CONTENT_EPHEMERALS: readonly ["create_memo_stream", "publish_presence", "publish_typing", "publish_streaming", "publish_turn", "publish_runtime_status", "publish_session_state", "publish_runtime_info", "publish_runtime_activity", "append_memo_chunk"];
14
+ export declare const ENDPOINT_CONTENT_EPHEMERALS: readonly ["prewarm_agents", "create_memo_stream", "publish_presence", "publish_typing", "publish_streaming", "publish_turn", "publish_runtime_status", "publish_session_state", "publish_runtime_info", "publish_runtime_activity", "append_memo_chunk"];
15
15
  export declare const ENDPOINT_CONTENT_EPHEMERAL_FAMILIES: readonly ["typing", "streaming", "turn-state", "agent-session", "runtime-card-state", "memo-streams", "runtime-info", "runtime-activity", "runtime-suppression", "runtime-silence", "runtime-attention", "call-attention", "agent-runtime", "presence"];
16
16
  export declare const ENDPOINT_CONTENT_EVENTS: readonly ["connected", "heartbeat", "agent.context", "replay.expired", "error", "participation.suppressed", "artifact.changed", "message.created", "message.snapshot", "message.updated", "message.deleted", "message.media_terminal", "conversation.updated", "conversation.changed", "conversation.removed", "conversations.changed", "contacts.changed", "contact.added", "contact.updated", "contact.removed", "presence", "typing", "runtime.updated", "runtime.control", "turn.updated", "voice.session.started", "voice.session.ended", ...string[]];
17
17
  export declare class EndpointContentPolicyError extends Error {
@@ -52,3 +52,4 @@ export * from './mlsDevGroupFeed.js';
52
52
  export * from './mlsDevFeedReceipt.js';
53
53
  export * from './mlsDevInteraction.js';
54
54
  export * from './mlsPrincipalAlias.js';
55
+ export type { AgentWakeConfiguration, AgentWakeHint } from './agentWake.js';
@@ -1,3 +1,4 @@
1
+ import type { AgentWakeConfiguration } from '../backend-contracts/index.js';
1
2
  import { type CanonMessage, type CanonConversation, type CanonUnifiedDiff, type CanonMessagesPage, type AgentContext, type MediaAttachment, type SendMessageOptions, type RegistrationStatus, type AgentOriginDeclaration, type SetRuntimeTurnOptions, type SetStreamingOptions } from './types.js';
2
3
  import type { RuntimeInputKind } from './runtime-cards.js';
3
4
  import type { ApprovalNativeRequestMetadata, ApprovalRequestCategory, ApprovalRequestDetail, ApprovalRisk, SessionRule } from './approval-types.js';
@@ -37,6 +38,11 @@ export declare class CanonClient {
37
38
  private endpointPublish;
38
39
  private authHeaders;
39
40
  getAgentMe(): Promise<AgentContext>;
41
+ /** Register (or explicitly remove) this installed agent's signed readiness callback. */
42
+ configureWake(configuration: AgentWakeConfiguration | null): Promise<{
43
+ revision?: string;
44
+ disabled?: true;
45
+ }>;
40
46
  discoverAgents(input?: DiscoverAgentsInput): Promise<DiscoverAgentsResult>;
41
47
  /** Targeted membership read; session hosts must not poll the entire account. */
42
48
  getConversation(conversationId: string): Promise<CanonConversation | null>;
package/dist/media.js CHANGED
@@ -18,8 +18,8 @@ import {
18
18
  toAnthropicImageBlock,
19
19
  toAnthropicImageBlocksWithinBudget,
20
20
  uploadMediaFile
21
- } from "./chunks/chunk-FCG2Z57F.js";
22
- import "./chunks/chunk-J63YVAKA.js";
21
+ } from "./chunks/chunk-GJO7KULY.js";
22
+ import "./chunks/chunk-5MI6Q3VS.js";
23
23
  export {
24
24
  DEFAULT_ANTHROPIC_REQUEST_HEADROOM_BYTES,
25
25
  DEFAULT_MEDIA_CACHE_DIR,
@@ -1,3 +1,4 @@
1
+ import type { AgentWakeConfiguration } from '../internal/backend-contracts/index.js';
1
2
  import { type ConnectorRelayPage, type ConnectorRelaySent } from '../internal/backend-contracts/index.js';
2
3
  import { type CanonEndpoint, type CanonRuntimeDescriptor, type CommunicateInput, type CommunicateResult } from '../internal/core/index.js';
3
4
  import { type RunnerMlsOptions } from './mls.js';
@@ -11,6 +12,8 @@ export interface RunnerOptions {
11
12
  version: string;
12
13
  };
13
14
  apiKey: string;
15
+ /** Signed, content-free wake callback installed by the agent. Null explicitly disables it. */
16
+ wake?: AgentWakeConfiguration | null;
14
17
  environmentId: string;
15
18
  /** CANON_HOME: a private 0700 directory, checked before anything is opened. */
16
19
  home: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonmsg/agent-sdk",
3
- "version": "12.2.1",
3
+ "version": "12.3.0",
4
4
  "description": "Canon Agent SDK — build AI agents that participate in Canon conversations",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -27,7 +27,7 @@
27
27
  "prepack": "npm run build"
28
28
  },
29
29
  "engines": {
30
- "node": ">=22.22.3"
30
+ "node": ">=22.23.4 <23 || >=24.22.1 <25 || >=26.12.1 <27"
31
31
  },
32
32
  "dependencies": {
33
33
  "@modelcontextprotocol/sdk": "^1.30.0",