zooid 0.14.0 → 0.15.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/bin.js CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  MediaClient,
6
6
  SpawnRegistry,
7
7
  buildAcpRegistry,
8
+ buildMentionContent,
8
9
  contextEligibleAgents,
9
10
  createMatrixTransport,
10
11
  ensureDefaultChannel,
@@ -19,7 +20,7 @@ import {
19
20
  renderTemplate,
20
21
  startAgentSocketServers,
21
22
  startWorkforcePublisher
22
- } from "./chunk-R5S26T7B.js";
23
+ } from "./chunk-35IKQPC5.js";
23
24
 
24
25
  // src/bin.ts
25
26
  import { resolve as resolve8 } from "path";
@@ -697,9 +698,15 @@ function shouldBindHttpListener(mode) {
697
698
  import { Cron } from "croner";
698
699
 
699
700
  // src/daemon/trigger-runner.ts
701
+ var warnedTargets = /* @__PURE__ */ new Set();
700
702
  async function fireTrigger(deps) {
701
- const { name, as, message, agentUserId, resolveRoom, ensureBot, sendMessage } = deps;
703
+ const { name, as, message, agentUserIds, resolveRoom, ensureBot, sendMessage, getJoinedMembers } = deps;
702
704
  try {
705
+ const target = message.mention.startsWith("@") ? message.mention : agentUserIds[message.mention];
706
+ if (!target) {
707
+ console.warn(`[trigger:${name}] unknown agent "${message.mention}" \u2014 skipping`);
708
+ return;
709
+ }
703
710
  const roomId = await resolveRoom(message.room);
704
711
  if (!roomId) {
705
712
  console.warn(`[trigger:${name}] cannot resolve room ${message.room} \u2014 skipping`);
@@ -710,13 +717,24 @@ async function fireTrigger(deps) {
710
717
  roomId,
711
718
  asUserId: as,
712
719
  content: {
713
- msgtype: "m.text",
714
- body: message.text,
715
- // Structural mention: routes deterministically AND disarms the raw-body
716
- // fallback in extractMentions, which only fires when nothing matched.
717
- "m.mentions": { user_ids: [agentUserId] }
720
+ ...buildMentionContent({ userId: target, text: message.text, msgtype: "m.text" }),
721
+ "dev.zooid.trigger": {
722
+ name,
723
+ fired_at: Date.now(),
724
+ ...message.ttlMs !== void 0 ? { ttl_ms: message.ttlMs } : {}
725
+ }
718
726
  }
719
727
  });
728
+ if (getJoinedMembers) {
729
+ const { joined } = await getJoinedMembers(roomId, as);
730
+ const key = `${name}|${target}`;
731
+ if (!(target in joined) && !warnedTargets.has(key)) {
732
+ warnedTargets.add(key);
733
+ console.warn(
734
+ `[trigger:${name}] ${target} is not in ${message.room} \u2014 nothing will handle this unless that agent joins before the message expires`
735
+ );
736
+ }
737
+ }
720
738
  } catch (err) {
721
739
  console.warn(`[trigger:${name}] failed:`, err.message);
722
740
  }
@@ -731,18 +749,22 @@ function validateCron(name, expr) {
731
749
  }
732
750
  }
733
751
  function startTriggerScheduler(deps) {
734
- const { triggers, agentUserIds, resolveRoom, ensureBot, sendMessage } = deps;
752
+ const { triggers, agentUserIds, resolveRoom, ensureBot, sendMessage, getJoinedMembers } = deps;
735
753
  const jobs = [];
736
754
  for (const [name, trigger] of Object.entries(triggers)) {
737
755
  if (!trigger.schedule) continue;
738
756
  const job = new Cron(trigger.schedule, () => {
739
757
  for (const message of trigger.messages) {
740
- const agentUserId = agentUserIds[message.mention];
741
- if (!agentUserId) {
742
- console.warn(`[trigger:${name}] unknown agent "${message.mention}" \u2014 skipping`);
743
- continue;
744
- }
745
- void fireTrigger({ name, as: trigger.as, message, agentUserId, resolveRoom, ensureBot, sendMessage });
758
+ void fireTrigger({
759
+ name,
760
+ as: trigger.as,
761
+ message,
762
+ agentUserIds,
763
+ resolveRoom,
764
+ ensureBot,
765
+ sendMessage,
766
+ getJoinedMembers
767
+ });
746
768
  }
747
769
  });
748
770
  jobs.push(job);
@@ -871,9 +893,25 @@ var MAX_BODY2 = 1e6;
871
893
  var MAX_OUTPUT_CHARS = 6e4;
872
894
  var TRUNCATION_MARKER = "\n\n\u2026 (truncated)";
873
895
  var DELIVERY_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
874
- var EVENT_HEADER_BY_PROVIDER = {
875
- github: "x-github-event"
896
+ var EVENT_SOURCE_BY_PROVIDER = {
897
+ github: { header: "x-github-event" },
898
+ stripe: { path: ["type"] },
899
+ standard: { path: ["type"] },
900
+ slack: { path: ["event", "type"] }
876
901
  };
902
+ function stringAt(body, path) {
903
+ let cursor = body;
904
+ for (const key of path) {
905
+ if (typeof cursor !== "object" || cursor === null) return void 0;
906
+ cursor = cursor[key];
907
+ }
908
+ return typeof cursor === "string" ? cursor : void 0;
909
+ }
910
+ function eventNameFor(provider, headers, body) {
911
+ const source = EVENT_SOURCE_BY_PROVIDER[provider];
912
+ if (!source) return void 0;
913
+ return "header" in source ? headers[source.header] : stringAt(body, source.path);
914
+ }
877
915
  var DELIVERY_ID_HEADER_BY_PROVIDER = {
878
916
  github: "x-github-delivery",
879
917
  standard: "webhook-id"
@@ -924,14 +962,13 @@ async function handleDelivery(deps, name, trigger, raw, headers, cache, customDe
924
962
  const idHeader = DELIVERY_ID_HEADER_BY_PROVIDER[webhook.provider];
925
963
  const deliveryId = customDeliveryId ?? (idHeader ? headers[idHeader] : void 0);
926
964
  if (deliveryId !== void 0 && cache.seen(`${name}:${deliveryId}`)) return;
927
- const eventHeader = EVENT_HEADER_BY_PROVIDER[webhook.provider];
928
- const event = eventHeader ? headers[eventHeader] : void 0;
929
965
  let body;
930
966
  try {
931
967
  body = JSON.parse(raw);
932
968
  } catch {
933
969
  body = void 0;
934
970
  }
971
+ const event = eventNameFor(webhook.provider, headers, body);
935
972
  const ctx = {
936
973
  event,
937
974
  body,
@@ -940,19 +977,15 @@ async function handleDelivery(deps, name, trigger, raw, headers, cache, customDe
940
977
  };
941
978
  for (const message of trigger.messages) {
942
979
  if (message.match !== void 0 && !evaluateMatch(message.match, ctx)) continue;
943
- const agentUserId = deps.agentUserIds[message.mention];
944
- if (!agentUserId) {
945
- console.warn(`[webhook:${name}] unknown agent "${message.mention}" \u2014 skipping`);
946
- continue;
947
- }
948
980
  await fireTrigger({
949
981
  name,
950
982
  as: trigger.as,
951
983
  message: { ...message, text: renderTemplate(message.text, ctx) },
952
- agentUserId,
984
+ agentUserIds: deps.agentUserIds,
953
985
  resolveRoom: deps.resolveRoom,
954
986
  ensureBot: deps.ensureBot,
955
- sendMessage: deps.sendMessage
987
+ sendMessage: deps.sendMessage,
988
+ getJoinedMembers: deps.getJoinedMembers
956
989
  });
957
990
  }
958
991
  } catch (err) {
@@ -1222,7 +1255,8 @@ async function startDaemon(opts = {}) {
1222
1255
  agentUserIds,
1223
1256
  resolveRoom,
1224
1257
  ensureBot,
1225
- sendMessage: (m) => client.sendMessage(m)
1258
+ sendMessage: (m) => client.sendMessage(m),
1259
+ getJoinedMembers: (roomId, asUserId2) => client.getJoinedMembers(roomId, asUserId2)
1226
1260
  });
1227
1261
  for (const [name] of webhookTriggers) {
1228
1262
  console.log(`[webhook] POST ${WEBHOOK_ROUTE_PREFIX}/${name}`);
@@ -1266,7 +1300,8 @@ async function startDaemon(opts = {}) {
1266
1300
  agentUserIds,
1267
1301
  resolveRoom,
1268
1302
  ensureBot,
1269
- sendMessage: (m) => client.sendMessage(m)
1303
+ sendMessage: (m) => client.sendMessage(m),
1304
+ getJoinedMembers: (roomId, asUserId2) => client.getJoinedMembers(roomId, asUserId2)
1270
1305
  });
1271
1306
  const scheduled = Object.values(config.triggers).filter((t) => t.schedule).length;
1272
1307
  if (scheduled > 0) console.log(`[trigger] scheduled ${scheduled} trigger(s)`);
@@ -1302,7 +1337,8 @@ async function startDaemon(opts = {}) {
1302
1337
  client,
1303
1338
  spaceRoomId,
1304
1339
  asUserId,
1305
- getAgents: () => bindings
1340
+ getAgents: () => bindings,
1341
+ stateKey: matrix.transport.workstation ?? ""
1306
1342
  });
1307
1343
  console.log(`[matrix] published dev.zooid.workforce (${bindings.length} agents)`);
1308
1344
  void publisher;