evolclaw 3.1.4 → 3.1.5
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 +10 -0
- package/dist/agents/claude-runner.js +348 -156
- package/dist/agents/kit-renderer.js +176 -21
- package/dist/aun/aid/agentmd.js +68 -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/p2p.js +26 -2
- package/dist/aun/rpc/connection.js +23 -30
- package/dist/channels/aun.js +77 -88
- package/dist/channels/dingtalk.js +1 -0
- package/dist/channels/feishu.js +270 -190
- package/dist/channels/qqbot.js +1 -0
- package/dist/channels/wechat.js +1 -0
- package/dist/channels/wecom.js +1 -0
- package/dist/cli/agent.js +11 -5
- package/dist/cli/bench.js +40 -23
- package/dist/cli/index.js +170 -44
- package/dist/cli/init-channel.js +5 -1
- package/dist/cli/model.js +324 -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/core/channel-loader.js +7 -4
- package/dist/core/command-handler.js +81 -86
- package/dist/core/evolagent-registry.js +1 -1
- package/dist/core/evolagent.js +4 -4
- package/dist/core/interaction-router.js +59 -0
- package/dist/core/message/message-bridge.js +6 -6
- package/dist/core/message/message-log.js +2 -2
- package/dist/core/message/message-processor.js +86 -101
- 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 +40 -49
- 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/scheduler.js +2 -1
- package/dist/index.js +6 -2
- package/dist/ipc.js +22 -0
- package/kits/docs/GUIDE.md +2 -2
- package/kits/docs/INDEX.md +11 -7
- package/kits/docs/channels/aun.md +56 -17
- package/kits/docs/channels/feishu.md +41 -12
- package/kits/docs/context-assembly.md +181 -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 +82 -0
- package/kits/docs/evolclaw/msg.md +86 -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 +11 -0
- package/kits/docs/venues/private.md +10 -0
- package/kits/eck_manifest.json +72 -36
- package/kits/rules/01-overview.md +20 -10
- package/kits/rules/06-channel.md +30 -27
- package/kits/templates/system-fragments/session.md +10 -3
- package/kits/templates/system-fragments/venue.md +9 -0
- package/package.json +11 -6
- 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/channels/aun.js
CHANGED
|
@@ -12,8 +12,8 @@ import { appendAidEvent } from '../utils/instance-registry.js';
|
|
|
12
12
|
import { appendMessageLog, buildOutboundEntry } from '../core/message/message-log.js';
|
|
13
13
|
import { chatDirPath } from '../core/session/session-fs-store.js';
|
|
14
14
|
import { appendAidLifecycle } from '../aun/aid/identity.js';
|
|
15
|
-
import {
|
|
16
|
-
import { loadAgent, saveAgent
|
|
15
|
+
import { getAidStore, loadClient, SLOT } from '../aun/aid/store.js';
|
|
16
|
+
import { loadAgent, saveAgent } from '../config-store.js';
|
|
17
17
|
import { getProcessStartTime } from '../utils/process-introspect.js';
|
|
18
18
|
import * as outbox from '../aun/outbox.js';
|
|
19
19
|
import { guessMime, formatSize } from '../utils/media-cache.js';
|
|
@@ -61,6 +61,9 @@ function getEvolclawVersion() {
|
|
|
61
61
|
export class AUNChannel {
|
|
62
62
|
config;
|
|
63
63
|
client = null;
|
|
64
|
+
store = null;
|
|
65
|
+
/** 实际连接的网关 URL(来自 authenticate() 返回值 / connection.state 事件),替代旧 (client as any)._gatewayUrl。 */
|
|
66
|
+
gatewayUrl = '';
|
|
64
67
|
projectPathProvider;
|
|
65
68
|
messageHandler;
|
|
66
69
|
recallHandler;
|
|
@@ -115,11 +118,6 @@ export class AUNChannel {
|
|
|
115
118
|
*/
|
|
116
119
|
async callAndTrace(method, params, opts) {
|
|
117
120
|
this.trace('OUT', method, params);
|
|
118
|
-
// [DIAG-STALE] 记录调用瞬间 SDK 内部 _state,证明是否在 reconnecting 中误发
|
|
119
|
-
const sdkStateBefore = this.client?._state ?? 'no-client';
|
|
120
|
-
if (sdkStateBefore !== 'connected') {
|
|
121
|
-
logger.warn(`[AUN][DIAG-STALE] callAndTrace ${method} on non-connected SDK: sdk_state=${sdkStateBefore} evolclaw_connected=${this.connected}`);
|
|
122
|
-
}
|
|
123
121
|
try {
|
|
124
122
|
const result = await this.client.call(method, params);
|
|
125
123
|
if (!opts?.silentOk) {
|
|
@@ -137,9 +135,6 @@ export class AUNChannel {
|
|
|
137
135
|
code: e?.code,
|
|
138
136
|
name: e?.name,
|
|
139
137
|
});
|
|
140
|
-
// [DIAG-STALE] 失败时再记录一次 SDK _state,看错误类型是否为 ConnectionError
|
|
141
|
-
const sdkStateAfter = this.client?._state ?? 'no-client';
|
|
142
|
-
logger.warn(`[AUN][DIAG-STALE] callAndTrace ${method} FAILED: err_name=${e?.name ?? '?'} err_code=${e?.code ?? '?'} sdk_state_before=${sdkStateBefore} sdk_state_after=${sdkStateAfter} evolclaw_connected=${this.connected}`);
|
|
143
138
|
logger.warn(`${this.logPrefix()} rpc ${method} failed: ${e?.name ?? ''}(${e?.code ?? ''}) ${e?.message ?? e}`);
|
|
144
139
|
throw e;
|
|
145
140
|
}
|
|
@@ -545,12 +540,17 @@ export class AUNChannel {
|
|
|
545
540
|
}
|
|
546
541
|
this.client = null;
|
|
547
542
|
}
|
|
543
|
+
if (this.store) {
|
|
544
|
+
try {
|
|
545
|
+
this.store.close();
|
|
546
|
+
}
|
|
547
|
+
catch { /* ignore */ }
|
|
548
|
+
this.store = null;
|
|
549
|
+
}
|
|
548
550
|
this.connected = false;
|
|
549
551
|
const aunPath = this.config.keystorePath || resolveRoot();
|
|
550
552
|
const aidName = this.config.aid;
|
|
551
|
-
|
|
552
|
-
|| process.env.AUN_ENCRYPTION_SEED
|
|
553
|
-
|| 'evol';
|
|
553
|
+
// encryptionSeed 由 getAidStore 内部解析(config / env / 'evol')
|
|
554
554
|
// Migration from ~/.aun is handled by ensureDataDirs() at startup with a marker file.
|
|
555
555
|
// Gateway URL 解析:优先用配置的 gatewayUrl,否则通过 well-known 自动发现
|
|
556
556
|
let gateway = this.config.gatewayUrl || '';
|
|
@@ -571,16 +571,18 @@ export class AUNChannel {
|
|
|
571
571
|
throw new Error('Cannot resolve gateway URL from AID');
|
|
572
572
|
}
|
|
573
573
|
logger.info(`${this.logPrefix()} Initializing: aid=${aidName}, gateway=${gateway}, aun_path=${aunPath}`);
|
|
574
|
-
//
|
|
575
|
-
//
|
|
576
|
-
const
|
|
574
|
+
// 构造 AIDStore(slot=evolclaw daemon,与 cli/netcheck 共享 evolclaw 隔离键)
|
|
575
|
+
// encryptionSeed / rootCaPath 由 getAidStore 内部注入
|
|
576
|
+
const store = await getAidStore({
|
|
577
|
+
slotId: SLOT.daemon,
|
|
577
578
|
aunPath,
|
|
578
|
-
|
|
579
|
-
aunSdkLog: this.config.aunSdkLog ?? true,
|
|
579
|
+
debug: this.config.aunSdkLog ?? true,
|
|
580
580
|
});
|
|
581
|
+
this.store = store;
|
|
582
|
+
const client = await loadClient(store, aidName);
|
|
581
583
|
this.client = client;
|
|
582
|
-
//
|
|
583
|
-
|
|
584
|
+
// 记录应用层发现的 gateway 作为初始值(authenticate 后会用权威值覆盖)
|
|
585
|
+
this.gatewayUrl = gateway;
|
|
584
586
|
// Register event handlers before connecting
|
|
585
587
|
client.on('message.received', (data) => {
|
|
586
588
|
this.trace('IN', 'message.received', data);
|
|
@@ -629,30 +631,16 @@ export class AUNChannel {
|
|
|
629
631
|
const d = data;
|
|
630
632
|
logger.warn(`${this.logPrefix()} Group message undecryptable: group=${d.group_id} from=${d.from} mid=${d.message_id} err=${d._decrypt_error}`);
|
|
631
633
|
});
|
|
632
|
-
// Authenticate
|
|
633
|
-
// Workaround: SDK 0.3.x _loadIdentityOrRaise doesn't set identity.aid from requested aid,
|
|
634
|
-
// causing gateway "missing aid" error. Patch to backfill aid on loaded identity.
|
|
635
|
-
const authFlow = client._auth;
|
|
636
|
-
if (authFlow && typeof authFlow._loadIdentityOrRaise === 'function') {
|
|
637
|
-
const origLoad = authFlow._loadIdentityOrRaise.bind(authFlow);
|
|
638
|
-
authFlow._loadIdentityOrRaise = (aid) => {
|
|
639
|
-
const identity = origLoad(aid);
|
|
640
|
-
if (identity && !identity.aid)
|
|
641
|
-
identity.aid = aid ?? authFlow._aid;
|
|
642
|
-
return identity;
|
|
643
|
-
};
|
|
644
|
-
}
|
|
645
|
-
let accessToken;
|
|
634
|
+
// Authenticate(拿权威 gateway 用于日志/状态;connect 内部也会复用 token)
|
|
646
635
|
try {
|
|
647
636
|
logger.info(`${this.logPrefix()} Authenticating as ${aidName}...`);
|
|
648
637
|
this.trace('OUT', 'auth.authenticate', { aid: aidName });
|
|
649
|
-
const auth = await client.
|
|
650
|
-
this.trace('OUT', 'auth.authenticate.ok', { aid:
|
|
651
|
-
this.trace('IN', 'auth.result', { aid:
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
client.
|
|
655
|
-
logger.info(`${this.logPrefix()} Authenticated as ${auth.aid ?? '?'}, gateway=${resolvedGateway}`);
|
|
638
|
+
const auth = await client.authenticate();
|
|
639
|
+
this.trace('OUT', 'auth.authenticate.ok', { aid: client.aid, gateway: auth?.gateway, hasToken: !!auth?.access_token });
|
|
640
|
+
this.trace('IN', 'auth.result', { aid: client.aid, gateway: auth?.gateway, hasToken: !!auth?.access_token });
|
|
641
|
+
const resolvedGateway = String(auth?.gateway ?? gateway);
|
|
642
|
+
this.gatewayUrl = resolvedGateway;
|
|
643
|
+
logger.info(`${this.logPrefix()} Authenticated as ${client.aid ?? '?'}, gateway=${resolvedGateway}`);
|
|
656
644
|
}
|
|
657
645
|
catch (e) {
|
|
658
646
|
const errMsg = e.message || String(e);
|
|
@@ -661,15 +649,9 @@ export class AUNChannel {
|
|
|
661
649
|
logger.error(`${this.logPrefix()} Authentication failed (${errName}): ${errMsg}`);
|
|
662
650
|
if (e.stack)
|
|
663
651
|
logger.debug(`${this.logPrefix()} Auth stack: ${e.stack}`);
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
logger.error(`${this.logPrefix()} No accessToken fallback available, scheduling retry`);
|
|
668
|
-
this.setAidStatus('failed', { lastError: `${errName}: ${errMsg}`.slice(0, 80) });
|
|
669
|
-
this.scheduleReconnect();
|
|
670
|
-
throw new Error('Authentication failed and no accessToken fallback available');
|
|
671
|
-
}
|
|
672
|
-
logger.warn(`${this.logPrefix()} Using accessToken fallback`);
|
|
652
|
+
this.setAidStatus('failed', { lastError: `${errName}: ${errMsg}`.slice(0, 80) });
|
|
653
|
+
this.scheduleReconnect();
|
|
654
|
+
throw new Error(`Authentication failed: ${errName}: ${errMsg}`);
|
|
673
655
|
}
|
|
674
656
|
// Connect (SDK auto_reconnect handles transient failures)
|
|
675
657
|
try {
|
|
@@ -678,11 +660,18 @@ export class AUNChannel {
|
|
|
678
660
|
agentName: this.config.agentName,
|
|
679
661
|
channelName: this.config.channelName,
|
|
680
662
|
});
|
|
681
|
-
this.trace('OUT', 'client.connect', { gateway:
|
|
682
|
-
await client.connect({
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
663
|
+
this.trace('OUT', 'client.connect', { gateway: this.gatewayUrl, extra_info: extraInfo });
|
|
664
|
+
await client.connect({
|
|
665
|
+
// connection_kind 默认 long;slot 已由 AID 携带(evolclaw daemon)
|
|
666
|
+
// extra_info:互踢诊断名片(0.4.3 公开 connect 已支持透传)
|
|
667
|
+
extra_info: extraInfo,
|
|
668
|
+
// max_attempts=0 = 无限重试(与 Go/Python 对齐),交由 SDK 自己跑指数退避
|
|
669
|
+
// initial_delay=1s,max_delay=300s(5min 封顶)
|
|
670
|
+
auto_reconnect: true,
|
|
671
|
+
retry_max_attempts: 0,
|
|
672
|
+
retry_initial_delay: 1.0,
|
|
673
|
+
retry_max_delay: 300.0,
|
|
674
|
+
});
|
|
686
675
|
this.trace('OUT', 'client.connect.ok', { aid: client.aid });
|
|
687
676
|
this._aid = this.client.aid ?? undefined;
|
|
688
677
|
const deviceId = this.client._device_id ?? '';
|
|
@@ -692,7 +681,7 @@ export class AUNChannel {
|
|
|
692
681
|
this.aidStatsCollector.setSelfName(this.config.aid, this._selfName);
|
|
693
682
|
this.connected = true;
|
|
694
683
|
this.connectedAt = Date.now();
|
|
695
|
-
this.setAidStatus('connected', { lastConnectedAt: Date.now(), lastError: undefined, gatewayUrl: this.
|
|
684
|
+
this.setAidStatus('connected', { lastConnectedAt: Date.now(), lastError: undefined, gatewayUrl: this.gatewayUrl });
|
|
696
685
|
// Workaround: SDK e2ee uses _identity.cert for sender_cert_fingerprint;
|
|
697
686
|
// if cert is missing, it falls back to public key SPKI fingerprint which
|
|
698
687
|
// causes peer cert lookup failures. Backfill from keystore if needed.
|
|
@@ -705,8 +694,8 @@ export class AUNChannel {
|
|
|
705
694
|
}
|
|
706
695
|
}
|
|
707
696
|
logger.info(`${this.logPrefix()} Connected as ${this._aid}`);
|
|
708
|
-
appendAidEvent({ ts: Date.now(), iso: new Date().toISOString(), event: 'connected', aid: this.config.aid, gateway: this.
|
|
709
|
-
appendAidLifecycle({ ts: Date.now(), iso: new Date().toISOString(), event: 'connected', aid: this.config.aid, gateway: this.
|
|
697
|
+
appendAidEvent({ ts: Date.now(), iso: new Date().toISOString(), event: 'connected', aid: this.config.aid, gateway: this.gatewayUrl });
|
|
698
|
+
appendAidLifecycle({ ts: Date.now(), iso: new Date().toISOString(), event: 'connected', aid: this.config.aid, gateway: this.gatewayUrl });
|
|
710
699
|
// Send welcome message to owner after first connection
|
|
711
700
|
await this.sendWelcomeMessage();
|
|
712
701
|
}
|
|
@@ -785,13 +774,10 @@ tags:
|
|
|
785
774
|
|
|
786
775
|
EvolClaw AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
787
776
|
`;
|
|
788
|
-
// Write locally
|
|
789
|
-
fs.mkdirSync(path.dirname(agentMdLocalPath), { recursive: true });
|
|
790
|
-
fs.writeFileSync(agentMdLocalPath, newAgentMd, 'utf-8');
|
|
791
|
-
logger.info(`${this.logPrefix()} Updated agent.md for ${aidName}`);
|
|
792
|
-
// Publish to AUN network via publishAgentMd (auto-sign)
|
|
777
|
+
// Write locally and publish to AUN network (auto-sign)
|
|
793
778
|
try {
|
|
794
|
-
await
|
|
779
|
+
const { agentmdPut } = await import('../aun/aid/agentmd.js');
|
|
780
|
+
await agentmdPut(newAgentMd, { aid: aidName, store: this.store });
|
|
795
781
|
logger.info(`${this.logPrefix()} Published agent.md to AUN network`);
|
|
796
782
|
}
|
|
797
783
|
catch (e) {
|
|
@@ -961,7 +947,7 @@ EvolClaw AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
961
947
|
const chatId = fromAid;
|
|
962
948
|
// 解析对端身份(30天缓存)
|
|
963
949
|
const selfAgentDir = path.join(resolvePaths().agentsDir, this.config.aid);
|
|
964
|
-
const peerIdentity = await PeerIdentityCache.resolve('aun', fromAid, selfAgentDir, this.
|
|
950
|
+
const peerIdentity = await PeerIdentityCache.resolve('aun', fromAid, selfAgentDir, this.store, false);
|
|
965
951
|
const shortAid = this.getShortAid(fromAid);
|
|
966
952
|
const displayName = peerIdentity.name || shortAid;
|
|
967
953
|
// 详细 dispatch 决策日志:记录消息为何被路由到 agent
|
|
@@ -1177,7 +1163,7 @@ EvolClaw AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
1177
1163
|
}
|
|
1178
1164
|
}
|
|
1179
1165
|
const selfAgentDir = path.join(resolvePaths().agentsDir, this.config.aid);
|
|
1180
|
-
const peerIdentity = await PeerIdentityCache.resolve('aun', senderAid, selfAgentDir, this.
|
|
1166
|
+
const peerIdentity = await PeerIdentityCache.resolve('aun', senderAid, selfAgentDir, this.store, false);
|
|
1181
1167
|
const shortAid = this.getShortAid(senderAid);
|
|
1182
1168
|
const displayName = peerIdentity.name || shortAid;
|
|
1183
1169
|
// 详细 dispatch 决策日志:记录消息为何被路由到 agent
|
|
@@ -1268,7 +1254,7 @@ EvolClaw AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
1268
1254
|
channelId: event.channelId || '',
|
|
1269
1255
|
channelType: 'aun',
|
|
1270
1256
|
content: event.text || '',
|
|
1271
|
-
|
|
1257
|
+
selfAID: this._aid,
|
|
1272
1258
|
groupId: event.groupId,
|
|
1273
1259
|
chatType: event.chatType,
|
|
1274
1260
|
peerId: event.userId || event.channelId || '',
|
|
@@ -1351,17 +1337,16 @@ EvolClaw AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
1351
1337
|
if (!data || typeof data !== 'object')
|
|
1352
1338
|
return;
|
|
1353
1339
|
const state = data.state ?? '';
|
|
1354
|
-
// [DIAG-STALE] 记录状态切换瞬间 evolclaw 的 connected 标志和 SDK 的内部 _state,
|
|
1355
|
-
// 用于证明"reconnecting 时 connected 保持 true,导致 sendMessage 误放行"的假设
|
|
1356
|
-
const sdkState = this.client?._state ?? 'no-client';
|
|
1357
|
-
const connectedBefore = this.connected;
|
|
1358
|
-
logger.info(`[AUN][DIAG-STALE] connection.state event: state=${state} attempt=${data.attempt ?? '-'} | connected_before=${connectedBefore} sdk_state=${sdkState}`);
|
|
1359
1340
|
if (state === 'connected') {
|
|
1360
1341
|
this.connected = true;
|
|
1361
1342
|
this.connectedAt = Date.now();
|
|
1362
1343
|
this.lastReconnectLogTime = 0;
|
|
1363
1344
|
this.lastReconnectLogAttempt = 0;
|
|
1364
|
-
|
|
1345
|
+
// connection.state 事件 payload 带实际连接的 gateway,更新本地缓存
|
|
1346
|
+
const evtGateway = data.gateway;
|
|
1347
|
+
if (typeof evtGateway === 'string' && evtGateway)
|
|
1348
|
+
this.gatewayUrl = evtGateway;
|
|
1349
|
+
this.setAidStatus('connected', { lastConnectedAt: Date.now(), lastError: undefined, gatewayUrl: this.gatewayUrl });
|
|
1365
1350
|
this.trace('IN', 'connection.state', data);
|
|
1366
1351
|
logger.info(`${this.logPrefix()} Connected`);
|
|
1367
1352
|
// 不在这里清 flapCount —— 短命连接一上来就会触发本分支,
|
|
@@ -1816,11 +1801,11 @@ EvolClaw AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
1816
1801
|
appendOutboundJsonl(channelId, text, msgId, encrypt, context, isGroup, msgType = 'text', source = 'daemon') {
|
|
1817
1802
|
try {
|
|
1818
1803
|
const sessionsDir = resolvePaths().sessionsDir;
|
|
1819
|
-
const
|
|
1820
|
-
const chatDir = chatDirPath(sessionsDir, 'aun', channelId,
|
|
1804
|
+
const selfAID = this.config.aid;
|
|
1805
|
+
const chatDir = chatDirPath(sessionsDir, 'aun', channelId, selfAID);
|
|
1821
1806
|
const chatmode = context?.metadata?.chatmode;
|
|
1822
1807
|
appendMessageLog(chatDir, buildOutboundEntry({
|
|
1823
|
-
from:
|
|
1808
|
+
from: selfAID,
|
|
1824
1809
|
to: channelId,
|
|
1825
1810
|
chatType: isGroup ? 'group' : 'private',
|
|
1826
1811
|
groupId: isGroup ? channelId : null,
|
|
@@ -1891,8 +1876,8 @@ EvolClaw AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
1891
1876
|
const tid = putRes?.thought_id;
|
|
1892
1877
|
logger.info(`${this.logPrefix()} thought.put ok group=${targetId} task=${taskId} stage=${stage} encrypt=${encrypt} tid=${tid ?? '?'}`);
|
|
1893
1878
|
this.eventBus?.publish?.({ type: 'message:thought-put', agentName: this.config.aid, channelId, taskId, text: thoughtText });
|
|
1894
|
-
// 文本类 thought 写入 jsonl(只对有 text 的 item,过滤 tool 等结构化项)
|
|
1895
1879
|
if (thoughtText) {
|
|
1880
|
+
this.aidStatsCollector?.recordOutbound(this.config.aid, channelId, Buffer.byteLength(thoughtText, 'utf-8'), thoughtText, false, encrypt, context?.metadata?.chatmode ?? 'proactive');
|
|
1896
1881
|
this.appendOutboundJsonl(channelId, thoughtText, tid ?? `thought-${Date.now()}`, encrypt, context, true, 'thought', 'daemon');
|
|
1897
1882
|
}
|
|
1898
1883
|
}
|
|
@@ -1903,6 +1888,7 @@ EvolClaw AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
1903
1888
|
logger.info(`${this.logPrefix()} thought.put ok p2p=${this.peerLabel(targetId)} task=${taskId} stage=${stage} encrypt=${encrypt} tid=${tid ?? '?'}`);
|
|
1904
1889
|
this.eventBus?.publish?.({ type: 'message:thought-put', agentName: this.config.aid, channelId, taskId, text: thoughtText });
|
|
1905
1890
|
if (thoughtText) {
|
|
1891
|
+
this.aidStatsCollector?.recordOutbound(this.config.aid, targetId, Buffer.byteLength(thoughtText, 'utf-8'), thoughtText, false, encrypt, context?.metadata?.chatmode ?? 'proactive');
|
|
1906
1892
|
this.appendOutboundJsonl(channelId, thoughtText, tid ?? `thought-${Date.now()}`, encrypt, context, false, 'thought', 'daemon');
|
|
1907
1893
|
}
|
|
1908
1894
|
}
|
|
@@ -2280,6 +2266,13 @@ EvolClaw AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
2280
2266
|
}
|
|
2281
2267
|
this.client = null;
|
|
2282
2268
|
}
|
|
2269
|
+
if (this.store) {
|
|
2270
|
+
try {
|
|
2271
|
+
this.store.close();
|
|
2272
|
+
}
|
|
2273
|
+
catch { /* ignore */ }
|
|
2274
|
+
this.store = null;
|
|
2275
|
+
}
|
|
2283
2276
|
this.connected = false;
|
|
2284
2277
|
appendAidEvent({ ts: Date.now(), iso: new Date().toISOString(), event: 'disconnected', aid: this.config.aid, reason: 'intentional' });
|
|
2285
2278
|
appendAidLifecycle({ ts: Date.now(), iso: new Date().toISOString(), event: 'disconnected', aid: this.config.aid, reason: 'intentional' });
|
|
@@ -2381,7 +2374,7 @@ EvolClaw AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
2381
2374
|
return { type: null };
|
|
2382
2375
|
try {
|
|
2383
2376
|
const selfAgentDir = path.join(resolvePaths().agentsDir, this.config.aid);
|
|
2384
|
-
const identity = await PeerIdentityCache.resolve('aun', aid, selfAgentDir, this.
|
|
2377
|
+
const identity = await PeerIdentityCache.resolve('aun', aid, selfAgentDir, this.store, false);
|
|
2385
2378
|
const type = identity.type === 'human' ? 'human' : 'ai';
|
|
2386
2379
|
const name = identity.name || undefined;
|
|
2387
2380
|
const info = { type, name };
|
|
@@ -2405,19 +2398,16 @@ EvolClaw AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
|
|
|
2405
2398
|
void this.fetchPeerInfo(aid).catch(() => { });
|
|
2406
2399
|
}
|
|
2407
2400
|
async uploadAgentMd(content) {
|
|
2408
|
-
if (!this.
|
|
2401
|
+
if (!this.store)
|
|
2409
2402
|
throw new Error('not connected');
|
|
2410
|
-
const {
|
|
2411
|
-
|
|
2412
|
-
fs.mkdirSync(path.dirname(localPath), { recursive: true });
|
|
2413
|
-
fs.writeFileSync(localPath, content, 'utf-8');
|
|
2414
|
-
await this.client.publishAgentMd();
|
|
2403
|
+
const { agentmdPut } = await import('../aun/aid/agentmd.js');
|
|
2404
|
+
await agentmdPut(content, { aid: this.config.aid, store: this.store });
|
|
2415
2405
|
}
|
|
2416
2406
|
async downloadAgentMd(aid) {
|
|
2417
|
-
if (!this.
|
|
2407
|
+
if (!this.store)
|
|
2418
2408
|
throw new Error('not connected');
|
|
2419
2409
|
const { agentmdSync } = await import('../aun/aid/agentmd.js');
|
|
2420
|
-
const result = await agentmdSync(aid, {
|
|
2410
|
+
const result = await agentmdSync(aid, { store: this.store ?? undefined });
|
|
2421
2411
|
return result.content ?? '';
|
|
2422
2412
|
}
|
|
2423
2413
|
}
|
|
@@ -2445,7 +2435,6 @@ export class AUNChannelPlugin {
|
|
|
2445
2435
|
gatewayUrl: inst.gatewayUrl,
|
|
2446
2436
|
accessToken: inst.accessToken,
|
|
2447
2437
|
flushDelay: inst.flushDelay,
|
|
2448
|
-
encryptionSeed: inst.encryptionSeed,
|
|
2449
2438
|
owner: inst.owner,
|
|
2450
2439
|
agentName: inst.agentName,
|
|
2451
2440
|
channelName: inst.name,
|
|
@@ -2636,7 +2625,7 @@ export class AUNChannelPlugin {
|
|
|
2636
2625
|
channel: adapter.channelName,
|
|
2637
2626
|
channelType,
|
|
2638
2627
|
channelId: opts.channelId,
|
|
2639
|
-
|
|
2628
|
+
selfAID: opts.selfAID,
|
|
2640
2629
|
groupId: opts.groupId,
|
|
2641
2630
|
content: opts.content,
|
|
2642
2631
|
chatType: opts.chatType || 'private',
|