@clwnt/clawnet 0.5.1 → 0.5.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/index.ts +2 -1
- package/package.json +1 -1
- package/src/cli.ts +12 -1
- package/src/service.ts +19 -2
package/index.ts
CHANGED
|
@@ -120,7 +120,8 @@ const plugin = {
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
if (args !== "link" && args !== "link reset") {
|
|
123
|
-
|
|
123
|
+
const { PLUGIN_VERSION } = await import("./src/service.js");
|
|
124
|
+
return { text: `ClawNet Plugin v${PLUGIN_VERSION}\n\nCommands:\n /clawnet status — show plugin configuration and health\n /clawnet test — test delivery to this chat\n /clawnet link — pin message delivery to this chat (use if messages aren't arriving)\n /clawnet link reset — unpin and return to automatic delivery\n /clawnet pause — temporarily stop polling\n /clawnet resume — restart polling\n\nUpdate: openclaw plugins update clawnet` };
|
|
124
125
|
}
|
|
125
126
|
|
|
126
127
|
// Load config and find clawnet accounts
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -5,6 +5,7 @@ import * as fs from "node:fs/promises";
|
|
|
5
5
|
import * as path from "node:path";
|
|
6
6
|
import * as os from "node:os";
|
|
7
7
|
import type { ClawnetConfig } from "./config.js";
|
|
8
|
+
import { PLUGIN_VERSION } from "./service.js";
|
|
8
9
|
|
|
9
10
|
const API_BASE = "https://api.clwnt.com";
|
|
10
11
|
const DEVICE_POLL_INTERVAL_MS = 3000;
|
|
@@ -148,6 +149,7 @@ export function buildStatusText(api: any): string {
|
|
|
148
149
|
|
|
149
150
|
lines.push("**ClawNet Status**\n");
|
|
150
151
|
|
|
152
|
+
lines.push(`Plugin version: ${PLUGIN_VERSION}`);
|
|
151
153
|
lines.push(`Plugin enabled: ${pluginEntry?.enabled ?? false}`);
|
|
152
154
|
if (pluginCfg) {
|
|
153
155
|
if (pluginCfg.paused) {
|
|
@@ -424,6 +426,7 @@ export function registerClawnetCli(params: { program: Command; api: any; cfg: Cl
|
|
|
424
426
|
// Upsert account
|
|
425
427
|
const accounts: any[] = pc.accounts ?? [];
|
|
426
428
|
const existingIdx = accounts.findIndex((a: any) => a.agentId === agentId || a.openclawAgentId === targetAgent);
|
|
429
|
+
const oldAccountId = existingIdx >= 0 ? accounts[existingIdx].id : null;
|
|
427
430
|
const newAccount = {
|
|
428
431
|
id: accountId,
|
|
429
432
|
token: `\${${envVarName}}`,
|
|
@@ -454,8 +457,15 @@ export function registerClawnetCli(params: { program: Command; api: any; cfg: Cl
|
|
|
454
457
|
"hook:",
|
|
455
458
|
);
|
|
456
459
|
|
|
457
|
-
//
|
|
460
|
+
// Remove old mapping if account ID changed (e.g., re-registered with new handle)
|
|
458
461
|
let mappings = cfg.hooks.mappings ?? [];
|
|
462
|
+
if (oldAccountId && oldAccountId !== accountId) {
|
|
463
|
+
const oldMappingId = `clawnet-${oldAccountId}`;
|
|
464
|
+
mappings = mappings.filter((m: any) => String(m?.id ?? "") !== oldMappingId);
|
|
465
|
+
console.log(` Removed stale mapping: ${oldMappingId}`);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// Upsert per-account clawnet mapping
|
|
459
469
|
mappings = upsertMapping(mappings, buildClawnetMapping(accountId, channel, targetAgent));
|
|
460
470
|
cfg.hooks.mappings = mappings;
|
|
461
471
|
|
|
@@ -570,6 +580,7 @@ export function registerClawnetCli(params: { program: Command; api: any; cfg: Cl
|
|
|
570
580
|
console.log("\n ClawNet Status\n");
|
|
571
581
|
|
|
572
582
|
// Plugin
|
|
583
|
+
console.log(` Plugin version: ${PLUGIN_VERSION}`);
|
|
573
584
|
console.log(` Plugin enabled: ${pluginEntry?.enabled ?? false}`);
|
|
574
585
|
if (pluginCfg) {
|
|
575
586
|
console.log(` Poll interval: ${pluginCfg.pollEverySeconds ?? "?"}s`);
|
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.
|
|
75
|
+
export const PLUGIN_VERSION = "0.5.3"; // 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)
|
|
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`);
|