evolclaw 3.1.3 → 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 +27 -0
- package/assets/.env.template +4 -0
- package/assets/config.json.template +6 -0
- package/assets/wechat-group-qr.jpeg +0 -0
- package/dist/agents/claude-runner.js +348 -156
- package/dist/agents/kit-renderer.js +211 -42
- package/dist/aun/aid/agentmd.js +75 -139
- package/dist/aun/aid/client.js +1 -14
- package/dist/aun/aid/identity.js +381 -54
- package/dist/aun/aid/index.js +3 -2
- package/dist/aun/aid/store.js +74 -0
- package/dist/aun/msg/p2p.js +26 -2
- package/dist/aun/rpc/connection.js +23 -35
- package/dist/channels/aun.js +92 -144
- 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 +26 -27
- package/dist/cli/bench.js +45 -34
- package/dist/cli/help.js +23 -0
- package/dist/cli/index.js +538 -77
- package/dist/cli/init-channel.js +7 -4
- package/dist/cli/link-rules.js +2 -1
- package/dist/cli/model.js +324 -0
- package/dist/cli/net-check.js +138 -56
- 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 +87 -93
- 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 +104 -118
- 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 +78 -44
- 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 +312 -251
- package/dist/core/session/session-mapper.js +9 -4
- package/dist/core/trigger/manager.js +37 -0
- package/dist/core/trigger/scheduler.js +2 -1
- package/dist/index.js +10 -3
- package/dist/ipc.js +22 -0
- package/dist/paths.js +87 -16
- package/dist/utils/npm-ops.js +18 -11
- 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 +75 -39
- package/kits/rules/01-overview.md +20 -10
- package/kits/rules/05-venue.md +2 -2
- package/kits/rules/06-channel.md +30 -27
- package/kits/templates/system-fragments/baseagent.md +7 -1
- package/kits/templates/system-fragments/channel.md +4 -1
- package/kits/templates/system-fragments/identity.md +4 -4
- package/kits/templates/system-fragments/relation.md +8 -5
- package/kits/templates/system-fragments/session.md +27 -0
- package/kits/templates/system-fragments/venue.md +13 -1
- package/package.json +13 -6
- package/dist/aun/aid/lifecycle-log.js +0 -33
- package/dist/net-check.js +0 -640
- package/dist/utils/aid-lifecycle-log.js +0 -33
- package/dist/watch-msg.js +0 -544
- 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/kits/templates/system-fragments/eckruntime.md +0 -14
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--bg: #0d1117;
|
|
3
|
+
--bg2: #161b22;
|
|
4
|
+
--bg3: #21262d;
|
|
5
|
+
--border: #30363d;
|
|
6
|
+
--fg: #e6edf3;
|
|
7
|
+
--dim: #8b949e;
|
|
8
|
+
--accent: #58a6ff;
|
|
9
|
+
--green: #3fb950;
|
|
10
|
+
--red: #f85149;
|
|
11
|
+
--orange: #db8e3c;
|
|
12
|
+
--blue: #58a6ff;
|
|
13
|
+
--magenta: #bc8cff;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
17
|
+
|
|
18
|
+
body {
|
|
19
|
+
font-family: -apple-system, "Segoe UI", "PingFang SC", "Microsoft YaHei", monospace;
|
|
20
|
+
background: var(--bg);
|
|
21
|
+
color: var(--fg);
|
|
22
|
+
font-size: 13px;
|
|
23
|
+
height: 100vh;
|
|
24
|
+
overflow: hidden;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* ── 配对页 ── */
|
|
28
|
+
.pair-page {
|
|
29
|
+
display: flex; align-items: center; justify-content: center;
|
|
30
|
+
height: 100vh;
|
|
31
|
+
}
|
|
32
|
+
.pair-box {
|
|
33
|
+
background: var(--bg2);
|
|
34
|
+
border: 1px solid var(--border);
|
|
35
|
+
border-radius: 12px;
|
|
36
|
+
padding: 40px 48px;
|
|
37
|
+
text-align: center;
|
|
38
|
+
min-width: 320px;
|
|
39
|
+
}
|
|
40
|
+
.pair-box h1 { font-size: 22px; margin-bottom: 8px; }
|
|
41
|
+
.pair-hint { color: var(--dim); margin-bottom: 24px; }
|
|
42
|
+
.pair-box input {
|
|
43
|
+
width: 100%;
|
|
44
|
+
font-size: 28px;
|
|
45
|
+
letter-spacing: 12px;
|
|
46
|
+
text-align: center;
|
|
47
|
+
padding: 12px;
|
|
48
|
+
background: var(--bg);
|
|
49
|
+
border: 1px solid var(--border);
|
|
50
|
+
border-radius: 8px;
|
|
51
|
+
color: var(--fg);
|
|
52
|
+
margin-bottom: 16px;
|
|
53
|
+
}
|
|
54
|
+
.pair-box input:focus { outline: none; border-color: var(--accent); }
|
|
55
|
+
.pair-box button {
|
|
56
|
+
width: 100%;
|
|
57
|
+
padding: 12px;
|
|
58
|
+
font-size: 15px;
|
|
59
|
+
background: var(--accent);
|
|
60
|
+
color: #fff;
|
|
61
|
+
border: none;
|
|
62
|
+
border-radius: 8px;
|
|
63
|
+
cursor: pointer;
|
|
64
|
+
}
|
|
65
|
+
.pair-box button:hover { opacity: 0.9; }
|
|
66
|
+
.pair-error { color: var(--red); margin-top: 12px; min-height: 18px; }
|
|
67
|
+
|
|
68
|
+
/* ── 主面板布局 ── */
|
|
69
|
+
.app { display: flex; flex-direction: column; height: 100vh; }
|
|
70
|
+
.topbar {
|
|
71
|
+
display: flex; align-items: center; gap: 24px;
|
|
72
|
+
padding: 0 16px; height: 44px;
|
|
73
|
+
background: var(--bg2);
|
|
74
|
+
border-bottom: 1px solid var(--border);
|
|
75
|
+
flex-shrink: 0;
|
|
76
|
+
}
|
|
77
|
+
.brand { font-weight: 600; }
|
|
78
|
+
.tabs { display: flex; gap: 4px; }
|
|
79
|
+
.tab {
|
|
80
|
+
background: none; border: none; color: var(--dim);
|
|
81
|
+
padding: 6px 14px; cursor: pointer; border-radius: 6px;
|
|
82
|
+
font-size: 13px; font-family: inherit;
|
|
83
|
+
}
|
|
84
|
+
.tab:hover { color: var(--fg); background: var(--bg3); }
|
|
85
|
+
.tab.active { color: var(--accent); background: var(--bg3); }
|
|
86
|
+
.conn-status { margin-left: auto; color: var(--dim); font-size: 12px; }
|
|
87
|
+
.conn-status.ok { color: var(--green); }
|
|
88
|
+
.conn-status.err { color: var(--red); }
|
|
89
|
+
|
|
90
|
+
.content { flex: 1; overflow: hidden; position: relative; }
|
|
91
|
+
.view { display: none; height: 100%; overflow: auto; }
|
|
92
|
+
.view.active { display: block; }
|
|
93
|
+
|
|
94
|
+
/* ── AID 表格 ── */
|
|
95
|
+
table { width: 100%; border-collapse: collapse; font-size: 12px; }
|
|
96
|
+
th, td { text-align: left; padding: 7px 12px; border-bottom: 1px solid var(--border); white-space: nowrap; }
|
|
97
|
+
th { color: var(--dim); font-weight: 500; position: sticky; top: 0; background: var(--bg2); }
|
|
98
|
+
tr:hover td { background: var(--bg2); }
|
|
99
|
+
.dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; }
|
|
100
|
+
.dot.on { background: var(--green); }
|
|
101
|
+
.dot.off { background: var(--red); }
|
|
102
|
+
.dot.idle { background: var(--orange); }
|
|
103
|
+
.preview { color: var(--dim); max-width: 360px; overflow: hidden; text-overflow: ellipsis; }
|
|
104
|
+
.banner { padding: 10px 16px; background: #3d2a1a; color: var(--orange); border-bottom: 1px solid var(--border); }
|
|
105
|
+
.empty { padding: 40px; text-align: center; color: var(--dim); }
|
|
106
|
+
|
|
107
|
+
/* ── Messages 三栏 ── */
|
|
108
|
+
.msg-layout, .sess-layout { display: flex; height: 100%; }
|
|
109
|
+
.msg-col { overflow-y: auto; height: 100%; }
|
|
110
|
+
.msg-aids { width: 220px; border-right: 1px solid var(--border); flex-shrink: 0; }
|
|
111
|
+
.msg-peers { width: 240px; border-right: 1px solid var(--border); flex-shrink: 0; }
|
|
112
|
+
.msg-stream { flex: 1; padding: 12px; }
|
|
113
|
+
.list-item {
|
|
114
|
+
padding: 8px 12px; cursor: pointer; border-bottom: 1px solid var(--border);
|
|
115
|
+
}
|
|
116
|
+
.list-item:hover { background: var(--bg2); }
|
|
117
|
+
.list-item.sel { background: var(--bg3); border-left: 2px solid var(--accent); }
|
|
118
|
+
.list-item .name { font-weight: 500; }
|
|
119
|
+
.list-item .sub { color: var(--dim); font-size: 11px; margin-top: 2px; }
|
|
120
|
+
.col-title { padding: 8px 12px; color: var(--dim); font-size: 11px; text-transform: uppercase; position: sticky; top: 0; background: var(--bg); border-bottom: 1px solid var(--border); }
|
|
121
|
+
|
|
122
|
+
.bubble { margin-bottom: 12px; max-width: 80%; }
|
|
123
|
+
.bubble.in { margin-right: auto; }
|
|
124
|
+
.bubble.out { margin-left: auto; }
|
|
125
|
+
.bubble .meta { font-size: 11px; color: var(--dim); margin-bottom: 3px; }
|
|
126
|
+
.bubble .body {
|
|
127
|
+
padding: 8px 10px; border-radius: 8px; white-space: pre-wrap; word-break: break-word;
|
|
128
|
+
background: var(--bg2); border: 1px solid var(--border);
|
|
129
|
+
}
|
|
130
|
+
.bubble.in .body { border-left: 2px solid var(--green); }
|
|
131
|
+
.bubble.out .body { border-left: 2px solid var(--blue); }
|
|
132
|
+
.tag { display: inline-block; padding: 0 5px; border-radius: 3px; font-size: 10px; margin-left: 4px; background: var(--bg3); color: var(--magenta); }
|
|
133
|
+
|
|
134
|
+
/* ── Sessions ── */
|
|
135
|
+
.sess-list { width: 360px; border-right: 1px solid var(--border); flex-shrink: 0; display: flex; flex-direction: column; overflow: hidden; }
|
|
136
|
+
.sess-filter { padding: 10px; border-bottom: 1px solid var(--border); display: flex; flex-direction: column; gap: 8px; flex-shrink: 0; }
|
|
137
|
+
.sess-filter select, .sess-filter input {
|
|
138
|
+
width: 100%; padding: 6px 8px; background: var(--bg); color: var(--fg);
|
|
139
|
+
border: 1px solid var(--border); border-radius: 6px; font-size: 12px; font-family: inherit;
|
|
140
|
+
}
|
|
141
|
+
.sess-filter select:focus, .sess-filter input:focus { outline: none; border-color: var(--accent); }
|
|
142
|
+
.sess-count { font-size: 11px; color: var(--dim); }
|
|
143
|
+
.sess-items { flex: 1; overflow-y: auto; }
|
|
144
|
+
|
|
145
|
+
.sess-items .list-item .name { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
146
|
+
.sess-items .list-item .sub { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
|
147
|
+
.bind-badge { display: inline-flex; align-items: center; gap: 3px; padding: 0 5px; border-radius: 3px; background: var(--bg3); color: var(--accent); font-size: 10px; }
|
|
148
|
+
.bind-badge .dot { width: 6px; height: 6px; margin: 0; }
|
|
149
|
+
.msg-count { color: var(--dim); }
|
|
150
|
+
|
|
151
|
+
.sess-detail { flex: 1; padding: 0; overflow-y: auto; }
|
|
152
|
+
|
|
153
|
+
/* 会话头 */
|
|
154
|
+
.sess-header { position: sticky; top: 0; background: var(--bg2); border-bottom: 1px solid var(--border); padding: 12px 20px; z-index: 1; }
|
|
155
|
+
.sh-title { font-size: 15px; font-weight: 600; margin-bottom: 8px; }
|
|
156
|
+
.sh-stats { display: flex; flex-wrap: wrap; gap: 12px; font-size: 12px; color: var(--dim); }
|
|
157
|
+
.sh-stat { display: inline-flex; align-items: center; gap: 4px; }
|
|
158
|
+
.sh-stat .dot { width: 7px; height: 7px; margin: 0 2px; }
|
|
159
|
+
.sh-path { font-size: 11px; color: var(--dim); margin-top: 6px; font-family: ui-monospace, Consolas, monospace; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
160
|
+
|
|
161
|
+
/* 顶部 4 类分类条 */
|
|
162
|
+
.sh-cats { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
|
|
163
|
+
.cat-chip { display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px; border-radius: 10px; font-size: 11px; background: var(--bg3); }
|
|
164
|
+
.cat-swatch { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
|
|
165
|
+
.cat-chip.cat-user_input .cat-swatch { background: var(--green); }
|
|
166
|
+
.cat-chip.cat-model_output .cat-swatch { background: var(--blue); }
|
|
167
|
+
.cat-chip.cat-tool_call .cat-swatch { background: var(--magenta); }
|
|
168
|
+
.cat-chip.cat-tool_result .cat-swatch { background: var(--orange); }
|
|
169
|
+
.cat-chip.cat-msg_send .cat-swatch { background: var(--cyan, #22d3a8); }
|
|
170
|
+
|
|
171
|
+
/* 视图切换工具条 */
|
|
172
|
+
.sess-toolbar { display: flex; align-items: center; gap: 12px; padding: 8px 20px; border-bottom: 1px solid var(--border); position: sticky; top: 0; background: var(--bg); z-index: 1; }
|
|
173
|
+
.view-toggle { padding: 4px 12px; border-radius: 14px; border: 1px solid var(--border); background: var(--bg3); color: var(--fg); cursor: pointer; font-size: 12px; font-family: inherit; }
|
|
174
|
+
.view-toggle.active { background: var(--accent); border-color: var(--accent); color: #fff; }
|
|
175
|
+
.toolbar-hint { font-size: 11px; color: var(--dim); }
|
|
176
|
+
.turn-list { padding-top: 8px; }
|
|
177
|
+
|
|
178
|
+
/* 对话视图:仿微信气泡 */
|
|
179
|
+
.chat-row { display: flex; flex-direction: column; margin: 10px 20px; max-width: 72%; }
|
|
180
|
+
.chat-row.in { align-items: flex-start; margin-right: auto; }
|
|
181
|
+
.chat-row.out { align-items: flex-end; margin-left: auto; }
|
|
182
|
+
.chat-bubble { padding: 9px 13px; border-radius: 12px; white-space: pre-wrap; word-break: break-word; line-height: 1.5; font-size: 13px; }
|
|
183
|
+
.chat-row.in .chat-bubble { background: var(--bg3); border-bottom-left-radius: 3px; }
|
|
184
|
+
.chat-row.out .chat-bubble { background: #2a6b3f; color: #eafff0; border-bottom-right-radius: 3px; }
|
|
185
|
+
.chat-time { font-size: 10px; color: var(--dim); margin-top: 3px; }
|
|
186
|
+
|
|
187
|
+
/* 处理过程折叠组 */
|
|
188
|
+
.proc-group { margin: 8px 20px; }
|
|
189
|
+
.proc-group > summary { cursor: pointer; color: var(--dim); font-size: 11px; padding: 4px 0; text-align: center; list-style: none; }
|
|
190
|
+
.proc-group > summary::-webkit-details-marker { display: none; }
|
|
191
|
+
.proc-group > summary:hover { color: var(--fg); }
|
|
192
|
+
.proc-body { border-left: 2px dashed var(--border); margin-left: 8px; padding-left: 4px; }
|
|
193
|
+
.proc-body .turn { margin: 8px 12px; }
|
|
194
|
+
|
|
195
|
+
/* 轮次:按 4 类着色(左色条 + 角色标签色)*/
|
|
196
|
+
.turn { margin: 0 20px 18px; border-left: 3px solid var(--border); padding-left: 12px; }
|
|
197
|
+
.turn:first-of-type { margin-top: 16px; }
|
|
198
|
+
.turn.cat-user_input { border-left-color: var(--green); }
|
|
199
|
+
.turn.cat-model_output { border-left-color: var(--blue); }
|
|
200
|
+
.turn.cat-tool_call { border-left-color: var(--magenta); }
|
|
201
|
+
.turn.cat-tool_result { border-left-color: var(--orange); }
|
|
202
|
+
.turn.cat-system { border-left-color: var(--dim); }
|
|
203
|
+
|
|
204
|
+
.turn-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px; }
|
|
205
|
+
.turn-role { font-weight: 600; font-size: 12px; }
|
|
206
|
+
.turn.cat-user_input .turn-role { color: var(--green); }
|
|
207
|
+
.turn.cat-model_output .turn-role { color: var(--blue); }
|
|
208
|
+
.turn.cat-tool_call .turn-role { color: var(--magenta); }
|
|
209
|
+
.turn.cat-tool_result .turn-role { color: var(--orange); }
|
|
210
|
+
.turn.cat-system .turn-role { color: var(--dim); }
|
|
211
|
+
.turn-time { font-size: 11px; color: var(--dim); }
|
|
212
|
+
.turn-usage { font-size: 11px; color: var(--dim); margin-left: auto; }
|
|
213
|
+
.turn-blocks { display: flex; flex-direction: column; gap: 8px; }
|
|
214
|
+
|
|
215
|
+
/* 普通文本块 */
|
|
216
|
+
.blk-text { white-space: pre-wrap; word-break: break-word; line-height: 1.55; }
|
|
217
|
+
|
|
218
|
+
/* 思考块(折叠) */
|
|
219
|
+
.blk-thinking { font-size: 12px; }
|
|
220
|
+
.blk-thinking summary { cursor: pointer; color: var(--magenta); opacity: 0.8; }
|
|
221
|
+
.blk-thinking-body { white-space: pre-wrap; word-break: break-word; color: var(--dim); margin-top: 6px; padding-left: 12px; border-left: 2px solid var(--border); font-style: italic; }
|
|
222
|
+
|
|
223
|
+
/* 工具调用块 */
|
|
224
|
+
.blk-tool { background: var(--bg2); border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; }
|
|
225
|
+
.tool-head { font-size: 12px; margin-bottom: 4px; }
|
|
226
|
+
.tool-name { font-weight: 600; color: var(--accent); font-family: ui-monospace, "SF Mono", Consolas, monospace; }
|
|
227
|
+
.tool-param { display: flex; gap: 8px; margin-top: 3px; font-size: 12px; align-items: baseline; }
|
|
228
|
+
.tool-param .pk { color: var(--dim); flex-shrink: 0; min-width: 64px; }
|
|
229
|
+
.tool-param .pv {
|
|
230
|
+
font-family: ui-monospace, "SF Mono", Consolas, monospace; color: var(--fg);
|
|
231
|
+
background: var(--bg); padding: 1px 6px; border-radius: 4px; word-break: break-all;
|
|
232
|
+
white-space: pre-wrap; display: block; flex: 1;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/* 工具结果块(折叠,默认收起) */
|
|
236
|
+
.blk-result { font-size: 12px; }
|
|
237
|
+
.blk-result summary { cursor: pointer; color: var(--dim); }
|
|
238
|
+
.blk-result.err summary { color: var(--red); }
|
|
239
|
+
.result-body {
|
|
240
|
+
margin-top: 6px; padding: 8px 10px; background: var(--bg); border: 1px solid var(--border);
|
|
241
|
+
border-radius: 6px; white-space: pre-wrap; word-break: break-word; max-height: 280px; overflow-y: auto;
|
|
242
|
+
font-family: ui-monospace, "SF Mono", Consolas, monospace; font-size: 11.5px; line-height: 1.5;
|
|
243
|
+
}
|
|
244
|
+
.blk-result.err .result-body { border-color: var(--red); }
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
|
|
@@ -128,18 +128,21 @@ export class ChannelLoader {
|
|
|
128
128
|
}
|
|
129
129
|
const SEP = '#';
|
|
130
130
|
export function formatChannelKey(k) {
|
|
131
|
-
|
|
131
|
+
if (k.selfAID.includes(SEP)) {
|
|
132
|
+
throw new Error(`Invalid selfAID (contains '#'): ${k.selfAID}`);
|
|
133
|
+
}
|
|
134
|
+
return `${k.type}${SEP}${k.selfAID}${SEP}${k.name}`;
|
|
132
135
|
}
|
|
133
136
|
export function parseChannelKey(key) {
|
|
134
137
|
const parts = key.split(SEP);
|
|
135
138
|
if (parts.length !== 3) {
|
|
136
139
|
throw new Error(`Invalid channel key (expected 3 segments separated by '#'): ${key}`);
|
|
137
140
|
}
|
|
138
|
-
const [type,
|
|
139
|
-
if (!type || !
|
|
141
|
+
const [type, selfAID, name] = parts;
|
|
142
|
+
if (!type || !selfAID || !name) {
|
|
140
143
|
throw new Error(`Invalid channel key (empty segment): ${key}`);
|
|
141
144
|
}
|
|
142
|
-
return { type,
|
|
145
|
+
return { type, selfAID, name };
|
|
143
146
|
}
|
|
144
147
|
export function tryParseChannelKey(key) {
|
|
145
148
|
try {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_PERMISSION_MODE } from '../types.js';
|
|
2
2
|
import { hasModelSwitcher, hasPermissionController } from '../agents/claude-runner.js';
|
|
3
3
|
import { getCodexEfforts } from '../agents/codex-runner.js';
|
|
4
|
-
import { resolveAnthropicConfig, resolveOpenaiConfig } from '../agents/resolve.js';
|
|
5
4
|
import { renderCommandCardAsText } from './interaction-router.js';
|
|
6
5
|
import { buildEnvelope, sendInteractionPayload } from './message/message-processor.js';
|
|
7
6
|
import { resolvePaths, getPackageRoot } from '../paths.js';
|
|
@@ -27,33 +26,13 @@ function getAvailableEfforts(agent, model) {
|
|
|
27
26
|
function formatModelUsage(_agent, _model) {
|
|
28
27
|
return '用法: /model <模型>';
|
|
29
28
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
catch { }
|
|
39
|
-
return {
|
|
40
|
-
apiBaseUrl: resolved.baseUrl,
|
|
41
|
-
apiKey: resolved.apiKey,
|
|
42
|
-
fallbackModels: agent.listModels?.() || [],
|
|
43
|
-
owner: 'openai',
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
let resolved = {};
|
|
47
|
-
try {
|
|
48
|
-
resolved = resolveAnthropicConfig({ agents: { claude: claudeConfig } }, claudeConfig);
|
|
49
|
-
}
|
|
50
|
-
catch { }
|
|
51
|
-
return {
|
|
52
|
-
apiBaseUrl: resolved.baseUrl,
|
|
53
|
-
apiKey: resolved.apiKey,
|
|
54
|
-
fallbackModels: ['claude-opus-4-7', 'claude-opus-4-6', 'claude-sonnet-4-6'],
|
|
55
|
-
owner: 'anthropic',
|
|
56
|
-
};
|
|
29
|
+
/**
|
|
30
|
+
* 模型展示标签:短别名 + 实际完整 ID(如 "opus (claude-opus-4-8)")。
|
|
31
|
+
* 仅用于展示;命令值/持久化仍使用短别名。完整 ID 不可用或与短名相同时只显示短名。
|
|
32
|
+
*/
|
|
33
|
+
function modelDisplayLabel(agent, model) {
|
|
34
|
+
const full = agent.resolveModelId?.(model);
|
|
35
|
+
return full && full !== model ? `${model} (${full})` : model;
|
|
57
36
|
}
|
|
58
37
|
/**
|
|
59
38
|
* 写入用户级 ~/.claude/settings.json(与 Claude CLI 行为一致)
|
|
@@ -410,8 +389,9 @@ export class CommandHandler {
|
|
|
410
389
|
return { session };
|
|
411
390
|
}
|
|
412
391
|
const ct = chatType === 'group' ? 'group' : chatType === 'private' ? 'private' : undefined;
|
|
392
|
+
const channelType = this.resolveChannelType(channel);
|
|
413
393
|
const session = await this.sessionManager.getActiveSession(channel, channelId)
|
|
414
|
-
?? await this.sessionManager.getOrCreateSession(channel, channelId, this.getEffectiveDefaultPath(channel), undefined, undefined, undefined, undefined, ct);
|
|
394
|
+
?? await this.sessionManager.getOrCreateSession(channel, channelId, this.getEffectiveDefaultPath(channel), undefined, undefined, undefined, undefined, ct, undefined, undefined, channelType);
|
|
415
395
|
// 如果 session 已存在但 chatType 跟传入的不一致,更新
|
|
416
396
|
if (ct && session.chatType !== ct) {
|
|
417
397
|
await this.sessionManager.updateSession(session.id, { chatType: ct });
|
|
@@ -635,7 +615,7 @@ export class CommandHandler {
|
|
|
635
615
|
const models = await agent.listModels() ?? [];
|
|
636
616
|
const currentModel = agent.getModel();
|
|
637
617
|
if (models.length > 0)
|
|
638
|
-
return models.map((m) => ({ value: m, label: m, selected: m === currentModel }));
|
|
618
|
+
return models.map((m) => ({ value: m, label: modelDisplayLabel(agent, m), selected: m === currentModel }));
|
|
639
619
|
}
|
|
640
620
|
return null;
|
|
641
621
|
}
|
|
@@ -1043,7 +1023,7 @@ export class CommandHandler {
|
|
|
1043
1023
|
env: { ...process.env, EVOLCLAW_HOME: resolvePaths().root }
|
|
1044
1024
|
}).unref();
|
|
1045
1025
|
this.eventBus.publish({ type: 'system:restart', channel, channelId });
|
|
1046
|
-
setTimeout(() => { process.kill(process.pid, 'SIGTERM'); },
|
|
1026
|
+
setTimeout(() => { process.kill(process.pid, 'SIGTERM'); }, 1000);
|
|
1047
1027
|
return { data: { action: 'restart', success: true } };
|
|
1048
1028
|
}
|
|
1049
1029
|
if (action === 'check') {
|
|
@@ -1160,12 +1140,12 @@ export class CommandHandler {
|
|
|
1160
1140
|
}
|
|
1161
1141
|
// 空闲检查:某些命令需要等待当前会话空闲
|
|
1162
1142
|
// 原则:仅对"写/破坏性"形态拦截,纯读/用法提示的无参形态始终放行
|
|
1163
|
-
// - 始终需要 idle(无参即写):/
|
|
1143
|
+
// - 始终需要 idle(无参即写):/clear /compact /repair /fork /new
|
|
1164
1144
|
// - 仅带参时需要 idle(无参是列表/用法):/session /baseagent /rewind
|
|
1165
1145
|
// - /chatmode:在 handler 内部自行做写操作的 idle 检查
|
|
1166
1146
|
// - /dispatch:在 handler 内部自行做写操作的 idle 检查
|
|
1167
1147
|
// - /safe:已禁用 no-op,不再要求 idle
|
|
1168
|
-
const idleAlways = ['/
|
|
1148
|
+
const idleAlways = ['/clear', '/compact', '/repair', '/fork', '/new'];
|
|
1169
1149
|
const idleWhenArg = ['/session', '/baseagent', '/rewind'];
|
|
1170
1150
|
const needsIdle = idleAlways.some(cmd => normalizedContent === cmd || normalizedContent.startsWith(cmd + ' ')) ||
|
|
1171
1151
|
idleWhenArg.some(cmd => normalizedContent.startsWith(cmd + ' '));
|
|
@@ -1175,13 +1155,19 @@ export class CommandHandler {
|
|
|
1175
1155
|
const threadSession = await this.sessionManager.getThreadSession(channel, channelId, threadId);
|
|
1176
1156
|
if (threadSession) {
|
|
1177
1157
|
const threadAgent = this.getAgent(channel, threadSession.agentId);
|
|
1178
|
-
|
|
1158
|
+
const isBusy = threadAgent.hasActiveStream(threadSession.id) ||
|
|
1159
|
+
this.messageQueue?.isProcessing(threadSession.id);
|
|
1160
|
+
if (isBusy) {
|
|
1179
1161
|
return { kind: 'command.error', text: '⚠️ 当前正在处理消息,请稍后再试\n使用 /stop 中断当前任务后重试' };
|
|
1180
1162
|
}
|
|
1181
1163
|
}
|
|
1182
1164
|
}
|
|
1183
|
-
else if (activeSession
|
|
1184
|
-
|
|
1165
|
+
else if (activeSession) {
|
|
1166
|
+
const isBusy = agent.hasActiveStream(activeSession.id) ||
|
|
1167
|
+
this.messageQueue?.isProcessing(activeSession.id);
|
|
1168
|
+
if (isBusy) {
|
|
1169
|
+
return { kind: 'command.error', text: '⚠️ 当前正在处理消息,请稍后再试\n使用 /stop 中断当前任务后重试' };
|
|
1170
|
+
}
|
|
1185
1171
|
}
|
|
1186
1172
|
}
|
|
1187
1173
|
// 检查是否以 / 开头(可能是命令)
|
|
@@ -1626,37 +1612,12 @@ export class CommandHandler {
|
|
|
1626
1612
|
const currentModel = hasModelSwitcher(setmodelAgent) ? setmodelAgent.getModel() : setmodelAgent.name;
|
|
1627
1613
|
const efforts = getAvailableEfforts(setmodelAgent, currentModel);
|
|
1628
1614
|
const currentEffort = setmodelAgent.getEffort?.() || 'auto';
|
|
1629
|
-
const
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
const timeout = setTimeout(() => controller.abort(), 5000);
|
|
1636
|
-
const resp = await fetch(modelsUrl, {
|
|
1637
|
-
signal: controller.signal,
|
|
1638
|
-
headers: { 'Authorization': `Bearer ${modelListSource.apiKey || ''}` },
|
|
1639
|
-
});
|
|
1640
|
-
clearTimeout(timeout);
|
|
1641
|
-
if (resp.ok) {
|
|
1642
|
-
modelListData = await resp.json();
|
|
1643
|
-
}
|
|
1644
|
-
}
|
|
1645
|
-
catch { }
|
|
1646
|
-
}
|
|
1647
|
-
// 兜底模型列表
|
|
1648
|
-
if (!modelListData || !modelListData.data || modelListData.data.length === 0) {
|
|
1649
|
-
const now = Math.floor(Date.now() / 1000);
|
|
1650
|
-
modelListData = {
|
|
1651
|
-
object: 'list',
|
|
1652
|
-
data: modelListSource.fallbackModels.map(id => ({
|
|
1653
|
-
id,
|
|
1654
|
-
object: 'model',
|
|
1655
|
-
created: now,
|
|
1656
|
-
owned_by: modelListSource.owner,
|
|
1657
|
-
})),
|
|
1658
|
-
};
|
|
1659
|
-
}
|
|
1615
|
+
const now = Math.floor(Date.now() / 1000);
|
|
1616
|
+
const modelIds = hasModelSwitcher(setmodelAgent) ? setmodelAgent.listModels() : [];
|
|
1617
|
+
const modelListData = {
|
|
1618
|
+
object: 'list',
|
|
1619
|
+
data: modelIds.map(id => ({ id, object: 'model', created: now, owned_by: setmodelAgent.name === 'codex' ? 'openai' : 'anthropic' })),
|
|
1620
|
+
};
|
|
1660
1621
|
return { kind: 'command.result', text: JSON.stringify({
|
|
1661
1622
|
current_model: currentModel,
|
|
1662
1623
|
current_effort: currentEffort,
|
|
@@ -1689,12 +1650,15 @@ export class CommandHandler {
|
|
|
1689
1650
|
kind: {
|
|
1690
1651
|
kind: 'command-card',
|
|
1691
1652
|
title: '🤖 切换模型',
|
|
1692
|
-
buttons: models.map((m) =>
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1653
|
+
buttons: models.map((m) => {
|
|
1654
|
+
const display = modelDisplayLabel(modelAgent, m);
|
|
1655
|
+
return {
|
|
1656
|
+
label: m === currentModel ? `✓ ${display}` : display,
|
|
1657
|
+
command: `/model ${m}`,
|
|
1658
|
+
style: (m === currentModel ? 'primary' : 'default'),
|
|
1659
|
+
disabled: m === currentModel,
|
|
1660
|
+
};
|
|
1661
|
+
}),
|
|
1698
1662
|
},
|
|
1699
1663
|
};
|
|
1700
1664
|
const replyCtx = this.getReplyContext(modelSession);
|
|
@@ -1704,14 +1668,14 @@ export class CommandHandler {
|
|
|
1704
1668
|
return { kind: 'command.result', text: cardResult };
|
|
1705
1669
|
}
|
|
1706
1670
|
// 降级:文本
|
|
1707
|
-
const modelList = models.map((m) => ` ${m === currentModel ? '✓' : ' '} ${m}`).join('\n');
|
|
1671
|
+
const modelList = models.map((m) => ` ${m === currentModel ? '✓' : ' '} ${modelDisplayLabel(modelAgent, m)}`).join('\n');
|
|
1708
1672
|
const effortHint = efforts.length > 0
|
|
1709
1673
|
? `\n推理强度: ${currentEffort === 'auto' ? 'auto (SDK默认)' : currentEffort} (使用 /effort 调整)`
|
|
1710
1674
|
: '';
|
|
1711
1675
|
if (isAdmin) {
|
|
1712
|
-
return { kind: 'command.result', text: `当前模型: ${currentModel}${effortHint}\n\n可用模型:\n${modelList}\n\n用法: /model <模型>` };
|
|
1676
|
+
return { kind: 'command.result', text: `当前模型: ${modelDisplayLabel(modelAgent, currentModel)}${effortHint}\n\n可用模型:\n${modelList}\n\n用法: /model <模型>` };
|
|
1713
1677
|
}
|
|
1714
|
-
return { kind: 'command.result', text: `当前模型: ${currentModel}${effortHint}` };
|
|
1678
|
+
return { kind: 'command.result', text: `当前模型: ${modelDisplayLabel(modelAgent, currentModel)}${effortHint}` };
|
|
1715
1679
|
}
|
|
1716
1680
|
// 带参(切换/调整)需 admin+;无参查询已在上方返回
|
|
1717
1681
|
if (!isAdmin)
|
|
@@ -1731,20 +1695,29 @@ export class CommandHandler {
|
|
|
1731
1695
|
else if (allEfforts.includes(arg)) {
|
|
1732
1696
|
return { kind: 'command.error', text: `⚠️ 请使用 /effort ${arg} 调整推理强度` };
|
|
1733
1697
|
}
|
|
1734
|
-
else if (models.includes(arg)) {
|
|
1735
|
-
newModel = arg;
|
|
1736
|
-
}
|
|
1737
1698
|
else {
|
|
1738
|
-
const
|
|
1739
|
-
|
|
1740
|
-
|
|
1699
|
+
const resolvedArg = hasModelSwitcher(modelAgent) ? (modelAgent.resolveModelId?.(arg) ?? arg) : arg;
|
|
1700
|
+
if (models.includes(resolvedArg)) {
|
|
1701
|
+
newModel = resolvedArg;
|
|
1702
|
+
}
|
|
1703
|
+
else if (models.includes(arg)) {
|
|
1704
|
+
newModel = arg;
|
|
1705
|
+
}
|
|
1706
|
+
else {
|
|
1707
|
+
const modelList = models.map((m) => ` ${m === currentModel ? '✓' : ' '} ${modelDisplayLabel(modelAgent, m)}`).join('\n');
|
|
1708
|
+
const effortHint = efforts.length > 0 ? `\n\n推理强度请使用 /effort 命令` : '';
|
|
1709
|
+
return { kind: 'command.error', text: `❌ 无效参数: ${arg}\n\n可用模型:\n${modelList}${effortHint}` };
|
|
1710
|
+
}
|
|
1741
1711
|
}
|
|
1742
1712
|
}
|
|
1743
1713
|
else {
|
|
1744
1714
|
// 双参数:model effort
|
|
1745
|
-
const [
|
|
1715
|
+
const [modelArgRaw, effortArg] = parts;
|
|
1716
|
+
const modelArg = hasModelSwitcher(modelAgent)
|
|
1717
|
+
? (models.includes(modelArgRaw) ? modelArgRaw : (modelAgent.resolveModelId?.(modelArgRaw) ?? modelArgRaw))
|
|
1718
|
+
: modelArgRaw;
|
|
1746
1719
|
if (!models.includes(modelArg)) {
|
|
1747
|
-
return { kind: 'command.error', text: `❌ 无效的模型ID: ${
|
|
1720
|
+
return { kind: 'command.error', text: `❌ 无效的模型ID: ${modelArgRaw}` };
|
|
1748
1721
|
}
|
|
1749
1722
|
const targetEfforts = getAvailableEfforts(modelAgent, modelArg);
|
|
1750
1723
|
if (targetEfforts.length === 0) {
|
|
@@ -2015,12 +1988,12 @@ export class CommandHandler {
|
|
|
2015
1988
|
const threadSession = await this.sessionManager.getThreadSession(channel, channelId, threadId);
|
|
2016
1989
|
if (threadSession) {
|
|
2017
1990
|
const threadAgent = this.getAgent(channel, threadSession.agentId);
|
|
2018
|
-
if (threadAgent.hasActiveStream(threadSession.id)) {
|
|
1991
|
+
if (threadAgent.hasActiveStream(threadSession.id) || this.messageQueue?.isProcessing(threadSession.id)) {
|
|
2019
1992
|
return { kind: 'command.error', text: '⚠️ 当前正在处理消息,请稍后再试\n使用 /stop 中断当前任务后重试' };
|
|
2020
1993
|
}
|
|
2021
1994
|
}
|
|
2022
1995
|
}
|
|
2023
|
-
else if (agent.hasActiveStream(chatmodeSession.id)) {
|
|
1996
|
+
else if (agent.hasActiveStream(chatmodeSession.id) || this.messageQueue?.isProcessing(chatmodeSession.id)) {
|
|
2024
1997
|
return { kind: 'command.error', text: '⚠️ 当前正在处理消息,请稍后再试\n使用 /stop 中断当前任务后重试' };
|
|
2025
1998
|
}
|
|
2026
1999
|
await this.sessionManager.updateSession(chatmodeSession.id, { sessionMode: arg });
|
|
@@ -2185,16 +2158,14 @@ export class CommandHandler {
|
|
|
2185
2158
|
// 尝试获取活跃会话(话题时直接查找话题 session)
|
|
2186
2159
|
let session;
|
|
2187
2160
|
if (threadId) {
|
|
2188
|
-
session = await this.sessionManager.getOrCreateSession(channel, channelId, this.getEffectiveDefaultPath(channel), threadId);
|
|
2161
|
+
session = await this.sessionManager.getOrCreateSession(channel, channelId, this.getEffectiveDefaultPath(channel), threadId, undefined, undefined, undefined, chatType, undefined, undefined, this.resolveChannelType(channel));
|
|
2189
2162
|
}
|
|
2190
2163
|
else {
|
|
2191
2164
|
session = await this.sessionManager.getActiveSession(channel, channelId);
|
|
2192
2165
|
}
|
|
2193
|
-
//
|
|
2194
|
-
if (!session
|
|
2195
|
-
|
|
2196
|
-
normalizedContent === '/status')) {
|
|
2197
|
-
session = await this.sessionManager.getOrCreateSession(channel, channelId, this.getEffectiveDefaultPath(channel));
|
|
2166
|
+
// 如果没有会话,自动创建(所有后续命令都需要 session)
|
|
2167
|
+
if (!session) {
|
|
2168
|
+
session = await this.sessionManager.getOrCreateSession(channel, channelId, this.getEffectiveDefaultPath(channel), undefined, undefined, undefined, undefined, chatType, undefined, undefined, this.resolveChannelType(channel));
|
|
2198
2169
|
}
|
|
2199
2170
|
// /status 命令:显示会话状态
|
|
2200
2171
|
if (normalizedContent === '/status') {
|
|
@@ -2418,6 +2389,27 @@ export class CommandHandler {
|
|
|
2418
2389
|
env: { ...process.env, EVOLCLAW_HOME: resolvePaths().root }
|
|
2419
2390
|
}).unref();
|
|
2420
2391
|
this.eventBus.publish({ type: 'system:restart', channel, channelId });
|
|
2392
|
+
// 先发送重启反馈消息,等待发送完成后再 kill 进程
|
|
2393
|
+
// 避免消息还没发出去进程就退出了
|
|
2394
|
+
const adapter = this.adapters.get(channel);
|
|
2395
|
+
if (adapter) {
|
|
2396
|
+
try {
|
|
2397
|
+
const envelope = buildEnvelope({
|
|
2398
|
+
taskId: `restart-${Date.now()}`,
|
|
2399
|
+
channel,
|
|
2400
|
+
channelId,
|
|
2401
|
+
agentName: 'system',
|
|
2402
|
+
chatmode: 'interactive',
|
|
2403
|
+
replyContext,
|
|
2404
|
+
});
|
|
2405
|
+
await adapter.send(envelope, { kind: 'command.result', text: '🔄 服务正在重启,请稍候...(约 5 秒后恢复)' });
|
|
2406
|
+
// 等待消息发送完成后再延迟 kill
|
|
2407
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
2408
|
+
}
|
|
2409
|
+
catch (err) {
|
|
2410
|
+
logger.error('[System] Failed to send restart notification:', err);
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2421
2413
|
// 发 SIGTERM 而非直接 process.exit(0),让 index.ts 的 shutdown() 先
|
|
2422
2414
|
// 正常关闭所有 channel(包括 Feishu WebSocket close frame),
|
|
2423
2415
|
// 避免 Feishu 服务端因连接异常断开而重推未 ack 的消息给新进程。
|
|
@@ -2448,7 +2440,8 @@ export class CommandHandler {
|
|
|
2448
2440
|
}
|
|
2449
2441
|
}
|
|
2450
2442
|
await executeRestart();
|
|
2451
|
-
|
|
2443
|
+
// executeRestart 内部已经发送了反馈消息,这里返回 null 避免重复发送
|
|
2444
|
+
return null;
|
|
2452
2445
|
}
|
|
2453
2446
|
// /upgrade 命令:检查版本更新,提示用户手动重启
|
|
2454
2447
|
if (normalizedContent === '/upgrade') {
|
|
@@ -3167,6 +3160,7 @@ export class CommandHandler {
|
|
|
3167
3160
|
nextFireAt,
|
|
3168
3161
|
targetChannel: parsed.targetChannel ?? channel,
|
|
3169
3162
|
targetChannelId: parsed.targetChannelId ?? channelId,
|
|
3163
|
+
targetChannelType: this.resolveChannelType(parsed.targetChannel ?? channel),
|
|
3170
3164
|
targetThreadId: parsed.targetThreadId,
|
|
3171
3165
|
targetSessionStrategy: parsed.targetSessionStrategy,
|
|
3172
3166
|
agentId: parsed.agentId,
|
|
@@ -51,7 +51,7 @@ export function detectDuplicates(agents) {
|
|
|
51
51
|
export class EvolAgentRegistry {
|
|
52
52
|
_agentsDir;
|
|
53
53
|
agents = new Map();
|
|
54
|
-
/** channel key (`<type>#<
|
|
54
|
+
/** channel key (`<type>#<selfAID>#<name>`) → agent aid */
|
|
55
55
|
channelIndex = new Map();
|
|
56
56
|
/** 启动期被 ConfigStore 跳过的目录(命名非法 / 缺 config.json / 校验失败等) */
|
|
57
57
|
skipped = [];
|
package/dist/core/evolagent.js
CHANGED
|
@@ -62,11 +62,11 @@ export class EvolAgent {
|
|
|
62
62
|
}
|
|
63
63
|
// ── Channels ──────────────────────────────────────────────────────────
|
|
64
64
|
/**
|
|
65
|
-
* effective channel key:`<type>#<
|
|
66
|
-
* AUN channel 的
|
|
65
|
+
* effective channel key:`<type>#<selfAID>#<name>`。
|
|
66
|
+
* AUN channel 的 selfAID 是 agent.aid,name 固定为 'main'。
|
|
67
67
|
*/
|
|
68
68
|
effectiveChannelName(type, rawName) {
|
|
69
|
-
return formatChannelKey({ type,
|
|
69
|
+
return formatChannelKey({ type, selfAID: this.aid, name: rawName });
|
|
70
70
|
}
|
|
71
71
|
channelInstanceNames() {
|
|
72
72
|
// AUN channel 隐式存在(从 agent.aid 派生),不需要在 channels[] 里声明
|
|
@@ -97,7 +97,7 @@ export class EvolAgent {
|
|
|
97
97
|
*/
|
|
98
98
|
isAunChannelKey(channelKey) {
|
|
99
99
|
const parsed = tryParseChannelKey(channelKey);
|
|
100
|
-
return parsed?.type === 'aun' && parsed.
|
|
100
|
+
return parsed?.type === 'aun' && parsed.selfAID === this.aid;
|
|
101
101
|
}
|
|
102
102
|
getOwner(channelKey) {
|
|
103
103
|
if (this.isAunChannelKey(channelKey)) {
|