@efengx/openclaw-channel-dragon 0.3.3 → 0.3.6

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.
Files changed (2) hide show
  1. package/dist/index.js +33 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -153,8 +153,29 @@ async function startPolling(ctx) {
153
153
  }
154
154
  });
155
155
  };
156
+ const consumePendingMessages = async () => {
157
+ try {
158
+ const pollUrl = `${orchestratorUrl}/api/agents/${agentId}/messages/poll`;
159
+ const res = await fetch(pollUrl);
160
+ if (res.ok) {
161
+ const data = (await res.json());
162
+ const messages = data.messages || [];
163
+ if (messages.length > 0) {
164
+ logger?.info?.(`dragon channel: [RECOVERY] Consuming ${messages.length} pending messages via polling.`);
165
+ for (const m of messages) {
166
+ await deliverToOpenClaw(String(m.content || ''), String(m.sessionId || 'default'), m.modelId, m.attachments);
167
+ }
168
+ }
169
+ }
170
+ }
171
+ catch (e) {
172
+ logger?.error?.(`dragon channel: [RECOVERY] Polling failed: ${e.message}`);
173
+ }
174
+ };
156
175
  const connectOnce = async () => {
157
176
  const sseUrl = `${orchestratorUrl}/api/agents/events`;
177
+ // Recovery: Catch up on any messages missed during downtime
178
+ void consumePendingMessages();
158
179
  const handleSseText = async (chunkText, bufRef) => {
159
180
  // Diagnostic: log first chunk of SSE if it's not a heartbeat comment
160
181
  const isHeartbeat = chunkText.trim().startsWith(':');
@@ -177,11 +198,17 @@ async function startPolling(ctx) {
177
198
  const dataStr = dataLines.join('\n');
178
199
  try {
179
200
  const evt = JSON.parse(dataStr);
180
- if (!evt || evt.agentId !== agentId)
201
+ if (!evt)
181
202
  continue;
182
203
  if (evt.type === 'WORKBENCH_MESSAGE') {
183
204
  const sendTs = evt.payload?.ts || 0;
184
205
  const latency = sendTs ? (Date.now() - sendTs) : 'unknown';
206
+ // Critical Log: Confirm receipt of SSE message
207
+ logger?.info?.(`dragon channel: [SSE] RECEIVED WORKBENCH_MESSAGE. agentId=${evt.agentId} (Current Config: ${agentId}), sessionId=${evt.payload?.sessionId}, latency=${latency}ms`);
208
+ if (evt.agentId !== agentId) {
209
+ logger?.warn?.(`dragon channel: [SSE] ID Mismatch! Event ID "${evt.agentId}" !== Config ID "${agentId}". Ignoring message.`);
210
+ continue;
211
+ }
185
212
  logger?.info?.(`dragon channel: [DEBUG] Received WORKBENCH_MESSAGE via SSE. AgentID=${evt.agentId}, ContentLen=${evt.payload?.content?.length}, Latency=${latency}ms`);
186
213
  logger?.info?.(`dragon channel: [DEBUG] Payload Content: "${evt.payload?.content?.substring(0, 500)}"`);
187
214
  logger?.info?.(`dragon channel: [DEBUG] Current Account Config: ${JSON.stringify(account)}`);
@@ -308,6 +335,10 @@ async function startPolling(ctx) {
308
335
  }
309
336
  };
310
337
  let attempt = 0;
338
+ // Safety: Periodic polling fallback every 60 seconds
339
+ const pollInterval = setInterval(() => {
340
+ void consumePendingMessages();
341
+ }, 60_000);
311
342
  while (!ctx.abortSignal.aborted) {
312
343
  try {
313
344
  attempt += 1;
@@ -323,6 +354,7 @@ async function startPolling(ctx) {
323
354
  await new Promise((r) => setTimeout(r, delayMs));
324
355
  }
325
356
  }
357
+ clearInterval(pollInterval);
326
358
  logger?.info?.({ agentId }, "dragon channel: SSE loop terminated");
327
359
  }
328
360
  const base = createChannelPluginBase({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@efengx/openclaw-channel-dragon",
3
- "version": "0.3.3",
3
+ "version": "0.3.6",
4
4
  "description": "Dragon workbench channel for OpenClaw",
5
5
  "author": "feng xiang <ofengx@gmail.com>",
6
6
  "type": "module",