@canonmsg/agent-sdk 13.3.0 → 13.3.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.
@@ -32,8 +32,9 @@ import {
32
32
  splitTextWithinBytes,
33
33
  utf8ByteLength,
34
34
  verifyCanonRuntimeConnection
35
- } from "./chunk-AVR7QCHK.js";
35
+ } from "./chunk-SS22I6HM.js";
36
36
  import {
37
+ EndpointError,
37
38
  NodeMlsDevCustodyError,
38
39
  createNodeMlsDevCustody,
39
40
  createPortableNodeMlsDevCustody
@@ -2686,7 +2687,7 @@ function relayRunnerHome(home, installationId) {
2686
2687
  __name(relayRunnerHome, "relayRunnerHome");
2687
2688
 
2688
2689
  // src/version.ts
2689
- var AGENT_SDK_VERSION = true ? "13.3.0" : void 0;
2690
+ var AGENT_SDK_VERSION = true ? "13.3.1" : void 0;
2690
2691
  var RUNNER_CLIENT = isCanonClientVersion(AGENT_SDK_VERSION) ? Object.freeze({ kind: "runner", version: AGENT_SDK_VERSION }) : void 0;
2691
2692
 
2692
2693
  // src/runner/runner.ts
@@ -3383,6 +3384,7 @@ function answerText(answer) {
3383
3384
  return answer.text?.trim() ? answer.text : "They answered with an empty message.";
3384
3385
  }
3385
3386
  __name(answerText, "answerText");
3387
+ var AGENT_KEY_REFUSED = "AGENT_KEY_REFUSED";
3386
3388
  var sha2564 = /* @__PURE__ */ __name((value) => createHash9("sha256").update(value).digest("hex"), "sha256");
3387
3389
  var toolText = /* @__PURE__ */ __name((text3, isError = false) => ({ content: [{ type: "text", text: text3 }], ...isError ? { isError } : {} }), "toolText");
3388
3390
  var turnEnded2 = /* @__PURE__ */ __name(() => new DOMException("This turn has ended", "AbortError"), "turnEnded");
@@ -3570,7 +3572,10 @@ async function createRunner(options) {
3570
3572
  await assertPrivateHome(home);
3571
3573
  const mls = options.mls === false ? void 0 : options.mls ?? (options.endpoint ? void 0 : defaultMlsDevice(home, options.environmentId));
3572
3574
  const log = options.log ?? ((line) => console.error(`[canon-runner] ${line}`));
3573
- const warn = /* @__PURE__ */ __name((what) => (error) => log(`${what}: ${error instanceof Error ? error.message : String(error)}`), "warn");
3575
+ const warn = /* @__PURE__ */ __name((what) => (error) => {
3576
+ if (mayEnd(error)) void recheck();
3577
+ log(`${what}: ${error instanceof Error ? error.message : String(error)}`);
3578
+ }, "warn");
3574
3579
  const abortGraceMs = options.abortGraceMs ?? 1e4;
3575
3580
  const noProgressMs = options.noProgressMs ?? 30 * 6e4;
3576
3581
  const askExpiryMs = options.askExpiryMs ?? 60 * 6e4;
@@ -3751,16 +3756,50 @@ async function createRunner(options) {
3751
3756
  }
3752
3757
  __name(refuse, "refuse");
3753
3758
  let homeSince = 0;
3759
+ let refusedBy;
3760
+ async function readAgent() {
3761
+ const refuse2 = /* @__PURE__ */ __name((error) => {
3762
+ refusedBy = error;
3763
+ options.onFatal?.(error);
3764
+ return error;
3765
+ }, "refuse");
3766
+ let me;
3767
+ try {
3768
+ me = await client.getAgentMe();
3769
+ } catch (error) {
3770
+ if (options.relay || !(error instanceof CanonApiError && error.status === 401)) throw error;
3771
+ throw refuse2(Object.assign(
3772
+ new Error(`Canon no longer accepts ${displayName ?? "this agent"}'s key: a new key replaced it, or the agent was deleted.`),
3773
+ { code: AGENT_KEY_REFUSED, cause: error }
3774
+ ));
3775
+ }
3776
+ if (!options.relay && me.home && (me.home.kind === "connector" || me.home.installationId !== void 0 && me.home.installationId !== installationId)) {
3777
+ throw refuse2(Object.assign(new Error(agentHomeElsewhereMessage(me.displayName, me.home)), { code: AGENT_HOME_ELSEWHERE }));
3778
+ }
3779
+ refusedBy = void 0;
3780
+ return me;
3781
+ }
3782
+ __name(readAgent, "readAgent");
3783
+ function mayEnd(error) {
3784
+ return (error instanceof EndpointError || error instanceof CanonApiError) && (error.code === AGENT_HOME_ELSEWHERE || error.status === 401 && error.code !== "CONNECTOR_ACCESS_TOKEN_EXPIRED");
3785
+ }
3786
+ __name(mayEnd, "mayEnd");
3787
+ let rechecking;
3788
+ function recheck() {
3789
+ if (options.relay || !client) return Promise.resolve();
3790
+ rechecking ??= readAgent().then(() => void 0, (error) => {
3791
+ if (error !== refusedBy) log(`home check: ${error instanceof Error ? error.message : String(error)}`);
3792
+ }).finally(() => {
3793
+ rechecking = void 0;
3794
+ });
3795
+ return within(rechecking, 1e4).then(() => void 0);
3796
+ }
3797
+ __name(recheck, "recheck");
3754
3798
  async function authorize() {
3755
3799
  await endpoint.mlsDevDevice.ensureReady();
3756
- const me = await client.getAgentMe();
3800
+ const me = await readAgent();
3757
3801
  requireMlsSupport({ environmentId: options.environmentId });
3758
3802
  if (me.agentId !== agentId || me.ownershipVersion !== ownershipVersion) throw new Error("MLS_AUTHORITY_REQUIRED");
3759
- if (!options.relay && me.home && (me.home.kind === "connector" || me.home.installationId !== void 0 && me.home.installationId !== installationId)) {
3760
- const error = Object.assign(new Error(agentHomeElsewhereMessage(me.displayName, me.home)), { code: AGENT_HOME_ELSEWHERE });
3761
- options.onFatal?.(error);
3762
- throw error;
3763
- }
3764
3803
  homeSince = !options.relay && me.home?.kind === "runner" ? me.home.since ?? 0 : 0;
3765
3804
  outboundClosed = me.outboundPolicy === "closed";
3766
3805
  if (outboundClosed && options.relay) throw new Error("MLS_AUTHORITY_REQUIRED");
@@ -5529,6 +5568,7 @@ ${JSON.stringify(result, null, 2)}`);
5529
5568
  ...options.fetch ? { fetch: options.fetch } : {}
5530
5569
  });
5531
5570
  const me = await client.getAgentMe();
5571
+ displayName = me.displayName;
5532
5572
  lock = acquireLock(runnerLockName(connection.environmentId, me.agentId), home);
5533
5573
  endpoint = await client.getEndpoint();
5534
5574
  const identity = await endpoint.ready();
@@ -5607,15 +5647,30 @@ ${JSON.stringify(result, null, 2)}`);
5607
5647
  roots = outbound ? (await Promise.all(outbound.roots.map((root) => realpath4(root).catch(() => "")))).filter(Boolean) : [];
5608
5648
  if (driver.capabilities.tools) tools = await startToolServer();
5609
5649
  await recover();
5610
- const publisher = createRuntimeStatePublisher({ agentId, clientType: CLIENT_TYPES[driver.name], hostMode: true, rtdb: initRTDBAuth(client) });
5650
+ const runtimeState = createRuntimeStatePublisher({ agentId, clientType: CLIENT_TYPES[driver.name], hostMode: true, rtdb: initRTDBAuth(client) });
5651
+ const publisher = {
5652
+ publishAgentRuntime: /* @__PURE__ */ __name((runtime) => refusedBy ? Promise.resolve() : runtimeState.publishAgentRuntime(runtime), "publishAgentRuntime"),
5653
+ clearAgentRuntime: /* @__PURE__ */ __name(() => refusedBy ? Promise.resolve() : runtimeState.clearAgentRuntime(), "clearAgentRuntime")
5654
+ };
5611
5655
  heartbeat = createRuntimeHeartbeat({ publisher, getRuntime: /* @__PURE__ */ __name(() => ({ runtimeDescriptor: descriptor }), "getRuntime"), onError: warn("runtime heartbeat") });
5612
5656
  inbound = endpoint.acceptInbound({ kind: "message.created", offer, onError: warn("inbox"), ...mlsOn ? { intervalMs: 1e3 } : {} });
5613
5657
  inbound.start();
5614
5658
  let reconnect = false;
5659
+ let streamUp = false;
5660
+ let following = Promise.resolve();
5661
+ const follow = /* @__PURE__ */ __name(() => {
5662
+ const check = reconnect;
5663
+ following = following.then(async () => {
5664
+ if (check) await recheck();
5665
+ if (streamUp) heartbeat?.connect();
5666
+ else void heartbeat?.disconnect();
5667
+ }).catch(warn("runtime heartbeat"));
5668
+ }, "follow");
5615
5669
  detach.push(endpoint.observeEvents(onEvent, {
5616
5670
  families: ["messages", "contacts", "runtime_turn"],
5617
5671
  onConnected: /* @__PURE__ */ __name(() => {
5618
- heartbeat?.connect();
5672
+ streamUp = true;
5673
+ follow();
5619
5674
  if (mlsOn) void noteAdmissions().catch(warn("room admission"));
5620
5675
  if (reconnect) {
5621
5676
  for (const target of rooms.values()) if (target.turn) scheduleControl(target);
@@ -5628,7 +5683,10 @@ ${JSON.stringify(result, null, 2)}`);
5628
5683
  }
5629
5684
  reconnect = true;
5630
5685
  }, "onConnected"),
5631
- onDisconnected: /* @__PURE__ */ __name(() => void heartbeat?.disconnect(), "onDisconnected"),
5686
+ onDisconnected: /* @__PURE__ */ __name(() => {
5687
+ streamUp = false;
5688
+ follow();
5689
+ }, "onDisconnected"),
5632
5690
  onError: warn("event stream")
5633
5691
  }));
5634
5692
  if (errands) {
@@ -7410,7 +7410,7 @@ function createEndpoint(options) {
7410
7410
  }
7411
7411
  __name(joinInvitedRoom, "joinInvitedRoom");
7412
7412
  async function discoverInviteeRooms() {
7413
- if (!mlsDevGroups || closed) return;
7413
+ if (!mlsDevGroups || closed || options.mlsDevDevice?.principal.type !== "human") return;
7414
7414
  const { requests } = await endpoint.query(
7415
7415
  "list_contact_requests",
7416
7416
  { direction: "inbound" }
package/dist/cli.js CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  runMlsDevSetup,
27
27
  startRelayChannel,
28
28
  writeRelayCredential
29
- } from "./chunks/chunk-ZT3TJZAV.js";
29
+ } from "./chunks/chunk-B6AOBWNZ.js";
30
30
  import {
31
31
  assertPrivateHome,
32
32
  runnerLockName
@@ -43,7 +43,7 @@ import {
43
43
  resolveCanonRuntimeConnection,
44
44
  runCli,
45
45
  verifyCanonRuntimeConnection
46
- } from "./chunks/chunk-AVR7QCHK.js";
46
+ } from "./chunks/chunk-SS22I6HM.js";
47
47
  import "./chunks/chunk-HFT75BNB.js";
48
48
  import "./chunks/chunk-NIORQKUI.js";
49
49
  import {
@@ -57,8 +57,10 @@ import { homedir, tmpdir } from "node:os";
57
57
  import { dirname, join, resolve } from "node:path";
58
58
  import { pathToFileURL } from "node:url";
59
59
  import { parseArgs } from "node:util";
60
+ var OWNER_DECLINED = "OWNER_DECLINED";
60
61
  function exitCodeFor(error) {
61
- return error?.code === AGENT_HOME_ELSEWHERE ? 0 : 1;
62
+ const code = error?.code;
63
+ return code === AGENT_HOME_ELSEWHERE || code === OWNER_DECLINED ? 0 : 1;
62
64
  }
63
65
  __name(exitCodeFor, "exitCodeFor");
64
66
  function stopThenExit(stop, code, exit = process.exit, boundMs = 15e3) {
@@ -615,7 +617,7 @@ async function ensureRegistered(values, driver) {
615
617
  throw new Error(`Nobody has answered the request for ${ask} yet. It stays open: run this command again to keep waiting.`);
616
618
  case "rejected":
617
619
  clearPendingRegistration(profile);
618
- throw new Error(`The owner declined ${ask}. Nothing was saved; run this command again to ask again.`);
620
+ throw Object.assign(new Error(`The owner declined ${ask}. Nothing was saved; run this command again to ask again.`), { code: OWNER_DECLINED });
619
621
  case "credential-expired":
620
622
  clearPendingRegistration(profile);
621
623
  throw new Error(`The owner approved ${ask}, but its key was not collected within 48 hours and Canon removed it. Run this command again to ask again.`);
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  runMlsDevSetup,
27
27
  runtimeDescriptor,
28
28
  startRelayChannel
29
- } from "./chunks/chunk-ZT3TJZAV.js";
29
+ } from "./chunks/chunk-B6AOBWNZ.js";
30
30
  import "./chunks/chunk-BQGXOAIW.js";
31
31
  import {
32
32
  CanonApiError,
@@ -52,7 +52,7 @@ import {
52
52
  toAnthropicImageBlock,
53
53
  toAnthropicImageBlocksWithinBudget,
54
54
  uploadMediaFile
55
- } from "./chunks/chunk-AVR7QCHK.js";
55
+ } from "./chunks/chunk-SS22I6HM.js";
56
56
  import "./chunks/chunk-HFT75BNB.js";
57
57
  import "./chunks/chunk-NIORQKUI.js";
58
58
  import "./chunks/chunk-CUPSYLBV.js";
package/dist/media.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  toAnthropicImageBlock,
19
19
  toAnthropicImageBlocksWithinBudget,
20
20
  uploadMediaFile
21
- } from "./chunks/chunk-AVR7QCHK.js";
21
+ } from "./chunks/chunk-SS22I6HM.js";
22
22
  import "./chunks/chunk-HFT75BNB.js";
23
23
  import "./chunks/chunk-NIORQKUI.js";
24
24
  import "./chunks/chunk-CUPSYLBV.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonmsg/agent-sdk",
3
- "version": "13.3.0",
3
+ "version": "13.3.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",