agent-bridge-aun 1.0.4 → 1.0.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.
- package/README.md +1 -1
- package/dist/src-ts/plugins/aun/index.js +23 -27
- package/dist/src-ts/plugins/aun/public/app.js +3 -3
- package/package.json +30 -8
- package/plugin.json +8 -2
- package/dist/src-ts/channel.js +0 -2
- package/dist/src-ts/local-aids.js +0 -26
- package/dist/src-ts/plugins/aun/evolcore.js +0 -54
package/README.md
CHANGED
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
|
|
7
7
|
该插件依赖 `@agentunion/fastaun`,要求 Node.js 22.16 或更高版本。
|
|
8
8
|
|
|
9
|
-
ABWeb 的 AUN
|
|
9
|
+
ABWeb 的 AUN 设置展示本机 AID 和已连接 AID,不再依赖 `ec` 命令。"本机 AID"来自插件密钥库(`store.list()`),`ec stop` 后仍然可见;"本工程 · 已连接"是插件当前保持连接的身份。列表先显示已关联 Agent 的身份,各组按最近成功关联的时间倒序排列,时间相同或旧记录没有时间时按 AID 名称排序。关联时间保存在插件配置的 `binding_times` 中,刷新或重启后保留;旧记录不补造时间,再次关联成功后开始记录。关联时只要求 AID 在本地密钥库中,由插件直接建立连接,不再执行 `ec agent set/reload` 配置 EvolCore 路由。
|
|
@@ -6,10 +6,8 @@ const node_module_1 = require("node:module");
|
|
|
6
6
|
const node_path_1 = require("node:path");
|
|
7
7
|
const node_url_1 = require("node:url");
|
|
8
8
|
const messages_1 = require("./messages");
|
|
9
|
-
const evolcore_1 = require("./evolcore");
|
|
10
|
-
const local_aids_1 = require("../../local-aids");
|
|
11
9
|
const manifest = {
|
|
12
|
-
id: "aun", version: "1.0.
|
|
10
|
+
id: "aun", version: "1.0.6", type: "channel", displayName: "AUN 通道",
|
|
13
11
|
entry: "dist/src-ts/plugins/aun/index.js", apiVersion: "1", process: "in-process",
|
|
14
12
|
capabilities: ["channel", "channel.identity.create", "channel.receive", "channel.send", "health"],
|
|
15
13
|
configSchema: "config.schema.json",
|
|
@@ -38,7 +36,6 @@ class AunPlugin {
|
|
|
38
36
|
store;
|
|
39
37
|
clients = new Map();
|
|
40
38
|
identities = new Set();
|
|
41
|
-
legacyCreatedAids = new Set();
|
|
42
39
|
bindings = {};
|
|
43
40
|
bindingTimes = {};
|
|
44
41
|
creating = false;
|
|
@@ -56,14 +53,13 @@ class AunPlugin {
|
|
|
56
53
|
}
|
|
57
54
|
identity = {
|
|
58
55
|
list: async () => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return [];
|
|
62
|
-
});
|
|
56
|
+
// 不再依赖 ec 命令:本地密钥库的 AID 全部列出,本工程连接的 AID 以 clients 为准
|
|
57
|
+
const local = this.listStoreAids();
|
|
63
58
|
return {
|
|
64
|
-
evolcore:
|
|
65
|
-
muAgentBridge: [...
|
|
59
|
+
evolcore: [],
|
|
60
|
+
muAgentBridge: [...this.clients.keys()].sort(),
|
|
66
61
|
localMuAgentBridge: [...this.identities].filter((aid) => !this.clients.has(aid)).sort(),
|
|
62
|
+
local,
|
|
67
63
|
};
|
|
68
64
|
},
|
|
69
65
|
create: async (aid, owner) => {
|
|
@@ -98,7 +94,7 @@ class AunPlugin {
|
|
|
98
94
|
this.creating = false;
|
|
99
95
|
}
|
|
100
96
|
},
|
|
101
|
-
bind: async (pluginId, aid,
|
|
97
|
+
bind: async (pluginId, aid, _port) => {
|
|
102
98
|
if (pluginId === "aun" || pluginId === "abweb")
|
|
103
99
|
throw new Error("只能关联 Agent 插件");
|
|
104
100
|
const previous = this.bindings;
|
|
@@ -124,14 +120,20 @@ class AunPlugin {
|
|
|
124
120
|
this.bindings[aid] = pluginId;
|
|
125
121
|
}
|
|
126
122
|
else {
|
|
127
|
-
|
|
123
|
+
// 不再调用 ec:只要 AID 在本地密钥库中就直接连接并绑定
|
|
124
|
+
const loaded = this.store.load(aid);
|
|
125
|
+
if (!loaded.ok || !loaded.data)
|
|
126
|
+
throw new Error("AID 不在本地密钥库中,无法关联");
|
|
127
|
+
await this.connectAid(aid);
|
|
128
|
+
if (!this.clients.has(aid))
|
|
128
129
|
throw new Error("AID 当前未连接");
|
|
129
|
-
await (0, evolcore_1.configureAidForPlugin)(pluginId, aid, port);
|
|
130
130
|
for (const [identity, target] of Object.entries(this.bindings))
|
|
131
131
|
if (target === pluginId) {
|
|
132
132
|
delete this.bindings[identity];
|
|
133
133
|
delete this.bindingTimes[identity];
|
|
134
134
|
}
|
|
135
|
+
this.bindings[aid] = pluginId;
|
|
136
|
+
this.identities.add(aid);
|
|
135
137
|
}
|
|
136
138
|
}
|
|
137
139
|
else {
|
|
@@ -165,18 +167,6 @@ class AunPlugin {
|
|
|
165
167
|
async activate(context) {
|
|
166
168
|
this.context = context;
|
|
167
169
|
this.config = { ...context.config };
|
|
168
|
-
this.legacyCreatedAids.clear();
|
|
169
|
-
try {
|
|
170
|
-
const created = JSON.parse(await (0, promises_1.readFile)((0, node_path_1.join)(context.dataDir, "..", "created-aids.json"), "utf8"));
|
|
171
|
-
if (Array.isArray(created))
|
|
172
|
-
for (const aid of created)
|
|
173
|
-
if (typeof aid === "string" && aidPattern.test(aid))
|
|
174
|
-
this.legacyCreatedAids.add(aid);
|
|
175
|
-
}
|
|
176
|
-
catch (error) {
|
|
177
|
-
if (error.code !== "ENOENT")
|
|
178
|
-
context.logger.warn("读取旧版身份创建记录失败", { error: safeError(error) });
|
|
179
|
-
}
|
|
180
170
|
for (const key of ["aid", "owner_aid", "aun_path", "encryption_seed", "root_ca_path", "allow_from", "agent_plugin"]) {
|
|
181
171
|
if (this.config[key] !== undefined && typeof this.config[key] !== "string")
|
|
182
172
|
throw new Error(`${key} 必须是字符串`);
|
|
@@ -303,10 +293,16 @@ class AunPlugin {
|
|
|
303
293
|
return this.json(response, 502, { error: safeError(error) });
|
|
304
294
|
}
|
|
305
295
|
};
|
|
296
|
+
listStoreAids() {
|
|
297
|
+
const result = this.store?.list();
|
|
298
|
+
if (!result?.ok || !Array.isArray(result.data?.identities))
|
|
299
|
+
return [];
|
|
300
|
+
return [...new Set(result.data.identities.filter((item) => item && typeof item.aid === "string" && aidPattern.test(item.aid)).map((item) => item.aid))].sort();
|
|
301
|
+
}
|
|
306
302
|
listIdentities = async (_request, response) => {
|
|
307
303
|
const groups = await this.identity.list();
|
|
308
|
-
const connected = new Set([...groups.evolcore, ...groups.muAgentBridge]);
|
|
309
|
-
const localAids = (
|
|
304
|
+
const connected = new Set([...groups.evolcore, ...groups.muAgentBridge, ...groups.localMuAgentBridge ?? []]);
|
|
305
|
+
const localAids = (groups.local ?? []).filter((aid) => !connected.has(aid));
|
|
310
306
|
this.json(response, 200, { groups, localAids, bindings: this.bindings, bindingTimes: this.bindingTimes });
|
|
311
307
|
};
|
|
312
308
|
saveSettings = async (request, response) => {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
configForm.elements.encryption_seed.value = "";
|
|
32
32
|
}
|
|
33
33
|
list.replaceChildren();
|
|
34
|
-
const entries = [["本工程 · 已连接", identities.groups.muAgentBridge || []], ["
|
|
34
|
+
const entries = [["本工程 · 已连接", identities.groups.muAgentBridge || []], ["本机 AID", identities.groups.local || []], ["本工程 · 未连接", identities.groups.localMuAgentBridge || []]]
|
|
35
35
|
.flatMap(([label, values], group) => values.map((aid) => ({ aid, label, group, bound: identities.bindings?.[aid] || agents.find((agent) => agent.id && agent.configAid === aid)?.id || "", time: Date.parse(identities.bindingTimes?.[aid] || "") || 0 })));
|
|
36
36
|
entries.sort((a, b) => Number(Boolean(b.bound)) - Number(Boolean(a.bound)) || a.group - b.group || b.time - a.time || a.aid.localeCompare(b.aid));
|
|
37
37
|
for (const { aid, label, bound } of entries) {
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
select.value = bound; select.onchange = () => { if (select.value) void bind(aid, select.value); };
|
|
43
43
|
cell.append(select); row.append(cell); list.append(row);
|
|
44
44
|
}
|
|
45
|
-
if (!list.children.length) { const row = document.createElement("tr"); const cell = document.createElement("td"); cell.colSpan = 4; cell.textContent = "
|
|
46
|
-
show(`${(identities.groups.
|
|
45
|
+
if (!list.children.length) { const row = document.createElement("tr"); const cell = document.createElement("td"); cell.colSpan = 4; cell.textContent = "暂无 AID"; row.append(cell); list.append(row); }
|
|
46
|
+
show(`${(identities.groups.muAgentBridge || []).length} 个已连接,${(identities.groups.local || []).length} 个本机 AID`);
|
|
47
47
|
} catch (error) { show(String(error), true); }
|
|
48
48
|
finally { loading = false; }
|
|
49
49
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-bridge-aun",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "mu-agent-bridge 的 AUN 通道插件。",
|
|
5
|
-
"keywords": [
|
|
6
|
-
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mu-agent-bridge-plugin",
|
|
7
|
+
"mu-agent-bridge-channel"
|
|
8
|
+
],
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://codeup.aliyun.com/6808da56fb3da14b899afd54/agent_bridge.git",
|
|
12
|
+
"directory": "packages/aun"
|
|
13
|
+
},
|
|
7
14
|
"main": "dist/src-ts/plugins/aun/index.js",
|
|
8
|
-
"files": [
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
15
|
+
"files": [
|
|
16
|
+
"dist/",
|
|
17
|
+
"plugin.json",
|
|
18
|
+
"config.schema.json",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"agentBridge": {
|
|
22
|
+
"plugin": "./plugin.json",
|
|
23
|
+
"type": "channel"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public",
|
|
27
|
+
"registry": "https://registry.npmjs.org"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=22.16.0"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@agentunion/fastaun": "0.5.18"
|
|
34
|
+
}
|
|
13
35
|
}
|
package/plugin.json
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "aun",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"type": "channel",
|
|
5
5
|
"displayName": "AUN 通道",
|
|
6
6
|
"entry": "dist/src-ts/plugins/aun/index.js",
|
|
7
7
|
"apiVersion": "1",
|
|
8
8
|
"process": "in-process",
|
|
9
|
-
"capabilities": [
|
|
9
|
+
"capabilities": [
|
|
10
|
+
"channel",
|
|
11
|
+
"channel.identity.create",
|
|
12
|
+
"channel.receive",
|
|
13
|
+
"channel.send",
|
|
14
|
+
"health"
|
|
15
|
+
],
|
|
10
16
|
"configSchema": "config.schema.json",
|
|
11
17
|
"managementPage": "/abweb/channels/aun"
|
|
12
18
|
}
|
package/dist/src-ts/channel.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.listExistingAids = listExistingAids;
|
|
4
|
-
const promises_1 = require("node:fs/promises");
|
|
5
|
-
const node_os_1 = require("node:os");
|
|
6
|
-
const node_path_1 = require("node:path");
|
|
7
|
-
async function listExistingAids() {
|
|
8
|
-
const root = (0, node_path_1.resolve)(process.env.EVOLCORE_HOME ?? (0, node_path_1.join)((0, node_os_1.homedir)(), ".evolcore"), "AIDs");
|
|
9
|
-
let names;
|
|
10
|
-
try {
|
|
11
|
-
names = await (0, promises_1.readdir)(root);
|
|
12
|
-
}
|
|
13
|
-
catch {
|
|
14
|
-
return [];
|
|
15
|
-
}
|
|
16
|
-
const available = await Promise.all(names.filter((name) => /^[a-zA-Z0-9.-]+$/.test(name)).map(async (name) => {
|
|
17
|
-
try {
|
|
18
|
-
await (0, promises_1.access)((0, node_path_1.join)(root, name, "private", "key.json"));
|
|
19
|
-
return name;
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
return undefined;
|
|
23
|
-
}
|
|
24
|
-
}));
|
|
25
|
-
return available.filter((name) => Boolean(name)).sort();
|
|
26
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.runEc = runEc;
|
|
4
|
-
exports.configureAidForPlugin = configureAidForPlugin;
|
|
5
|
-
exports.listConnectedAids = listConnectedAids;
|
|
6
|
-
const node_child_process_1 = require("node:child_process");
|
|
7
|
-
const node_util_1 = require("node:util");
|
|
8
|
-
const local_aids_1 = require("../../local-aids");
|
|
9
|
-
const execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
10
|
-
async function runEc(args) {
|
|
11
|
-
try {
|
|
12
|
-
const { stdout } = await execFileAsync("ec", args, { shell: process.platform === "win32", timeout: 15_000, maxBuffer: 1024 * 1024 });
|
|
13
|
-
return JSON.parse(stdout);
|
|
14
|
-
}
|
|
15
|
-
catch (error) {
|
|
16
|
-
const stdout = error.stdout;
|
|
17
|
-
if (stdout) {
|
|
18
|
-
try {
|
|
19
|
-
return JSON.parse(stdout);
|
|
20
|
-
}
|
|
21
|
-
catch { /* 保留原始命令错误 */ }
|
|
22
|
-
}
|
|
23
|
-
throw error;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
async function configureAidForPlugin(pluginId, aid, port, run = runEc) {
|
|
27
|
-
if (!aid)
|
|
28
|
-
return;
|
|
29
|
-
if (!/^[a-z0-9_-]+$/.test(pluginId))
|
|
30
|
-
throw new Error("插件 ID 格式无效");
|
|
31
|
-
const path = pluginId === "dsh" ? "/dsh/v1" : pluginId === "qwenwork" ? "/v1" : `/api/agents/${pluginId}/v1`;
|
|
32
|
-
for (const [key, value] of [
|
|
33
|
-
["baseagents.ecagent.baseUrl", `http://127.0.0.1:${port}${path}`],
|
|
34
|
-
["baseagents.ecagent.apiKey", "mab-local"],
|
|
35
|
-
["baseagents.ecagent.model", pluginId],
|
|
36
|
-
["active_baseagent", "ecagent"],
|
|
37
|
-
]) {
|
|
38
|
-
const result = await run(["agent", "set", aid, key, value, "--format", "json"]);
|
|
39
|
-
if (!result?.ok)
|
|
40
|
-
throw new Error(`配置 AID ${aid} 失败:${key};${result?.code ?? ""} ${result?.error ?? "未知错误"}`);
|
|
41
|
-
}
|
|
42
|
-
const result = await run(["agent", "reload", aid, "--format", "json"]);
|
|
43
|
-
if (!result?.ok)
|
|
44
|
-
throw new Error(`重载 AID ${aid} 失败:${result?.code ?? ""} ${result?.error ?? "未知错误"}`);
|
|
45
|
-
}
|
|
46
|
-
async function listConnectedAids(run = runEc) {
|
|
47
|
-
const result = await run(["agent", "list", "--format", "json"]);
|
|
48
|
-
if (!result.ok || !Array.isArray(result.agents))
|
|
49
|
-
throw new Error("读取 EvolCore Agent 列表失败");
|
|
50
|
-
const candidates = result.agents.filter((agent) => agent.status === "running" && typeof agent.aid === "string" && /^[a-zA-Z0-9.-]+$/.test(agent.aid) && agent.channels?.some((channel) => channel.startsWith("aun#")));
|
|
51
|
-
const details = await Promise.all(candidates.map((agent) => run(["agent", "show", agent.aid, "--format", "json"]).catch(() => null)));
|
|
52
|
-
const local = new Set(await (0, local_aids_1.listExistingAids)());
|
|
53
|
-
return details.filter((detail) => detail?.ok && detail.status === "running" && detail.connection?.status === "connected" && local.has(detail.aid)).map((detail) => detail.aid).sort();
|
|
54
|
-
}
|