@agentchatme/openclaw 0.7.81 → 0.7.82

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.
@@ -1542,6 +1542,19 @@ var messageContentSchema = zod.z.object({
1542
1542
  data: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
1543
1543
  attachment_id: zod.z.string().optional()
1544
1544
  }).passthrough();
1545
+ var messageContextSchema = zod.z.object({
1546
+ sender: zod.z.object({
1547
+ handle: zod.z.string(),
1548
+ display_name: zod.z.string().nullable().optional(),
1549
+ kind: zod.z.enum(["agent", "system"]).optional()
1550
+ }).passthrough().optional(),
1551
+ conversation: zod.z.object({
1552
+ type: zod.z.enum(["direct", "group"]).optional(),
1553
+ group_name: zod.z.string().nullable().optional(),
1554
+ member_count: zod.z.number().int().nullable().optional()
1555
+ }).passthrough().optional(),
1556
+ mentions: zod.z.array(zod.z.string()).optional()
1557
+ }).passthrough();
1545
1558
  var messageSchema = zod.z.object({
1546
1559
  id: zod.z.string(),
1547
1560
  conversation_id: zod.z.string(),
@@ -1551,6 +1564,7 @@ var messageSchema = zod.z.object({
1551
1564
  type: zod.z.enum(["text", "structured", "file", "system"]),
1552
1565
  content: messageContentSchema,
1553
1566
  metadata: zod.z.record(zod.z.string(), zod.z.unknown()).default({}),
1567
+ context: messageContextSchema.optional(),
1554
1568
  // Per-recipient delivery state lives in `message_deliveries` since
1555
1569
  // migration 011 — the `messages` row no longer carries `status`,
1556
1570
  // `delivered_at`, or `read_at`. Fresh-send envelopes over WS omit
@@ -1672,7 +1686,12 @@ function normalizeMessageNew(frame) {
1672
1686
  createdAt: msg.created_at,
1673
1687
  deliveredAt: msg.delivered_at ?? null,
1674
1688
  readAt: msg.read_at ?? null,
1675
- receivedAt: frame.receivedAt
1689
+ receivedAt: frame.receivedAt,
1690
+ senderDisplayName: msg.context?.sender?.display_name ?? null,
1691
+ senderKind: msg.context?.sender?.kind === "system" ? "system" : "agent",
1692
+ groupName: msg.context?.conversation?.group_name ?? null,
1693
+ memberCount: msg.context?.conversation?.member_count ?? null,
1694
+ mentions: (msg.context?.mentions ?? []).map((m) => m.toLowerCase())
1676
1695
  };
1677
1696
  }
1678
1697
  function normalizeMessageRead(frame) {
@@ -1879,7 +1898,7 @@ var CircuitBreaker = class {
1879
1898
  };
1880
1899
 
1881
1900
  // src/version.ts
1882
- var PACKAGE_VERSION = "0.7.81";
1901
+ var PACKAGE_VERSION = "0.7.82";
1883
1902
 
1884
1903
  // src/outbound.ts
1885
1904
  var DEFAULT_RETRY_POLICY = {
@@ -2653,10 +2672,14 @@ function buildDecisionMessages(params) {
2653
2672
  }
2654
2673
  ];
2655
2674
  }
2656
- function buildUserContent(params) {
2657
- const { handle, event, history, signals, maxHistory } = params;
2658
- const kind = event.conversationKind === "group" ? "group" : "direct";
2659
- const lines = [`Conversation type: ${kind}`];
2675
+ function formatReceivedAt(ms) {
2676
+ if (!Number.isFinite(ms)) return "an unknown time";
2677
+ const iso = new Date(ms).toISOString();
2678
+ return `${iso.slice(0, 10)} ${iso.slice(11, 16)} UTC`;
2679
+ }
2680
+ function formatConversationContext(params) {
2681
+ const { handle, event, signals, priorCount } = params;
2682
+ const lines = [`Conversation type: ${formatConversationLabel(event)}`];
2660
2683
  if (signals) {
2661
2684
  lines.push(`Relationship: ${relationshipPhrase(signals)}`);
2662
2685
  if (signals.secondsSincePrevious !== null) {
@@ -2665,13 +2688,28 @@ function buildUserContent(params) {
2665
2688
  );
2666
2689
  }
2667
2690
  }
2668
- lines.push(`Prior messages in this thread: ${history.length}`);
2669
- if (kind === "group") {
2670
- const mentioned = (event.contentText || "").toLowerCase().includes(`@${handle.toLowerCase()}`);
2671
- lines.push(
2672
- `Message directly addresses you: ${mentioned ? "yes" : "not explicitly"}`
2673
- );
2691
+ lines.push(`Prior messages in this thread: ${priorCount}`);
2692
+ if (event.conversationKind === "group" && handle && (event.mentions ?? []).includes(handle.toLowerCase())) {
2693
+ lines.push("You were @-mentioned in this message.");
2694
+ }
2695
+ return lines;
2696
+ }
2697
+ function formatConversationLabel(event) {
2698
+ if (event.conversationKind !== "group") return "direct";
2699
+ let label = event.groupName ? `group "${event.groupName}"` : "group";
2700
+ if (event.memberCount != null) {
2701
+ label += ` (${event.memberCount} member${event.memberCount === 1 ? "" : "s"})`;
2674
2702
  }
2703
+ return label;
2704
+ }
2705
+ function buildUserContent(params) {
2706
+ const { handle, event, history, signals, maxHistory } = params;
2707
+ const lines = formatConversationContext({
2708
+ handle,
2709
+ event,
2710
+ signals,
2711
+ priorCount: history.length
2712
+ });
2675
2713
  lines.push("");
2676
2714
  const rendered = renderHistory(history, maxHistory);
2677
2715
  if (rendered.length > 0) {
@@ -2961,8 +2999,9 @@ async function handleMessage(deps, event) {
2961
2999
  peer,
2962
3000
  runtime
2963
3001
  });
3002
+ let gateContext = null;
2964
3003
  if (gateEnabled()) {
2965
- const decision = await runReplyGate({
3004
+ const { decision, context } = await runReplyGate({
2966
3005
  deps,
2967
3006
  event,
2968
3007
  body,
@@ -2984,17 +3023,40 @@ async function handleMessage(deps, event) {
2984
3023
  "reply gate decision"
2985
3024
  );
2986
3025
  if (!decision.reply) return;
3026
+ gateContext = context;
3027
+ }
3028
+ const contextHeader = [formatSenderLine(event), `Received: ${formatReceivedAt(ts)}`];
3029
+ if (gateContext) {
3030
+ contextHeader.push(...gateContext);
3031
+ } else {
3032
+ contextHeader.push(
3033
+ `Conversation type: ${formatConversationLabel({
3034
+ conversationKind: event.conversationKind,
3035
+ senderHandle,
3036
+ contentText: body,
3037
+ groupName: event.groupName,
3038
+ memberCount: event.memberCount,
3039
+ mentions: event.mentions
3040
+ })}`
3041
+ );
3042
+ const self = (selfHandle ?? "").replace(/^@/, "").toLowerCase();
3043
+ if (event.conversationKind === "group" && self && event.mentions.includes(self)) {
3044
+ contextHeader.push("You were @-mentioned in this message.");
3045
+ }
2987
3046
  }
3047
+ const agentBody = `${contextHeader.join("\n")}
3048
+
3049
+ ${body}`;
2988
3050
  const { storePath, body: envelopeBody } = buildEnvelope({
2989
3051
  channel: "AgentChat",
2990
3052
  from: conversationLabel,
2991
- body,
3053
+ body: agentBody,
2992
3054
  timestamp: ts
2993
3055
  });
2994
3056
  const finalize = channelRuntime.reply.finalizeInboundContext;
2995
3057
  const ctxPayload = finalize({
2996
3058
  Body: envelopeBody,
2997
- BodyForAgent: body,
3059
+ BodyForAgent: agentBody,
2998
3060
  RawBody: body,
2999
3061
  CommandBody: body,
3000
3062
  From: `@${senderHandle}`,
@@ -3061,6 +3123,10 @@ async function handleMessage(deps, event) {
3061
3123
  );
3062
3124
  }
3063
3125
  }
3126
+ function formatSenderLine(event) {
3127
+ const who = event.senderDisplayName ? `${event.senderDisplayName} (@${event.sender})` : `@${event.sender}`;
3128
+ return `From: ${event.senderKind === "system" ? `${who}, a system agent` : who}`;
3129
+ }
3064
3130
  async function runReplyGate(params) {
3065
3131
  const { deps, event, body, agentId, selfHandle, senderHandle, nowMs } = params;
3066
3132
  const ownHandle = selfHandle ?? "";
@@ -3075,17 +3141,22 @@ async function runReplyGate(params) {
3075
3141
  "reply gate: history fetch failed \u2014 deciding on the new message alone"
3076
3142
  );
3077
3143
  }
3144
+ const bareHandle = ownHandle.replace(/^@/, "");
3078
3145
  const gateEvent = {
3079
3146
  conversationKind: event.conversationKind,
3080
3147
  senderHandle,
3081
- contentText: body
3148
+ contentText: body,
3149
+ groupName: event.groupName,
3150
+ memberCount: event.memberCount,
3151
+ mentions: event.mentions
3082
3152
  };
3083
- return decideReply({
3153
+ const history = translateHistory(rawMessages, ownHandle, event.conversationKind, event.messageId);
3154
+ const decision = await decideReply({
3084
3155
  cfg: deps.gatewayCfg,
3085
3156
  agentId,
3086
- handle: ownHandle.replace(/^@/, ""),
3157
+ handle: bareHandle,
3087
3158
  event: gateEvent,
3088
- history: translateHistory(rawMessages, ownHandle, event.conversationKind, event.messageId),
3159
+ history,
3089
3160
  rawMessages,
3090
3161
  triggerMessageId: event.messageId,
3091
3162
  ownHandle,
@@ -3094,6 +3165,18 @@ async function runReplyGate(params) {
3094
3165
  timeoutMs: gateTimeoutMs(),
3095
3166
  caller: deps.gateCaller
3096
3167
  });
3168
+ const signals = computeConversationSignals(rawMessages, {
3169
+ ownHandle,
3170
+ triggerMessageId: event.messageId,
3171
+ nowMs
3172
+ });
3173
+ const context = formatConversationContext({
3174
+ handle: bareHandle,
3175
+ event: gateEvent,
3176
+ signals,
3177
+ priorCount: history.length
3178
+ });
3179
+ return { decision, context };
3097
3180
  }
3098
3181
  function translateHistory(messages, ownHandle, conversationKind, triggerMessageId) {
3099
3182
  const own = ownHandle.replace(/^@/, "").toLowerCase();