@clwnt/clawnet 0.5.1 → 0.5.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clwnt/clawnet",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "type": "module",
5
5
  "description": "ClawNet integration for OpenClaw — poll inbox, route messages to hooks",
6
6
  "files": [
package/src/cli.ts CHANGED
@@ -424,6 +424,7 @@ export function registerClawnetCli(params: { program: Command; api: any; cfg: Cl
424
424
  // Upsert account
425
425
  const accounts: any[] = pc.accounts ?? [];
426
426
  const existingIdx = accounts.findIndex((a: any) => a.agentId === agentId || a.openclawAgentId === targetAgent);
427
+ const oldAccountId = existingIdx >= 0 ? accounts[existingIdx].id : null;
427
428
  const newAccount = {
428
429
  id: accountId,
429
430
  token: `\${${envVarName}}`,
@@ -454,8 +455,15 @@ export function registerClawnetCli(params: { program: Command; api: any; cfg: Cl
454
455
  "hook:",
455
456
  );
456
457
 
457
- // Upsert per-account clawnet mapping
458
+ // Remove old mapping if account ID changed (e.g., re-registered with new handle)
458
459
  let mappings = cfg.hooks.mappings ?? [];
460
+ if (oldAccountId && oldAccountId !== accountId) {
461
+ const oldMappingId = `clawnet-${oldAccountId}`;
462
+ mappings = mappings.filter((m: any) => String(m?.id ?? "") !== oldMappingId);
463
+ console.log(` Removed stale mapping: ${oldMappingId}`);
464
+ }
465
+
466
+ // Upsert per-account clawnet mapping
459
467
  mappings = upsertMapping(mappings, buildClawnetMapping(accountId, channel, targetAgent));
460
468
  cfg.hooks.mappings = mappings;
461
469
 
package/src/service.ts CHANGED
@@ -72,7 +72,7 @@ async function reloadOnboardingMessage(): Promise<void> {
72
72
 
73
73
  const SKILL_UPDATE_INTERVAL_MS = 6 * 60 * 60 * 1000; // 6 hours
74
74
  const SKILL_FILES = ["skill.json", "api-reference.md", "inbox-handler.md", "capabilities.json", "hook-template.txt", "tool-descriptions.json", "onboarding-message.txt"];
75
- const PLUGIN_VERSION = "0.5.1"; // Reported to server via PATCH /me every 6h
75
+ const PLUGIN_VERSION = "0.5.2"; // Reported to server via PATCH /me every 6h
76
76
 
77
77
  // --- Service ---
78
78
 
@@ -88,6 +88,10 @@ export function createClawnetService(params: { api: any; cfg: ClawnetConfig }) {
88
88
  // Per-account concurrency lock: only 1 LLM run at a time per account
89
89
  const accountBusy = new Set<string>();
90
90
 
91
+ // Per-account delivery lock: skip re-delivery while LLM is processing
92
+ const deliveryLock = new Map<string, Date>(); // accountId -> lock expires at
93
+ const DELIVERY_LOCK_TTL_MS = 10 * 60 * 1000; // 10 minutes
94
+
91
95
  // Per-account debounce: accumulate messages before sending
92
96
  const pendingMessages = new Map<string, InboxMessage[]>();
93
97
  const debounceTimers = new Map<string, ReturnType<typeof setTimeout>>();
@@ -222,6 +226,7 @@ export function createClawnetService(params: { api: any; cfg: ClawnetConfig }) {
222
226
 
223
227
  state.counters.batchesSent++;
224
228
  state.counters.delivered += messages.length;
229
+ deliveryLock.set(accountId, new Date(Date.now() + DELIVERY_LOCK_TTL_MS));
225
230
  api.logger.info(
226
231
  `[clawnet] ${accountId}: delivered ${messages.length} message(s) to ${agentId}`,
227
232
  );
@@ -329,7 +334,19 @@ export function createClawnetService(params: { api: any; cfg: ClawnetConfig }) {
329
334
  }
330
335
  }
331
336
 
332
- if (checkData.count === 0) return;
337
+ if (checkData.count === 0) {
338
+ // Inbox clear — release any delivery lock (agent finished processing)
339
+ deliveryLock.delete(account.id);
340
+ return;
341
+ }
342
+
343
+ // Skip if a recent webhook delivery is still being processed by the LLM.
344
+ // TTL-based lock: after successful POST, lock for 10 min to let the agent work.
345
+ const lockUntil = deliveryLock.get(account.id);
346
+ if (lockUntil && new Date() < lockUntil) {
347
+ api.logger.debug?.(`[clawnet] ${account.id}: ${checkData.count} message(s) waiting (delivery lock active, skipping)`);
348
+ return;
349
+ }
333
350
 
334
351
  state.lastInboxNonEmptyAt = new Date();
335
352
  api.logger.info(`[clawnet] ${account.id}: ${checkData.count} message(s) waiting`);