openclaw-lark-multi-agent 1.8.21 → 1.8.22
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/config.d.ts +8 -5
- package/dist/config.js +4 -5
- package/dist/feishu-bot.js +4 -4
- package/dist/go-controller.d.ts +2 -2
- package/dist/go-controller.js +12 -12
- package/package.json +1 -1
package/dist/config.d.ts
CHANGED
|
@@ -13,13 +13,16 @@ export interface BotConfig {
|
|
|
13
13
|
locale?: Locale;
|
|
14
14
|
/** Optional per-bot thinking level (informational fallback for footers). */
|
|
15
15
|
thinking?: string;
|
|
16
|
-
/** OpenClaw agent
|
|
16
|
+
/** OpenClaw agent that owns this bot's sessions.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
18
|
+
* Selects which agent entry (from agents.entries in openclaw.json) owns
|
|
19
|
+
* this bot's sessions — its workspace, memory, identity and model routing.
|
|
20
|
+
* Optional: a bot that does not name an agent keeps the historical `main`
|
|
21
|
+
* agent, so existing configs behave exactly as before.
|
|
22
|
+
* The legacy field name `profile` is accepted as an alias and migrated.
|
|
22
23
|
* Defaults to "main" when absent or blank. */
|
|
24
|
+
agent?: string;
|
|
25
|
+
/** @deprecated Use `agent` instead. Accepted as an alias. */
|
|
23
26
|
profile?: string;
|
|
24
27
|
}
|
|
25
28
|
export interface OpenClawConfig {
|
package/dist/config.js
CHANGED
|
@@ -23,11 +23,10 @@ export function loadConfig(path) {
|
|
|
23
23
|
config.locale = normalizeLocale(config.locale);
|
|
24
24
|
for (const bot of config.bots) {
|
|
25
25
|
bot.locale = normalizeLocale(bot.locale || config.locale);
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
bot.profile = profile || DEFAULT_BOT_PROFILE;
|
|
26
|
+
// `agent` is the canonical field; `profile` is a legacy alias.
|
|
27
|
+
const agent = String(bot.agent ?? bot.profile ?? "").trim();
|
|
28
|
+
bot.agent = agent || DEFAULT_BOT_PROFILE;
|
|
29
|
+
bot.profile = bot.agent;
|
|
31
30
|
// An empty model means "follow the profile's own model".
|
|
32
31
|
const model = String(bot.model == null ? "" : bot.model).trim();
|
|
33
32
|
bot.model = model || undefined;
|
package/dist/feishu-bot.js
CHANGED
|
@@ -400,7 +400,7 @@ export class FeishuBot {
|
|
|
400
400
|
this.goController = new GoController({
|
|
401
401
|
botName: config.name,
|
|
402
402
|
fallbackModel: config.model || "",
|
|
403
|
-
|
|
403
|
+
agent: this.profile,
|
|
404
404
|
store,
|
|
405
405
|
client: openclawClient,
|
|
406
406
|
executorSessionKeyFor: (chatId) => this.physicalSessionKey(chatId),
|
|
@@ -487,7 +487,7 @@ export class FeishuBot {
|
|
|
487
487
|
* Defaults to "main" so a configuration written before profiles existed
|
|
488
488
|
* keeps its historical behaviour exactly. */
|
|
489
489
|
get profile() {
|
|
490
|
-
return String(this.config.profile || "main").trim() || "main";
|
|
490
|
+
return String(this.config.agent || this.config.profile || "main").trim() || "main";
|
|
491
491
|
}
|
|
492
492
|
getSessionKey(chatId) {
|
|
493
493
|
return `lma-${this.config.name.toLowerCase()}-${chatId}`;
|
|
@@ -702,7 +702,7 @@ export class FeishuBot {
|
|
|
702
702
|
await this.wsClient.start({ eventDispatcher: this.eventDispatcher });
|
|
703
703
|
if (this.identityClosed)
|
|
704
704
|
return;
|
|
705
|
-
console.log(`[${this.config.name}] Bot started (model: ${this.config.model || `
|
|
705
|
+
console.log(`[${this.config.name}] Bot started (model: ${this.config.model || `agent ${this.profile}`}, open_id: ${this.botOpenId || "unknown"})`);
|
|
706
706
|
// Drain any unsynced messages left from previous run
|
|
707
707
|
this.drainOnStartup();
|
|
708
708
|
void this.drainIdentityIngress().catch(err => console.warn(`[${this.config.name}] Identity ingress recovery failed:`, err.message));
|
|
@@ -5998,7 +5998,7 @@ export class FeishuBot {
|
|
|
5998
5998
|
return;
|
|
5999
5999
|
}
|
|
6000
6000
|
if (nextModel === this.config.model) {
|
|
6001
|
-
await this.replyMessage(messageId, `🤖 ${this.config.name} 已经在使用:${this.config.model || `
|
|
6001
|
+
await this.replyMessage(messageId, `🤖 ${this.config.name} 已经在使用:${this.config.model || `agent ${this.profile}`}`);
|
|
6002
6002
|
return;
|
|
6003
6003
|
}
|
|
6004
6004
|
if (!this.configPath) {
|
package/dist/go-controller.d.ts
CHANGED
|
@@ -75,8 +75,8 @@ export type GoClient = {
|
|
|
75
75
|
export type GoControllerDeps = {
|
|
76
76
|
botName: string;
|
|
77
77
|
fallbackModel: string;
|
|
78
|
-
/** OpenClaw
|
|
79
|
-
|
|
78
|
+
/** OpenClaw agent that owns this bot's sessions (default "main"). */
|
|
79
|
+
agent?: string;
|
|
80
80
|
store: import("./message-store.js").MessageStore;
|
|
81
81
|
client: GoClient;
|
|
82
82
|
/** Executor session key for a chat (e.g. lma-<bot>-<chatId>). */
|
package/dist/go-controller.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/** Independent LMA supervision. MessageStore owns objective, criteria and completion. */
|
|
2
2
|
import { goSnapshotBlocked } from "./go-runtime-gate.js";
|
|
3
|
-
/** Logical (
|
|
3
|
+
/** Logical (agent-free) part of a session key. */
|
|
4
4
|
const withoutAgentPrefix = (key) => key.replace(/^agent:[^:]+:/, '');
|
|
5
|
-
/** Physical session key for a logical executor key under this bot's
|
|
6
|
-
const physicalKey = (key,
|
|
5
|
+
/** Physical session key for a logical executor key under this bot's agent. */
|
|
6
|
+
const physicalKey = (key, agentName) => {
|
|
7
7
|
if (/^agent:[^:]+:/.test(key))
|
|
8
8
|
return key;
|
|
9
|
-
const
|
|
10
|
-
return `agent:${
|
|
9
|
+
const resolved = String(agentName || "main").trim() || "main";
|
|
10
|
+
return `agent:${resolved}:${key}`;
|
|
11
11
|
};
|
|
12
12
|
const CHECK_DELAY_MS = Number(process.env.OPENCLAW_LARK_MULTI_AGENT_GO_CHECK_DELAY_MS || 20000);
|
|
13
13
|
const CHECKER_TIMEOUT_MS = Number(process.env.OPENCLAW_LARK_MULTI_AGENT_GO_CHECKER_TIMEOUT_MS || 10 * 60 * 1000);
|
|
@@ -129,7 +129,7 @@ export class GoController {
|
|
|
129
129
|
const executor = sessionKey === job.executorSessionKey;
|
|
130
130
|
const result = executor ? await client.collectGoExecutorRun({ runId: receipt.runId, sessionKey, sessionId: expectedSessionId, timeoutMs: CHECKER_TIMEOUT_MS }) : null;
|
|
131
131
|
if (result && (result.runId !== receipt.runId || result.sessionId !== expectedSessionId ||
|
|
132
|
-
(result.sessionKey !== sessionKey && result.sessionKey !== physicalKey(sessionKey, this.d.
|
|
132
|
+
(result.sessionKey !== sessionKey && result.sessionKey !== physicalKey(sessionKey, this.d.agent))))
|
|
133
133
|
throw new Error("Executor result identity mismatch");
|
|
134
134
|
const text = result ? result.text : await client.collectGoRun({ runId: receipt.runId, sessionKey, sessionId: expectedSessionId, timeoutMs: CHECKER_TIMEOUT_MS });
|
|
135
135
|
this.d.store.recordGoRunResult(jobId, actionKey, { state: "complete", runId: receipt.runId, text, ...(result ? { executorResult: result } : {}) });
|
|
@@ -214,9 +214,9 @@ export class GoController {
|
|
|
214
214
|
return;
|
|
215
215
|
}
|
|
216
216
|
// The Go supervision path talks to the Gateway directly, so it uses the
|
|
217
|
-
// PHYSICAL key throughout (
|
|
217
|
+
// PHYSICAL key throughout (agent included) exactly like the executor
|
|
218
218
|
// session itself.
|
|
219
|
-
const executorKey = physicalKey(this.d.executorSessionKeyFor(chatId), this.d.
|
|
219
|
+
const executorKey = physicalKey(this.d.executorSessionKeyFor(chatId), this.d.agent);
|
|
220
220
|
if (await this.safetyUnavailable(executorKey)) {
|
|
221
221
|
await this.d.reply(messageId, "❌ Go 未启动:当前运行时尚未验证 Checker 工具隔离、精确子孙任务/投递门禁及条件发送。不能仅凭提示词安全开启自动监督。独立模式无需原生 Goal;普通聊天不受影响。");
|
|
222
222
|
return;
|
|
@@ -242,10 +242,10 @@ export class GoController {
|
|
|
242
242
|
|| (typeof session.model === "string" && session.model
|
|
243
243
|
? (typeof session.modelProvider === "string" && session.modelProvider && !session.model.includes("/") ? `${session.modelProvider}/${session.model}` : session.model)
|
|
244
244
|
: this.d.fallbackModel);
|
|
245
|
-
// The checker session NAME stays
|
|
245
|
+
// The checker session NAME stays agent-free (lma- -> lma-go-), exactly like
|
|
246
246
|
// every other logical key LMA stores. It is addressed under the bot's
|
|
247
|
-
//
|
|
248
|
-
const checkerKey = physicalKey(`${withoutAgentPrefix(executorKey).replace(/^lma-/, "lma-go-")}-${crypto.randomUUID()}`, this.d.
|
|
247
|
+
// agent only when it is actually handed to the Gateway.
|
|
248
|
+
const checkerKey = physicalKey(`${withoutAgentPrefix(executorKey).replace(/^lma-/, "lma-go-")}-${crypto.randomUUID()}`, this.d.agent);
|
|
249
249
|
try {
|
|
250
250
|
await this.d.client.createSession({ key: checkerKey, model: resolvedModel, label: `Go Checker: ${this.d.botName} ${chatId.slice(-6)}` });
|
|
251
251
|
}
|
|
@@ -364,7 +364,7 @@ export class GoController {
|
|
|
364
364
|
if (saved?.state !== "complete") {
|
|
365
365
|
const result = await this.d.client.readGoExecutorRunResult?.({ ...send, runId: receipt.runId });
|
|
366
366
|
if (!result || result.runId !== receipt.runId || result.sessionId !== job.executorSessionId ||
|
|
367
|
-
![job.executorSessionKey, physicalKey(job.executorSessionKey, this.d.
|
|
367
|
+
![job.executorSessionKey, physicalKey(job.executorSessionKey, this.d.agent)].includes(result.sessionKey)) {
|
|
368
368
|
this.d.store.recordGoRunResult(job.id, send.actionKey, { state: "unknown", runId: receipt.runId });
|
|
369
369
|
continue;
|
|
370
370
|
}
|