openclaw-quiubo 2.6.61 → 2.6.63
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/index.js +149 -147
- package/dist/index.js.map +3 -3
- package/dist/src/activity-hook.d.ts +6 -0
- package/dist/src/activity-hook.d.ts.map +1 -1
- package/dist/src/channel.d.ts.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13455,6 +13455,152 @@ function formatUptime(ms) {
|
|
|
13455
13455
|
return `${minutes}m`;
|
|
13456
13456
|
}
|
|
13457
13457
|
|
|
13458
|
+
// src/session-utils.ts
|
|
13459
|
+
function extractGroupIdFromSessionKey(key) {
|
|
13460
|
+
if (!key) return void 0;
|
|
13461
|
+
const match = key.match(
|
|
13462
|
+
/quiubo:([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i
|
|
13463
|
+
);
|
|
13464
|
+
return match?.[1];
|
|
13465
|
+
}
|
|
13466
|
+
function extractAgentIdFromSessionKey(key) {
|
|
13467
|
+
if (!key) return "main";
|
|
13468
|
+
const match = key.match(/^agent:([^:]+):quiubo:/);
|
|
13469
|
+
return match?.[1] ?? "main";
|
|
13470
|
+
}
|
|
13471
|
+
function resolveAccountId(config, agentId) {
|
|
13472
|
+
const bindings = config?.bindings ?? [];
|
|
13473
|
+
const matched = bindings.find(
|
|
13474
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13475
|
+
(b) => b?.match?.channel === "quiubo" && b?.agentId === agentId
|
|
13476
|
+
);
|
|
13477
|
+
return matched?.match?.accountId ?? "default";
|
|
13478
|
+
}
|
|
13479
|
+
|
|
13480
|
+
// src/activity-hook.ts
|
|
13481
|
+
var activeToolCounts = /* @__PURE__ */ new Map();
|
|
13482
|
+
var lastSentAt = /* @__PURE__ */ new Map();
|
|
13483
|
+
var pendingIdle = /* @__PURE__ */ new Map();
|
|
13484
|
+
var DEBOUNCE_MS = 2e3;
|
|
13485
|
+
var IDLE_DELAY_MS = 8e3;
|
|
13486
|
+
function isSessionWorking(sessionKey) {
|
|
13487
|
+
return (activeToolCounts.get(sessionKey) ?? 0) > 0;
|
|
13488
|
+
}
|
|
13489
|
+
function generateLabel(toolName, params) {
|
|
13490
|
+
switch (toolName) {
|
|
13491
|
+
case "exec":
|
|
13492
|
+
case "bash":
|
|
13493
|
+
case "Bash": {
|
|
13494
|
+
const cmd = typeof params?.command === "string" ? params.command : "";
|
|
13495
|
+
const first = cmd.split(/[&&||;|]/)[0].trim();
|
|
13496
|
+
const word = first.split(/\s+/)[0] || "";
|
|
13497
|
+
if (!word) return "Running command...";
|
|
13498
|
+
const truncated = word.length > 50 ? word.slice(0, 50) + "\u2026" : word;
|
|
13499
|
+
return `Running ${truncated}...`;
|
|
13500
|
+
}
|
|
13501
|
+
case "read":
|
|
13502
|
+
case "Read":
|
|
13503
|
+
return "Reading files...";
|
|
13504
|
+
case "write":
|
|
13505
|
+
case "Write":
|
|
13506
|
+
case "edit":
|
|
13507
|
+
case "Edit":
|
|
13508
|
+
return "Writing code...";
|
|
13509
|
+
case "web_search":
|
|
13510
|
+
case "WebSearch":
|
|
13511
|
+
return "Searching the web...";
|
|
13512
|
+
case "web_fetch":
|
|
13513
|
+
case "WebFetch":
|
|
13514
|
+
return "Fetching page...";
|
|
13515
|
+
case "grep":
|
|
13516
|
+
case "Grep":
|
|
13517
|
+
case "glob":
|
|
13518
|
+
case "Glob":
|
|
13519
|
+
return "Searching codebase...";
|
|
13520
|
+
case "Task":
|
|
13521
|
+
return "Running sub-agent...";
|
|
13522
|
+
default:
|
|
13523
|
+
return "Working...";
|
|
13524
|
+
}
|
|
13525
|
+
}
|
|
13526
|
+
function registerActivityHook(api) {
|
|
13527
|
+
api.on(
|
|
13528
|
+
"before_tool_call",
|
|
13529
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13530
|
+
(_event, ctx) => {
|
|
13531
|
+
const sessionKey = ctx.sessionKey;
|
|
13532
|
+
const groupId = extractGroupIdFromSessionKey(sessionKey);
|
|
13533
|
+
if (!groupId) return;
|
|
13534
|
+
const key = sessionKey;
|
|
13535
|
+
const prev = activeToolCounts.get(key) ?? 0;
|
|
13536
|
+
activeToolCounts.set(key, prev + 1);
|
|
13537
|
+
const pendingTimer = pendingIdle.get(key);
|
|
13538
|
+
if (pendingTimer) {
|
|
13539
|
+
clearTimeout(pendingTimer);
|
|
13540
|
+
pendingIdle.delete(key);
|
|
13541
|
+
return;
|
|
13542
|
+
}
|
|
13543
|
+
if (prev === 0) {
|
|
13544
|
+
const now = Date.now();
|
|
13545
|
+
const last = lastSentAt.get(key) ?? 0;
|
|
13546
|
+
if (now - last < DEBOUNCE_MS) return;
|
|
13547
|
+
lastSentAt.set(key, now);
|
|
13548
|
+
const config = api.runtime?.config ?? api.config;
|
|
13549
|
+
const agentId = extractAgentIdFromSessionKey(sessionKey);
|
|
13550
|
+
const accountId = resolveAccountId(config, agentId);
|
|
13551
|
+
const client = clients.get(accountId);
|
|
13552
|
+
const accountCfg = accounts.get(accountId);
|
|
13553
|
+
if (!client || !accountCfg?.botIdentityId) return;
|
|
13554
|
+
const toolName = ctx.toolName ?? ctx.tool ?? "";
|
|
13555
|
+
const label = generateLabel(toolName, ctx.params ?? ctx.input);
|
|
13556
|
+
client.sendActivity(groupId, {
|
|
13557
|
+
identityId: accountCfg.botIdentityId,
|
|
13558
|
+
state: "working",
|
|
13559
|
+
tool: toolName || void 0,
|
|
13560
|
+
label
|
|
13561
|
+
}).catch((err) => {
|
|
13562
|
+
console.warn(`[quiubo] activity-hook working failed: ${err}`);
|
|
13563
|
+
});
|
|
13564
|
+
}
|
|
13565
|
+
},
|
|
13566
|
+
{ name: "quiubo-activity-before" }
|
|
13567
|
+
);
|
|
13568
|
+
api.on(
|
|
13569
|
+
"after_tool_call",
|
|
13570
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13571
|
+
(_event, ctx) => {
|
|
13572
|
+
const sessionKey = ctx.sessionKey;
|
|
13573
|
+
const groupId = extractGroupIdFromSessionKey(sessionKey);
|
|
13574
|
+
if (!groupId) return;
|
|
13575
|
+
const key = sessionKey;
|
|
13576
|
+
const prev = activeToolCounts.get(key) ?? 0;
|
|
13577
|
+
const next = Math.max(0, prev - 1);
|
|
13578
|
+
activeToolCounts.set(key, next);
|
|
13579
|
+
if (next === 0) {
|
|
13580
|
+
const idleTimer = setTimeout(() => {
|
|
13581
|
+
pendingIdle.delete(key);
|
|
13582
|
+
lastSentAt.delete(key);
|
|
13583
|
+
if ((activeToolCounts.get(key) ?? 0) > 0) return;
|
|
13584
|
+
const config = api.runtime?.config ?? api.config;
|
|
13585
|
+
const agentId = extractAgentIdFromSessionKey(sessionKey);
|
|
13586
|
+
const accountId = resolveAccountId(config, agentId);
|
|
13587
|
+
const client = clients.get(accountId);
|
|
13588
|
+
const accountCfg = accounts.get(accountId);
|
|
13589
|
+
if (!client || !accountCfg?.botIdentityId) return;
|
|
13590
|
+
client.sendActivity(groupId, {
|
|
13591
|
+
identityId: accountCfg.botIdentityId,
|
|
13592
|
+
state: "idle"
|
|
13593
|
+
}).catch((err) => {
|
|
13594
|
+
console.warn(`[quiubo] activity-hook idle failed: ${err}`);
|
|
13595
|
+
});
|
|
13596
|
+
}, IDLE_DELAY_MS);
|
|
13597
|
+
pendingIdle.set(key, idleTimer);
|
|
13598
|
+
}
|
|
13599
|
+
},
|
|
13600
|
+
{ name: "quiubo-activity-after" }
|
|
13601
|
+
);
|
|
13602
|
+
}
|
|
13603
|
+
|
|
13458
13604
|
// src/channel.ts
|
|
13459
13605
|
var KEYS_DIR = join2(process.env.HOME ?? process.env.USERPROFILE ?? "", ".openclaw", "cron");
|
|
13460
13606
|
async function loadOrGenerateKeys(cfg, accountId) {
|
|
@@ -14769,7 +14915,10 @@ async function routeInboundMessage(opts) {
|
|
|
14769
14915
|
}
|
|
14770
14916
|
}
|
|
14771
14917
|
log?.info?.(`[${accountId}] Quiubo: inbound from ${senderId} in group ${groupId}: ${text?.slice(0, 100)}${mediaPaths.length > 0 ? ` [${mediaPaths.length} image(s)]` : ""}`);
|
|
14918
|
+
const agentId = resolveAgentId(cfg, accountId);
|
|
14919
|
+
const sessionKey = buildSessionKey(agentId, groupId);
|
|
14772
14920
|
const sendTyping = async () => {
|
|
14921
|
+
if (isSessionWorking(sessionKey)) return;
|
|
14773
14922
|
try {
|
|
14774
14923
|
await client.sendTypingIndicator(groupId, botIdentityId);
|
|
14775
14924
|
log?.info?.(`[${accountId}] Quiubo: typing indicator sent for group ${groupId}`);
|
|
@@ -14779,8 +14928,6 @@ async function routeInboundMessage(opts) {
|
|
|
14779
14928
|
};
|
|
14780
14929
|
await sendTyping();
|
|
14781
14930
|
const typingInterval = setInterval(sendTyping, 4e3);
|
|
14782
|
-
const agentId = resolveAgentId(cfg, accountId);
|
|
14783
|
-
const sessionKey = buildSessionKey(agentId, groupId);
|
|
14784
14931
|
log?.info?.(`[${accountId}] [delivery:inbound] agentId=${agentId}, sessionKey=${sessionKey}, To=quiubo:${groupId}, ConversationLabel=quiubo:${groupId}`);
|
|
14785
14932
|
const ctxPayload = runtime2.channel.reply.finalizeInboundContext({
|
|
14786
14933
|
Body: text,
|
|
@@ -14929,30 +15076,6 @@ async function routeInboundMessage(opts) {
|
|
|
14929
15076
|
|
|
14930
15077
|
// src/create-post-tool.ts
|
|
14931
15078
|
import { readFile as readFile3 } from "fs/promises";
|
|
14932
|
-
|
|
14933
|
-
// src/session-utils.ts
|
|
14934
|
-
function extractGroupIdFromSessionKey(key) {
|
|
14935
|
-
if (!key) return void 0;
|
|
14936
|
-
const match = key.match(
|
|
14937
|
-
/quiubo:([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i
|
|
14938
|
-
);
|
|
14939
|
-
return match?.[1];
|
|
14940
|
-
}
|
|
14941
|
-
function extractAgentIdFromSessionKey(key) {
|
|
14942
|
-
if (!key) return "main";
|
|
14943
|
-
const match = key.match(/^agent:([^:]+):quiubo:/);
|
|
14944
|
-
return match?.[1] ?? "main";
|
|
14945
|
-
}
|
|
14946
|
-
function resolveAccountId(config, agentId) {
|
|
14947
|
-
const bindings = config?.bindings ?? [];
|
|
14948
|
-
const matched = bindings.find(
|
|
14949
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14950
|
-
(b) => b?.match?.channel === "quiubo" && b?.agentId === agentId
|
|
14951
|
-
);
|
|
14952
|
-
return matched?.match?.accountId ?? "default";
|
|
14953
|
-
}
|
|
14954
|
-
|
|
14955
|
-
// src/create-post-tool.ts
|
|
14956
15079
|
var IMAGE_MIME_TYPES2 = {
|
|
14957
15080
|
".jpg": "image/jpeg",
|
|
14958
15081
|
".jpeg": "image/jpeg",
|
|
@@ -15160,127 +15283,6 @@ function registerGroupContextHook(api) {
|
|
|
15160
15283
|
);
|
|
15161
15284
|
}
|
|
15162
15285
|
|
|
15163
|
-
// src/activity-hook.ts
|
|
15164
|
-
var activeToolCounts = /* @__PURE__ */ new Map();
|
|
15165
|
-
var lastSentAt = /* @__PURE__ */ new Map();
|
|
15166
|
-
var pendingIdle = /* @__PURE__ */ new Map();
|
|
15167
|
-
var DEBOUNCE_MS = 2e3;
|
|
15168
|
-
var IDLE_DELAY_MS = 5e3;
|
|
15169
|
-
function generateLabel(toolName, params) {
|
|
15170
|
-
switch (toolName) {
|
|
15171
|
-
case "exec":
|
|
15172
|
-
case "bash":
|
|
15173
|
-
case "Bash": {
|
|
15174
|
-
const cmd = typeof params?.command === "string" ? params.command : "";
|
|
15175
|
-
const first = cmd.split(/[&&||;|]/)[0].trim();
|
|
15176
|
-
const word = first.split(/\s+/)[0] || "";
|
|
15177
|
-
if (!word) return "Running command...";
|
|
15178
|
-
const truncated = word.length > 50 ? word.slice(0, 50) + "\u2026" : word;
|
|
15179
|
-
return `Running ${truncated}...`;
|
|
15180
|
-
}
|
|
15181
|
-
case "read":
|
|
15182
|
-
case "Read":
|
|
15183
|
-
return "Reading files...";
|
|
15184
|
-
case "write":
|
|
15185
|
-
case "Write":
|
|
15186
|
-
case "edit":
|
|
15187
|
-
case "Edit":
|
|
15188
|
-
return "Writing code...";
|
|
15189
|
-
case "web_search":
|
|
15190
|
-
case "WebSearch":
|
|
15191
|
-
return "Searching the web...";
|
|
15192
|
-
case "web_fetch":
|
|
15193
|
-
case "WebFetch":
|
|
15194
|
-
return "Fetching page...";
|
|
15195
|
-
case "grep":
|
|
15196
|
-
case "Grep":
|
|
15197
|
-
case "glob":
|
|
15198
|
-
case "Glob":
|
|
15199
|
-
return "Searching codebase...";
|
|
15200
|
-
case "Task":
|
|
15201
|
-
return "Running sub-agent...";
|
|
15202
|
-
default:
|
|
15203
|
-
return "Working...";
|
|
15204
|
-
}
|
|
15205
|
-
}
|
|
15206
|
-
function registerActivityHook(api) {
|
|
15207
|
-
api.on(
|
|
15208
|
-
"before_tool_call",
|
|
15209
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15210
|
-
(_event, ctx) => {
|
|
15211
|
-
const sessionKey = ctx.sessionKey;
|
|
15212
|
-
const groupId = extractGroupIdFromSessionKey(sessionKey);
|
|
15213
|
-
if (!groupId) return;
|
|
15214
|
-
const key = sessionKey;
|
|
15215
|
-
const prev = activeToolCounts.get(key) ?? 0;
|
|
15216
|
-
activeToolCounts.set(key, prev + 1);
|
|
15217
|
-
const pendingTimer = pendingIdle.get(key);
|
|
15218
|
-
if (pendingTimer) {
|
|
15219
|
-
clearTimeout(pendingTimer);
|
|
15220
|
-
pendingIdle.delete(key);
|
|
15221
|
-
return;
|
|
15222
|
-
}
|
|
15223
|
-
if (prev === 0) {
|
|
15224
|
-
const now = Date.now();
|
|
15225
|
-
const last = lastSentAt.get(key) ?? 0;
|
|
15226
|
-
if (now - last < DEBOUNCE_MS) return;
|
|
15227
|
-
lastSentAt.set(key, now);
|
|
15228
|
-
const config = api.runtime?.config ?? api.config;
|
|
15229
|
-
const agentId = extractAgentIdFromSessionKey(sessionKey);
|
|
15230
|
-
const accountId = resolveAccountId(config, agentId);
|
|
15231
|
-
const client = clients.get(accountId);
|
|
15232
|
-
const accountCfg = accounts.get(accountId);
|
|
15233
|
-
if (!client || !accountCfg?.botIdentityId) return;
|
|
15234
|
-
const toolName = ctx.toolName ?? ctx.tool ?? "";
|
|
15235
|
-
const label = generateLabel(toolName, ctx.params ?? ctx.input);
|
|
15236
|
-
client.sendActivity(groupId, {
|
|
15237
|
-
identityId: accountCfg.botIdentityId,
|
|
15238
|
-
state: "working",
|
|
15239
|
-
tool: toolName || void 0,
|
|
15240
|
-
label
|
|
15241
|
-
}).catch((err) => {
|
|
15242
|
-
console.warn(`[quiubo] activity-hook working failed: ${err}`);
|
|
15243
|
-
});
|
|
15244
|
-
}
|
|
15245
|
-
},
|
|
15246
|
-
{ name: "quiubo-activity-before" }
|
|
15247
|
-
);
|
|
15248
|
-
api.on(
|
|
15249
|
-
"after_tool_call",
|
|
15250
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15251
|
-
(_event, ctx) => {
|
|
15252
|
-
const sessionKey = ctx.sessionKey;
|
|
15253
|
-
const groupId = extractGroupIdFromSessionKey(sessionKey);
|
|
15254
|
-
if (!groupId) return;
|
|
15255
|
-
const key = sessionKey;
|
|
15256
|
-
const prev = activeToolCounts.get(key) ?? 0;
|
|
15257
|
-
const next = Math.max(0, prev - 1);
|
|
15258
|
-
activeToolCounts.set(key, next);
|
|
15259
|
-
if (next === 0) {
|
|
15260
|
-
const idleTimer = setTimeout(() => {
|
|
15261
|
-
pendingIdle.delete(key);
|
|
15262
|
-
lastSentAt.delete(key);
|
|
15263
|
-
if ((activeToolCounts.get(key) ?? 0) > 0) return;
|
|
15264
|
-
const config = api.runtime?.config ?? api.config;
|
|
15265
|
-
const agentId = extractAgentIdFromSessionKey(sessionKey);
|
|
15266
|
-
const accountId = resolveAccountId(config, agentId);
|
|
15267
|
-
const client = clients.get(accountId);
|
|
15268
|
-
const accountCfg = accounts.get(accountId);
|
|
15269
|
-
if (!client || !accountCfg?.botIdentityId) return;
|
|
15270
|
-
client.sendActivity(groupId, {
|
|
15271
|
-
identityId: accountCfg.botIdentityId,
|
|
15272
|
-
state: "idle"
|
|
15273
|
-
}).catch((err) => {
|
|
15274
|
-
console.warn(`[quiubo] activity-hook idle failed: ${err}`);
|
|
15275
|
-
});
|
|
15276
|
-
}, IDLE_DELAY_MS);
|
|
15277
|
-
pendingIdle.set(key, idleTimer);
|
|
15278
|
-
}
|
|
15279
|
-
},
|
|
15280
|
-
{ name: "quiubo-activity-after" }
|
|
15281
|
-
);
|
|
15282
|
-
}
|
|
15283
|
-
|
|
15284
15286
|
// src/polling-gateway.ts
|
|
15285
15287
|
var PollingGateway = class {
|
|
15286
15288
|
client;
|