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 CHANGED
@@ -6,4 +6,4 @@
6
6
 
7
7
  该插件依赖 `@agentunion/fastaun`,要求 Node.js 22.16 或更高版本。
8
8
 
9
- ABWeb 的 AUN 设置仅展示已连接 AID。列表先显示已关联 Agent 的身份,同类中本工程身份在 EvolCore 身份前面;各组按最近成功关联的时间倒序排列,时间相同或旧记录没有时间时按 AID 名称排序。关联时间保存在插件配置的 `binding_times` 中,刷新或重启后保留;旧记录不补造时间,再次关联成功后开始记录。
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.4", type: "channel", displayName: "AUN 通道",
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
- const connected = await (this.options.connectedAids ?? evolcore_1.listConnectedAids)().catch((error) => {
60
- this.context?.logger.warn("查询 EvolCore 已连接身份失败", { error: safeError(error) });
61
- return [];
62
- });
56
+ // 不再依赖 ec 命令:本地密钥库的 AID 全部列出,本工程连接的 AID 以 clients 为准
57
+ const local = this.listStoreAids();
63
58
  return {
64
- evolcore: connected.filter((aid) => !this.identities.has(aid) && !this.legacyCreatedAids.has(aid)),
65
- muAgentBridge: [...new Set([...this.clients.keys(), ...connected.filter((aid) => this.legacyCreatedAids.has(aid))])].sort(),
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, port) => {
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
- if (!(await (0, evolcore_1.listConnectedAids)()).includes(aid))
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 = (await (0, local_aids_1.listExistingAids)()).filter((aid) => !connected.has(aid));
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 || []], ["EvolCore · 已连接", identities.groups.evolcore || []]]
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 = "暂无已连接 AID"; row.append(cell); list.append(row); }
46
- show(`${(identities.groups.evolcore || []).length + (identities.groups.muAgentBridge || []).length} 个已连接 AID`);
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.4",
3
+ "version": "1.0.6",
4
4
  "description": "mu-agent-bridge 的 AUN 通道插件。",
5
- "keywords": ["mu-agent-bridge-plugin", "mu-agent-bridge-channel"],
6
- "repository": { "type": "git", "url": "https://codeup.aliyun.com/6808da56fb3da14b899afd54/agent_bridge.git", "directory": "packages/aun" },
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": ["dist/", "plugin.json", "config.schema.json", "README.md"],
9
- "agentBridge": { "plugin": "./plugin.json", "type": "channel" },
10
- "publishConfig": { "access": "public", "registry": "https://registry.npmjs.org" },
11
- "engines": { "node": ">=22.16.0" },
12
- "dependencies": { "@agentunion/fastaun": "0.5.18" }
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.4",
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": ["channel", "channel.identity.create", "channel.receive", "channel.send", "health"],
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
  }
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -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
- }