evolclaw 3.1.4 → 3.1.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/CHANGELOG.md +60 -0
- package/dist/agents/claude-runner.js +398 -161
- package/dist/agents/kit-renderer.js +191 -25
- package/dist/aun/aid/agentmd.js +75 -103
- package/dist/aun/aid/client.js +1 -29
- package/dist/aun/aid/identity.js +105 -64
- package/dist/aun/aid/index.js +2 -1
- package/dist/aun/aid/store.js +74 -0
- package/dist/aun/msg/group.js +2 -2
- package/dist/aun/msg/p2p.js +26 -2
- package/dist/aun/rpc/connection.js +23 -30
- package/dist/channels/aun.js +174 -99
- package/dist/channels/dingtalk.js +2 -1
- package/dist/channels/feishu.js +301 -199
- package/dist/channels/qqbot.js +2 -1
- package/dist/channels/wechat.js +2 -1
- package/dist/channels/wecom.js +2 -1
- package/dist/cli/agent.js +21 -16
- package/dist/cli/bench.js +41 -28
- package/dist/cli/help.js +8 -0
- package/dist/cli/index.js +176 -87
- package/dist/cli/init-channel.js +5 -1
- package/dist/cli/init.js +37 -21
- package/dist/cli/link-rules.js +1 -7
- package/dist/cli/model.js +549 -0
- package/dist/cli/net-check.js +133 -50
- package/dist/cli/watch-msg.js +7 -7
- package/dist/cli/watch-web/debug-log.js +18 -0
- package/dist/cli/watch-web/server.js +306 -0
- package/dist/cli/watch-web/sources/aid.js +63 -0
- package/dist/cli/watch-web/sources/msg.js +70 -0
- package/dist/cli/watch-web/sources/session.js +638 -0
- package/dist/cli/watch-web/sources/types.js +10 -0
- package/dist/cli/watch-web/static/app.js +546 -0
- package/dist/cli/watch-web/static/index.html +54 -0
- package/dist/cli/watch-web/static/style.css +247 -0
- package/dist/config-store.js +1 -22
- package/dist/core/channel-loader.js +7 -4
- package/dist/core/command-handler.js +261 -133
- package/dist/core/evolagent-registry.js +1 -1
- package/dist/core/evolagent.js +4 -22
- package/dist/core/interaction-router.js +59 -0
- package/dist/core/message/im-renderer.js +9 -20
- package/dist/core/message/message-bridge.js +13 -9
- package/dist/core/message/message-log.js +2 -2
- package/dist/core/message/message-processor.js +211 -123
- package/dist/core/message/stream-idle-monitor.js +21 -0
- package/dist/core/model/model-catalog.js +215 -0
- package/dist/core/model/model-scope.js +250 -0
- package/dist/core/relation/peer-identity.js +58 -55
- package/dist/core/relation/peer-key.js +16 -0
- package/dist/core/session/session-fs-store.js +34 -55
- package/dist/core/session/session-key.js +24 -0
- package/dist/core/session/session-manager.js +308 -251
- package/dist/core/session/session-mapper.js +9 -4
- package/dist/core/trigger/manager.js +3 -3
- package/dist/core/trigger/parser.js +4 -4
- package/dist/core/trigger/scheduler.js +22 -7
- package/dist/index.js +61 -7
- package/dist/ipc.js +23 -1
- package/dist/utils/error-utils.js +6 -0
- package/dist/utils/process-introspect.js +7 -5
- package/kits/docs/GUIDE.md +2 -2
- package/kits/docs/INDEX.md +8 -8
- package/kits/docs/channels/aun.md +56 -17
- package/kits/docs/channels/feishu.md +41 -12
- package/kits/docs/context-assembly.md +182 -0
- package/kits/docs/evolclaw/INDEX.md +43 -0
- package/kits/docs/evolclaw/agent.md +49 -0
- package/kits/docs/evolclaw/aid.md +49 -0
- package/kits/docs/evolclaw/ctl.md +46 -0
- package/kits/docs/evolclaw/group.md +89 -0
- package/kits/docs/evolclaw/model.md +51 -0
- package/kits/docs/evolclaw/msg.md +91 -0
- package/kits/docs/evolclaw/rpc.md +35 -0
- package/kits/docs/evolclaw/storage.md +49 -0
- package/kits/docs/venues/aun-group.md +10 -0
- package/kits/docs/venues/aun-private.md +10 -0
- package/kits/docs/venues/client-desktop.md +10 -0
- package/kits/docs/venues/client-mobile.md +10 -0
- package/kits/docs/venues/feishu-group.md +13 -0
- package/kits/docs/venues/feishu-private.md +9 -0
- package/kits/docs/venues/group.md +23 -0
- package/kits/docs/venues/private.md +10 -0
- package/kits/eck_manifest.json +81 -36
- package/kits/rules/01-overview.md +20 -10
- package/kits/rules/06-channel.md +34 -27
- package/kits/templates/system-fragments/baseagent.md +7 -1
- package/kits/templates/system-fragments/channel.md +7 -5
- package/kits/templates/system-fragments/commands.md +19 -0
- package/kits/templates/system-fragments/session.md +19 -3
- package/kits/templates/system-fragments/venue.md +24 -0
- package/package.json +10 -5
- package/dist/aun/aid/lifecycle-log.js +0 -33
- package/dist/utils/aid-lifecycle-log.js +0 -33
- package/kits/docs/evolclaw/AGENT_CMD.md +0 -31
- package/kits/docs/evolclaw/MSG_GROUP.md +0 -30
- package/kits/docs/evolclaw/MSG_PRIVATE.md +0 -72
- package/kits/docs/evolclaw/tools.md +0 -25
package/dist/aun/aid/identity.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import crypto from 'crypto';
|
|
4
|
-
import {
|
|
4
|
+
import { getAidStore, loadAid, loadClient, AidLoadError, SLOT } from './store.js';
|
|
5
|
+
import { downloadCaRoot } from './client.js';
|
|
5
6
|
import { resolvePaths, agentMdPath, aunPath as defaultAunPath } from '../../paths.js';
|
|
6
7
|
// ==================== Validation ====================
|
|
7
8
|
export function isValidAid(name) {
|
|
@@ -94,41 +95,39 @@ export function aidList(aunPath) {
|
|
|
94
95
|
*/
|
|
95
96
|
export async function verifySignAbility(aid, opts) {
|
|
96
97
|
const aunPath = opts?.aunPath ?? defaultAunPath();
|
|
97
|
-
let
|
|
98
|
+
let ownStore = null;
|
|
98
99
|
try {
|
|
99
|
-
let
|
|
100
|
-
if (!
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
let store = opts?.store;
|
|
101
|
+
if (!store) {
|
|
102
|
+
store = await getAidStore({ slotId: SLOT.cli, aunPath });
|
|
103
|
+
ownStore = store;
|
|
103
104
|
}
|
|
104
|
-
|
|
105
|
-
let
|
|
105
|
+
// 加载本地 AID 值对象(含私钥),sign + verify 全本地完成
|
|
106
|
+
let aidObj;
|
|
106
107
|
try {
|
|
107
|
-
|
|
108
|
+
aidObj = loadAid(store, aid);
|
|
108
109
|
}
|
|
109
110
|
catch (e) {
|
|
110
|
-
|
|
111
|
+
const code = e instanceof AidLoadError ? e.code : 'LOAD_FAILED';
|
|
112
|
+
return { ok: false, reason: `load failed: ${code} ${String(e?.message || e).slice(0, 100)}` };
|
|
111
113
|
}
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
if (!
|
|
115
|
-
return { ok: false, reason:
|
|
116
|
-
let result;
|
|
117
|
-
try {
|
|
118
|
-
result = await client.auth.verifyAgentMd(signed, { aid, certPem });
|
|
114
|
+
const probe = `# probe\naid: "${aid}"\n`;
|
|
115
|
+
const signRes = aidObj.signAgentMd(probe);
|
|
116
|
+
if (!signRes.ok) {
|
|
117
|
+
return { ok: false, reason: `sign failed: ${String(signRes.error?.message || signRes.error?.code).slice(0, 120)}` };
|
|
119
118
|
}
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
const verifyRes = aidObj.verifyAgentMd(signRes.data.signed);
|
|
120
|
+
if (!verifyRes.ok) {
|
|
121
|
+
return { ok: false, reason: `verify threw: ${String(verifyRes.error?.message || verifyRes.error?.code).slice(0, 120)}` };
|
|
122
122
|
}
|
|
123
|
-
|
|
124
|
-
if (verified)
|
|
123
|
+
if (verifyRes.data.status === 'verified')
|
|
125
124
|
return { ok: true };
|
|
126
|
-
return { ok: false, reason: `verify failed: ${
|
|
125
|
+
return { ok: false, reason: `verify failed: ${verifyRes.data.status ?? 'unknown'}${verifyRes.data.reason ? ' — ' + verifyRes.data.reason : ''}` };
|
|
127
126
|
}
|
|
128
127
|
finally {
|
|
129
|
-
if (
|
|
128
|
+
if (ownStore) {
|
|
130
129
|
try {
|
|
131
|
-
|
|
130
|
+
ownStore.close();
|
|
132
131
|
}
|
|
133
132
|
catch { /* ignore */ }
|
|
134
133
|
}
|
|
@@ -141,7 +140,7 @@ export async function verifySignAbility(aid, opts) {
|
|
|
141
140
|
export async function aidListVerified(aunPath) {
|
|
142
141
|
const list = aidList(aunPath);
|
|
143
142
|
const root = aunPath ?? defaultAunPath();
|
|
144
|
-
const
|
|
143
|
+
const store = await getAidStore({ slotId: SLOT.cli, aunPath: root });
|
|
145
144
|
try {
|
|
146
145
|
for (const a of list) {
|
|
147
146
|
// canSign=false 的 AID 不必跑实测,结论已经明确
|
|
@@ -161,7 +160,7 @@ export async function aidListVerified(aunPath) {
|
|
|
161
160
|
});
|
|
162
161
|
continue;
|
|
163
162
|
}
|
|
164
|
-
const r = await verifySignAbility(a.aid, { aunPath: root,
|
|
163
|
+
const r = await verifySignAbility(a.aid, { aunPath: root, store });
|
|
165
164
|
a.signVerified = r.ok;
|
|
166
165
|
if (!r.ok)
|
|
167
166
|
a.signError = r.reason;
|
|
@@ -173,7 +172,7 @@ export async function aidListVerified(aunPath) {
|
|
|
173
172
|
}
|
|
174
173
|
finally {
|
|
175
174
|
try {
|
|
176
|
-
|
|
175
|
+
store.close();
|
|
177
176
|
}
|
|
178
177
|
catch { /* ignore */ }
|
|
179
178
|
}
|
|
@@ -182,43 +181,79 @@ export async function aidListVerified(aunPath) {
|
|
|
182
181
|
export async function aidCreate(aid, opts) {
|
|
183
182
|
const aunPath = opts?.aunPath ?? defaultAunPath();
|
|
184
183
|
const aidDir = path.join(aunPath, 'AIDs', aid);
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
const result = await client.auth.createAid({ aid });
|
|
193
|
-
const gateway = result.gateway || '';
|
|
194
|
-
const caDownloaded = await downloadCaRoot(aunPath, gateway);
|
|
195
|
-
const caCertPath = path.join(aunPath, 'CA', 'root', 'root.crt');
|
|
196
|
-
if (caDownloaded && fs.existsSync(caCertPath)) {
|
|
184
|
+
const hasPrivateKey = fs.existsSync(path.join(aidDir, 'private'));
|
|
185
|
+
// 如果私钥已存在,先验证签名能力
|
|
186
|
+
if (hasPrivateKey) {
|
|
187
|
+
const verifyResult = await verifySignAbility(aid, { aunPath });
|
|
188
|
+
if (verifyResult.ok) {
|
|
189
|
+
// 身份有效:加载并认证,返回已认证的 client
|
|
190
|
+
const store = await getAidStore({ slotId: SLOT.cli, aunPath });
|
|
197
191
|
try {
|
|
198
|
-
await
|
|
192
|
+
const client = await loadClient(store, aid);
|
|
193
|
+
const auth = await client.authenticate();
|
|
194
|
+
return { aid, alreadyExisted: true, gateway: String(auth?.gateway ?? ''), client, store };
|
|
199
195
|
}
|
|
200
|
-
catch {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
let gatewayUrl = gateway;
|
|
205
|
-
if (!gatewayUrl) {
|
|
206
|
-
try {
|
|
207
|
-
const discovery = new GatewayDiscovery({});
|
|
208
|
-
gatewayUrl = await discovery.discover(`https://${aid}/.well-known/aun-gateway`);
|
|
196
|
+
catch (e) {
|
|
197
|
+
store.close();
|
|
198
|
+
throw e;
|
|
209
199
|
}
|
|
210
|
-
catch { /* fall through */ }
|
|
211
200
|
}
|
|
212
|
-
|
|
213
|
-
|
|
201
|
+
// 签名验证失败
|
|
202
|
+
if (!opts?.force) {
|
|
203
|
+
const error = new Error(`AID ${aid} 已存在但身份无效(${verifyResult.reason || '签名验证失败'})。\n` +
|
|
204
|
+
`使用 --force 参数尝试恢复或重新注册。`);
|
|
205
|
+
error.code = 'AID_INVALID';
|
|
206
|
+
error.reason = verifyResult.reason;
|
|
207
|
+
throw error;
|
|
208
|
+
}
|
|
209
|
+
// --force:先尝试 authenticate 恢复证书
|
|
210
|
+
const recoverStore = await getAidStore({ slotId: SLOT.cli, aunPath });
|
|
211
|
+
try {
|
|
212
|
+
const recoverClient = await loadClient(recoverStore, aid);
|
|
213
|
+
const auth = await recoverClient.authenticate();
|
|
214
|
+
return { aid, alreadyExisted: true, gateway: String(auth?.gateway ?? ''), client: recoverClient, store: recoverStore };
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
recoverStore.close();
|
|
218
|
+
fs.rmSync(aidDir, { recursive: true, force: true });
|
|
214
219
|
}
|
|
215
|
-
return { aid, alreadyExisted: false, gateway: gatewayUrl, client };
|
|
216
220
|
}
|
|
217
|
-
|
|
221
|
+
// 新注册流程:AIDStore.register → downloadCaRoot → load → authenticate
|
|
222
|
+
const store = await getAidStore({ slotId: SLOT.cli, aunPath });
|
|
223
|
+
try {
|
|
224
|
+
const regResult = await store.register(aid);
|
|
225
|
+
if (!regResult.ok) {
|
|
226
|
+
const e = new Error(regResult.error.message);
|
|
227
|
+
e.code = regResult.error.code;
|
|
228
|
+
throw e;
|
|
229
|
+
}
|
|
230
|
+
// 注册成功后下载 CA 根证书(如果还没有)
|
|
231
|
+
// 从 AID well-known 发现 gateway 用于 CA 下载
|
|
232
|
+
let gatewayUrl = '';
|
|
218
233
|
try {
|
|
219
|
-
await
|
|
234
|
+
const { GatewayDiscovery } = await import('@agentunion/fastaun');
|
|
235
|
+
const discovery = new GatewayDiscovery({});
|
|
236
|
+
gatewayUrl = await discovery.discover(`https://${aid}/.well-known/aun-gateway`);
|
|
220
237
|
}
|
|
221
|
-
catch { /*
|
|
238
|
+
catch { /* fall through */ }
|
|
239
|
+
if (gatewayUrl) {
|
|
240
|
+
await downloadCaRoot(aunPath, gatewayUrl);
|
|
241
|
+
}
|
|
242
|
+
// 重建 store(CA 可能刚下载,需要 rootCaPath 生效)
|
|
243
|
+
store.close();
|
|
244
|
+
const store2 = await getAidStore({ slotId: SLOT.cli, aunPath });
|
|
245
|
+
try {
|
|
246
|
+
const client = await loadClient(store2, aid);
|
|
247
|
+
await client.authenticate();
|
|
248
|
+
return { aid, alreadyExisted: false, gateway: gatewayUrl, client, store: store2 };
|
|
249
|
+
}
|
|
250
|
+
catch (e) {
|
|
251
|
+
store2.close();
|
|
252
|
+
throw e;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
catch (e) {
|
|
256
|
+
store.close();
|
|
222
257
|
throw e;
|
|
223
258
|
}
|
|
224
259
|
}
|
|
@@ -263,11 +298,11 @@ export async function aidShow(aid, opts) {
|
|
|
263
298
|
let agentMdSignatureReason;
|
|
264
299
|
let signVerified = null;
|
|
265
300
|
let signError;
|
|
266
|
-
// 先做一次签名自检(共享
|
|
267
|
-
const
|
|
301
|
+
// 先做一次签名自检(共享 store,避免重复起 SDK)
|
|
302
|
+
const store = await getAidStore({ slotId: SLOT.cli, aunPath });
|
|
268
303
|
try {
|
|
269
304
|
if (hasPrivateKey && certPem && !certExpired && keyMatchesCert !== false) {
|
|
270
|
-
const r = await verifySignAbility(aid, { aunPath,
|
|
305
|
+
const r = await verifySignAbility(aid, { aunPath, store });
|
|
271
306
|
signVerified = r.ok;
|
|
272
307
|
if (!r.ok)
|
|
273
308
|
signError = r.reason;
|
|
@@ -290,16 +325,22 @@ export async function aidShow(aid, opts) {
|
|
|
290
325
|
agentMdSignature = 'unsigned';
|
|
291
326
|
}
|
|
292
327
|
else {
|
|
293
|
-
|
|
294
|
-
|
|
328
|
+
// 用本地 AID 值对象验签(含本地 cert 公钥)
|
|
329
|
+
const aidObj = loadAid(store, aid);
|
|
330
|
+
const result = aidObj.verifyAgentMd(content);
|
|
331
|
+
if (!result.ok) {
|
|
332
|
+
agentMdSignature = 'unknown';
|
|
333
|
+
agentMdSignatureReason = String(result.error?.message || result.error?.code).slice(0, 100);
|
|
334
|
+
}
|
|
335
|
+
else if (result.data.status === 'verified') {
|
|
295
336
|
agentMdSignature = 'verified';
|
|
296
337
|
}
|
|
297
|
-
else if (result.status === 'unsigned') {
|
|
338
|
+
else if (result.data.status === 'unsigned') {
|
|
298
339
|
agentMdSignature = 'unsigned';
|
|
299
340
|
}
|
|
300
341
|
else {
|
|
301
342
|
agentMdSignature = 'invalid';
|
|
302
|
-
agentMdSignatureReason = result.reason;
|
|
343
|
+
agentMdSignatureReason = result.data.reason;
|
|
303
344
|
}
|
|
304
345
|
}
|
|
305
346
|
}
|
|
@@ -311,7 +352,7 @@ export async function aidShow(aid, opts) {
|
|
|
311
352
|
}
|
|
312
353
|
finally {
|
|
313
354
|
try {
|
|
314
|
-
|
|
355
|
+
store.close();
|
|
315
356
|
}
|
|
316
357
|
catch { }
|
|
317
358
|
}
|
package/dist/aun/aid/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { isValidAid, aidList, aidListVerified, aidCreate, aidShow, aidDelete, aidLookup, verifySignAbility, probePkiRecoverability, appendAidLifecycle, readAidLifecycle } from './identity.js';
|
|
2
2
|
export { buildInitialAgentMd, agentmdGet, agentmdPut, agentmdSync } from './agentmd.js';
|
|
3
|
-
export { MIN_AUN_CORE_SDK, AUN_CORE_SDK_PKG, isAunSdkVersionOk, resolveAunCoreSdkPkg, ensureAunSdk, isAunSdkReady, downloadCaRoot,
|
|
3
|
+
export { MIN_AUN_CORE_SDK, AUN_CORE_SDK_PKG, isAunSdkVersionOk, resolveAunCoreSdkPkg, ensureAunSdk, isAunSdkReady, downloadCaRoot, suppressSdkLogs, } from './client.js';
|
|
4
|
+
export { getAidStore, loadClient, loadAid, AidLoadError, SLOT } from './store.js';
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Slot 命名约定(基于 fastaun 0.4.3 隔离键语义)。
|
|
5
|
+
*
|
|
6
|
+
* slotIsolationKey 取第一个分隔符(空格/'/'/':')之前的部分作为隔离键,
|
|
7
|
+
* 隔离键相同 = 共享消费通道(token / seq 游标 / 消息过滤)。
|
|
8
|
+
*
|
|
9
|
+
* 'evolclaw daemon' → 隔离键 'evolclaw' ┐
|
|
10
|
+
* 'evolclaw cli' → 隔离键 'evolclaw' ├ 共享 evolclaw 消费通道
|
|
11
|
+
* 'evolclaw netcheck' → 隔离键 'evolclaw' ┘
|
|
12
|
+
* 'evolclaw-bench' → 隔离键 'evolclaw-bench'(连字符非分隔符)→ 独立通道
|
|
13
|
+
*
|
|
14
|
+
* 设计意图:
|
|
15
|
+
* - daemon 长连接 + cli 短连接共存于 evolclaw 通道(1 长 + N 短,短连接不踢长连接)
|
|
16
|
+
* - netcheck 长连接抢 evolclaw 长连接位 → 踢掉 daemon(用于踢人/extra_info 测试)
|
|
17
|
+
* - bench 各并发单元用 evolclaw-bench-<N>,各自独立隔离键,互不干扰
|
|
18
|
+
*/
|
|
19
|
+
export const SLOT = {
|
|
20
|
+
daemon: 'evolclaw daemon',
|
|
21
|
+
cli: 'evolclaw cli',
|
|
22
|
+
bench: 'evolclaw-bench',
|
|
23
|
+
netcheck: 'evolclaw netcheck',
|
|
24
|
+
};
|
|
25
|
+
/** 加载身份失败时抛出,携带 SDK 的错误码与消息。 */
|
|
26
|
+
export class AidLoadError extends Error {
|
|
27
|
+
code;
|
|
28
|
+
constructor(code, message) {
|
|
29
|
+
super(message);
|
|
30
|
+
this.name = 'AidLoadError';
|
|
31
|
+
this.code = code;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 统一构造 AIDStore。
|
|
36
|
+
*
|
|
37
|
+
* 接管旧 createAunClient 的职责:注入 encryptionSeed、rootCaPath、debug、slotId。
|
|
38
|
+
* deviceId 不传 —— 由 SDK 从 {aunPath}/.device_id 读取或生成(同机共享)。
|
|
39
|
+
*/
|
|
40
|
+
export async function getAidStore(opts) {
|
|
41
|
+
const { aunPath: defaultAunPath } = await import('../../paths.js');
|
|
42
|
+
const { loadProcessConfig } = await import('../../config-store.js');
|
|
43
|
+
const { AIDStore } = await import('@agentunion/fastaun');
|
|
44
|
+
const aunPath = opts.aunPath ?? defaultAunPath();
|
|
45
|
+
const encryptionSeed = loadProcessConfig().aun?.encryptionSeed
|
|
46
|
+
?? process.env.AUN_ENCRYPTION_SEED
|
|
47
|
+
?? 'evol';
|
|
48
|
+
const caCertPath = path.join(aunPath, 'CA', 'root', 'root.crt');
|
|
49
|
+
const storeOpts = {
|
|
50
|
+
aunPath,
|
|
51
|
+
encryptionSeed,
|
|
52
|
+
slotId: opts.slotId,
|
|
53
|
+
debug: opts.debug ?? false,
|
|
54
|
+
};
|
|
55
|
+
if (fs.existsSync(caCertPath))
|
|
56
|
+
storeOpts.rootCaPath = caCertPath;
|
|
57
|
+
return new AIDStore(storeOpts);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 从 store 加载本地身份并构造已就绪的 AUNClient(尚未连接)。
|
|
61
|
+
*
|
|
62
|
+
* load 失败(证书缺失/过期/链断裂/私钥不匹配等)抛 AidLoadError,携带 SDK 错误码。
|
|
63
|
+
*/
|
|
64
|
+
export async function loadClient(store, aid) {
|
|
65
|
+
const { AUNClient } = await import('@agentunion/fastaun');
|
|
66
|
+
return new AUNClient(loadAid(store, aid));
|
|
67
|
+
}
|
|
68
|
+
/** 加载本地 AID 值对象(用于离线签名/验签,无需连接)。load 失败抛 AidLoadError。 */
|
|
69
|
+
export function loadAid(store, aid) {
|
|
70
|
+
const r = store.load(aid);
|
|
71
|
+
if (!r.ok)
|
|
72
|
+
throw new AidLoadError(r.error.code, r.error.message);
|
|
73
|
+
return r.data.aid;
|
|
74
|
+
}
|
package/dist/aun/msg/group.js
CHANGED
|
@@ -70,11 +70,11 @@ export async function groupPull(args) {
|
|
|
70
70
|
export async function groupAck(args) {
|
|
71
71
|
const conn = await createShortConnection(args.from, { aunPath: args.aunPath, slotId: args.slotId });
|
|
72
72
|
try {
|
|
73
|
-
const result = await conn.call('group.ack', { group_id: args.groupId,
|
|
73
|
+
const result = await conn.call('group.ack', { group_id: args.groupId, msg_seq: args.seq });
|
|
74
74
|
return {
|
|
75
75
|
ok: true,
|
|
76
76
|
group_id: result?.group_id ?? args.groupId,
|
|
77
|
-
ack_seq: result?.ack_seq ?? args.seq,
|
|
77
|
+
ack_seq: result?.cursor ?? result?.ack_seq ?? args.seq,
|
|
78
78
|
latest_message_seq: result?.latest_message_seq,
|
|
79
79
|
};
|
|
80
80
|
}
|
package/dist/aun/msg/p2p.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import { createShortConnection } from '../rpc/index.js';
|
|
3
|
+
import { getAidStore, SLOT } from '../aid/store.js';
|
|
3
4
|
import { uploadFileAndBuildPayload } from './upload.js';
|
|
4
5
|
import { appendMessageLog, buildOutboundEntry } from '../../core/message/message-log.js';
|
|
5
6
|
import { chatDirPath } from '../../core/session/session-fs-store.js';
|
|
@@ -7,11 +8,21 @@ import { resolvePaths } from '../../paths.js';
|
|
|
7
8
|
export async function msgSend(args) {
|
|
8
9
|
const conn = await createShortConnection(args.from, { aunPath: args.aunPath, slotId: args.slotId });
|
|
9
10
|
try {
|
|
10
|
-
// 1. 解析对端身份(30
|
|
11
|
+
// 1. 解析对端身份(30天缓存)。身份解析走 HTTP+PKI(store),与发消息的短连接无关。
|
|
11
12
|
const { agentsDir } = resolvePaths();
|
|
12
13
|
const selfAgentDir = path.join(agentsDir, args.from);
|
|
13
14
|
const { PeerIdentityCache } = await import('../../core/relation/peer-identity.js');
|
|
14
|
-
const
|
|
15
|
+
const idStore = await getAidStore({ slotId: args.slotId ?? SLOT.cli, aunPath: args.aunPath });
|
|
16
|
+
let peerIdentity;
|
|
17
|
+
try {
|
|
18
|
+
peerIdentity = await PeerIdentityCache.resolve('aun', args.to, selfAgentDir, idStore, false);
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
try {
|
|
22
|
+
idStore.close();
|
|
23
|
+
}
|
|
24
|
+
catch { /* ignore */ }
|
|
25
|
+
}
|
|
15
26
|
// 2. 决定 chatmode(遵循来源1-3)
|
|
16
27
|
// 私聊:非 human 对端 → proactive,human 对端 → interactive
|
|
17
28
|
const chatmode = peerIdentity.isAgent ? 'proactive' : 'interactive';
|
|
@@ -81,6 +92,19 @@ export async function msgSend(args) {
|
|
|
81
92
|
msgType: 'text',
|
|
82
93
|
source,
|
|
83
94
|
}));
|
|
95
|
+
// 通知 daemon 更新 stats(如果 daemon 在运行)
|
|
96
|
+
try {
|
|
97
|
+
const { ipcQuery } = await import('../../ipc.js');
|
|
98
|
+
await ipcQuery(resolvePaths().socket, {
|
|
99
|
+
type: 'aun-aid-stats-record-outbound',
|
|
100
|
+
aid: args.from,
|
|
101
|
+
toPeer: args.to,
|
|
102
|
+
text: textContent,
|
|
103
|
+
encrypt: args.encrypt === true,
|
|
104
|
+
chatmode,
|
|
105
|
+
}, 1000);
|
|
106
|
+
}
|
|
107
|
+
catch { /* daemon 不在或 IPC 失败都忽略 */ }
|
|
84
108
|
}
|
|
85
109
|
catch { }
|
|
86
110
|
}
|
|
@@ -1,32 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { createAunClient } from '../aid/client.js';
|
|
3
|
-
import { loadProcessConfig } from '../../config-store.js';
|
|
1
|
+
import { getAidStore, loadClient, SLOT } from '../aid/store.js';
|
|
4
2
|
export async function createShortConnection(aid, opts) {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
await client.close();
|
|
28
|
-
}
|
|
29
|
-
catch { /* ignore */ }
|
|
30
|
-
},
|
|
31
|
-
};
|
|
3
|
+
const store = await getAidStore({ slotId: opts?.slotId ?? SLOT.cli, aunPath: opts?.aunPath });
|
|
4
|
+
try {
|
|
5
|
+
const client = await loadClient(store, aid);
|
|
6
|
+
await client.connect({ connection_kind: 'short', short_ttl_ms: 30000, auto_reconnect: false });
|
|
7
|
+
return {
|
|
8
|
+
async call(method, params) {
|
|
9
|
+
return client.call(method, params);
|
|
10
|
+
},
|
|
11
|
+
async close() {
|
|
12
|
+
try {
|
|
13
|
+
await client.close();
|
|
14
|
+
}
|
|
15
|
+
finally {
|
|
16
|
+
store.close();
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
catch (e) {
|
|
22
|
+
store.close();
|
|
23
|
+
throw e;
|
|
24
|
+
}
|
|
32
25
|
}
|