lightclawbot 1.2.6-beta.0 → 1.2.6
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.
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
export const LIGHTSOUL_CONFIG_PATH = path.join(process.env.HOME || '', '.config/lightsoul/config.json');
|
|
4
|
+
export function parseSoulIdMap(raw) {
|
|
5
|
+
const map = {};
|
|
6
|
+
let parsed;
|
|
7
|
+
try {
|
|
8
|
+
parsed = JSON.parse(raw);
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
console.error('Failed to parse lightsoul config:', error);
|
|
12
|
+
return map;
|
|
13
|
+
}
|
|
14
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
15
|
+
return map;
|
|
16
|
+
}
|
|
17
|
+
for (const [agentId, value] of Object.entries(parsed)) {
|
|
18
|
+
if (typeof value === 'string' && value.trim()) {
|
|
19
|
+
map[agentId] = value.trim();
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
23
|
+
const soulId = value.soulId;
|
|
24
|
+
if (typeof soulId === 'string' && soulId.trim()) {
|
|
25
|
+
map[agentId] = soulId.trim();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return map;
|
|
30
|
+
}
|
|
31
|
+
export function readSoulIdMap(configPath = LIGHTSOUL_CONFIG_PATH) {
|
|
32
|
+
return parseSoulIdMap(fs.readFileSync(configPath, 'utf8'));
|
|
33
|
+
}
|
|
34
|
+
export function attachSoulIdsToAgents(agents, soulMap) {
|
|
35
|
+
return agents.map((agent) => {
|
|
36
|
+
const id = typeof agent.id === 'string' ? agent.id.trim() : '';
|
|
37
|
+
const name = typeof agent.name === 'string' ? agent.name.trim() : '';
|
|
38
|
+
const soulId = (id && soulMap[id]) || (name && soulMap[name]) || undefined;
|
|
39
|
+
return soulId ? { ...agent, soulId } : agent;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
@@ -20,8 +20,52 @@ import { handleChatList, handleChatCreate, handleChatUpdate, handleChatDelete }
|
|
|
20
20
|
import { uploadFileToServer } from '../file-storage.js';
|
|
21
21
|
import { guessMimeByExt } from '../media.js';
|
|
22
22
|
import { ensureSessionInHistory, readChatsFile, resolveChatsFilePath } from '../utils/common.js';
|
|
23
|
+
import { attachSoulIdsToAgents, readSoulIdMap, LIGHTSOUL_CONFIG_PATH } from './agent-soul.js';
|
|
23
24
|
import * as fs from 'node:fs';
|
|
24
25
|
import * as path from 'node:path';
|
|
26
|
+
const getNonEmptyString = (value) => {
|
|
27
|
+
if (typeof value !== 'string')
|
|
28
|
+
return undefined;
|
|
29
|
+
const trimmed = value.trim();
|
|
30
|
+
return trimmed || undefined;
|
|
31
|
+
};
|
|
32
|
+
const isMainAgent = (agent) => {
|
|
33
|
+
const id = getNonEmptyString(agent.id);
|
|
34
|
+
const name = getNonEmptyString(agent.name);
|
|
35
|
+
return id === DEFAULT_AGENT_ID || name === DEFAULT_AGENT_ID;
|
|
36
|
+
};
|
|
37
|
+
const withDefaultWorkspace = (agent, defaultWorkspace) => {
|
|
38
|
+
if (!defaultWorkspace || getNonEmptyString(agent.workspace))
|
|
39
|
+
return agent;
|
|
40
|
+
return { ...agent, workspace: defaultWorkspace };
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* 组装 agents:request 响应列表,确保单 agent 场景也返回默认 main agent。
|
|
44
|
+
*/
|
|
45
|
+
export const normalizeAgentsWithMainAgent = (currentCfg) => {
|
|
46
|
+
const agentsConfig = currentCfg.agents;
|
|
47
|
+
const agentsList = Array.isArray(agentsConfig?.list) ? agentsConfig.list : [];
|
|
48
|
+
const defaultWorkspace = getNonEmptyString(agentsConfig?.defaults?.workspace);
|
|
49
|
+
let hasMainAgent = false;
|
|
50
|
+
const normalizedAgents = agentsList.map((agent) => {
|
|
51
|
+
if (!isMainAgent(agent))
|
|
52
|
+
return agent;
|
|
53
|
+
hasMainAgent = true;
|
|
54
|
+
return withDefaultWorkspace(agent, defaultWorkspace);
|
|
55
|
+
});
|
|
56
|
+
if (hasMainAgent)
|
|
57
|
+
return normalizedAgents;
|
|
58
|
+
const mainAgent = {
|
|
59
|
+
id: DEFAULT_AGENT_ID,
|
|
60
|
+
name: DEFAULT_AGENT_ID,
|
|
61
|
+
displayName: DEFAULT_AGENT_ID,
|
|
62
|
+
isDefault: true,
|
|
63
|
+
};
|
|
64
|
+
if (defaultWorkspace) {
|
|
65
|
+
mainAgent.workspace = defaultWorkspace;
|
|
66
|
+
}
|
|
67
|
+
return [mainAgent, ...normalizedAgents];
|
|
68
|
+
};
|
|
25
69
|
/**
|
|
26
70
|
* 绑定所有 Socket.IO 事件监听器到指定 socket 实例。
|
|
27
71
|
*
|
|
@@ -267,7 +311,7 @@ export function bindSocketHandlers(socket, deps) {
|
|
|
267
311
|
});
|
|
268
312
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
269
313
|
// 事件:Agents 列表请求(agents:request)
|
|
270
|
-
// 职责:读取 openclaw.json 中 agents.list
|
|
314
|
+
// 职责:读取 openclaw.json 中 agents.list,并在单 agent 场景补齐默认 main(支持热更新,不缓存)
|
|
271
315
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
272
316
|
socket.on(EVENT_AGENTS_REQUEST, (data, ack) => {
|
|
273
317
|
// 立即回复 ACK,告知服务端请求已收到
|
|
@@ -280,14 +324,21 @@ export function bindSocketHandlers(socket, deps) {
|
|
|
280
324
|
// 获取插件运行时,读取最新配置
|
|
281
325
|
const pluginRuntime = getLightclawRuntime();
|
|
282
326
|
const currentCfg = pluginRuntime.config.loadConfig();
|
|
283
|
-
const agentsList = currentCfg
|
|
284
|
-
|
|
327
|
+
const agentsList = normalizeAgentsWithMainAgent(currentCfg);
|
|
328
|
+
let agentsWithSoulIds = agentsList;
|
|
329
|
+
try {
|
|
330
|
+
agentsWithSoulIds = attachSoulIdsToAgents(agentsList, readSoulIdMap());
|
|
331
|
+
}
|
|
332
|
+
catch (soulErr) {
|
|
333
|
+
log?.warn(`[${CHANNEL_KEY}] Failed to read soul config ${LIGHTSOUL_CONFIG_PATH}: ${soulErr instanceof Error ? soulErr.message : String(soulErr)}`);
|
|
334
|
+
}
|
|
335
|
+
log?.info(`[${CHANNEL_KEY}] Agents request: count=${agentsWithSoulIds.length}`);
|
|
285
336
|
const agentsMsgId = generateMsgId();
|
|
286
337
|
reliableEmitter.emitWithAck(EVENT_AGENTS_RESPONSE, {
|
|
287
338
|
msgId: agentsMsgId,
|
|
288
339
|
to: data.from,
|
|
289
340
|
from: botClientId,
|
|
290
|
-
agents:
|
|
341
|
+
agents: agentsWithSoulIds,
|
|
291
342
|
timestamp: Date.now(),
|
|
292
343
|
}, agentsMsgId);
|
|
293
344
|
}
|