@agentchatme/openclaw 0.7.81 → 0.7.821

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.
@@ -1515,6 +1515,19 @@ var messageContentSchema = z.object({
1515
1515
  data: z.record(z.string(), z.unknown()).optional(),
1516
1516
  attachment_id: z.string().optional()
1517
1517
  }).passthrough();
1518
+ var messageContextSchema = z.object({
1519
+ sender: z.object({
1520
+ handle: z.string(),
1521
+ display_name: z.string().nullable().optional(),
1522
+ kind: z.enum(["agent", "system"]).optional()
1523
+ }).passthrough().optional(),
1524
+ conversation: z.object({
1525
+ type: z.enum(["direct", "group"]).optional(),
1526
+ group_name: z.string().nullable().optional(),
1527
+ member_count: z.number().int().nullable().optional()
1528
+ }).passthrough().optional(),
1529
+ mentions: z.array(z.string()).optional()
1530
+ }).passthrough();
1518
1531
  var messageSchema = z.object({
1519
1532
  id: z.string(),
1520
1533
  conversation_id: z.string(),
@@ -1524,6 +1537,7 @@ var messageSchema = z.object({
1524
1537
  type: z.enum(["text", "structured", "file", "system"]),
1525
1538
  content: messageContentSchema,
1526
1539
  metadata: z.record(z.string(), z.unknown()).default({}),
1540
+ context: messageContextSchema.optional(),
1527
1541
  // Per-recipient delivery state lives in `message_deliveries` since
1528
1542
  // migration 011 — the `messages` row no longer carries `status`,
1529
1543
  // `delivered_at`, or `read_at`. Fresh-send envelopes over WS omit
@@ -1645,7 +1659,12 @@ function normalizeMessageNew(frame) {
1645
1659
  createdAt: msg.created_at,
1646
1660
  deliveredAt: msg.delivered_at ?? null,
1647
1661
  readAt: msg.read_at ?? null,
1648
- receivedAt: frame.receivedAt
1662
+ receivedAt: frame.receivedAt,
1663
+ senderDisplayName: msg.context?.sender?.display_name ?? null,
1664
+ senderKind: msg.context?.sender?.kind === "system" ? "system" : "agent",
1665
+ groupName: msg.context?.conversation?.group_name ?? null,
1666
+ memberCount: msg.context?.conversation?.member_count ?? null,
1667
+ mentions: (msg.context?.mentions ?? []).map((m) => m.toLowerCase())
1649
1668
  };
1650
1669
  }
1651
1670
  function normalizeMessageRead(frame) {
@@ -1852,7 +1871,7 @@ var CircuitBreaker = class {
1852
1871
  };
1853
1872
 
1854
1873
  // src/version.ts
1855
- var PACKAGE_VERSION = "0.7.81";
1874
+ var PACKAGE_VERSION = "0.7.821";
1856
1875
 
1857
1876
  // src/outbound.ts
1858
1877
  var DEFAULT_RETRY_POLICY = {
@@ -2626,10 +2645,14 @@ function buildDecisionMessages(params) {
2626
2645
  }
2627
2646
  ];
2628
2647
  }
2629
- function buildUserContent(params) {
2630
- const { handle, event, history, signals, maxHistory } = params;
2631
- const kind = event.conversationKind === "group" ? "group" : "direct";
2632
- const lines = [`Conversation type: ${kind}`];
2648
+ function formatReceivedAt(ms) {
2649
+ if (!Number.isFinite(ms)) return "an unknown time";
2650
+ const iso = new Date(ms).toISOString();
2651
+ return `${iso.slice(0, 10)} ${iso.slice(11, 16)} UTC`;
2652
+ }
2653
+ function formatConversationContext(params) {
2654
+ const { handle, event, signals, priorCount } = params;
2655
+ const lines = [`Conversation type: ${formatConversationLabel(event)}`];
2633
2656
  if (signals) {
2634
2657
  lines.push(`Relationship: ${relationshipPhrase(signals)}`);
2635
2658
  if (signals.secondsSincePrevious !== null) {
@@ -2638,13 +2661,28 @@ function buildUserContent(params) {
2638
2661
  );
2639
2662
  }
2640
2663
  }
2641
- lines.push(`Prior messages in this thread: ${history.length}`);
2642
- if (kind === "group") {
2643
- const mentioned = (event.contentText || "").toLowerCase().includes(`@${handle.toLowerCase()}`);
2644
- lines.push(
2645
- `Message directly addresses you: ${mentioned ? "yes" : "not explicitly"}`
2646
- );
2664
+ lines.push(`Prior messages in this thread: ${priorCount}`);
2665
+ if (event.conversationKind === "group" && handle && (event.mentions ?? []).includes(handle.toLowerCase())) {
2666
+ lines.push("You were @-mentioned in this message.");
2667
+ }
2668
+ return lines;
2669
+ }
2670
+ function formatConversationLabel(event) {
2671
+ if (event.conversationKind !== "group") return "direct";
2672
+ let label = event.groupName ? `group "${event.groupName}"` : "group";
2673
+ if (event.memberCount != null) {
2674
+ label += ` (${event.memberCount} member${event.memberCount === 1 ? "" : "s"})`;
2647
2675
  }
2676
+ return label;
2677
+ }
2678
+ function buildUserContent(params) {
2679
+ const { handle, event, history, signals, maxHistory } = params;
2680
+ const lines = formatConversationContext({
2681
+ handle,
2682
+ event,
2683
+ signals,
2684
+ priorCount: history.length
2685
+ });
2648
2686
  lines.push("");
2649
2687
  const rendered = renderHistory(history, maxHistory);
2650
2688
  if (rendered.length > 0) {
@@ -2934,8 +2972,9 @@ async function handleMessage(deps, event) {
2934
2972
  peer,
2935
2973
  runtime
2936
2974
  });
2975
+ let gateContext = null;
2937
2976
  if (gateEnabled()) {
2938
- const decision = await runReplyGate({
2977
+ const { decision, context } = await runReplyGate({
2939
2978
  deps,
2940
2979
  event,
2941
2980
  body,
@@ -2957,17 +2996,40 @@ async function handleMessage(deps, event) {
2957
2996
  "reply gate decision"
2958
2997
  );
2959
2998
  if (!decision.reply) return;
2999
+ gateContext = context;
3000
+ }
3001
+ const contextHeader = [formatSenderLine(event), `Received: ${formatReceivedAt(ts)}`];
3002
+ if (gateContext) {
3003
+ contextHeader.push(...gateContext);
3004
+ } else {
3005
+ contextHeader.push(
3006
+ `Conversation type: ${formatConversationLabel({
3007
+ conversationKind: event.conversationKind,
3008
+ senderHandle,
3009
+ contentText: body,
3010
+ groupName: event.groupName,
3011
+ memberCount: event.memberCount,
3012
+ mentions: event.mentions
3013
+ })}`
3014
+ );
3015
+ const self = (selfHandle ?? "").replace(/^@/, "").toLowerCase();
3016
+ if (event.conversationKind === "group" && self && event.mentions.includes(self)) {
3017
+ contextHeader.push("You were @-mentioned in this message.");
3018
+ }
2960
3019
  }
3020
+ const agentBody = `${contextHeader.join("\n")}
3021
+
3022
+ ${body}`;
2961
3023
  const { storePath, body: envelopeBody } = buildEnvelope({
2962
3024
  channel: "AgentChat",
2963
3025
  from: conversationLabel,
2964
- body,
3026
+ body: agentBody,
2965
3027
  timestamp: ts
2966
3028
  });
2967
3029
  const finalize = channelRuntime.reply.finalizeInboundContext;
2968
3030
  const ctxPayload = finalize({
2969
3031
  Body: envelopeBody,
2970
- BodyForAgent: body,
3032
+ BodyForAgent: agentBody,
2971
3033
  RawBody: body,
2972
3034
  CommandBody: body,
2973
3035
  From: `@${senderHandle}`,
@@ -3034,6 +3096,10 @@ async function handleMessage(deps, event) {
3034
3096
  );
3035
3097
  }
3036
3098
  }
3099
+ function formatSenderLine(event) {
3100
+ const who = event.senderDisplayName ? `${event.senderDisplayName} (@${event.sender})` : `@${event.sender}`;
3101
+ return `From: ${event.senderKind === "system" ? `${who}, a system agent` : who}`;
3102
+ }
3037
3103
  async function runReplyGate(params) {
3038
3104
  const { deps, event, body, agentId, selfHandle, senderHandle, nowMs } = params;
3039
3105
  const ownHandle = selfHandle ?? "";
@@ -3048,17 +3114,22 @@ async function runReplyGate(params) {
3048
3114
  "reply gate: history fetch failed \u2014 deciding on the new message alone"
3049
3115
  );
3050
3116
  }
3117
+ const bareHandle = ownHandle.replace(/^@/, "");
3051
3118
  const gateEvent = {
3052
3119
  conversationKind: event.conversationKind,
3053
3120
  senderHandle,
3054
- contentText: body
3121
+ contentText: body,
3122
+ groupName: event.groupName,
3123
+ memberCount: event.memberCount,
3124
+ mentions: event.mentions
3055
3125
  };
3056
- return decideReply({
3126
+ const history = translateHistory(rawMessages, ownHandle, event.conversationKind, event.messageId);
3127
+ const decision = await decideReply({
3057
3128
  cfg: deps.gatewayCfg,
3058
3129
  agentId,
3059
- handle: ownHandle.replace(/^@/, ""),
3130
+ handle: bareHandle,
3060
3131
  event: gateEvent,
3061
- history: translateHistory(rawMessages, ownHandle, event.conversationKind, event.messageId),
3132
+ history,
3062
3133
  rawMessages,
3063
3134
  triggerMessageId: event.messageId,
3064
3135
  ownHandle,
@@ -3067,6 +3138,18 @@ async function runReplyGate(params) {
3067
3138
  timeoutMs: gateTimeoutMs(),
3068
3139
  caller: deps.gateCaller
3069
3140
  });
3141
+ const signals = computeConversationSignals(rawMessages, {
3142
+ ownHandle,
3143
+ triggerMessageId: event.messageId,
3144
+ nowMs
3145
+ });
3146
+ const context = formatConversationContext({
3147
+ handle: bareHandle,
3148
+ event: gateEvent,
3149
+ signals,
3150
+ priorCount: history.length
3151
+ });
3152
+ return { decision, context };
3070
3153
  }
3071
3154
  function translateHistory(messages, ownHandle, conversationKind, triggerMessageId) {
3072
3155
  const own = ownHandle.replace(/^@/, "").toLowerCase();
@@ -4767,75 +4850,77 @@ function profileToEntry(agent) {
4767
4850
  ...agent.avatar_url ? { avatarUrl: agent.avatar_url } : {}
4768
4851
  };
4769
4852
  }
4770
- var agentchatDirectoryAdapter = {
4771
- async self({ cfg, accountId }) {
4772
- const config = resolveAccount(cfg, accountId);
4773
- if (!config) return null;
4774
- const client = getClient({ accountId: accountId ?? "default", config });
4775
- try {
4776
- const me = await client.getMe();
4777
- return profileToEntry(me);
4778
- } catch {
4779
- return null;
4780
- }
4781
- },
4782
- async listPeers({ cfg, accountId, query, limit }) {
4783
- const config = resolveAccount(cfg, accountId);
4784
- if (!config) return [];
4785
- const q = (query ?? "").trim();
4786
- if (q.length < 2) return [];
4787
- const client = getClient({ accountId: accountId ?? "default", config });
4788
- try {
4789
- const result = await client.searchAgents(q, { limit: limit ?? 20 });
4790
- return result.agents.map(profileToEntry);
4791
- } catch {
4792
- return [];
4793
- }
4794
- },
4795
- async listPeersLive(params) {
4796
- return this.listPeers(params);
4797
- },
4798
- async listGroups({ cfg, accountId, query, limit }) {
4799
- const config = resolveAccount(cfg, accountId);
4800
- if (!config) return [];
4801
- const client = getClient({ accountId: accountId ?? "default", config });
4802
- try {
4803
- const convs = await client.listConversations();
4804
- const q = (query ?? "").trim().toLowerCase();
4805
- const groupRows = convs.filter((c) => c.type === "group");
4806
- const filtered = q ? groupRows.filter((c) => (c.group_name ?? "").toLowerCase().includes(q)) : groupRows;
4807
- const cap = limit ?? 50;
4808
- return filtered.slice(0, cap).map((c) => ({
4809
- kind: "group",
4810
- id: c.id,
4811
- name: c.group_name ?? "Untitled group",
4812
- ...c.group_avatar_url ? { avatarUrl: c.group_avatar_url } : {}
4813
- }));
4814
- } catch {
4815
- return [];
4816
- }
4817
- },
4818
- async listGroupsLive(params) {
4819
- return this.listGroups(params);
4820
- },
4821
- async listGroupMembers({ cfg, accountId, groupId, limit }) {
4822
- const config = resolveAccount(cfg, accountId);
4823
- if (!config) return [];
4824
- const client = getClient({ accountId: accountId ?? "default", config });
4825
- try {
4826
- const group = await client.getGroup(groupId);
4827
- const cap = limit ?? 256;
4828
- return group.members.slice(0, cap).map((m) => ({
4829
- kind: "user",
4830
- id: m.handle,
4831
- handle: m.handle,
4832
- name: m.display_name ?? m.handle
4833
- }));
4834
- } catch {
4835
- return [];
4836
- }
4853
+ var directorySelf = async ({ cfg, accountId }) => {
4854
+ const config = resolveAccount(cfg, accountId);
4855
+ if (!config) return null;
4856
+ const client = getClient({ accountId: accountId ?? "default", config });
4857
+ try {
4858
+ const me = await client.getMe();
4859
+ return profileToEntry(me);
4860
+ } catch {
4861
+ return null;
4837
4862
  }
4838
4863
  };
4864
+ var listPeers = async ({ cfg, accountId, query, limit }) => {
4865
+ const config = resolveAccount(cfg, accountId);
4866
+ if (!config) return [];
4867
+ const q = (query ?? "").trim();
4868
+ if (q.length < 2) return [];
4869
+ const client = getClient({ accountId: accountId ?? "default", config });
4870
+ try {
4871
+ const result = await client.searchAgents(q, { limit: limit ?? 20 });
4872
+ return result.agents.map(profileToEntry);
4873
+ } catch {
4874
+ return [];
4875
+ }
4876
+ };
4877
+ var listGroups = async ({ cfg, accountId, query, limit }) => {
4878
+ const config = resolveAccount(cfg, accountId);
4879
+ if (!config) return [];
4880
+ const client = getClient({ accountId: accountId ?? "default", config });
4881
+ try {
4882
+ const convs = await client.listConversations();
4883
+ const q = (query ?? "").trim().toLowerCase();
4884
+ const groupRows = convs.filter((c) => c.type === "group");
4885
+ const filtered = q ? groupRows.filter((c) => (c.group_name ?? "").toLowerCase().includes(q)) : groupRows;
4886
+ const cap = limit ?? 50;
4887
+ return filtered.slice(0, cap).map((c) => ({
4888
+ kind: "group",
4889
+ id: c.id,
4890
+ name: c.group_name ?? "Untitled group",
4891
+ ...c.group_avatar_url ? { avatarUrl: c.group_avatar_url } : {}
4892
+ }));
4893
+ } catch {
4894
+ return [];
4895
+ }
4896
+ };
4897
+ var listGroupMembers = async ({ cfg, accountId, groupId, limit }) => {
4898
+ const config = resolveAccount(cfg, accountId);
4899
+ if (!config) return [];
4900
+ const client = getClient({ accountId: accountId ?? "default", config });
4901
+ try {
4902
+ const group = await client.getGroup(groupId);
4903
+ const cap = limit ?? 256;
4904
+ return group.members.slice(0, cap).map((m) => ({
4905
+ kind: "user",
4906
+ id: m.handle,
4907
+ handle: m.handle,
4908
+ name: m.display_name ?? m.handle
4909
+ }));
4910
+ } catch {
4911
+ return [];
4912
+ }
4913
+ };
4914
+ var agentchatDirectoryAdapter = {
4915
+ self: directorySelf,
4916
+ listPeers,
4917
+ // `*Live` are literal aliases of the base impls — never `this.listPeers!`,
4918
+ // which breaks when the runtime forwards the method detached.
4919
+ listPeersLive: listPeers,
4920
+ listGroups,
4921
+ listGroupsLive: listGroups,
4922
+ listGroupMembers
4923
+ };
4839
4924
 
4840
4925
  // src/binding/resolver.ts
4841
4926
  function resolveAccount2(cfg, accountId) {