openclaw-agentmail-listener 0.4.2 → 0.4.3

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/README.md CHANGED
@@ -63,19 +63,45 @@ Subject: Hello there
63
63
  Preview: This is the first 200 chars of the email body...
64
64
  ```
65
65
 
66
- The event is keyed with `contextKey: agentmail:<messageId>` to deduplicate repeated events for the same message.
66
+ The event is keyed with `contextKey: cron:agentmail:<messageId>` so it is both deduplicated and surfaced in the heartbeat prompt (see [How wake works](#how-wake-works) for details).
67
67
 
68
68
  ## How wake works
69
69
 
70
- After enqueuing a system event, the plugin calls `requestHeartbeatNow()` from the OpenClaw plugin SDK with reason `"wake"`. This bypasses heartbeat file gates and triggers an immediate agent turn so the email is processed right away — no waiting for the next scheduled heartbeat.
70
+ After enqueuing a system event, the plugin calls `requestHeartbeatNow()` with reason `"exec-event"`. This does two things:
71
+
72
+ 1. **Bypasses file gates** — the heartbeat fires immediately without requiring HEARTBEAT.md
73
+ 2. **Inspects pending events** — the enqueued system event is included in the heartbeat prompt
74
+
75
+ The `cron:` prefix on the contextKey ensures the event passes through OpenClaw's `hasTaggedCronEvents` check, which enables event inspection and renders the email content via `buildCronEventPrompt`. Without this prefix, the event would be enqueued but silently discarded from the prompt.
76
+
77
+ > **Why not `reason: "wake"`?** The `"wake"` reason bypasses file gates but does _not_ enable `shouldInspectPendingEvents` in the heartbeat runner, so system events are ignored. `"exec-event"` enables both.
78
+
79
+ **Important config for proactive delivery:**
80
+
81
+ The heartbeat `target` must be set to a channel (e.g. `"whatsapp"`, `"telegram"`) or `"last"` — otherwise the agent processes the email but the response is silently dropped (default target is `"none"`).
82
+
83
+ ```json
84
+ {
85
+ "agents": {
86
+ "defaults": {
87
+ "heartbeat": {
88
+ "every": "1h",
89
+ "target": "whatsapp"
90
+ }
91
+ }
92
+ }
93
+ }
94
+ ```
95
+
96
+ **Note:** The `requests-in-flight` check is global — if any conversation is active on any channel, the wake is deferred (retries every 1s until the queue clears).
71
97
 
72
98
  ## Architecture
73
99
 
74
100
  - **Raw WebSocket** — connects directly to `wss://ws.agentmail.to/v0` with API key as query param (no SDK dependency for the WebSocket layer)
75
101
  - **Reconnection** — exponential backoff (1s → 2s → 4s → ... → 60s max) with ±10% jitter
76
102
  - **Keepalive** — sends WebSocket pings every 30 seconds
77
- - **In-process wake** — uses `api.runtime.system.requestHeartbeatNow()` (no HTTP round-trips)
78
- - **System events** — uses `api.runtime.system.enqueueSystemEvent()` to route to the agent session
103
+ - **In-process wake** — uses `api.runtime.system.requestHeartbeatNow()` with `reason: "exec-event"` (no HTTP round-trips)
104
+ - **System events** — uses `api.runtime.system.enqueueSystemEvent()` with `cron:`-prefixed contextKey to ensure prompt visibility
79
105
 
80
106
  ## Dependencies
81
107
 
package/dist/index.js CHANGED
@@ -192,10 +192,10 @@ function handleEventInner(api, cfg, event) {
192
192
  const sessionKey = cfg.sessionKey ?? "agent:main:main";
193
193
  api.runtime.system.enqueueSystemEvent(eventText, {
194
194
  sessionKey,
195
- contextKey: `agentmail:${messageId}`
195
+ contextKey: `cron:agentmail:${messageId}`
196
196
  });
197
197
  api.runtime.system.requestHeartbeatNow({
198
- reason: "wake",
198
+ reason: "exec-event",
199
199
  sessionKey
200
200
  });
201
201
  api.logger.info("agentmail-listener: heartbeat wake requested");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-agentmail-listener",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "type": "module",
5
5
  "description": "OpenClaw plugin: AgentMail listener — injects system events when emails arrive",
6
6
  "files": [