@zooid/transport-matrix 0.9.1 → 0.11.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.ts CHANGED
@@ -263,6 +263,14 @@ interface ThreadState {
263
263
  participants: string[];
264
264
  /** Agent names @mentioned in the thread root event (or subsequently). */
265
265
  rootMentions: string[];
266
+ /**
267
+ * Agent-to-agent call edges: sub-agent name → the agent that @mentioned
268
+ * (called) it in this thread. A sub's bare reply bubbles up to its caller;
269
+ * a caller never implicitly re-triggers its callee. Makes agent↔agent
270
+ * acknowledgement loops structurally impossible. See [[ZOD039]] §
271
+ * Implicit triggers → Directional continuation.
272
+ */
273
+ callers: Record<string, string>;
266
274
  }
267
275
  interface MaybeEvent {
268
276
  type?: string;
package/dist/index.js CHANGED
@@ -53,7 +53,9 @@ var MatrixClient = class {
53
53
  ];
54
54
  }
55
55
  if (opts.userPowerLevels && Object.keys(opts.userPowerLevels).length > 0) {
56
- body.power_level_content_override = { users: opts.userPowerLevels };
56
+ const users = { ...opts.userPowerLevels };
57
+ if (users[opts.senderUserId] === void 0) users[opts.senderUserId] = 100;
58
+ body.power_level_content_override = { users };
57
59
  }
58
60
  const r = await this.fetch(
59
61
  `${this.homeserver}/_matrix/client/v3/createRoom?user_id=${encodeURIComponent(opts.senderUserId)}`,
@@ -532,11 +534,16 @@ function route(event, agents, threadStates) {
532
534
  continue;
533
535
  }
534
536
  if (threadState) {
535
- const lastPoster = threadState.participants.at(-1);
536
- if (lastPoster) {
537
- if (lastPoster === a.name) matches.push(a);
538
- } else if (threadState.rootMentions.includes(a.name)) {
539
- matches.push(a);
537
+ const senderAgent = agents.find((x) => x.userId === event.sender);
538
+ if (senderAgent) {
539
+ if (threadState.callers[senderAgent.name] === a.name) matches.push(a);
540
+ } else {
541
+ const lastPoster = threadState.participants.at(-1);
542
+ if (lastPoster) {
543
+ if (lastPoster === a.name) matches.push(a);
544
+ } else if (threadState.rootMentions.includes(a.name)) {
545
+ matches.push(a);
546
+ }
540
547
  }
541
548
  }
542
549
  }
@@ -664,14 +671,20 @@ var BotPool = class {
664
671
  this.agents,
665
672
  room
666
673
  );
667
- resolved = await this.client.createRoom({
668
- roomAliasName: aliasLocalpart,
669
- invite: opts.adminUserId ? [opts.adminUserId] : [],
670
- senderUserId: sender,
671
- name: aliasLocalpart,
672
- ...opts.spaceRoomId ? { restrictedToSpaceId: opts.spaceRoomId } : {},
673
- ...userPowerLevels ? { userPowerLevels } : {}
674
- });
674
+ try {
675
+ resolved = await this.client.createRoom({
676
+ roomAliasName: aliasLocalpart,
677
+ invite: opts.adminUserId ? [opts.adminUserId] : [],
678
+ senderUserId: sender,
679
+ name: aliasLocalpart,
680
+ ...opts.spaceRoomId ? { restrictedToSpaceId: opts.spaceRoomId } : {},
681
+ ...userPowerLevels ? { userPowerLevels } : {}
682
+ });
683
+ } catch (err) {
684
+ const raced = await this.client.resolveAlias(room);
685
+ if (!raced) throw err;
686
+ resolved = raced;
687
+ }
675
688
  }
676
689
  aliasToId.set(room, resolved);
677
690
  }
@@ -1389,14 +1402,15 @@ function createMatrixTransport(opts) {
1389
1402
  if (matches.length > 0 && promotedRoot) {
1390
1403
  let st = threadStates.get(promotedRoot);
1391
1404
  if (!st) {
1392
- st = { participants: [], rootMentions: [] };
1405
+ st = { participants: [], rootMentions: [], callers: {} };
1393
1406
  threadStates.set(promotedRoot, st);
1394
1407
  }
1395
1408
  const msgMentions = new Set(extractMentions(evt));
1409
+ const senderAgent = bindings.find((b) => b.userId === evt.sender);
1396
1410
  for (const a of bindings) {
1397
- if (msgMentions.has(a.userId) && !st.rootMentions.includes(a.name)) {
1398
- st.rootMentions.push(a.name);
1399
- }
1411
+ if (!msgMentions.has(a.userId)) continue;
1412
+ if (!st.rootMentions.includes(a.name)) st.rootMentions.push(a.name);
1413
+ if (senderAgent && a.name !== senderAgent.name) st.callers[a.name] = senderAgent.name;
1400
1414
  }
1401
1415
  }
1402
1416
  for (const a of matches) {
@@ -1405,7 +1419,7 @@ function createMatrixTransport(opts) {
1405
1419
  if (!promotedRoot) return;
1406
1420
  let st = threadStates.get(promotedRoot);
1407
1421
  if (!st) {
1408
- st = { participants: [], rootMentions: [] };
1422
+ st = { participants: [], rootMentions: [], callers: {} };
1409
1423
  threadStates.set(promotedRoot, st);
1410
1424
  }
1411
1425
  if (st.participants.at(-1) !== a.name) st.participants.push(a.name);
@@ -1581,16 +1595,18 @@ function createMatrixTransport(opts) {
1581
1595
  };
1582
1596
  }
1583
1597
  async function rebuildThreadState(client, roomId, rootEventId, bindings) {
1584
- const state = { participants: [], rootMentions: [] };
1598
+ const state = { participants: [], rootMentions: [], callers: {} };
1585
1599
  const asUser = (bindings.find((b) => b.rooms.some((r) => r.alias === roomId)) ?? bindings[0])?.userId;
1586
1600
  if (!asUser) return state;
1587
1601
  const root = await client.fetchEvent(roomId, rootEventId, asUser);
1588
1602
  if (root) {
1589
1603
  const rootMentions = new Set(extractMentions(root));
1604
+ const rootSender = root.sender;
1605
+ const rootSenderAgent = rootSender ? bindings.find((b) => b.userId === rootSender) : void 0;
1590
1606
  for (const a of bindings) {
1591
- if (rootMentions.has(a.userId) && !state.rootMentions.includes(a.name)) {
1592
- state.rootMentions.push(a.name);
1593
- }
1607
+ if (!rootMentions.has(a.userId)) continue;
1608
+ if (!state.rootMentions.includes(a.name)) state.rootMentions.push(a.name);
1609
+ if (rootSenderAgent && a.name !== rootSenderAgent.name) state.callers[a.name] = rootSenderAgent.name;
1594
1610
  }
1595
1611
  }
1596
1612
  const { chunk: thread } = await client.fetchThreadRelations({
@@ -1600,15 +1616,16 @@ async function rebuildThreadState(client, roomId, rootEventId, bindings) {
1600
1616
  });
1601
1617
  for (const ev of thread) {
1602
1618
  const mentions = new Set(extractMentions(ev));
1619
+ const evSender = ev.sender;
1620
+ const evSenderAgent = evSender ? bindings.find((b) => b.userId === evSender) : void 0;
1603
1621
  for (const a of bindings) {
1604
- if (mentions.has(a.userId) && !state.rootMentions.includes(a.name)) {
1605
- state.rootMentions.push(a.name);
1606
- }
1622
+ if (!mentions.has(a.userId)) continue;
1623
+ if (!state.rootMentions.includes(a.name)) state.rootMentions.push(a.name);
1624
+ if (evSenderAgent && a.name !== evSenderAgent.name) state.callers[a.name] = evSenderAgent.name;
1607
1625
  }
1608
- const sender = ev.sender;
1609
1626
  const type = ev.type;
1610
- if (type === "m.room.message" && sender) {
1611
- const a = bindings.find((b) => b.userId === sender);
1627
+ if (type === "m.room.message" && evSender) {
1628
+ const a = bindings.find((b) => b.userId === evSender);
1612
1629
  if (a && state.participants.at(-1) !== a.name) state.participants.push(a.name);
1613
1630
  }
1614
1631
  }