openclaw-lark-multi-agent 0.1.4 → 0.1.5
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/dist/openclaw-client.d.ts +4 -1
- package/dist/openclaw-client.js +51 -10
- package/package.json +1 -1
|
@@ -25,8 +25,9 @@ export declare class OpenClawClient {
|
|
|
25
25
|
private sessionMessageCallbacks;
|
|
26
26
|
/** Session keys that should be re-subscribed on reconnect */
|
|
27
27
|
private subscribedKeys;
|
|
28
|
-
/** Session keys with active chatSend — suppress proactive message delivery */
|
|
28
|
+
/** Session keys with active/recent chatSend — suppress proactive message delivery */
|
|
29
29
|
private suppressedSessions;
|
|
30
|
+
private suppressedSessionTimers;
|
|
30
31
|
constructor(config: OpenClawConfig);
|
|
31
32
|
connect(): Promise<void>;
|
|
32
33
|
private _doConnect;
|
|
@@ -68,6 +69,8 @@ export declare class OpenClawClient {
|
|
|
68
69
|
* deliver=false prevents OpenClaw from auto-posting to channels.
|
|
69
70
|
*/
|
|
70
71
|
abortChat(sessionKey: string, runId: string): Promise<any>;
|
|
72
|
+
private suppressSessionKeys;
|
|
73
|
+
private releaseSuppressedSessionKeysAfter;
|
|
71
74
|
chatSend(params: {
|
|
72
75
|
sessionKey: string;
|
|
73
76
|
message: string;
|
package/dist/openclaw-client.js
CHANGED
|
@@ -21,8 +21,9 @@ export class OpenClawClient {
|
|
|
21
21
|
sessionMessageCallbacks = new Map();
|
|
22
22
|
/** Session keys that should be re-subscribed on reconnect */
|
|
23
23
|
subscribedKeys = new Set();
|
|
24
|
-
/** Session keys with active chatSend — suppress proactive message delivery */
|
|
24
|
+
/** Session keys with active/recent chatSend — suppress proactive message delivery */
|
|
25
25
|
suppressedSessions = new Set();
|
|
26
|
+
suppressedSessionTimers = new Map();
|
|
26
27
|
constructor(config) {
|
|
27
28
|
this.config = config;
|
|
28
29
|
}
|
|
@@ -149,11 +150,23 @@ export class OpenClawClient {
|
|
|
149
150
|
proactiveText = content;
|
|
150
151
|
}
|
|
151
152
|
else if (Array.isArray(content)) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
153
|
+
const hasToolBlock = content.some((part) => {
|
|
154
|
+
const type = String(part?.type || "").toLowerCase();
|
|
155
|
+
return type === "toolcall" || type === "tool_call" || type === "tooluse" || type === "tool_use" || type === "toolresult" || type === "tool_result";
|
|
156
|
+
});
|
|
157
|
+
// Do not deliver mixed text+toolCall assistant messages through
|
|
158
|
+
// the proactive final-text path; those are usually intermediate
|
|
159
|
+
// reasoning/status during a tool loop. Tool calls are still
|
|
160
|
+
// delivered via the verbose channel from agent item events when
|
|
161
|
+
// /verbose is enabled. Cron final messages arrive as text-only
|
|
162
|
+
// (optionally with thinking).
|
|
163
|
+
if (!hasToolBlock) {
|
|
164
|
+
proactiveText = content
|
|
165
|
+
.filter((part) => part?.type === "text" && typeof part.text === "string")
|
|
166
|
+
.map((part) => part.text)
|
|
167
|
+
.join("\n")
|
|
168
|
+
.trim();
|
|
169
|
+
}
|
|
157
170
|
}
|
|
158
171
|
}
|
|
159
172
|
if (proactiveText) {
|
|
@@ -438,11 +451,32 @@ export class OpenClawClient {
|
|
|
438
451
|
const key = sessionKey.startsWith("agent:main:") ? sessionKey.slice("agent:main:".length) : sessionKey;
|
|
439
452
|
return this.rpc("chat.abort", { sessionKey: key, runId }, 5000).catch(() => { });
|
|
440
453
|
}
|
|
454
|
+
suppressSessionKeys(keys) {
|
|
455
|
+
for (const key of keys) {
|
|
456
|
+
const timer = this.suppressedSessionTimers.get(key);
|
|
457
|
+
if (timer)
|
|
458
|
+
clearTimeout(timer);
|
|
459
|
+
this.suppressedSessionTimers.delete(key);
|
|
460
|
+
this.suppressedSessions.add(key);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
releaseSuppressedSessionKeysAfter(keys, delayMs) {
|
|
464
|
+
for (const key of keys) {
|
|
465
|
+
const oldTimer = this.suppressedSessionTimers.get(key);
|
|
466
|
+
if (oldTimer)
|
|
467
|
+
clearTimeout(oldTimer);
|
|
468
|
+
const timer = setTimeout(() => {
|
|
469
|
+
this.suppressedSessions.delete(key);
|
|
470
|
+
this.suppressedSessionTimers.delete(key);
|
|
471
|
+
}, delayMs);
|
|
472
|
+
this.suppressedSessionTimers.set(key, timer);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
441
475
|
async chatSend(params) {
|
|
442
476
|
const sk = params.sessionKey;
|
|
443
477
|
const fullSessionKey = `agent:main:${sk}`;
|
|
444
|
-
|
|
445
|
-
this.
|
|
478
|
+
const suppressedKeys = [sk, fullSessionKey];
|
|
479
|
+
this.suppressSessionKeys(suppressedKeys);
|
|
446
480
|
try {
|
|
447
481
|
// Drop stale buffered events for this session before starting a new run.
|
|
448
482
|
// This prevents an old final text (e.g. previous "ok") from being consumed by
|
|
@@ -461,8 +495,11 @@ export class OpenClawClient {
|
|
|
461
495
|
return await this.collectReply(result.runId, params.timeoutMs || 1800000, sk);
|
|
462
496
|
}
|
|
463
497
|
finally {
|
|
464
|
-
|
|
465
|
-
|
|
498
|
+
// OpenClaw can emit the final assistant session.message a moment after
|
|
499
|
+
// collectReply returns. Keep a short grace window so normal chat replies
|
|
500
|
+
// are not delivered twice via the proactive-message path. Cron/LMA runs
|
|
501
|
+
// are unaffected because they do not go through chatSend.
|
|
502
|
+
this.releaseSuppressedSessionKeysAfter(suppressedKeys, 30000);
|
|
466
503
|
}
|
|
467
504
|
}
|
|
468
505
|
/**
|
|
@@ -547,6 +584,10 @@ export class OpenClawClient {
|
|
|
547
584
|
}
|
|
548
585
|
async disconnect() {
|
|
549
586
|
this.shouldReconnect = false;
|
|
587
|
+
for (const timer of this.suppressedSessionTimers.values())
|
|
588
|
+
clearTimeout(timer);
|
|
589
|
+
this.suppressedSessionTimers.clear();
|
|
590
|
+
this.suppressedSessions.clear();
|
|
550
591
|
if (this.ws) {
|
|
551
592
|
this.ws.close();
|
|
552
593
|
this.ws = null;
|