@ouro.bot/cli 0.1.0-alpha.519 → 0.1.0-alpha.520

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.
@@ -416,6 +416,7 @@ exports.sessionToolDefinitions = [
416
416
  messageCount: count,
417
417
  trustLevel: ctx?.context?.friend?.trustLevel,
418
418
  summarize: ctx?.summarize,
419
+ archiveFallback: true,
419
420
  });
420
421
  if (sessionTail.kind === "missing") {
421
422
  return NO_SESSION_FOUND_MESSAGE;
@@ -51,13 +51,17 @@ const runtime_1 = require("../../nerves/runtime");
51
51
  message: "booting BlueBubbles entrypoint",
52
52
  meta: { entry: "bluebubbles", agentName },
53
53
  });
54
- Promise.resolve().then(() => __importStar(require("../../heart/runtime-credentials"))).then(async ({ refreshMachineRuntimeCredentialConfig, refreshRuntimeCredentialConfig }) => {
55
- await refreshRuntimeCredentialConfig(agentName, { preserveCachedOnFailure: true }).catch(() => undefined);
54
+ Promise.resolve().then(() => __importStar(require("../../heart/runtime-credentials"))).then(async ({ readMachineRuntimeCredentialConfig, refreshMachineRuntimeCredentialConfig, refreshRuntimeCredentialConfig, waitForRuntimeCredentialBootstrap, }) => {
55
+ await waitForRuntimeCredentialBootstrap(agentName);
56
56
  const { loadOrCreateMachineIdentity } = await Promise.resolve().then(() => __importStar(require("../../heart/machine-identity")));
57
57
  const machine = loadOrCreateMachineIdentity();
58
- await refreshMachineRuntimeCredentialConfig(agentName, machine.machineId, { preserveCachedOnFailure: true }).catch(() => undefined);
58
+ const machineConfig = readMachineRuntimeCredentialConfig(agentName);
59
+ if (!machineConfig.ok) {
60
+ await refreshMachineRuntimeCredentialConfig(agentName, machine.machineId, { preserveCachedOnFailure: true }).catch(() => undefined);
61
+ }
59
62
  const { startBlueBubblesApp } = await Promise.resolve().then(() => __importStar(require("./index")));
60
63
  await startBlueBubblesApp();
64
+ void refreshRuntimeCredentialConfig(agentName, { preserveCachedOnFailure: true }).catch(() => undefined);
61
65
  })
62
66
  .catch((error) => {
63
67
  (0, runtime_1.emitNervesEvent)({
@@ -668,12 +668,11 @@ function isAgentSelfHandle(senderExternalId, ownHandles) {
668
668
  return false;
669
669
  }
670
670
  /**
671
- * In-memory store of agent iMessage handles auto-discovered from
672
- * `event.fromMe === true` events. Bluebubbles attributes the agent's
673
- * canonical handle as `event.sender.externalId` on outbound messages
674
- * capturing it here makes the next `isFromMe`-missing group echo
675
- * (the bug that motivated `bluebubbles.ownHandles` originally) recoverable
676
- * even before the operator has populated the config.
671
+ * In-memory store of agent iMessage handles auto-discovered from group-chat
672
+ * `event.fromMe === true` events. Bluebubbles can attribute the peer's handle
673
+ * as `event.sender.externalId` on 1:1 outbound messages, so discovery is
674
+ * intentionally limited to the group echo bug that motivated
675
+ * `bluebubbles.ownHandles` originally.
677
676
  *
678
677
  * Per-process. A daemon restart re-learns from the next outbound. The
679
678
  * accompanying nerves event (`senses.bluebubbles_own_handle_discovered`)
@@ -709,6 +708,40 @@ function recordDiscoveredOwnHandle(senderExternalId) {
709
708
  });
710
709
  return true;
711
710
  }
711
+ function isSelfFriendRecord(friend, agentName) {
712
+ if (!friend || friend.kind !== "agent")
713
+ return false;
714
+ const normalizedAgent = agentName.trim().toLowerCase();
715
+ const name = friend.name?.trim().toLowerCase();
716
+ const bundleName = friend.agentMeta?.bundleName?.trim().toLowerCase();
717
+ return name === normalizedAgent || bundleName === normalizedAgent;
718
+ }
719
+ async function shouldFilterAgentSelfHandle(event, resolvedDeps) {
720
+ if (!event.chat.isGroup)
721
+ return false;
722
+ if (!isAgentSelfHandle(event.sender.externalId, resolvedDeps.getOwnHandles()))
723
+ return false;
724
+ const store = resolvedDeps.createFriendStore();
725
+ const knownFriend = await store
726
+ .findByExternalId("imessage-handle", event.sender.externalId)
727
+ .catch(() => null);
728
+ if (knownFriend && !isSelfFriendRecord(knownFriend, resolvedDeps.getAgentName())) {
729
+ (0, runtime_1.emitNervesEvent)({
730
+ level: "warn",
731
+ component: "senses",
732
+ event: "senses.bluebubbles_self_handle_bypassed_known_friend",
733
+ message: "did not filter bluebubbles sender even though it matched ownHandles because it resolves to a known non-self friend",
734
+ meta: {
735
+ messageGuid: event.messageGuid,
736
+ kind: event.kind,
737
+ senderExternalId: event.sender.externalId,
738
+ friendId: knownFriend.id,
739
+ },
740
+ });
741
+ return false;
742
+ }
743
+ return true;
744
+ }
712
745
  async function handleBlueBubblesNormalizedEvent(event, resolvedDeps, source) {
713
746
  const client = resolvedDeps.createClient();
714
747
  const agentName = resolvedDeps.getAgentName();
@@ -722,15 +755,18 @@ async function handleBlueBubblesNormalizedEvent(event, resolvedDeps, source) {
722
755
  kind: event.kind,
723
756
  },
724
757
  });
725
- recordDiscoveredOwnHandle(event.sender.externalId);
758
+ if (event.chat.isGroup)
759
+ recordDiscoveredOwnHandle(event.sender.externalId);
726
760
  return { handled: true, notifiedAgent: false, kind: event.kind, reason: "from_me" };
727
761
  }
728
762
  // Fallback self-detection: BlueBubbles sometimes broadcasts a group-chat
729
763
  // outbound message back through the webhook with `isFromMe` missing/false.
730
764
  // Without this guard the agent ingests its own message and replies to it
731
765
  // ("Slugger talking to himself"). Compare the sender's externalId against
732
- // the agent's known iMessage handles.
733
- if (isAgentSelfHandle(event.sender.externalId, resolvedDeps.getOwnHandles())) {
766
+ // the agent's known iMessage handles. Keep this group-only: 1:1 outbound
767
+ // echoes can be attributed to the peer handle, and stale ownHandles entries
768
+ // must not make real DMs disappear.
769
+ if (await shouldFilterAgentSelfHandle(event, resolvedDeps)) {
734
770
  (0, runtime_1.emitNervesEvent)({
735
771
  level: "warn",
736
772
  component: "senses",
@@ -49,7 +49,7 @@ if (!agentName) {
49
49
  meta: { entry: "cli", agentName },
50
50
  });
51
51
  Promise.resolve().then(() => __importStar(require("../heart/runtime-credentials"))).then(async ({ refreshRuntimeCredentialConfig }) => {
52
- await refreshRuntimeCredentialConfig(agentName, { preserveCachedOnFailure: true }).catch(() => undefined);
52
+ void refreshRuntimeCredentialConfig(agentName, { preserveCachedOnFailure: true }).catch(() => undefined);
53
53
  const { main } = await Promise.resolve().then(() => __importStar(require("./cli")));
54
54
  main();
55
55
  })
@@ -49,7 +49,7 @@ if (!agentName) {
49
49
  meta: { entry: "teams", agentName },
50
50
  });
51
51
  Promise.resolve().then(() => __importStar(require("../heart/runtime-credentials"))).then(async ({ refreshRuntimeCredentialConfig }) => {
52
- await refreshRuntimeCredentialConfig(agentName, { preserveCachedOnFailure: true }).catch(() => undefined);
52
+ void refreshRuntimeCredentialConfig(agentName, { preserveCachedOnFailure: true }).catch(() => undefined);
53
53
  const { startTeamsApp } = await Promise.resolve().then(() => __importStar(require("./teams")));
54
54
  startTeamsApp();
55
55
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.519",
3
+ "version": "0.1.0-alpha.520",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",