evolcore 0.0.25 → 0.0.27

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.
Files changed (304) hide show
  1. package/CHANGELOG.md +632 -565
  2. package/LICENSE +21 -21
  3. package/README.md +455 -455
  4. package/bin/codex-managed-acl.ps1 +203 -160
  5. package/bin/codex-managed-hook.mjs +208 -208
  6. package/bin/ec-safe-output.js +327 -327
  7. package/bin/ec.js +40 -29
  8. package/bin/install-codex-managed-hooks.mjs +582 -555
  9. package/dist/agents/baseagent-availability.js +68 -0
  10. package/dist/agents/baseagent.js +96 -46
  11. package/dist/agents/claude-runner.js +172 -33
  12. package/dist/agents/codex/app-server-client.js +76 -31
  13. package/dist/agents/codex/catalog.js +1 -1
  14. package/dist/agents/codex/diagnostics.js +34 -1
  15. package/dist/agents/codex-runner.js +434 -446
  16. package/dist/agents/ecagent-runner.js +174 -34
  17. package/dist/agents/gemini-runner.js +8 -7
  18. package/dist/agents/runner-types.js +75 -19
  19. package/dist/aun/aid/agentmd.js +151 -36
  20. package/dist/aun/aid/client.js +1 -1
  21. package/dist/aun/aid/control-aid.js +180 -1
  22. package/dist/aun/aid/identity.js +4 -4
  23. package/dist/aun/aid/index.js +1 -1
  24. package/dist/aun/aid/store.js +17 -13
  25. package/dist/aun/group/history.js +303 -0
  26. package/dist/aun/group/identity.js +43 -0
  27. package/dist/aun/group/index.js +5 -0
  28. package/dist/aun/{msg/group.js → group/operations.js} +162 -39
  29. package/dist/aun/{menu-client.js → menu/client.js} +85 -6
  30. package/dist/aun/menu/index.js +2 -0
  31. package/dist/aun/menu/transport.js +49 -0
  32. package/dist/aun/msg/index.js +2 -1
  33. package/dist/aun/msg/managed-operation.js +85 -19
  34. package/dist/aun/msg/mention-schema.js +51 -0
  35. package/dist/aun/msg/p2p.js +19 -9
  36. package/dist/aun/msg/upload.js +43 -80
  37. package/dist/aun/outbox.js +29 -7
  38. package/dist/aun/rpc/client.js +1 -0
  39. package/dist/aun/storage/client.js +39 -50
  40. package/dist/channels/aun.js +842 -318
  41. package/dist/channels/daemon.js +10 -6
  42. package/dist/cli/agent-command.js +212 -89
  43. package/dist/cli/agent-create.js +626 -11
  44. package/dist/cli/agent.js +125 -13
  45. package/dist/cli/aun-commands.js +487 -337
  46. package/dist/cli/bench.js +20 -20
  47. package/dist/cli/config.js +55 -33
  48. package/dist/cli/contact.js +72 -15
  49. package/dist/cli/ctl-command.js +24 -24
  50. package/dist/cli/daemon-commands.js +140 -63
  51. package/dist/cli/diag.js +31 -0
  52. package/dist/cli/fs-command.js +70 -70
  53. package/dist/cli/handoff-command.js +46 -14
  54. package/dist/cli/index.js +91 -79
  55. package/dist/cli/init.js +34 -1
  56. package/dist/cli/link-rules.js +21 -21
  57. package/dist/cli/managed-command-guard.js +5 -1
  58. package/dist/cli/menu-client.js +51 -32
  59. package/dist/cli/model.js +3 -3
  60. package/dist/cli/net-check.js +22 -22
  61. package/dist/cli/queue-command.js +31 -31
  62. package/dist/cli/response.js +32 -32
  63. package/dist/cli/restart-monitor.js +103 -42
  64. package/dist/cli/stats.js +51 -51
  65. package/dist/cli/task-command.js +59 -0
  66. package/dist/cli/task-context.js +97 -49
  67. package/dist/cli/trigger-command.js +74 -64
  68. package/dist/config/builtin-roles.js +11 -0
  69. package/dist/config/config-field-policy.js +11 -0
  70. package/dist/config/config-manager.js +32 -4
  71. package/dist/config/config-operation-service.js +160 -0
  72. package/dist/config/contact-book-store.js +1 -1
  73. package/dist/config/contact-book.js +1 -1
  74. package/dist/config/contact-operation-service.js +97 -8
  75. package/dist/config/peer-role-resolver.js +1 -1
  76. package/dist/config/resolved-config-op.js +30 -7
  77. package/dist/config-store.js +1 -1
  78. package/dist/core/agent-application-service.js +7 -1
  79. package/dist/core/audit/event-key.js +17 -2
  80. package/dist/core/audit/log-integrity.js +34 -8
  81. package/dist/core/auth/agent-delegation.js +48 -14
  82. package/dist/core/auth/auth-gateway.js +2 -0
  83. package/dist/core/auth/authorization-audit.js +53 -49
  84. package/dist/core/auth/operation-authorizer.js +90 -7
  85. package/dist/core/auth/operation-catalog.js +145 -4
  86. package/dist/core/auth/remote-access-store.js +155 -10
  87. package/dist/core/bootstrap-messages.js +66 -7
  88. package/dist/core/bootstrap-service.js +111 -20
  89. package/dist/core/command/agent-control.js +88 -7
  90. package/dist/core/command/agent-storage-menu.js +443 -0
  91. package/dist/core/command/cli-intent-parser.js +19 -0
  92. package/dist/core/command/command-handler.js +159 -65
  93. package/dist/core/command/data-root-resolver.js +273 -0
  94. package/dist/core/command/diag-service.js +118 -0
  95. package/dist/core/command/group-menu.js +7 -2
  96. package/dist/core/command/menu-catalog.js +46 -7
  97. package/dist/core/command/menu-handler.js +392 -100
  98. package/dist/core/command/menu-protocol.js +45 -6
  99. package/dist/core/command/menu-token-store.js +41 -8
  100. package/dist/core/command/role-menu.js +2 -2
  101. package/dist/core/command/slash-gate.js +34 -4
  102. package/dist/core/command/slash-handler.js +123 -43
  103. package/dist/core/event-catalog.js +4 -0
  104. package/dist/core/evolagent-registry.js +28 -2
  105. package/dist/core/group/invite-service.js +924 -0
  106. package/dist/core/handoff/runtime.js +205 -27
  107. package/dist/core/handoff/store.js +193 -4
  108. package/dist/core/interaction-router.js +22 -8
  109. package/dist/core/message/im-renderer.js +146 -34
  110. package/dist/core/message/message-bridge.js +163 -20
  111. package/dist/core/message/message-log.js +5 -3
  112. package/dist/core/message/message-queue.js +99 -41
  113. package/dist/core/message/message-utils.js +1 -0
  114. package/dist/core/message/response-engine.js +755 -144
  115. package/dist/core/model/catalog-service.js +79 -49
  116. package/dist/core/model/context-window-suffix.js +33 -0
  117. package/dist/core/model/model-catalog.js +1 -1
  118. package/dist/core/model/model-permission.js +12 -3
  119. package/dist/core/permission/approval-gateway.js +36 -3
  120. package/dist/core/permission/ec-command-parser.js +112 -41
  121. package/dist/core/permission/protected-paths.js +134 -16
  122. package/dist/core/permission/sandbox-runtime.js +108 -17
  123. package/dist/core/permission/tool-error-code.js +15 -0
  124. package/dist/core/permission/tool-policy.js +9 -8
  125. package/dist/core/relation/peer-identity.js +57 -6
  126. package/dist/core/relation/shared-data.js +106 -0
  127. package/dist/core/role/runtime-policy.js +64 -0
  128. package/dist/core/runtime-lock.js +10 -26
  129. package/dist/core/session/runner-task-history.js +170 -0
  130. package/dist/core/session/session-manager.js +34 -6
  131. package/dist/core/session/session-mapper.js +41 -0
  132. package/dist/core/session/session-turn-coordinator.js +37 -7
  133. package/dist/core/session/session-turns.js +48 -7
  134. package/dist/core/task/task-recovery-service.js +176 -0
  135. package/dist/core/task/task-resume-operation.js +32 -0
  136. package/dist/eck/group-rules-sync.js +5 -3
  137. package/dist/eck/kit-renderer.js +1 -0
  138. package/dist/index.js +588 -217
  139. package/dist/ipc.js +193 -15
  140. package/dist/paths.js +17 -4
  141. package/dist/product.js +2 -0
  142. package/dist/response-system/engines/v1/proactive-flow.js +59 -2
  143. package/dist/stats/billing.js +41 -15
  144. package/dist/stats/db.js +159 -159
  145. package/dist/stats/eck-vars.js +9 -9
  146. package/dist/stats/price-resolver.js +28 -10
  147. package/dist/stats/query.js +139 -139
  148. package/dist/stats/role-budget.js +6 -6
  149. package/dist/stats/writer.js +51 -51
  150. package/dist/trigger/event-source.js +19 -0
  151. package/dist/trigger/feedback.js +233 -40
  152. package/dist/trigger/parser.js +55 -5
  153. package/dist/trigger/patch.js +9 -0
  154. package/dist/trigger/scheduler.js +30 -4
  155. package/dist/trigger/validation.js +20 -3
  156. package/dist/utils/cross-platform.js +30 -1
  157. package/dist/utils/ecweb-utils.js +1 -0
  158. package/dist/utils/error-dict.json +160 -160
  159. package/dist/utils/error-utils.js +61 -2
  160. package/dist/utils/evolcore-version.js +129 -0
  161. package/dist/utils/logger.js +26 -14
  162. package/dist/utils/macos-autostart.js +22 -22
  163. package/dist/utils/model-prices.jsonl +23 -23
  164. package/dist/utils/npm-ops.js +176 -35
  165. package/dist/utils/tool-summary.js +59 -3
  166. package/dist/utils/welcome.js +196 -23
  167. package/ecagent/LICENSE +21 -21
  168. package/ecagent/NOTICE +11 -11
  169. package/ecagent/README.md +61 -61
  170. package/ecagent/dist/harness/agent-harness.js +3 -0
  171. package/ecagent/dist/harness/compaction/branch-summarization.js +30 -30
  172. package/ecagent/dist/harness/compaction/compaction.js +83 -83
  173. package/ecagent/dist/harness/messages.js +7 -7
  174. package/ecagent/dist/harness/session/jsonl-storage.js +21 -2
  175. package/kits/docs/GUIDE.md +20 -20
  176. package/kits/docs/INDEX.md +60 -66
  177. package/kits/docs/aun/CHEATSHEET.md +19 -19
  178. package/kits/docs/aun/SYNC_PROTOCOL.md +15 -15
  179. package/kits/docs/channels/aun.md +69 -56
  180. package/kits/docs/channels/feishu.md +56 -56
  181. package/kits/docs/context-assembly.md +379 -367
  182. package/kits/docs/eck_templates/GUIDE.template.md +22 -22
  183. package/kits/docs/eck_templates/INDEX.template.md +28 -28
  184. package/kits/docs/eck_templates/path-registry.template.md +33 -33
  185. package/kits/docs/eck_templates/runtime.template.md +19 -19
  186. package/kits/docs/evolcore/INDEX.md +76 -71
  187. package/kits/docs/evolcore/agent-create.md +202 -165
  188. package/kits/docs/evolcore/agent.md +99 -67
  189. package/kits/docs/evolcore/aid.md +68 -60
  190. package/kits/docs/evolcore/codex-windows-sandbox.md +146 -146
  191. package/kits/docs/evolcore/config.md +241 -195
  192. package/kits/docs/evolcore/contact.md +75 -68
  193. package/kits/docs/evolcore/ctl.md +46 -46
  194. package/kits/docs/evolcore/event.md +216 -216
  195. package/kits/docs/evolcore/fs-architecture.md +1215 -1215
  196. package/kits/docs/evolcore/fs.md +110 -110
  197. package/kits/docs/evolcore/group-collaboration.md +244 -244
  198. package/kits/docs/evolcore/group-fs.md +17 -17
  199. package/kits/docs/evolcore/group-rules.md +251 -251
  200. package/kits/docs/evolcore/group.md +267 -152
  201. package/kits/docs/evolcore/menu-client.md +58 -34
  202. package/kits/docs/evolcore/model.md +50 -50
  203. package/kits/docs/evolcore/msg.md +169 -165
  204. package/kits/docs/evolcore/response.md +75 -75
  205. package/kits/docs/evolcore/rpc.md +37 -37
  206. package/kits/docs/evolcore/self-summary.md +29 -29
  207. package/kits/docs/evolcore/stats.md +83 -83
  208. package/kits/docs/evolcore/storage.md +53 -50
  209. package/kits/docs/evolcore/task.md +14 -0
  210. package/kits/docs/evolcore/trigger.md +623 -575
  211. package/kits/docs/identity/AID_PROFILE_SPEC.md +26 -26
  212. package/kits/docs/identity/PATH_OPS.md +16 -16
  213. package/kits/docs/identity/ROLE_DETAIL.md +25 -25
  214. package/kits/docs/identity/identity-tools.md +26 -26
  215. package/kits/docs/path-registry.md +62 -62
  216. package/kits/docs/prompt-loading-architecture.md +269 -269
  217. package/kits/docs/venues/aun-group.md +45 -45
  218. package/kits/docs/venues/aun-private.md +10 -10
  219. package/kits/docs/venues/client-desktop.md +10 -10
  220. package/kits/docs/venues/client-mobile.md +10 -10
  221. package/kits/docs/venues/feishu-group.md +13 -13
  222. package/kits/docs/venues/feishu-private.md +9 -9
  223. package/kits/docs/venues/group.md +42 -25
  224. package/kits/docs/venues/private.md +10 -10
  225. package/kits/eck_manifest.auxiliary.json +43 -43
  226. package/kits/eck_manifest.json +217 -190
  227. package/kits/eck_message_manifest.json +74 -74
  228. package/kits/migrations/README-role-config-v4.md +32 -32
  229. package/kits/migrations/migrate-contact-book-v2.mjs +748 -748
  230. package/kits/migrations/migrate-role-config-v4.mjs +614 -614
  231. package/kits/migrations/migrate-role-config-v5.mjs +365 -365
  232. package/kits/migrations/rename-config-file.mjs +99 -99
  233. package/kits/rules/01-overview.md +166 -162
  234. package/kits/rules/02-navigation.md +96 -96
  235. package/kits/rules/03-identity.md +36 -36
  236. package/kits/rules/04-relation.md +76 -75
  237. package/kits/rules/05-venue.md +60 -60
  238. package/kits/rules/06-channel.md +65 -63
  239. package/kits/schemas/_meta.json +53 -53
  240. package/kits/schemas/agent-config.schema.1.json +177 -177
  241. package/kits/schemas/agent-config.schema.10.json +395 -395
  242. package/kits/schemas/agent-config.schema.11.json +421 -421
  243. package/kits/schemas/agent-config.schema.12.json +451 -427
  244. package/kits/schemas/agent-config.schema.2.json +239 -239
  245. package/kits/schemas/agent-config.schema.3.json +119 -119
  246. package/kits/schemas/agent-config.schema.4.json +208 -208
  247. package/kits/schemas/agent-config.schema.5.json +326 -326
  248. package/kits/schemas/agent-config.schema.6.json +322 -322
  249. package/kits/schemas/agent-config.schema.7.json +303 -303
  250. package/kits/schemas/agent-config.schema.8.json +304 -304
  251. package/kits/schemas/agent-config.schema.9.json +364 -364
  252. package/kits/schemas/contact-book.schema.1.json +36 -36
  253. package/kits/schemas/contact-book.schema.2.json +43 -43
  254. package/kits/schemas/contact-book.schema.3.json +67 -67
  255. package/kits/schemas/daemon.schema.1.json +91 -91
  256. package/kits/schemas/daemon.schema.2.json +101 -101
  257. package/kits/schemas/daemon.schema.3.json +123 -123
  258. package/kits/schemas/daemon.schema.4.json +136 -136
  259. package/kits/schemas/daemon.schema.5.json +135 -135
  260. package/kits/schemas/daemon.schema.6.json +131 -131
  261. package/kits/schemas/defaults.schema.1.json +81 -81
  262. package/kits/schemas/defaults.schema.2.json +85 -85
  263. package/kits/schemas/defaults.schema.3.json +73 -73
  264. package/kits/schemas/defaults.schema.4.json +107 -107
  265. package/kits/schemas/defaults.schema.5.json +119 -119
  266. package/kits/schemas/menu-exec-schema-commands.md +208 -208
  267. package/kits/schemas/migrations/README.md +30 -30
  268. package/kits/schemas/relation-config.schema.1.json +158 -158
  269. package/kits/schemas/relation-config.schema.2.json +73 -73
  270. package/kits/schemas/relation-config.schema.3.json +50 -50
  271. package/kits/schemas/relation-config.schema.4.json +47 -47
  272. package/kits/schemas/relation-config.schema.5.json +47 -47
  273. package/kits/schemas/relation-config.schema.6.json +46 -46
  274. package/kits/schemas/relation-config.schema.7.json +59 -59
  275. package/kits/schemas/relation-config.schema.8.json +103 -103
  276. package/kits/schemas/role-config.schema.1.json +215 -201
  277. package/kits/schemas/role-registry.schema.1.json +35 -35
  278. package/kits/schemas/single-session.schema.1.json +31 -31
  279. package/kits/schemas/single-session.schema.2.json +57 -57
  280. package/kits/schemas/single-session.schema.3.json +32 -32
  281. package/kits/templates/bootstrap-welcome.md +17 -17
  282. package/kits/templates/message-fragments/handoff-context-to-target.md +9 -9
  283. package/kits/templates/message-fragments/handoff-request-to-target.md +19 -19
  284. package/kits/templates/message-fragments/handoff-response-to-origin.md +9 -9
  285. package/kits/templates/message-fragments/inject-default.md +2 -2
  286. package/kits/templates/message-fragments/item.md +2 -2
  287. package/kits/templates/roles/admin.json +92 -92
  288. package/kits/templates/roles/member.json +101 -96
  289. package/kits/templates/roles/owner.json +9 -9
  290. package/kits/templates/roles/visitor.json +90 -85
  291. package/kits/templates/system-fragments/baseagent.md +14 -14
  292. package/kits/templates/system-fragments/bootstrap.md +53 -34
  293. package/kits/templates/system-fragments/channel.md +28 -64
  294. package/kits/templates/system-fragments/commands.md +36 -28
  295. package/kits/templates/system-fragments/group-unread-history.md +7 -0
  296. package/kits/templates/system-fragments/identity.md +13 -13
  297. package/kits/templates/system-fragments/relation.md +19 -19
  298. package/kits/templates/system-fragments/reply.md +56 -0
  299. package/kits/templates/system-fragments/session.md +59 -59
  300. package/kits/templates/system-fragments/venue.md +31 -31
  301. package/package.json +104 -98
  302. package/dist/aun/group-identity.js +0 -9
  303. /package/dist/aun/{group-fs-download.js → group/fs-download.js} +0 -0
  304. /package/dist/aun/{msg/group-index.js → group/index-rpc.js} +0 -0
@@ -635,28 +635,28 @@ export async function cmdNet(args) {
635
635
  const formatJson = args.includes('--format') && args.includes('json');
636
636
  const kickTest = args.includes('--kick-test');
637
637
  if (isHelpFlag(sub) || wantsHelp(args)) {
638
- console.log(`用法: ec net check [<aid>] [--format json] [--kick-test]
639
-
640
- 检查 AUN 网络链路连通性(11 步逐层诊断)。
641
-
642
- 步骤:
643
- 1. DNS (AID) AID 域名解析
644
- 2. Discovery .well-known/aun-gateway 获取网关地址
645
- 3. DNS (Gateway) 网关域名解析
646
- 4. TCP 网关端口连接
647
- 5. TLS TLS 握手 + 证书验证
648
- 6. WSS WebSocket 升级握手
649
- 7. Auth AID 认证(login1 + login2 → token)
650
- 8. Session 会话建立
651
- 9. Ping meta.ping RPC
652
- 10. Echo self-to-self 消息收发
653
- 11. KickTest 踢人测试 / extra_info 验证(可选)
654
-
655
- 参数:
656
- <aid> 要检查的 AID(可选,默认取前 3 个本地 AID)
657
-
658
- 选项:
659
- --format json JSON 格式输出
638
+ console.log(`用法: ec net check [<aid>] [--format json] [--kick-test]
639
+
640
+ 检查 AUN 网络链路连通性(11 步逐层诊断)。
641
+
642
+ 步骤:
643
+ 1. DNS (AID) AID 域名解析
644
+ 2. Discovery .well-known/aun-gateway 获取网关地址
645
+ 3. DNS (Gateway) 网关域名解析
646
+ 4. TCP 网关端口连接
647
+ 5. TLS TLS 握手 + 证书验证
648
+ 6. WSS WebSocket 升级握手
649
+ 7. Auth AID 认证(login1 + login2 → token)
650
+ 8. Session 会话建立
651
+ 9. Ping meta.ping RPC
652
+ 10. Echo self-to-self 消息收发
653
+ 11. KickTest 踢人测试 / extra_info 验证(可选)
654
+
655
+ 参数:
656
+ <aid> 要检查的 AID(可选,默认取前 3 个本地 AID)
657
+
658
+ 选项:
659
+ --format json JSON 格式输出
660
660
  --kick-test 启用踢人测试(会断开 daemon 长连接,daemon 会自动重连)`);
661
661
  return;
662
662
  }
@@ -1,38 +1,38 @@
1
1
  import { resolvePaths } from '../paths.js';
2
2
  import { ipcQuery } from '../ipc.js';
3
- import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
3
+ import { readDelegationCredential } from '../core/auth/agent-delegation.js';
4
4
  import { getArgValue, isHelpFlag, wantsHelp } from './help.js';
5
5
  export async function cmdQueue(args) {
6
6
  if (args.length === 0 || isHelpFlag(args[0]) || wantsHelp(args)) {
7
- console.log(`用法: ec queue --agent <aid> [选项]
8
-
9
- 查询与操作 EvolAgent 的消息队列。
10
-
11
- 查询:
12
- --agent <aid> 必填,目标 agent(如 mybot.agentid.pub)
13
- --after <time> 只显示 adapter 接收时间晚于该值的消息(epoch ms 或 ISO)
14
- --before <time> 只显示 adapter 接收时间早于该值的消息(epoch ms 或 ISO)
15
- --showid 显示 messageId
16
- --full 显示完整消息内容(不截断)
17
- --format json 以 JSON 格式输出
18
-
19
- JSON 时间字段:
20
- receivedAt adapter 收到消息时间(epoch ms)
21
- enqueuedAt 实际进入队列时间(epoch ms)
22
- queueWaitMs 排队等待时长(ms)
23
- processingStartedAt 开始处理时间(epoch ms,active)
24
-
25
- 操作:
26
- --clear 清空该 agent 的所有待处理消息
27
- --cancel <messageId> 取消指定消息
28
- --interrupt --sessionkey <key> 打断指定 session 的处理中任务
29
-
30
- 示例:
31
- ec queue --agent mybot.agentid.pub
32
- ec queue --agent mybot.agentid.pub --after 2026-08-19T12:00:00+08:00
33
- ec queue --agent mybot.agentid.pub --showid
34
- ec queue --agent mybot.agentid.pub --clear
35
- ec queue --agent mybot.agentid.pub --cancel msg_d4e5f6
7
+ console.log(`用法: ec queue --agent <aid> [选项]
8
+
9
+ 查询与操作 EvolAgent 的消息队列。
10
+
11
+ 查询:
12
+ --agent <aid> 必填,目标 agent(如 mybot.agentid.pub)
13
+ --after <time> 只显示 adapter 接收时间晚于该值的消息(epoch ms 或 ISO)
14
+ --before <time> 只显示 adapter 接收时间早于该值的消息(epoch ms 或 ISO)
15
+ --showid 显示 messageId
16
+ --full 显示完整消息内容(不截断)
17
+ --format json 以 JSON 格式输出
18
+
19
+ JSON 时间字段:
20
+ receivedAt adapter 收到消息时间(epoch ms)
21
+ enqueuedAt 实际进入队列时间(epoch ms)
22
+ queueWaitMs 排队等待时长(ms)
23
+ processingStartedAt 开始处理时间(epoch ms,active)
24
+
25
+ 操作:
26
+ --clear 清空该 agent 的所有待处理消息
27
+ --cancel <messageId> 取消指定消息
28
+ --interrupt --sessionkey <key> 打断指定 session 的处理中任务
29
+
30
+ 示例:
31
+ ec queue --agent mybot.agentid.pub
32
+ ec queue --agent mybot.agentid.pub --after 2026-08-19T12:00:00+08:00
33
+ ec queue --agent mybot.agentid.pub --showid
34
+ ec queue --agent mybot.agentid.pub --clear
35
+ ec queue --agent mybot.agentid.pub --cancel msg_d4e5f6
36
36
  ec queue --agent mybot.agentid.pub --interrupt --sessionkey feishu#oc_abc123#main`);
37
37
  return;
38
38
  }
@@ -98,7 +98,7 @@ JSON 时间字段:
98
98
  after,
99
99
  before,
100
100
  sessionId: managed,
101
- delegationToken: process.env[AGENT_DELEGATION_TOKEN_ENV],
101
+ delegationToken: readDelegationCredential(),
102
102
  } : {
103
103
  type: 'queue-snapshot',
104
104
  agent,
@@ -17,7 +17,7 @@ import { ResponseModeRegistry } from '../response-system/registry.js';
17
17
  import { registerBuiltinModes } from '../response-system/modes/index.js';
18
18
  import { ipcQuery } from '../ipc.js';
19
19
  import { resolvePaths } from '../paths.js';
20
- import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
20
+ import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
21
21
  const RESPONSE_MODE_FIELD = 'responseMode';
22
22
  const RESPONSE_MODE_PARAMS_FIELD = 'responseModeParams';
23
23
  /**
@@ -59,7 +59,7 @@ function fail(formatJson, code, message) {
59
59
  }
60
60
  async function managedConfig(fieldArgs, formatJson) {
61
61
  const sessionId = process.env.EVOLCORE_SESSION_ID;
62
- const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
62
+ const delegationToken = readDelegationCredential();
63
63
  if (!sessionId)
64
64
  fail(formatJson, 'NO_SESSION', 'EVOLCORE_SESSION_ID is not set');
65
65
  if (!delegationToken)
@@ -191,36 +191,36 @@ function sourceLabel(target) {
191
191
  default: return String(target);
192
192
  }
193
193
  }
194
- const HELP = `用法: ec response <command> [options]
195
-
196
- Commands:
197
- list 列出所有响应模式(内置 + 元数据)
198
- current 显示当前作用域生效的模式 + 参数
199
- info <mode-id> 查看单个模式详情(场景/配置参数)
200
- set <mode-id> 设置响应模式
201
- reset 清除指定作用域的 responseMode 设置
202
- config <mode-id> 查看指定模式的配置参数
203
- config set <k> <v> 修改模式配置参数(--mode 指定模式)
204
-
205
- 作用域(由参数决定,越具体越优先:关系 > agent):
206
- --self <aid> agent级 → config.json
207
- --self <aid> --peer <X> 关系级 → relations/<peerKey>/config.json
208
-
209
- Options:
210
- --self <aid> 本端 AID
211
- --peer <X> 对端:channelType#channelId 或裸 aid(裸 aid 视为 aun#<aid>)
212
- --mode <id> 模式 id(config set 专用)
213
- --format json 输出 JSON
214
- --help, -h 各子命令均支持
215
-
216
- 示例:
217
- ec response list
218
- ec response current --self bot.agentid.pub
219
- ec response info single-session
220
- ec response set single-session --self bot.agentid.pub
221
- ec response set single-session --self bot.agentid.pub --peer aun#team.group.com
222
- ec response config single-session --self bot.agentid.pub
223
- ec response config set tool_use_reminder false --mode single-session --self bot.agentid.pub
194
+ const HELP = `用法: ec response <command> [options]
195
+
196
+ Commands:
197
+ list 列出所有响应模式(内置 + 元数据)
198
+ current 显示当前作用域生效的模式 + 参数
199
+ info <mode-id> 查看单个模式详情(场景/配置参数)
200
+ set <mode-id> 设置响应模式
201
+ reset 清除指定作用域的 responseMode 设置
202
+ config <mode-id> 查看指定模式的配置参数
203
+ config set <k> <v> 修改模式配置参数(--mode 指定模式)
204
+
205
+ 作用域(由参数决定,越具体越优先:关系 > agent):
206
+ --self <aid> agent级 → config.json
207
+ --self <aid> --peer <X> 关系级 → relations/<peerKey>/config.json
208
+
209
+ Options:
210
+ --self <aid> 本端 AID
211
+ --peer <X> 对端:channelType#channelId 或裸 aid(裸 aid 视为 aun#<aid>)
212
+ --mode <id> 模式 id(config set 专用)
213
+ --format json 输出 JSON
214
+ --help, -h 各子命令均支持
215
+
216
+ 示例:
217
+ ec response list
218
+ ec response current --self bot.agentid.pub
219
+ ec response info single-session
220
+ ec response set single-session --self bot.agentid.pub
221
+ ec response set single-session --self bot.agentid.pub --peer aun#team.group.com
222
+ ec response config single-session --self bot.agentid.pub
223
+ ec response config set tool_use_reminder false --mode single-session --self bot.agentid.pub
224
224
  ec response reset --self bot.agentid.pub --peer alice.agentid.pub`;
225
225
  // ── list ────────────────────────────────────────────────────────────────
226
226
  function cmdList(args, formatJson) {
@@ -15,7 +15,10 @@ import { shouldSuppressRealRestart } from '../utils/restart-safety.js';
15
15
  import { rotateStdoutLog } from '../utils/log-writer.js';
16
16
  import { inspectDataMigrationRequirement } from '../core/data-migration.js';
17
17
  import { DAEMON_SHUTDOWN_TIMEOUT_MS, requestDaemonShutdown } from './daemon-commands.js';
18
+ import { getProcessStartTime, startTimeMatches } from '../utils/process-introspect.js';
18
19
  const execFileAsync = promisify(execFile);
20
+ // Bound network notifications so they cannot hold up recovery after shutdown.
21
+ const OWNER_NOTIFICATION_TIMEOUT_MS = 5000;
19
22
  /**
20
23
  * The package this monitor operates on, which is not always the one it runs
21
24
  * from.
@@ -43,6 +46,15 @@ function cleanEnv() {
43
46
  delete process.env[key];
44
47
  }
45
48
  }
49
+ function isPidReused(pid, expectedStartedAt) {
50
+ if (expectedStartedAt === undefined)
51
+ return false;
52
+ const actualStartedAt = getProcessStartTime(pid);
53
+ return actualStartedAt !== null && !startTimeMatches(expectedStartedAt, actualStartedAt);
54
+ }
55
+ function reportPidReused(pid, log) {
56
+ log(`Process ${pid} no longer refers to the recorded daemon; treating the original process as exited`);
57
+ }
46
58
  export async function cmdRestartMonitor() {
47
59
  // Defense in depth: a unit test that accidentally executes the real restart
48
60
  // path must not detach a persistent daemon from the test worker.
@@ -117,9 +129,11 @@ export async function cmdRestartMonitor() {
117
129
  }
118
130
  // Test daemons live in one temporary HOME per test, so the current HOME's
119
131
  // instance registry cannot see them. Their strict environment markers make
120
- // them safe to reap globally on every real restart.
132
+ // them safe to reap globally on every real restart. Keep one process-table
133
+ // snapshot for both orphan categories; each Windows CIM scan is expensive.
134
+ const orphanSnapshot = findOrphanProcesses();
121
135
  {
122
- const leakedTestDaemons = findOrphanProcesses().filter(o => o.confirmedTestDaemon);
136
+ const leakedTestDaemons = orphanSnapshot.filter(o => o.confirmedTestDaemon);
123
137
  if (leakedTestDaemons.length > 0) {
124
138
  const killed = killOrphans(leakedTestDaemons);
125
139
  log(`Cleaned ${killed.length} leaked test daemon(s): ${killed.join(', ')}`);
@@ -130,7 +144,7 @@ export async function cmdRestartMonitor() {
130
144
  // still alive. Refuse to create a second daemon when an unregistered process
131
145
  // from this package is found; a duplicate would connect AUN and kick the
132
146
  // existing session before failing on IPC/port ownership.
133
- const runtimeOrphans = findOrphanProcesses().filter(o => {
147
+ const runtimeOrphans = orphanSnapshot.filter(o => {
134
148
  if (o.confirmedTestDaemon)
135
149
  return false;
136
150
  const homeMatches = o.evolcoreHome && normalizePath(o.evolcoreHome) === normalizePath(p.root);
@@ -165,6 +179,7 @@ export async function cmdRestartMonitor() {
165
179
  const aliveMains = oldStatus.mains.filter(m => m.alive);
166
180
  if (aliveMains.length > 0) {
167
181
  const oldPids = aliveMains.map(m => m.record.pid);
182
+ const expectedStarts = new Map(aliveMains.map(m => [m.record.pid, m.record.startedAt]));
168
183
  log(`Monitoring ${oldPids.length} main process(es): ${oldPids.join(', ')}`);
169
184
  const gracefulPid = await requestDaemonShutdown(p.socket, DAEMON_SHUTDOWN_TIMEOUT_MS, 'restart-monitor', new Set(oldPids));
170
185
  // 没有收到 IPC shutdown 确认的进程才走信号兜底
@@ -177,15 +192,39 @@ export async function cmdRestartMonitor() {
177
192
  }
178
193
  }
179
194
  const exited = await Promise.all(oldPids.map(async (oldPid) => {
195
+ const expectedStartedAt = expectedStarts.get(oldPid);
196
+ if (isPidReused(oldPid, expectedStartedAt)) {
197
+ reportPidReused(oldPid, log);
198
+ return true;
199
+ }
180
200
  if (await platform.waitForProcessExit(oldPid, 30_000)) {
201
+ if (isPidReused(oldPid, expectedStartedAt)) {
202
+ reportPidReused(oldPid, log);
203
+ return true;
204
+ }
181
205
  log(`Process ${oldPid} has exited`);
182
206
  return true;
183
207
  }
184
- log(`ERROR: Process ${oldPid} still running after 30s, force killing`);
208
+ if (isPidReused(oldPid, expectedStartedAt)) {
209
+ reportPidReused(oldPid, log);
210
+ return true;
211
+ }
212
+ const state = platform.getProcessState(oldPid);
213
+ log(`ERROR: Process ${oldPid} still running after 30s${state ? ` (state=${state})` : ''}, force killing`);
214
+ if (isPidReused(oldPid, expectedStartedAt)) {
215
+ reportPidReused(oldPid, log);
216
+ return true;
217
+ }
185
218
  platform.killProcess(oldPid, true);
186
219
  const forced = await platform.waitForProcessExit(oldPid, 5_000);
187
- if (!forced)
188
- log(`ERROR: Process ${oldPid} survived forced termination`);
220
+ if (isPidReused(oldPid, expectedStartedAt)) {
221
+ reportPidReused(oldPid, log);
222
+ return true;
223
+ }
224
+ if (!forced) {
225
+ const finalState = platform.getProcessState(oldPid);
226
+ log(`ERROR: Process ${oldPid} survived forced termination${finalState ? ` (state=${finalState})` : ''}`);
227
+ }
189
228
  return forced;
190
229
  }));
191
230
  if (exited.some(result => !result)) {
@@ -194,7 +233,9 @@ export async function cmdRestartMonitor() {
194
233
  cleanupPendingFile(pendingFile, log);
195
234
  process.exit(1);
196
235
  }
197
- await sleep(3000);
236
+ // waitForProcessExit above already observed the old daemon exit. A fixed
237
+ // three-second delay only serialized the restart path and was not needed
238
+ // for instance-file cleanup.
198
239
  cleanupInstances();
199
240
  }
200
241
  // 版本检查与自动升级
@@ -202,7 +243,10 @@ export async function cmdRestartMonitor() {
202
243
  // 升级会原地替换整包,先留一个可回退的产物副本。备份放 EVOLCORE_HOME 而非包目录:
203
244
  // Linux/macOS 的全局目录常常不可写,而 HOME 一定可写。
204
245
  const upgradeBackup = await backupDistForUpgrade(p, log);
205
- const upgrade = await tryUpgrade();
246
+ const [upgrade, ecwebUpgrade] = await Promise.all([
247
+ tryUpgrade(),
248
+ tryUpgradeGlobalPkg(() => resolveGlobalPkg(WEB_PACKAGE_NAME), WEB_PACKAGE_NAME),
249
+ ]);
206
250
  let upgradeRolledBack;
207
251
  switch (upgrade.status) {
208
252
  case 'upgraded':
@@ -243,8 +287,8 @@ export async function cmdRestartMonitor() {
243
287
  await notifyDaemonOwners(p, `⚠️ evolcore 升级失败,使用当前版本继续\n${upgrade.error ?? ''}`.trim(), log);
244
288
  break;
245
289
  }
246
- // EC Web 是独立全局包,已安装时单独检查升级。
247
- const ecwebUpgrade = await tryUpgradeGlobalPkg(() => resolveGlobalPkg(WEB_PACKAGE_NAME), WEB_PACKAGE_NAME);
290
+ // EC Web 是独立全局包,已安装时单独检查升级;与 EvolCore registry
291
+ // 查询并行执行,npm 安装阶段由 npm-ops 的全局锁串行化。
248
292
  switch (ecwebUpgrade.status) {
249
293
  case 'upgraded':
250
294
  log(`✅ ${WEB_PACKAGE_NAME} upgraded: ${ecwebUpgrade.from} → ${ecwebUpgrade.to}`);
@@ -438,6 +482,18 @@ async function sendHealSummary(p, attempts, log) {
438
482
  function sleep(ms) {
439
483
  return new Promise(resolve => setTimeout(resolve, ms));
440
484
  }
485
+ function withTimeout(promise, timeoutMs) {
486
+ let timer;
487
+ const timeout = new Promise((_, reject) => {
488
+ timer = setTimeout(() => reject(new Error(`timeout after ${timeoutMs}ms`)), timeoutMs);
489
+ // Keep the monitor alive until recovery can resume, even if the SDK's
490
+ // pending operation has no referenced handles of its own.
491
+ });
492
+ return Promise.race([promise, timeout]).finally(() => {
493
+ if (timer)
494
+ clearTimeout(timer);
495
+ });
496
+ }
441
497
  function normalizePath(value) {
442
498
  return value.replace(/[\\/]+/g, '/').toLowerCase();
443
499
  }
@@ -710,6 +766,11 @@ async function revertToPreviousBuild(log) {
710
766
  * back up or the copy failed — the caller then knows rollback is unavailable.
711
767
  */
712
768
  async function backupDistForUpgrade(p, log) {
769
+ // Linked/source checkouts cannot be upgraded by npm. Copying dist/ here was
770
+ // pure restart overhead and made every source restart rewrite the artifact
771
+ // tree even when no build was needed.
772
+ if (fs.existsSync(path.join(targetPackageRoot(), 'src')))
773
+ return null;
713
774
  const distDir = path.join(targetPackageRoot(), 'dist');
714
775
  if (!distArtifactIsUsable(distDir))
715
776
  return null;
@@ -851,36 +912,36 @@ async function invokeClaude(claudePath, p, attempt, maxAttempts, timeout, log) {
851
912
  const selfHealLog = p.selfHealLog;
852
913
  const stdoutLog = path.join(p.logs, 'stdout.log');
853
914
  const selfHealExists = fs.existsSync(selfHealLog) ? '存在,请先阅读之前的修复记录' : '不存在(首次修复)';
854
- const prompt = `EvolCore 服务启动失败,需要你诊断并修复。这是第 ${attempt}/${maxAttempts} 次自动修复尝试。
855
-
856
- 关键信息:
857
- - 项目目录:${projectDir}
858
- - EVOLCORE_HOME:${p.root}
859
- - 错误日志:${stdoutLog}
860
- - 主日志:${p.logs}/daemon-*.log(按小时切片,读最新的那个,包含 config 校验失败等关键错误)
861
- - 修复记录:${selfHealLog}(${selfHealExists})
862
-
863
- ⚠️ 重要诊断技巧:
864
- - stdout.log 可能是空的(进程秒退时 logger 输出不会到 stdout),一定要同时读 daemon-*.log 最新文件
865
- - 必须实际运行进程来复现错误:\`EVOLCORE_HOME=${p.root} node dist/index.js 2>&1\`,观察输出和退出码
866
- - 检查是否有旧进程仍在运行:\`ps aux | grep 'node.*dist/index.js' | grep -v grep\`,旧进程可能占用端口或锁文件
867
- - 可以运行 \`EVOLCORE_HOME=${p.root} node dist/cli/index.js diagnose\` 快速检查配置和数据库
868
- - 如果进程无任何输出就 exit(1),说明是 process.exit(1) 被显式调用,搜索源码中所有 process.exit(1) 位置
869
- - 配置文件使用双 rename 原子写(foo.json → foo.json_ → foo.json__),崩溃时可从 foo.json_ 恢复
870
-
871
- 请执行以下步骤:
872
- 1. 读取 ${stdoutLog} 和 ${p.logs}/daemon-*.log(最新文件)的最后 50 行
873
- 2. 运行 \`EVOLCORE_HOME=${p.root} node dist/index.js 2>&1\` 复现错误(设置 10 秒超时)
874
- 3. 如果 ${selfHealLog} 存在,先阅读之前的修复记录,避免重复尝试已失败的方案
875
- 4. 根据实际复现的错误修复代码
876
- 5. 执行 npm run build 确认编译通过
877
- 6. 验证修复:启动服务确认 ready.signal 已写入,然后执行 \`EVOLCORE_HOME=${p.root} node dist/cli/index.js stop\` 优雅停止(restart-monitor 会负责最终启动)
878
- 7. 将本次修复内容追加到 ${selfHealLog},格式:
879
- ## 第 ${attempt} 次修复 - {时间}
880
- - 错误原因:...
881
- - 修复方案:...
882
- - 修改文件:...
883
-
915
+ const prompt = `EvolCore 服务启动失败,需要你诊断并修复。这是第 ${attempt}/${maxAttempts} 次自动修复尝试。
916
+
917
+ 关键信息:
918
+ - 项目目录:${projectDir}
919
+ - EVOLCORE_HOME:${p.root}
920
+ - 错误日志:${stdoutLog}
921
+ - 主日志:${p.logs}/daemon-*.log(按小时切片,读最新的那个,包含 config 校验失败等关键错误)
922
+ - 修复记录:${selfHealLog}(${selfHealExists})
923
+
924
+ ⚠️ 重要诊断技巧:
925
+ - stdout.log 可能是空的(进程秒退时 logger 输出不会到 stdout),一定要同时读 daemon-*.log 最新文件
926
+ - 必须实际运行进程来复现错误:\`EVOLCORE_HOME=${p.root} node dist/index.js 2>&1\`,观察输出和退出码
927
+ - 检查是否有旧进程仍在运行:\`ps aux | grep 'node.*dist/index.js' | grep -v grep\`,旧进程可能占用端口或锁文件
928
+ - 可以运行 \`EVOLCORE_HOME=${p.root} node dist/cli/index.js diagnose\` 快速检查配置和数据库
929
+ - 如果进程无任何输出就 exit(1),说明是 process.exit(1) 被显式调用,搜索源码中所有 process.exit(1) 位置
930
+ - 配置文件使用双 rename 原子写(foo.json → foo.json_ → foo.json__),崩溃时可从 foo.json_ 恢复
931
+
932
+ 请执行以下步骤:
933
+ 1. 读取 ${stdoutLog} 和 ${p.logs}/daemon-*.log(最新文件)的最后 50 行
934
+ 2. 运行 \`EVOLCORE_HOME=${p.root} node dist/index.js 2>&1\` 复现错误(设置 10 秒超时)
935
+ 3. 如果 ${selfHealLog} 存在,先阅读之前的修复记录,避免重复尝试已失败的方案
936
+ 4. 根据实际复现的错误修复代码
937
+ 5. 执行 npm run build 确认编译通过
938
+ 6. 验证修复:启动服务确认 ready.signal 已写入,然后执行 \`EVOLCORE_HOME=${p.root} node dist/cli/index.js stop\` 优雅停止(restart-monitor 会负责最终启动)
939
+ 7. 将本次修复内容追加到 ${selfHealLog},格式:
940
+ ## 第 ${attempt} 次修复 - {时间}
941
+ - 错误原因:...
942
+ - 修复方案:...
943
+ - 修改文件:...
944
+
884
945
  注意:只修复导致启动失败的问题,不要做额外的重构或优化。`;
885
946
  try {
886
947
  log(`Invoking claude CLI (attempt ${attempt}, timeout ${timeout / 60000}min)...`);
@@ -962,12 +1023,12 @@ async function notifyDaemonOwners(p, message, log) {
962
1023
  const text = formatDaemonOwnerNotice(p, message);
963
1024
  for (const owner of validOwners) {
964
1025
  try {
965
- const result = await msgSend({
1026
+ const result = await withTimeout(msgSend({
966
1027
  from: daemonAid,
967
1028
  to: owner,
968
1029
  body: { mode: 'text', text },
969
1030
  slotId: 'restart-monitor',
970
- });
1031
+ }), OWNER_NOTIFICATION_TIMEOUT_MS);
971
1032
  if (!result.ok) {
972
1033
  log(`Daemon owner notification failed for ${owner}: ${result.error}`);
973
1034
  continue;
package/dist/cli/stats.js CHANGED
@@ -6,52 +6,52 @@ import { wantsHelp } from './help.js';
6
6
  import { readBestTaskRuntimeContext } from './task-context.js';
7
7
  import { queryAggregated, querySessionTurns, queryContextBreakdown, queryTopPeers, queryTopModels, queryMessageAggregated, queryPeerList, querySummary, queryPeerDaily, queryTaskModelCalls, querySessionModelCalls } from '../stats/query.js';
8
8
  import { getBudgetStatus } from '../stats/budget.js';
9
- const HELP = `ec stats — Token 用量与费用统计
10
-
11
- Usage: ec stats [options]
12
-
13
- 时间范围:
14
- (无参数) 今日概览
15
- --today 同上
16
- --hour 最近 24 小时,按小时分组
17
- --week 本周
18
- --month 本月
19
- --from <date> --to <date> 任意区间(YYYY-MM-DD)
20
-
21
- 维度过滤(可组合):
22
- --agent <aid> 指定 agent
23
- --peer <X> 对端(裸 AID 自动前缀 aun#,或 channel#id 格式)
24
- --model <model-id> 指定模型
25
- --session <id> 指定会话
26
-
27
- 聚合粒度:
28
- --by hour|day|week|month|model|peer|agent
29
-
30
- 快捷视图:
31
- --session <id> 单个会话明细
32
- --session <id> --last 会话最后一轮用量 + 累计(等价 status.completed)
33
- --context <id> 会话 context breakdown 细目
34
- --budget 预算状态
35
- --top-peers [--limit N] 对端排行
36
- --top-models [--limit N] 模型排行
37
- --traffic 消息收发条数与字节数
38
- --sql "<query>" 直接执行只读 SQL
39
- --rebuild 全量重建日聚合表 usage_daily(运维兜底/排查)
40
- --peers [--limit N] 私聊对端列表(带累计 token/calls/活跃日)
41
- --groups [--limit N] 群聊列表(同上)
42
- --summary 指定时间范围总消耗汇总(token/USD/CNY)
43
- --peer-detail <id> 指定对端 AID 或 peer_key,按天返回消耗明细
44
- --task-calls <taskId> 一个 task 的逐次大模型调用明细
45
- --session-calls <id> 一个会话的逐次大模型调用明细
46
-
47
- 输出格式:
48
- --format json JSON 输出
49
- --help, -h 显示此帮助
50
-
51
- 示例:
52
- ec stats
53
- ec stats --month --agent bot.agentid.pub
54
- ec stats --peer alice.aid.pub
9
+ const HELP = `ec stats — Token 用量与费用统计
10
+
11
+ Usage: ec stats [options]
12
+
13
+ 时间范围:
14
+ (无参数) 今日概览
15
+ --today 同上
16
+ --hour 最近 24 小时,按小时分组
17
+ --week 本周
18
+ --month 本月
19
+ --from <date> --to <date> 任意区间(YYYY-MM-DD)
20
+
21
+ 维度过滤(可组合):
22
+ --agent <aid> 指定 agent
23
+ --peer <X> 对端(裸 AID 自动前缀 aun#,或 channel#id 格式)
24
+ --model <model-id> 指定模型
25
+ --session <id> 指定会话
26
+
27
+ 聚合粒度:
28
+ --by hour|day|week|month|model|peer|agent
29
+
30
+ 快捷视图:
31
+ --session <id> 单个会话明细
32
+ --session <id> --last 会话最后一轮用量 + 累计(等价 status.completed)
33
+ --context <id> 会话 context breakdown 细目
34
+ --budget 预算状态
35
+ --top-peers [--limit N] 对端排行
36
+ --top-models [--limit N] 模型排行
37
+ --traffic 消息收发条数与字节数
38
+ --sql "<query>" 直接执行只读 SQL
39
+ --rebuild 全量重建日聚合表 usage_daily(运维兜底/排查)
40
+ --peers [--limit N] 私聊对端列表(带累计 token/calls/活跃日)
41
+ --groups [--limit N] 群聊列表(同上)
42
+ --summary 指定时间范围总消耗汇总(token/USD/CNY)
43
+ --peer-detail <id> 指定对端 AID 或 peer_key,按天返回消耗明细
44
+ --task-calls <taskId> 一个 task 的逐次大模型调用明细
45
+ --session-calls <id> 一个会话的逐次大模型调用明细
46
+
47
+ 输出格式:
48
+ --format json JSON 输出
49
+ --help, -h 显示此帮助
50
+
51
+ 示例:
52
+ ec stats
53
+ ec stats --month --agent bot.agentid.pub
54
+ ec stats --peer alice.aid.pub
55
55
  ec stats --session abc123 --format json`;
56
56
  const RESET = '\x1b[0m';
57
57
  const BOLD = '\x1b[1m';
@@ -246,11 +246,11 @@ export async function handleStats(args) {
246
246
  const batch = allEvents.slice(i, i + batchSize);
247
247
  for (const event of batch) {
248
248
  const prices = resolvePrices(home, event); // 不传 gatewayPricing,全走本地 JSONL
249
- db.prepare(`
250
- UPDATE usage_events
251
- SET cost_official_usd = ?, cost_official_cny = ?,
252
- cost_gateway_usd = ?, cost_gateway_cny = ?
253
- WHERE id = ?
249
+ db.prepare(`
250
+ UPDATE usage_events
251
+ SET cost_official_usd = ?, cost_official_cny = ?,
252
+ cost_gateway_usd = ?, cost_gateway_cny = ?
253
+ WHERE id = ?
254
254
  `).run(prices.official?.usd ?? null, prices.official?.cny ?? null, prices.gateway?.usd ?? null, prices.gateway?.cny ?? null, event.id);
255
255
  updated++;
256
256
  }
@@ -0,0 +1,59 @@
1
+ import { resolvePaths } from '../paths.js';
2
+ import { ipcQuery } from '../ipc.js';
3
+ import { readDelegationCredential } from '../core/auth/agent-delegation.js';
4
+ import { wantsHelp } from './help.js';
5
+ const TASK_HELP = `用法: ec task resume <sessionId> [--format json]
6
+
7
+ 恢复指定 EvolCore 会话的暂停任务或异常中断任务。
8
+ 暂停时释放工具门控;异常中断时继续原 baseagent 会话。
9
+ 已完成、正在执行或等待必要输入/审批的任务不会重复启动。
10
+
11
+ 独立 CLI 使用本地 control token;托管任务使用当前会话的 delegation,
12
+ 需有 Agent 管理权限,普通托管任务只能恢复本 Agent 的会话。`;
13
+ export async function cmdTask(args) {
14
+ if (!args.length || wantsHelp(args)) {
15
+ console.log(TASK_HELP);
16
+ return;
17
+ }
18
+ const json = args.includes('--format') && args[args.indexOf('--format') + 1] === 'json';
19
+ const printError = (code, error) => {
20
+ if (json)
21
+ console.log(JSON.stringify({ ok: false, code, error }));
22
+ else
23
+ console.error(error);
24
+ process.exitCode = 1;
25
+ };
26
+ const targetSessionId = args[1]?.trim();
27
+ if (args[0] !== 'resume' || !targetSessionId || targetSessionId.startsWith('-')
28
+ || !(args.length === 2 || (args.length === 4 && args[2] === '--format' && args[3] === 'json'))) {
29
+ printError('INVALID_ARGUMENT', TASK_HELP);
30
+ return;
31
+ }
32
+ const sessionId = process.env.EVOLCORE_SESSION_ID;
33
+ const delegationToken = readDelegationCredential();
34
+ if (sessionId !== undefined && !sessionId.trim()) {
35
+ printError('INVALID_DELEGATION', 'EVOLCORE_SESSION_ID 不能为空');
36
+ return;
37
+ }
38
+ if (sessionId && !delegationToken) {
39
+ printError('DELEGATION_REQUIRED', '托管任务缺少 delegation token');
40
+ return;
41
+ }
42
+ const result = await ipcQuery(resolvePaths().socket, {
43
+ type: 'task.resume',
44
+ targetSessionId,
45
+ ...(sessionId ? { sessionId, delegationToken } : {}),
46
+ }, 10_000);
47
+ if (!result) {
48
+ printError('IPC_UNAVAILABLE', '无法连接 EvolCore 服务;请查询任务状态后再决定是否重试');
49
+ return;
50
+ }
51
+ if (json)
52
+ console.log(JSON.stringify(result));
53
+ else if ('message' in result)
54
+ console.log(result.message);
55
+ else
56
+ console.error(result.error);
57
+ if (!result.ok)
58
+ process.exitCode = 1;
59
+ }