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
package/dist/cli/agent.js
CHANGED
|
@@ -2,7 +2,7 @@ import fs from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import os from 'os';
|
|
4
4
|
import readline from 'readline';
|
|
5
|
-
import { resolvePaths } from '../paths.js';
|
|
5
|
+
import { resolvePaths, agentMdPath as getAgentMdPathFromPaths, aunPath as defaultAunPath } from '../paths.js';
|
|
6
6
|
import { loadDefaults, loadAllAgents, loadAgent, saveAgent, ensureAgentDirSkeleton } from '../config-store.js';
|
|
7
7
|
import { ipcQuery } from '../ipc.js';
|
|
8
8
|
import { CONFIG_SCHEMA_VERSION } from '../types.js';
|
|
@@ -46,12 +46,11 @@ function deriveAgentProjectPath(rootPath, aid) {
|
|
|
46
46
|
return `${candidate}~${i}`;
|
|
47
47
|
}
|
|
48
48
|
function readAgentMdIdentity(aid) {
|
|
49
|
-
const
|
|
50
|
-
const agentMdPath = path.join(aunPath, 'AIDs', aid, 'agent.md');
|
|
49
|
+
const agentMdFilePath = getAgentMdPathFromPaths(aid);
|
|
51
50
|
try {
|
|
52
|
-
if (!fs.existsSync(
|
|
51
|
+
if (!fs.existsSync(agentMdFilePath))
|
|
53
52
|
return { name: null, description: null };
|
|
54
|
-
const content = fs.readFileSync(
|
|
53
|
+
const content = fs.readFileSync(agentMdFilePath, 'utf-8');
|
|
55
54
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
56
55
|
if (!fmMatch)
|
|
57
56
|
return { name: null, description: null };
|
|
@@ -68,8 +67,7 @@ function readAgentMdIdentity(aid) {
|
|
|
68
67
|
}
|
|
69
68
|
}
|
|
70
69
|
function getAgentMdPath(aid) {
|
|
71
|
-
|
|
72
|
-
return path.join(aunPath, 'AIDs', aid, 'agent.md');
|
|
70
|
+
return getAgentMdPathFromPaths(aid);
|
|
73
71
|
}
|
|
74
72
|
function getNestedValue(obj, keyPath) {
|
|
75
73
|
const keys = keyPath.split('.');
|
|
@@ -391,10 +389,8 @@ export async function agentCreateInteractive(opts = {}) {
|
|
|
391
389
|
if (agentDescription) {
|
|
392
390
|
content = content.replace(/^description:\s*".*?"$/m, `description: "${agentDescription}"`);
|
|
393
391
|
}
|
|
394
|
-
const aunPath = process.env.AUN_HOME ||
|
|
395
|
-
|
|
396
|
-
fs.mkdirSync(path.dirname(agentMdPath), { recursive: true });
|
|
397
|
-
fs.writeFileSync(agentMdPath, content, 'utf-8');
|
|
392
|
+
const aunPath = process.env.AUN_HOME || defaultAunPath();
|
|
393
|
+
// agentmdPut 会写本地文件到 agentMdPath(aid) 并调用 publishAgentMd
|
|
398
394
|
// Upload with retry (3 attempts, 2s delay between retries)
|
|
399
395
|
const MAX_ATTEMPTS = 3;
|
|
400
396
|
const RETRY_DELAY_MS = 2000;
|
|
@@ -423,11 +419,14 @@ export async function agentCreateInteractive(opts = {}) {
|
|
|
423
419
|
catch (e) {
|
|
424
420
|
console.warn(` ⚠ agent.md generation failed: ${e?.message || e}`);
|
|
425
421
|
}
|
|
426
|
-
// Attempt hot-load via IPC (if daemon is running)
|
|
422
|
+
// Attempt hot-load via IPC (if daemon is running).
|
|
423
|
+
// Cold-starting a new agent (connecting AUN WebSocket) routinely takes
|
|
424
|
+
// >3s, so use a generous timeout to avoid a false "service not running"
|
|
425
|
+
// report while the daemon actually finishes bringing the agent online.
|
|
427
426
|
let hotLoaded = false;
|
|
428
427
|
let hotLoadError;
|
|
429
428
|
try {
|
|
430
|
-
const ipcResult = await ipcQuery(p.socket, { type: 'evolagent.load', aid });
|
|
429
|
+
const ipcResult = await ipcQuery(p.socket, { type: 'evolagent.load', aid }, 30_000);
|
|
431
430
|
if (ipcResult?.ok) {
|
|
432
431
|
hotLoaded = true;
|
|
433
432
|
}
|
|
@@ -547,10 +546,8 @@ export async function agentCreateNonInteractive(opts) {
|
|
|
547
546
|
if (agentDescription) {
|
|
548
547
|
content = content.replace(/^description:\s*".*?"$/m, `description: "${agentDescription}"`);
|
|
549
548
|
}
|
|
550
|
-
const aunPath = process.env.AUN_HOME ||
|
|
551
|
-
|
|
552
|
-
fs.mkdirSync(path.dirname(agentMdPath), { recursive: true });
|
|
553
|
-
fs.writeFileSync(agentMdPath, content, 'utf-8');
|
|
549
|
+
const aunPath = process.env.AUN_HOME || defaultAunPath();
|
|
550
|
+
// agentmdPut 会写本地文件到 agentMdPath(aid) 并调用 publishAgentMd
|
|
554
551
|
const MAX_ATTEMPTS = 3;
|
|
555
552
|
const RETRY_DELAY_MS = 2000;
|
|
556
553
|
let lastError;
|
|
@@ -575,11 +572,14 @@ export async function agentCreateNonInteractive(opts) {
|
|
|
575
572
|
catch (e) {
|
|
576
573
|
console.warn(`⚠ agent.md generation failed: ${e?.message || e}`);
|
|
577
574
|
}
|
|
578
|
-
// Attempt hot-load via IPC (if daemon is running)
|
|
575
|
+
// Attempt hot-load via IPC (if daemon is running).
|
|
576
|
+
// Cold-starting a new agent (connecting AUN WebSocket) routinely takes
|
|
577
|
+
// >3s, so use a generous timeout to avoid a false "service not running"
|
|
578
|
+
// report while the daemon actually finishes bringing the agent online.
|
|
579
579
|
let hotLoaded = false;
|
|
580
580
|
let hotLoadError;
|
|
581
581
|
try {
|
|
582
|
-
const ipcResult = await ipcQuery(p.socket, { type: 'evolagent.load', aid: opts.aid });
|
|
582
|
+
const ipcResult = await ipcQuery(p.socket, { type: 'evolagent.load', aid: opts.aid }, 30_000);
|
|
583
583
|
if (ipcResult?.ok) {
|
|
584
584
|
hotLoaded = true;
|
|
585
585
|
}
|
|
@@ -603,7 +603,7 @@ export async function agentCreateNonInteractive(opts) {
|
|
|
603
603
|
export async function agentSyncAids() {
|
|
604
604
|
const p = resolvePaths();
|
|
605
605
|
const { aidList } = await import('../aun/aid/index.js');
|
|
606
|
-
const aunPath = process.env.AUN_HOME ||
|
|
606
|
+
const aunPath = process.env.AUN_HOME || defaultAunPath();
|
|
607
607
|
const allAids = aidList(aunPath);
|
|
608
608
|
const localAids = allAids.filter(a => a.hasPrivateKey).map(a => a.aid);
|
|
609
609
|
if (localAids.length === 0) {
|
|
@@ -835,7 +835,7 @@ export async function agentChannelUpsert(opts) {
|
|
|
835
835
|
return {
|
|
836
836
|
ok: true,
|
|
837
837
|
aid: opts.aid,
|
|
838
|
-
channelKey: `${opts.channel.type}#${
|
|
838
|
+
channelKey: `${opts.channel.type}#${opts.aid}#${opts.channel.name}`,
|
|
839
839
|
reloaded,
|
|
840
840
|
};
|
|
841
841
|
}
|
|
@@ -869,12 +869,12 @@ export async function agentDelete(aid, purge = false) {
|
|
|
869
869
|
}
|
|
870
870
|
// ==================== agentRename ====================
|
|
871
871
|
export async function agentRename(aid, newName) {
|
|
872
|
-
const aunPath = process.env.AUN_HOME ||
|
|
873
|
-
const
|
|
874
|
-
if (!fs.existsSync(
|
|
872
|
+
const aunPath = process.env.AUN_HOME || defaultAunPath();
|
|
873
|
+
const agentMdFilePath = getAgentMdPathFromPaths(aid);
|
|
874
|
+
if (!fs.existsSync(agentMdFilePath)) {
|
|
875
875
|
return { ok: false, error: `agent.md not found for ${aid}. Run: evolclaw aid agentmd put ${aid}` };
|
|
876
876
|
}
|
|
877
|
-
let content = fs.readFileSync(
|
|
877
|
+
let content = fs.readFileSync(agentMdFilePath, 'utf-8');
|
|
878
878
|
const fmMatch = content.match(/^(---\n)([\s\S]*?)(\n---)/);
|
|
879
879
|
if (!fmMatch) {
|
|
880
880
|
return { ok: false, error: `agent.md has no valid frontmatter for ${aid}` };
|
|
@@ -889,8 +889,7 @@ export async function agentRename(aid, newName) {
|
|
|
889
889
|
newFm = `name: "${newName}"\n${fm}`;
|
|
890
890
|
}
|
|
891
891
|
content = fmMatch[1] + newFm + fmMatch[3] + content.slice(fmMatch[0].length);
|
|
892
|
-
|
|
893
|
-
// Upload
|
|
892
|
+
// agentmdPut 会写本地文件并 publishAgentMd
|
|
894
893
|
let uploaded = false;
|
|
895
894
|
try {
|
|
896
895
|
const { agentmdPut } = await import('../aun/aid/index.js');
|
package/dist/cli/bench.js
CHANGED
|
@@ -6,7 +6,9 @@ import { execFile } from 'child_process';
|
|
|
6
6
|
import { promisify } from 'util';
|
|
7
7
|
import { aidList, aidCreate } from '../aun/aid/identity.js';
|
|
8
8
|
import { msgSend, msgPull } from '../aun/msg/index.js';
|
|
9
|
-
import { getPackageRoot } from '../paths.js';
|
|
9
|
+
import { getPackageRoot, aunPath as defaultAunPath } from '../paths.js';
|
|
10
|
+
import { getAidStore, loadClient, SLOT } from '../aun/aid/store.js';
|
|
11
|
+
import { isHelpFlag } from './help.js';
|
|
10
12
|
const execFileAsync = promisify(execFile);
|
|
11
13
|
// ==================== ANSI ====================
|
|
12
14
|
const GREEN = '\x1b[32m';
|
|
@@ -246,42 +248,48 @@ function computeMetrics(results, received, durationSec) {
|
|
|
246
248
|
function filterBySize(results, received, cls, durationSec) {
|
|
247
249
|
return computeMetrics(results.filter(r => r.sizeClass === cls), received.filter(r => r.sizeClass === cls), durationSec);
|
|
248
250
|
}
|
|
249
|
-
async function benchAuth(aids, concurrency, aunPath
|
|
250
|
-
const
|
|
251
|
-
const path = (await import('path')).default;
|
|
252
|
-
const fs = (await import('fs')).default;
|
|
253
|
-
const os = (await import('os')).default;
|
|
254
|
-
const resolvedAunPath = aunPath ?? path.join(os.homedir(), '.aun');
|
|
255
|
-
const caCertPath = path.join(resolvedAunPath, 'CA', 'root', 'root.crt');
|
|
256
|
-
const tasks = aids.map(aid => async () => {
|
|
251
|
+
async function benchAuth(aids, concurrency, aunPath) {
|
|
252
|
+
const tasks = aids.map((aid, index) => async () => {
|
|
257
253
|
const start = Date.now();
|
|
254
|
+
const slotId = `${SLOT.bench}-${index}`;
|
|
255
|
+
let store = null;
|
|
256
|
+
let client = null;
|
|
258
257
|
try {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
const authResult = await client.auth.authenticate({ aid });
|
|
265
|
-
const accessToken = authResult?.access_token ?? client._access_token;
|
|
266
|
-
const gateway = client._gatewayUrl ?? authResult?.gateway ?? '';
|
|
267
|
-
await client.connect({ access_token: accessToken, gateway, slot_id: slotId ?? '', connection_kind: 'short' }, { auto_reconnect: false });
|
|
258
|
+
store = await getAidStore({ slotId, aunPath });
|
|
259
|
+
client = await loadClient(store, aid);
|
|
260
|
+
await client.connect({ auto_reconnect: false });
|
|
261
|
+
const gateway = ''; // Gateway URL not exposed in 0.4.3
|
|
262
|
+
const authMs = Date.now() - start;
|
|
268
263
|
try {
|
|
269
264
|
await client.close();
|
|
270
265
|
}
|
|
271
266
|
catch { }
|
|
272
|
-
|
|
267
|
+
try {
|
|
268
|
+
store.close();
|
|
269
|
+
}
|
|
270
|
+
catch { }
|
|
271
|
+
return { aid, ok: true, authMs, gateway };
|
|
273
272
|
}
|
|
274
273
|
catch (e) {
|
|
274
|
+
if (client)
|
|
275
|
+
try {
|
|
276
|
+
await client.close();
|
|
277
|
+
}
|
|
278
|
+
catch { }
|
|
279
|
+
if (store)
|
|
280
|
+
try {
|
|
281
|
+
store.close();
|
|
282
|
+
}
|
|
283
|
+
catch { }
|
|
275
284
|
return { aid, ok: false, authMs: Date.now() - start, error: e.message };
|
|
276
285
|
}
|
|
277
286
|
});
|
|
278
287
|
return runPool(tasks, concurrency);
|
|
279
288
|
}
|
|
280
|
-
async function benchSwitch(aids, rounds, aunPath, useCli,
|
|
289
|
+
async function benchSwitch(aids, rounds, aunPath, useCli, encrypt) {
|
|
281
290
|
const results = [];
|
|
282
291
|
const start = Date.now();
|
|
283
292
|
let seq = 0;
|
|
284
|
-
const slot = slotId ?? 'bench';
|
|
285
293
|
for (let round = 0; round < rounds; round++) {
|
|
286
294
|
for (let i = 0; i < aids.length; i++) {
|
|
287
295
|
const from = aids[i];
|
|
@@ -292,8 +300,9 @@ async function benchSwitch(aids, rounds, aunPath, useCli, slotId, encrypt) {
|
|
|
292
300
|
let ok = false;
|
|
293
301
|
let serverTimestamp;
|
|
294
302
|
if (useCli) {
|
|
303
|
+
const slotId = `${SLOT.bench}-${i}`;
|
|
295
304
|
try {
|
|
296
|
-
const res = await withTimeout(cliSend(from, to, text,
|
|
305
|
+
const res = await withTimeout(cliSend(from, to, text, slotId, encrypt), 10000, `${from.split('.')[0]}→${to.split('.')[0]}`);
|
|
297
306
|
ok = res.ok;
|
|
298
307
|
serverTimestamp = res.timestamp;
|
|
299
308
|
}
|
|
@@ -302,8 +311,9 @@ async function benchSwitch(aids, rounds, aunPath, useCli, slotId, encrypt) {
|
|
|
302
311
|
}
|
|
303
312
|
}
|
|
304
313
|
else {
|
|
314
|
+
const slotId = `${SLOT.bench}-${i}`;
|
|
305
315
|
try {
|
|
306
|
-
const res = await withTimeout(msgSend({ from, to, body: { mode: 'text', text }, slotId
|
|
316
|
+
const res = await withTimeout(msgSend({ from, to, body: { mode: 'text', text }, slotId, aunPath, encrypt }), 10000, `${from.split('.')[0]}→${to.split('.')[0]}`);
|
|
307
317
|
ok = res.ok;
|
|
308
318
|
serverTimestamp = res.ok ? res.timestamp : undefined;
|
|
309
319
|
}
|
|
@@ -363,7 +373,7 @@ async function cliAuth(aid, slotId) {
|
|
|
363
373
|
}
|
|
364
374
|
// ==================== Main Command ====================
|
|
365
375
|
export async function cmdBench(args) {
|
|
366
|
-
if (args[0]
|
|
376
|
+
if (isHelpFlag(args[0])) {
|
|
367
377
|
console.log(`用法: evolclaw bench [options]
|
|
368
378
|
|
|
369
379
|
AUN 消息系统性能基准测试。使用多个本地 AID 并发互发消息,
|
|
@@ -398,7 +408,6 @@ Options:
|
|
|
398
408
|
const defaultWait = encrypt ? '10' : '3';
|
|
399
409
|
const waitSec = Math.max(1, parseInt(getArgValue(args, '--wait') || defaultWait, 10));
|
|
400
410
|
const sessionId = crypto.randomBytes(4).toString('hex');
|
|
401
|
-
const benchSlot = `bench-${sessionId}`;
|
|
402
411
|
if (!formatJson) {
|
|
403
412
|
console.log(`\n${BOLD} evolclaw bench${RST} — AUN 消息性能基准测试`);
|
|
404
413
|
console.log(` ${'━'.repeat(50)}`);
|
|
@@ -411,14 +420,14 @@ Options:
|
|
|
411
420
|
const aids = [];
|
|
412
421
|
// AID is usable if: has private key + cert not expired + key/cert public key match
|
|
413
422
|
const { aidShow } = await import('../aun/aid/identity.js');
|
|
414
|
-
const resolvedAunPath = aunPath ??
|
|
423
|
+
const resolvedAunPath = aunPath ?? defaultAunPath();
|
|
415
424
|
const usableAids = [];
|
|
416
425
|
const skippedAids = [];
|
|
417
426
|
for (const a of allAids) {
|
|
418
427
|
if (!a.hasPrivateKey)
|
|
419
428
|
continue;
|
|
420
429
|
try {
|
|
421
|
-
const info = aidShow(a.aid, { aunPath });
|
|
430
|
+
const info = await aidShow(a.aid, { aunPath });
|
|
422
431
|
if (!info.certExpiresAt) {
|
|
423
432
|
skippedAids.push({ aid: a.aid, reason: '无证书' });
|
|
424
433
|
continue;
|
|
@@ -501,14 +510,15 @@ Options:
|
|
|
501
510
|
authTasks.push(...aids);
|
|
502
511
|
let authResults;
|
|
503
512
|
if (cliMode) {
|
|
504
|
-
const cliAuthTasks = authTasks.map(aid => async () => {
|
|
505
|
-
const
|
|
513
|
+
const cliAuthTasks = authTasks.map((aid, index) => async () => {
|
|
514
|
+
const slotId = `${SLOT.bench}-${index}`;
|
|
515
|
+
const r = await cliAuth(aid, slotId);
|
|
506
516
|
return { aid, ok: r.ok, authMs: r.authMs };
|
|
507
517
|
});
|
|
508
518
|
authResults = await runPool(cliAuthTasks, concurrency);
|
|
509
519
|
}
|
|
510
520
|
else {
|
|
511
|
-
authResults = await benchAuth(authTasks, concurrency, aunPath
|
|
521
|
+
authResults = await benchAuth(authTasks, concurrency, aunPath);
|
|
512
522
|
}
|
|
513
523
|
const authOk = authResults.filter(r => r.ok);
|
|
514
524
|
const authFail = authResults.filter(r => !r.ok);
|
|
@@ -598,7 +608,7 @@ Options:
|
|
|
598
608
|
// Suppress SDK error logs during send phase (we track errors ourselves)
|
|
599
609
|
const origError2 = console.error;
|
|
600
610
|
console.error = () => { };
|
|
601
|
-
const sendFns = tasks.map(t => async () => {
|
|
611
|
+
const sendFns = tasks.map((t, taskIndex) => async () => {
|
|
602
612
|
let lastError;
|
|
603
613
|
let retries = 0;
|
|
604
614
|
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
@@ -611,10 +621,11 @@ Options:
|
|
|
611
621
|
? buildFileChunkText(t.seq, fileChunks.length, sendTs, sessionId, fileChunks[t.seq]?.toString('base64') ?? '')
|
|
612
622
|
: buildMessageText(t.seq, t.sizeClass, sendTs, sessionId);
|
|
613
623
|
const t0 = Date.now();
|
|
624
|
+
const slotId = `${SLOT.bench}-${taskIndex % concurrency}`;
|
|
614
625
|
try {
|
|
615
626
|
const sendPromise = cliMode
|
|
616
|
-
? cliSend(t.from, t.to, text,
|
|
617
|
-
: msgSend({ from: t.from, to: t.to, body: { mode: 'text', text }, slotId
|
|
627
|
+
? cliSend(t.from, t.to, text, slotId, encrypt)
|
|
628
|
+
: msgSend({ from: t.from, to: t.to, body: { mode: 'text', text }, slotId, aunPath, encrypt });
|
|
618
629
|
const res = await withTimeout(sendPromise, SEND_TIMEOUT_MS, `${t.from.split('.')[0]}→${t.to.split('.')[0]}`);
|
|
619
630
|
if (cliMode) {
|
|
620
631
|
const cliRes = res;
|
|
@@ -928,7 +939,7 @@ Options:
|
|
|
928
939
|
if (!formatJson)
|
|
929
940
|
console.log(`${DIM} Phase 5: 频繁切换账号收发测试${RST}`);
|
|
930
941
|
const switchRounds = Math.max(2, Math.min(rounds, 5));
|
|
931
|
-
const switchOut = await benchSwitch(aids, switchRounds, aunPath, cliMode,
|
|
942
|
+
const switchOut = await benchSwitch(aids, switchRounds, aunPath, cliMode, encrypt);
|
|
932
943
|
const switchOkResults = switchOut.results.filter(r => r.ok);
|
|
933
944
|
const switchLatencies = switchOkResults
|
|
934
945
|
.filter(r => r.serverTimestamp !== undefined)
|
package/dist/cli/help.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI help 检测 helper。
|
|
3
|
+
*
|
|
4
|
+
* 把 7 种历史写法统一为两个语义清晰的函数:
|
|
5
|
+
* - isHelpFlag(token):单 token 是否是 help 标记('help' / '--help' / '-h')
|
|
6
|
+
* - wantsHelp(args):args 任意位置出现 help 标记
|
|
7
|
+
*
|
|
8
|
+
* 两套 API 服务于不同语义:
|
|
9
|
+
* - 顶层路由(如 cmdAid 看到第一个 token 是子命令名时)必须用 isHelpFlag(sub),
|
|
10
|
+
* 否则 `ec aid delete --help` 会被顶层吞掉,永远到不了 delete 自己的 help。
|
|
11
|
+
* - 单层命令(如 cmdLinkRules、cmdAid 的具体 sub 处理块内)用 wantsHelp(args)
|
|
12
|
+
* 更宽松,任意位置都识别。
|
|
13
|
+
*/
|
|
14
|
+
const HELP_TOKENS = new Set(['help', '--help', '-h']);
|
|
15
|
+
export function isHelpFlag(token) {
|
|
16
|
+
return token !== undefined && HELP_TOKENS.has(token);
|
|
17
|
+
}
|
|
18
|
+
export function wantsHelp(args) {
|
|
19
|
+
for (const a of args)
|
|
20
|
+
if (HELP_TOKENS.has(a))
|
|
21
|
+
return true;
|
|
22
|
+
return false;
|
|
23
|
+
}
|