agent-bridge-aun 1.0.32 → 1.0.34

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.
@@ -12,7 +12,7 @@ const agent_1 = require("../../agent");
12
12
  const messages_1 = require("./messages");
13
13
  const attachments_1 = require("./attachments");
14
14
  const manifest = {
15
- id: "aun", version: "1.0.32", type: "channel", displayName: "AUN 通道",
15
+ id: "aun", version: "1.0.34", type: "channel", displayName: "AUN 通道",
16
16
  entry: "dist/src-ts/plugins/aun/index.js", apiVersion: "1", process: "in-process",
17
17
  capabilities: ["channel", "channel.identity.create", "channel.receive", "channel.send", "health", "cli"],
18
18
  configSchema: "config.schema.json",
@@ -83,10 +83,11 @@ class AunPlugin {
83
83
  identity = {
84
84
  list: async () => {
85
85
  const own = new Set([...this.createdAids, ...this.legacyCreatedAids]);
86
+ const known = new Set([...this.clients.keys(), ...this.listStoreAids()]);
86
87
  return {
87
- evolcore: [...this.clients.keys()].filter((aid) => !own.has(aid)).sort(),
88
- muAgentBridge: [...this.clients.keys()].filter((aid) => own.has(aid)).sort(),
89
- localMuAgentBridge: [...own].filter((aid) => !this.clients.has(aid)).sort(),
88
+ evolcore: [...known].filter((aid) => !own.has(aid)).sort(),
89
+ muAgentBridge: [...known].filter((aid) => own.has(aid)).sort(),
90
+ localMuAgentBridge: [...own].filter((aid) => !known.has(aid)).sort(),
90
91
  };
91
92
  },
92
93
  create: async (aid, owner) => {
@@ -124,42 +125,29 @@ class AunPlugin {
124
125
  }
125
126
  },
126
127
  bind: async (pluginId, aid, _port) => {
128
+ if (!aid || !aidPattern.test(aid))
129
+ throw new Error("AID 格式无效,必须指定要关联的 AID");
127
130
  if (pluginId === "aun" || pluginId === "abweb")
128
131
  throw new Error("只能关联 Agent 插件");
132
+ if (this.context?.pluginStatus(pluginId) !== "ready")
133
+ throw new Error("目标 Agent 插件未启动");
129
134
  const previous = this.bindings;
130
135
  const previousTimes = this.bindingTimes;
131
- this.bindings = { ...previous };
132
- this.bindingTimes = { ...previousTimes };
136
+ const connection = this.clients.get(aid);
137
+ const hadIdentity = this.identities.has(aid);
138
+ const hadSubscription = Boolean(connection?.subscription);
133
139
  try {
134
- if (aid) {
135
- if (!aidPattern.test(aid))
136
- throw new Error("AID 格式无效");
137
- if (this.context?.pluginStatus(pluginId) !== "ready")
138
- throw new Error("目标 Agent 插件未启动");
139
- if (this.identities.has(aid) || this.legacyCreatedAids.has(aid)) {
140
- if (!this.clients.has(aid))
141
- await this.connectAid(aid);
142
- if (!this.clients.has(aid))
143
- throw new Error("AID 当前未连接");
144
- this.bindings[aid] = pluginId;
145
- }
146
- else {
147
- // 本地身份由插件直接接管,不再通过 ec 配置路由。
148
- const loaded = this.store.load(aid);
149
- if (!loaded.ok || !loaded.data)
150
- throw new Error("AID 不在本地密钥库中,无法关联");
151
- this.identities.add(aid);
152
- if (!this.clients.has(aid))
153
- await this.connectAid(aid);
154
- if (!this.clients.has(aid))
155
- throw new Error("AID 当前未连接");
156
- this.bindings[aid] = pluginId;
157
- }
158
- }
159
- else
160
- throw new Error("必须指定要关联的 AID");
161
- if (aid)
162
- this.bindingTimes[aid] = new Date().toISOString();
140
+ const loaded = this.store.load(aid);
141
+ if (!loaded.ok || !loaded.data)
142
+ throw new Error("AID 不在本地密钥库中,无法关联");
143
+ this.identities.add(aid);
144
+ if (!connection)
145
+ await this.connectAid(aid);
146
+ if (!this.clients.has(aid))
147
+ throw new Error("AID 当前未连接");
148
+ this.bindings = { ...previous, [aid]: pluginId };
149
+ this.bindingTimes = { ...previousTimes, [aid]: new Date().toISOString() };
150
+ this.subscribeAid(aid);
163
151
  await this.persist();
164
152
  }
165
153
  catch (error) {
@@ -167,6 +155,29 @@ class AunPlugin {
167
155
  this.bindingTimes = previousTimes;
168
156
  this.config.bindings = previous;
169
157
  this.config.binding_times = previousTimes;
158
+ if (!hadIdentity)
159
+ this.identities.delete(aid);
160
+ this.config.identities = [...this.identities].sort();
161
+ if (!hadSubscription) {
162
+ this.clients.get(aid)?.subscription?.unsubscribe();
163
+ if (connection)
164
+ connection.subscription = undefined;
165
+ }
166
+ if (!connection) {
167
+ try {
168
+ await this.clients.get(aid)?.client.close();
169
+ }
170
+ catch (closeError) {
171
+ this.context?.logger.warn("AUN 关联回滚关闭连接失败", { aid, error: safeError(closeError) });
172
+ }
173
+ finally {
174
+ this.clients.delete(aid);
175
+ if (!this.clients.size) {
176
+ this.status = "degraded";
177
+ this.healthMessage = "暂无已连接 AID";
178
+ }
179
+ }
180
+ }
170
181
  this.context?.logger.error("AUN 身份关联失败", { aid, pluginId, error: safeError(error) });
171
182
  throw error;
172
183
  }
@@ -177,6 +188,8 @@ class AunPlugin {
177
188
  throw new Error("AID 格式无效");
178
189
  if (this.bindings[aid] !== pluginId)
179
190
  throw new Error("指定 AID 当前未关联到该 Agent");
191
+ if ([...this.pendingMessages.keys()].some(key => JSON.parse(key)[0] === aid))
192
+ throw new Error("该 AID 正在处理消息,请等待任务完成后再解绑");
180
193
  const previous = this.bindings;
181
194
  const previousTimes = this.bindingTimes;
182
195
  this.bindings = { ...previous };
@@ -193,6 +206,21 @@ class AunPlugin {
193
206
  this.config.binding_times = previousTimes;
194
207
  throw error;
195
208
  }
209
+ const connection = this.clients.get(aid);
210
+ connection?.subscription?.unsubscribe();
211
+ try {
212
+ await connection?.client.close();
213
+ }
214
+ catch (error) {
215
+ this.context?.logger.warn("AUN 解绑已完成,关闭连接失败", { aid, pluginId, error: safeError(error) });
216
+ }
217
+ finally {
218
+ this.clients.delete(aid);
219
+ if (!this.clients.size) {
220
+ this.status = "degraded";
221
+ this.healthMessage = "暂无已连接 AID";
222
+ }
223
+ }
196
224
  this.context?.logger.info("AUN 单个身份关联已解除", { aid, pluginId });
197
225
  },
198
226
  };
@@ -206,6 +234,7 @@ class AunPlugin {
206
234
  async activate(context) {
207
235
  this.context = context;
208
236
  this.config = { ...context.config };
237
+ this.identities.clear();
209
238
  this.legacyCreatedAids.clear();
210
239
  this.createdAids.clear();
211
240
  try {
@@ -265,15 +294,25 @@ class AunPlugin {
265
294
  if (this.aid)
266
295
  this.identities.add(this.aid);
267
296
  this.acceptingMessages = true;
268
- for (const aid of this.identities)
269
- await this.connectAid(aid);
270
- // 密钥库中的其余 AID 也自动连接:不再依赖 ec 或 EvolCore 进程
271
- for (const aid of this.listStoreAids()) {
272
- this.identities.add(aid);
273
- if (!this.clients.has(aid))
297
+ // 只订阅明确关联 Agent 的身份,避免接管 EvolCore 或其它 AID 的消息。
298
+ for (const aid of Object.keys(this.bindings)) {
299
+ const target = this.bindings[aid];
300
+ if (!target || !context.pluginStatus(target)) {
301
+ context.logger.warn("AUN 跳过目标插件不存在的旧绑定,未连接身份", { aid, agentPlugin: target });
302
+ continue;
303
+ }
304
+ if (context.pluginStatus(target) !== "ready")
305
+ context.logger.warn("AUN 恢复已有显式绑定,目标插件尚未就绪;关联保持不变", { aid, agentPlugin: target, status: context.pluginStatus(target) });
306
+ if (aidPattern.test(aid))
274
307
  await this.connectAid(aid);
275
308
  }
276
309
  }
310
+ subscribeAid(aid) {
311
+ const connection = this.clients.get(aid);
312
+ if (!connection || connection.subscription || !this.bindings[aid])
313
+ return;
314
+ connection.subscription = connection.client.on("message.received", (payload) => this.onMessage(payload, aid));
315
+ }
277
316
  async connectAid(aid) {
278
317
  try {
279
318
  await this.prepareTrustRoots(aid);
@@ -281,7 +320,7 @@ class AunPlugin {
281
320
  if (!loaded.ok || !loaded.data)
282
321
  throw new Error(loaded.error?.message ?? "本地密钥库中不存在该 AID");
283
322
  const client = new this.sdk.AUNClient(loaded.data.aid);
284
- const subscription = this.identities.has(aid) || this.legacyCreatedAids.has(aid)
323
+ const subscription = this.bindings[aid]
285
324
  ? client.on("message.received", (payload) => this.onMessage(payload, aid))
286
325
  : undefined;
287
326
  try {
@@ -945,7 +984,7 @@ class AunPlugin {
945
984
  exports.AunPlugin = AunPlugin;
946
985
  exports.default = AunPlugin;
947
986
  function safeError(error) {
948
- return redact(error instanceof Error ? error.message : String(error)).slice(0, 240);
987
+ return redact(error instanceof Error ? error.message : String(error));
949
988
  }
950
989
  async function readResponse(response, limit) {
951
990
  if (!response.body) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-bridge-aun",
3
- "version": "1.0.32",
3
+ "version": "1.0.34",
4
4
  "description": "mu-agent-bridge 的 AUN 通道插件。",
5
5
  "keywords": [
6
6
  "mu-agent-bridge-plugin",
package/plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "aun",
3
- "version": "1.0.32",
3
+ "version": "1.0.34",
4
4
  "type": "channel",
5
5
  "displayName": "AUN 通道",
6
6
  "entry": "dist/src-ts/plugins/aun/index.js",