evolcore 0.0.7 → 0.0.9

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 (230) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +38 -4
  3. package/dist/agents/baseagent.js +117 -24
  4. package/dist/agents/claude-runner.js +31 -2
  5. package/dist/agents/codex-app-server-client.js +37 -2
  6. package/dist/agents/codex-runner.js +11 -3
  7. package/dist/aun/aid/control-aid.js +40 -27
  8. package/dist/aun/aid/domain.js +23 -0
  9. package/dist/aun/msg/group.js +9 -9
  10. package/dist/aun/msg/p2p.js +11 -6
  11. package/dist/aun/msg/upload.js +43 -29
  12. package/dist/aun/outbox.js +48 -5
  13. package/dist/channels/aun.js +225 -71
  14. package/dist/cli/aun-commands.js +10 -7
  15. package/dist/cli/bench.js +4 -3
  16. package/dist/cli/daemon-commands.js +208 -68
  17. package/dist/cli/data-command.js +62 -35
  18. package/dist/cli/index.js +11 -1
  19. package/dist/cli/init-channel.js +1 -1
  20. package/dist/cli/init.js +112 -17
  21. package/dist/cli/model.js +5 -5
  22. package/dist/cli/restart-monitor.js +102 -22
  23. package/dist/config/builtin-role-templates.js +4 -3
  24. package/dist/config/config-field-policy.js +6 -2
  25. package/dist/config/config-manager.js +79 -11
  26. package/dist/config/gateway-config.js +80 -35
  27. package/dist/config/role-schema.js +18 -3
  28. package/dist/config/role-service.js +3 -3
  29. package/dist/config/role-store.js +4 -3
  30. package/dist/config-store.js +19 -3
  31. package/dist/core/auth/operation-authorizer.js +3 -1
  32. package/dist/core/baseagent-loader.js +5 -3
  33. package/dist/core/bootstrap-service.js +0 -12
  34. package/dist/core/capability/providers/codex-capability-provider.js +2 -2
  35. package/dist/core/channel-loader.js +15 -2
  36. package/dist/core/command/command-handler.js +1 -1
  37. package/dist/core/command/evol-menu-version-gate.js +3 -2
  38. package/dist/core/command/menu-handler.js +50 -28
  39. package/dist/core/command/menu-protocol.js +7 -4
  40. package/dist/core/command/slash-handler.js +4 -4
  41. package/dist/core/data-migration.js +517 -24
  42. package/dist/core/inference/text-inference.js +18 -5
  43. package/dist/core/message/message-bridge.js +17 -6
  44. package/dist/core/message/response-engine.js +22 -3
  45. package/dist/core/model/config-scope.js +3 -3
  46. package/dist/core/permission/tool-policy.js +18 -0
  47. package/dist/core/protected-paths.js +12 -1
  48. package/dist/index.js +794 -725
  49. package/dist/ipc.js +3 -1
  50. package/dist/product.js +1 -0
  51. package/dist/utils/autostart.js +27 -0
  52. package/dist/utils/codex-cli.js +39 -0
  53. package/dist/utils/cross-platform.js +147 -18
  54. package/dist/utils/ecweb-utils.js +15 -2
  55. package/dist/utils/instance-registry.js +43 -6
  56. package/dist/utils/macos-autostart.js +179 -0
  57. package/dist/utils/process-introspect.js +7 -3
  58. package/dist/utils/windows-autostart.js +130 -0
  59. package/ecagent/dist/agent-loop.d.ts +1 -1
  60. package/ecagent/dist/agent-loop.js +1 -1
  61. package/ecagent/dist/agent.d.ts +1 -1
  62. package/ecagent/dist/agent.js +1 -1
  63. package/ecagent/dist/harness/agent-harness.d.ts +1 -1
  64. package/ecagent/dist/harness/compaction/branch-summarization.d.ts +1 -1
  65. package/ecagent/dist/harness/compaction/compaction.d.ts +1 -1
  66. package/ecagent/dist/harness/compaction/utils.d.ts +1 -1
  67. package/ecagent/dist/harness/messages.d.ts +1 -1
  68. package/ecagent/dist/harness/session/session.d.ts +1 -1
  69. package/ecagent/dist/harness/types.d.ts +1 -1
  70. package/ecagent/dist/proxy.d.ts +1 -1
  71. package/ecagent/dist/proxy.js +1 -1
  72. package/ecagent/dist/types.d.ts +1 -1
  73. package/kits/migrations/migrate-role-config-v5.mjs +27 -2
  74. package/kits/rules/01-overview.md +3 -2
  75. package/kits/schemas/_meta.json +2 -1
  76. package/kits/schemas/agent-config.schema.10.json +19 -1
  77. package/kits/schemas/daemon.schema.4.json +136 -0
  78. package/kits/schemas/defaults.schema.4.json +15 -1
  79. package/kits/schemas/relation-config.schema.8.json +22 -1
  80. package/kits/schemas/role-config.schema.1.json +2 -2
  81. package/package.json +2 -4
  82. package/ecagent/dist/agent-loop.d.ts.map +0 -1
  83. package/ecagent/dist/agent-loop.js.map +0 -1
  84. package/ecagent/dist/agent.d.ts.map +0 -1
  85. package/ecagent/dist/agent.js.map +0 -1
  86. package/ecagent/dist/harness/agent-harness.d.ts.map +0 -1
  87. package/ecagent/dist/harness/agent-harness.js.map +0 -1
  88. package/ecagent/dist/harness/compaction/branch-summarization.d.ts.map +0 -1
  89. package/ecagent/dist/harness/compaction/branch-summarization.js.map +0 -1
  90. package/ecagent/dist/harness/compaction/compaction.d.ts.map +0 -1
  91. package/ecagent/dist/harness/compaction/compaction.js.map +0 -1
  92. package/ecagent/dist/harness/compaction/utils.d.ts.map +0 -1
  93. package/ecagent/dist/harness/compaction/utils.js.map +0 -1
  94. package/ecagent/dist/harness/env/nodejs.d.ts.map +0 -1
  95. package/ecagent/dist/harness/env/nodejs.js.map +0 -1
  96. package/ecagent/dist/harness/messages.d.ts.map +0 -1
  97. package/ecagent/dist/harness/messages.js.map +0 -1
  98. package/ecagent/dist/harness/prompt-templates.d.ts.map +0 -1
  99. package/ecagent/dist/harness/prompt-templates.js.map +0 -1
  100. package/ecagent/dist/harness/session/jsonl-repo.d.ts.map +0 -1
  101. package/ecagent/dist/harness/session/jsonl-repo.js.map +0 -1
  102. package/ecagent/dist/harness/session/jsonl-storage.d.ts.map +0 -1
  103. package/ecagent/dist/harness/session/jsonl-storage.js.map +0 -1
  104. package/ecagent/dist/harness/session/memory-repo.d.ts.map +0 -1
  105. package/ecagent/dist/harness/session/memory-repo.js.map +0 -1
  106. package/ecagent/dist/harness/session/memory-storage.d.ts.map +0 -1
  107. package/ecagent/dist/harness/session/memory-storage.js.map +0 -1
  108. package/ecagent/dist/harness/session/repo-utils.d.ts.map +0 -1
  109. package/ecagent/dist/harness/session/repo-utils.js.map +0 -1
  110. package/ecagent/dist/harness/session/session.d.ts.map +0 -1
  111. package/ecagent/dist/harness/session/session.js.map +0 -1
  112. package/ecagent/dist/harness/session/uuid.d.ts.map +0 -1
  113. package/ecagent/dist/harness/session/uuid.js.map +0 -1
  114. package/ecagent/dist/harness/skills.d.ts.map +0 -1
  115. package/ecagent/dist/harness/skills.js.map +0 -1
  116. package/ecagent/dist/harness/system-prompt.d.ts.map +0 -1
  117. package/ecagent/dist/harness/system-prompt.js.map +0 -1
  118. package/ecagent/dist/harness/types.d.ts.map +0 -1
  119. package/ecagent/dist/harness/types.js.map +0 -1
  120. package/ecagent/dist/harness/utils/shell-output.d.ts.map +0 -1
  121. package/ecagent/dist/harness/utils/shell-output.js.map +0 -1
  122. package/ecagent/dist/harness/utils/truncate.d.ts.map +0 -1
  123. package/ecagent/dist/harness/utils/truncate.js.map +0 -1
  124. package/ecagent/dist/index.d.ts.map +0 -1
  125. package/ecagent/dist/index.js.map +0 -1
  126. package/ecagent/dist/node.d.ts.map +0 -1
  127. package/ecagent/dist/node.js.map +0 -1
  128. package/ecagent/dist/proxy.d.ts.map +0 -1
  129. package/ecagent/dist/proxy.js.map +0 -1
  130. package/ecagent/dist/runtime/api/lazy.d.ts.map +0 -1
  131. package/ecagent/dist/runtime/api/lazy.js.map +0 -1
  132. package/ecagent/dist/runtime/api/pi-messages.d.ts.map +0 -1
  133. package/ecagent/dist/runtime/api/pi-messages.js.map +0 -1
  134. package/ecagent/dist/runtime/api/pi-messages.lazy.d.ts.map +0 -1
  135. package/ecagent/dist/runtime/api/pi-messages.lazy.js.map +0 -1
  136. package/ecagent/dist/runtime/auth/context.d.ts.map +0 -1
  137. package/ecagent/dist/runtime/auth/context.js.map +0 -1
  138. package/ecagent/dist/runtime/auth/credential-store.d.ts.map +0 -1
  139. package/ecagent/dist/runtime/auth/credential-store.js.map +0 -1
  140. package/ecagent/dist/runtime/auth/helpers.d.ts.map +0 -1
  141. package/ecagent/dist/runtime/auth/helpers.js.map +0 -1
  142. package/ecagent/dist/runtime/auth/resolve.d.ts.map +0 -1
  143. package/ecagent/dist/runtime/auth/resolve.js.map +0 -1
  144. package/ecagent/dist/runtime/auth/types.d.ts.map +0 -1
  145. package/ecagent/dist/runtime/auth/types.js.map +0 -1
  146. package/ecagent/dist/runtime/compat.d.ts.map +0 -1
  147. package/ecagent/dist/runtime/compat.js.map +0 -1
  148. package/ecagent/dist/runtime/index.d.ts.map +0 -1
  149. package/ecagent/dist/runtime/index.js.map +0 -1
  150. package/ecagent/dist/runtime/models.d.ts.map +0 -1
  151. package/ecagent/dist/runtime/models.js.map +0 -1
  152. package/ecagent/dist/runtime/oauth.d.ts.map +0 -1
  153. package/ecagent/dist/runtime/oauth.js.map +0 -1
  154. package/ecagent/dist/runtime/providers/faux.d.ts.map +0 -1
  155. package/ecagent/dist/runtime/providers/faux.js.map +0 -1
  156. package/ecagent/dist/runtime/types.d.ts.map +0 -1
  157. package/ecagent/dist/runtime/types.js.map +0 -1
  158. package/ecagent/dist/runtime/utils/diagnostics.d.ts.map +0 -1
  159. package/ecagent/dist/runtime/utils/diagnostics.js.map +0 -1
  160. package/ecagent/dist/runtime/utils/event-stream.d.ts.map +0 -1
  161. package/ecagent/dist/runtime/utils/event-stream.js.map +0 -1
  162. package/ecagent/dist/runtime/utils/headers.d.ts.map +0 -1
  163. package/ecagent/dist/runtime/utils/headers.js.map +0 -1
  164. package/ecagent/dist/runtime/utils/json-parse.d.ts.map +0 -1
  165. package/ecagent/dist/runtime/utils/json-parse.js.map +0 -1
  166. package/ecagent/dist/runtime/utils/oauth/types.d.ts.map +0 -1
  167. package/ecagent/dist/runtime/utils/oauth/types.js.map +0 -1
  168. package/ecagent/dist/runtime/utils/overflow.d.ts.map +0 -1
  169. package/ecagent/dist/runtime/utils/overflow.js.map +0 -1
  170. package/ecagent/dist/runtime/utils/provider-env.d.ts.map +0 -1
  171. package/ecagent/dist/runtime/utils/provider-env.js.map +0 -1
  172. package/ecagent/dist/runtime/utils/retry.d.ts.map +0 -1
  173. package/ecagent/dist/runtime/utils/retry.js.map +0 -1
  174. package/ecagent/dist/runtime/utils/typebox-helpers.d.ts.map +0 -1
  175. package/ecagent/dist/runtime/utils/typebox-helpers.js.map +0 -1
  176. package/ecagent/dist/runtime/utils/validation.d.ts.map +0 -1
  177. package/ecagent/dist/runtime/utils/validation.js.map +0 -1
  178. package/ecagent/dist/types.d.ts.map +0 -1
  179. package/ecagent/dist/types.js.map +0 -1
  180. package/ecagent/package.json +0 -93
  181. package/ecagent/src/agent-loop.ts +0 -792
  182. package/ecagent/src/agent.ts +0 -575
  183. package/ecagent/src/harness/agent-harness.ts +0 -1029
  184. package/ecagent/src/harness/compaction/branch-summarization.ts +0 -261
  185. package/ecagent/src/harness/compaction/compaction.ts +0 -753
  186. package/ecagent/src/harness/compaction/utils.ts +0 -144
  187. package/ecagent/src/harness/env/nodejs.ts +0 -569
  188. package/ecagent/src/harness/messages.ts +0 -164
  189. package/ecagent/src/harness/prompt-templates.ts +0 -267
  190. package/ecagent/src/harness/session/jsonl-repo.ts +0 -179
  191. package/ecagent/src/harness/session/jsonl-storage.ts +0 -314
  192. package/ecagent/src/harness/session/memory-repo.ts +0 -50
  193. package/ecagent/src/harness/session/memory-storage.ts +0 -133
  194. package/ecagent/src/harness/session/repo-utils.ts +0 -51
  195. package/ecagent/src/harness/session/session.ts +0 -338
  196. package/ecagent/src/harness/session/uuid.ts +0 -54
  197. package/ecagent/src/harness/skills.ts +0 -375
  198. package/ecagent/src/harness/system-prompt.ts +0 -34
  199. package/ecagent/src/harness/types.ts +0 -838
  200. package/ecagent/src/harness/utils/shell-output.ts +0 -135
  201. package/ecagent/src/harness/utils/truncate.ts +0 -344
  202. package/ecagent/src/index.ts +0 -46
  203. package/ecagent/src/node.ts +0 -2
  204. package/ecagent/src/proxy.ts +0 -367
  205. package/ecagent/src/runtime/api/lazy.ts +0 -70
  206. package/ecagent/src/runtime/api/pi-messages.lazy.ts +0 -4
  207. package/ecagent/src/runtime/api/pi-messages.ts +0 -436
  208. package/ecagent/src/runtime/auth/context.ts +0 -45
  209. package/ecagent/src/runtime/auth/credential-store.ts +0 -47
  210. package/ecagent/src/runtime/auth/helpers.ts +0 -46
  211. package/ecagent/src/runtime/auth/resolve.ts +0 -141
  212. package/ecagent/src/runtime/auth/types.ts +0 -182
  213. package/ecagent/src/runtime/compat.ts +0 -158
  214. package/ecagent/src/runtime/index.ts +0 -31
  215. package/ecagent/src/runtime/models.ts +0 -452
  216. package/ecagent/src/runtime/oauth.ts +0 -1
  217. package/ecagent/src/runtime/providers/faux.ts +0 -538
  218. package/ecagent/src/runtime/types.ts +0 -718
  219. package/ecagent/src/runtime/utils/diagnostics.ts +0 -45
  220. package/ecagent/src/runtime/utils/event-stream.ts +0 -88
  221. package/ecagent/src/runtime/utils/headers.ts +0 -18
  222. package/ecagent/src/runtime/utils/json-parse.ts +0 -124
  223. package/ecagent/src/runtime/utils/oauth/types.ts +0 -79
  224. package/ecagent/src/runtime/utils/overflow.ts +0 -165
  225. package/ecagent/src/runtime/utils/provider-env.ts +0 -52
  226. package/ecagent/src/runtime/utils/retry.ts +0 -101
  227. package/ecagent/src/runtime/utils/typebox-helpers.ts +0 -24
  228. package/ecagent/src/runtime/utils/validation.ts +0 -310
  229. package/ecagent/src/types.ts +0 -430
  230. package/ecagent/tsconfig.build.json +0 -32
@@ -16,9 +16,8 @@ import { chatDirPath } from '../core/session/session-fs-store.js';
16
16
  import { appendHintAdd, appendHintRemove, parseInjectRequest } from '../core/message/pending-hints.js';
17
17
  import { appendAidLifecycle } from '../aun/aid/identity.js';
18
18
  import { getAidStore, loadClient, SLOT } from '../aun/aid/store.js';
19
- import { uploadFileAndBuildPayload } from '../aun/msg/upload.js';
19
+ import { MAX_AUN_ATTACHMENT_SIZE, uploadBufferAndBuildPayload, uploadFileAndBuildPayload } from '../aun/msg/upload.js';
20
20
  import { loadAgent, saveAgent } from '../config-store.js';
21
- import { activeBaseagent } from '../core/model/config-scope.js';
22
21
  import { resolveEffective } from '../config/config-manager.js';
23
22
  import { isManagementRole } from '../config/builtin-roles.js';
24
23
  import { mentionModeToDispatch } from '../config/mention-mode.js';
@@ -35,6 +34,19 @@ import { isExplicitGroupId } from '../aun/group-identity.js';
35
34
  import { refreshAgentDisplayName, resolveAgentDisplayName } from '../aun/aid/agentmd.js';
36
35
  import { readInstalledEvolcoreVersion } from '../utils/evolcore-version.js';
37
36
  export const AUN_HANDOFF_MARKER_FIELD = '_evolcore_handoff_id';
37
+ const AUN_INTERACTION_CARD_TTL_MS = 24 * 60 * 60 * 1000;
38
+ const IMAGE_MIME_TYPE = /^image\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/i;
39
+ function normalizeImageMimeType(mimeType) {
40
+ const normalized = mimeType?.split(';', 1)[0].trim().toLowerCase();
41
+ if (!normalized)
42
+ return undefined;
43
+ if (!normalized.startsWith('image/'))
44
+ return undefined;
45
+ if (!IMAGE_MIME_TYPE.test(normalized)) {
46
+ throw new Error('result.image MIME type must be a valid image media type');
47
+ }
48
+ return normalized;
49
+ }
38
50
  /**
39
51
  * 构造 connect extra_info:自描述本进程身份。
40
52
  *
@@ -275,8 +287,8 @@ export class AUNChannel {
275
287
  }
276
288
  }
277
289
  /** 判断 channelId 是否为群组 ID
278
- * - 新格式:group.{issuer}/{group_no|group_name}
279
- * - 数字群号:{group_no}.{issuer}(如 11117.agentid.pub
290
+ * - 新格式:group.{aidDomain}/{group_no|group_name}
291
+ * - 数字群号:{group_no}.{aidDomain}(如 11117.example.com
280
292
  * - 兼容旧格式:grp_xxx、g-xxx.agentid.pub
281
293
  */
282
294
  /** 判断 channelId 是否群组 ID(public:plugin adapter 闭包需调用) */
@@ -359,10 +371,11 @@ export class AUNChannel {
359
371
  || (channelId && !this.isGroupId(channelId) ? channelId : '')
360
372
  || '';
361
373
  if (cardInfo.isCommandCard) {
362
- // CommandCard:action_value 是完整 slash 命令,构造伪入站消息
363
- this.cardMessageIdMap.delete(cardMsgId);
374
+ // CommandCard:action_value 是完整 slash 命令,构造伪入站消息。
375
+ // 先完成点击者鉴权,再消费 mapping;否则群成员的一次误点会让发起者
376
+ // 无法继续操作同一张卡片。
377
+ const chatType = channelId ? (this.isGroupId(channelId) ? 'group' : 'private') : 'private';
364
378
  if (this.messageHandler && actionValue.startsWith('/')) {
365
- const chatType = channelId ? (this.isGroupId(channelId) ? 'group' : 'private') : 'private';
366
379
  // Initiator 校验:仅群聊需要(私聊信道一对一,点击者恒为对端 = initiator)。
367
380
  // 身份只信认证信封提取的 cardClickerAid,非 payload 自报。
368
381
  if (chatType === 'group' && !cardClickerAid) {
@@ -376,6 +389,9 @@ export class AUNChannel {
376
389
  this.notifyCardActionFailure(channelId, '⚠️ 仅卡片发起者可操作', cardClickerAid, threadId);
377
390
  return '';
378
391
  }
392
+ // 已通过鉴权并即将进入处理流程;此时才消费 mapping,避免非发起者
393
+ // 或非法命令点击导致卡片提前失效。
394
+ this.cardMessageIdMap.delete(cardMsgId);
379
395
  Promise.resolve(this.messageHandler({
380
396
  channelId: channelId || '',
381
397
  channelType: 'aun',
@@ -495,7 +511,7 @@ export class AUNChannel {
495
511
  }
496
512
  }
497
513
  else if (this.ownedCardMsgIds.has(cardMsgId)) {
498
- // 本 agent 发出的卡片,但 entry 已过期(20min TTL)
514
+ // 本 agent 发出的卡片,但 entry 已过期(24h TTL)
499
515
  logger.debug(`${this.logPrefix()} action_card_reply expired: cardMsgId=${cardMsgId}`);
500
516
  this.notifyCardActionFailure(channelId, '⚠️ 卡片已失效,请重新发起');
501
517
  }
@@ -579,6 +595,38 @@ export class AUNChannel {
579
595
  parts.push('---');
580
596
  return parts.join('\n');
581
597
  }
598
+ // 结构化 link/location 必须优先保留业务字段。部分客户端同时提供
599
+ // 顶层 text(仅供展示),若先返回该字段会丢失 URL、坐标和地址。
600
+ if (obj.type === 'link') {
601
+ const parts = [];
602
+ if (typeof obj.title === 'string' && obj.title)
603
+ parts.push(`标题: ${obj.title}`);
604
+ if (typeof obj.description === 'string' && obj.description)
605
+ parts.push(`描述: ${obj.description}`);
606
+ if (typeof obj.url === 'string' && obj.url)
607
+ parts.push(`URL: ${obj.url}`);
608
+ if (text && !parts.includes(text))
609
+ parts.push(text);
610
+ return parts.length > 0 ? parts.join('\n') : text || JSON.stringify(payload);
611
+ }
612
+ if (obj.type === 'location') {
613
+ const parts = [];
614
+ if (typeof obj.name === 'string' && obj.name)
615
+ parts.push(`地点: ${obj.name}`);
616
+ if (typeof obj.address === 'string' && obj.address)
617
+ parts.push(`地址: ${obj.address}`);
618
+ if (typeof obj.latitude === 'number' && Number.isFinite(obj.latitude))
619
+ parts.push(`纬度: ${obj.latitude}`);
620
+ if (typeof obj.longitude === 'number' && Number.isFinite(obj.longitude))
621
+ parts.push(`经度: ${obj.longitude}`);
622
+ if (typeof obj.precision_m === 'number' && Number.isFinite(obj.precision_m))
623
+ parts.push(`精度: ${obj.precision_m}m`);
624
+ if (typeof obj.map_url === 'string' && obj.map_url)
625
+ parts.push(`地图: ${obj.map_url}`);
626
+ if (text && !parts.includes(text))
627
+ parts.push(text);
628
+ return parts.length > 0 ? parts.join('\n') : text || JSON.stringify(payload);
629
+ }
582
630
  if (typeof obj.text === 'string')
583
631
  return text;
584
632
  return JSON.stringify(payload);
@@ -713,8 +761,11 @@ export class AUNChannel {
713
761
  this.messageSeqMap.delete(messageId);
714
762
  }
715
763
  shouldEncrypt(_peerId) {
716
- // Default to plaintext; only encrypt when session is explicitly marked encrypted
717
- return false;
764
+ return this.config.defaultEncrypt ?? true;
765
+ }
766
+ /** Effective channel default for callers that must persist a concrete transport choice. */
767
+ getDefaultEncrypt() {
768
+ return this.shouldEncrypt(this.config.aid);
718
769
  }
719
770
  _aid;
720
771
  _selfName; // 本地 agent.md 中的 name,首次 connect 时读取
@@ -884,8 +935,12 @@ export class AUNChannel {
884
935
  this.store = store;
885
936
  const client = await loadClient(store, aidName);
886
937
  this.client = client;
887
- // 仅作为配置/状态展示。当前 SDK public API 不接受 authenticate gateway override;
888
- // 实际 gateway SDK discovery + token-store metadata cache 解析。
938
+ // fastaun gives a preset in-memory gateway precedence over its metadata
939
+ // cache and AID discovery. authenticate({ gateway }) is deliberately
940
+ // rejected by its public API, so set the documented client preset before
941
+ // authentication instead.
942
+ if (configuredGateway)
943
+ client._gatewayUrl = configuredGateway;
889
944
  this.gatewayUrl = configuredGateway;
890
945
  // Register event handlers before connecting
891
946
  client.on('message.received', (data) => {
@@ -1138,13 +1193,10 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
1138
1193
  await this.callAndTrace('message.send', {
1139
1194
  to: owner,
1140
1195
  payload: { type: 'text', text: welcomeText },
1141
- encrypt: true,
1196
+ encrypt: this.shouldEncrypt(owner),
1142
1197
  persist_required: true,
1143
1198
  });
1144
1199
  logger.info(`${this.logPrefix()} Welcome message sent to owner: ${owner}`);
1145
- // Send binding credential for Evol App to persist locally
1146
- // active_baseagent 经 config-scope 解析。
1147
- await this.sendBindingCredential(owner, agentDisplayName, activeBaseagent(aidName)).catch(e => logger.warn(`${this.logPrefix()} Binding credential failed: ${e}`));
1148
1200
  // Mark agent as initialized in config.json (replaces old agent.md frontmatter flag)
1149
1201
  try {
1150
1202
  const fresh = loadAgent(aidName);
@@ -1162,17 +1214,6 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
1162
1214
  logger.warn(`${this.logPrefix()} Failed to send welcome message: ${e}`);
1163
1215
  }
1164
1216
  }
1165
- async sendBindingCredential(owner, name, baseagent) {
1166
- if (!this.client)
1167
- return;
1168
- await this.callAndTrace('message.send', {
1169
- to: owner,
1170
- payload: { type: 'binding', aid: this.config.aid, name, owner, baseagent },
1171
- encrypt: true,
1172
- persist_required: true,
1173
- });
1174
- logger.info(`${this.logPrefix()} Binding credential sent to owner: ${owner}`);
1175
- }
1176
1217
  // ── Event handlers ──────────────────────────────────────────
1177
1218
  /**
1178
1219
  * 统一处理入站附件:下载 → 图片识别+base64 注入 → 拼接文本。
@@ -1364,24 +1405,24 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
1364
1405
  return null;
1365
1406
  }
1366
1407
  isTrustedStorageHost(host, normalizedOwner) {
1367
- const trustedIssuers = new Set();
1368
- // 对端 issuer(文件所有者 owner_aid)
1369
- const peerIssuer = this.extractIssuer(normalizedOwner);
1370
- if (peerIssuer)
1371
- trustedIssuers.add(peerIssuer);
1372
- // 本端 issuer(自己的 AID)
1373
- const selfIssuer = this.extractIssuer((this.getAid() || '').toLowerCase());
1374
- if (selfIssuer)
1375
- trustedIssuers.add(selfIssuer);
1376
- // 校验 host 是否为任一可信 issuer 的存储域名
1377
- for (const issuer of trustedIssuers) {
1378
- if (host === `storage.${issuer}`)
1408
+ const trustedAidDomains = new Set();
1409
+ // 对端 AID domain(文件所有者 owner_aid)
1410
+ const peerAidDomain = this.extractAidDomain(normalizedOwner);
1411
+ if (peerAidDomain)
1412
+ trustedAidDomains.add(peerAidDomain);
1413
+ // 本端 AID domain(自己的 AID)
1414
+ const selfAidDomain = this.extractAidDomain((this.getAid() || '').toLowerCase());
1415
+ if (selfAidDomain)
1416
+ trustedAidDomains.add(selfAidDomain);
1417
+ // 校验 host 是否为任一可信 AID domain 的存储域名
1418
+ for (const aidDomain of trustedAidDomains) {
1419
+ if (host === `storage.${aidDomain}`)
1379
1420
  return true;
1380
1421
  }
1381
1422
  return false;
1382
1423
  }
1383
- /** 从 AID 提取 issuer(去掉首段 label)。`mybot.agentid.pub` → `agentid.pub` */
1384
- extractIssuer(aid) {
1424
+ /** 从 AID 提取后缀 domain(去掉首段 label)。`mybot.example.com` → `example.com` */
1425
+ extractAidDomain(aid) {
1385
1426
  if (!aid || !aid.includes('.'))
1386
1427
  return '';
1387
1428
  return aid.split('.').slice(1).join('.');
@@ -1921,7 +1962,7 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
1921
1962
  //
1922
1963
  // observable=true 时,Agent 收发的每条 AUN 消息(原始信封 + 解密后明文
1923
1964
  // payload)镜像一份给 owners[]。入站在所有过滤之前转发;出站在真实发送
1924
- // 成功后转发。外层一律明文。详见 docs/observer-mode-design.md。
1965
+ // 成功后转发。Observer 使用 daemon 的全局 AUN 默认加密设置,业务合同保持不变。
1925
1966
  // observable / owners 不在此处缓存——由 daemon 注入 resolver,从 EvolAgent 的
1926
1967
  // in-memory merged config(启动/重启/热重载时统一更新的唯一缓存)读取,避免重复缓存。
1927
1968
  observerConfigResolver;
@@ -1984,7 +2025,7 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
1984
2025
  this.emitForward('outbound', result, recipientOwners);
1985
2026
  }
1986
2027
  /**
1987
- * 实际投递 observer.forward 给每个 owner,外层一律明文。
2028
+ * 实际投递 observer.forward 给每个 owner,使用 daemon 的全局 AUN 默认加密设置。
1988
2029
  * original 为 SDK 给到的原始对象(入站回调 data / 出站 SendResult),整体透传,
1989
2030
  * 不挑字段、不改字段——SDK 加任何字段都会自动一并转发给 owner。
1990
2031
  */
@@ -1995,9 +2036,10 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
1995
2036
  agent_aid: this.config.aid,
1996
2037
  original,
1997
2038
  };
2039
+ const encrypt = this.shouldEncrypt('observer.forward');
1998
2040
  for (const ownerAid of owners) {
1999
- this.callAndTrace('message.send', { to: ownerAid, payload: forwardPayload, encrypt: false })
2000
- .catch(e => logger.debug(`${this.logPrefix()} observer.forward to ${ownerAid} failed: ${e}`));
2041
+ this.callAndTrace('message.send', { to: ownerAid, payload: forwardPayload, encrypt })
2042
+ .catch(e => logger.warn(`${this.logPrefix()} observer.forward send to ${ownerAid} failed: ${e}`));
2001
2043
  }
2002
2044
  }
2003
2045
  // ── 观察者插话(Observer Insert,v0.3 待用上下文提示) ──────────────
@@ -2007,7 +2049,7 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
2007
2049
  // (不 dispatch、不跑 LLM、不回 owner);下一条对端消息到达时由 message-processor
2008
2050
  // 回放消费、注入渲染层。action=add 加提示 / remove 撤销。
2009
2051
  // 详见 docs/observer-insert-design.md 第一部分。
2010
- /** 回 observer.inject.ack 给 owner(明文)。accepted 在成功写盘之后发出。 */
2052
+ /** 回 observer.inject.ack 给 owner;加密使用 daemon 的全局 AUN 默认设置。 */
2011
2053
  emitInjectAck(ownerAid, injectId, data, error) {
2012
2054
  if (!this.connected || !this.client)
2013
2055
  return;
@@ -2018,8 +2060,8 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
2018
2060
  ackPayload.data = data;
2019
2061
  if (error)
2020
2062
  ackPayload.error = error;
2021
- this.callAndTrace('message.send', { to: ownerAid, payload: ackPayload, encrypt: false })
2022
- .catch(e => logger.debug(`${this.logPrefix()} observer.inject.ack to ${ownerAid} failed: ${e}`));
2063
+ this.callAndTrace('message.send', { to: ownerAid, payload: ackPayload, encrypt: this.shouldEncrypt(ownerAid) })
2064
+ .catch(e => logger.warn(`${this.logPrefix()} observer.inject.ack send to ${ownerAid} failed: ${e}`));
2023
2065
  }
2024
2066
  /** 处理 observer.inject:鉴权 + 校验 + 只落盘到 pending-hints(不触发处理、不回 owner)。 */
2025
2067
  handleObserverInject(fromAid, payload, displayName, peerType) {
@@ -2519,9 +2561,6 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
2519
2561
  }
2520
2562
  }
2521
2563
  payloadByteLength(payload, logText) {
2522
- if (payload.type === 'image' && typeof payload.data_base64 === 'string') {
2523
- return Buffer.byteLength(payload.data_base64, 'utf-8');
2524
- }
2525
2564
  return Buffer.byteLength(logText, 'utf-8');
2526
2565
  }
2527
2566
  applyReplyContextToPayload(payload, context) {
@@ -2541,11 +2580,16 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
2541
2580
  const timer = setTimeout(() => this.invalidatedInteractions.delete(interactionId), 24 * 60 * 60 * 1000);
2542
2581
  timer.unref?.();
2543
2582
  }
2544
- async recallInteractionCard(messageId) {
2583
+ async recallInteractionCard(messageId, channelId) {
2545
2584
  if (!this.client || !this.connected)
2546
2585
  return false;
2547
2586
  try {
2548
- await this.callAndTrace('message.recall', { message_ids: [messageId] }, { silentError: true });
2587
+ const isGroup = channelId ? this.isGroupId(channelId) : false;
2588
+ const method = isGroup ? 'group.recall' : 'message.recall';
2589
+ const params = isGroup
2590
+ ? { group_id: channelId, message_ids: [messageId] }
2591
+ : { message_ids: [messageId] };
2592
+ await this.callAndTrace(method, params, { silentError: true });
2549
2593
  return true;
2550
2594
  }
2551
2595
  catch (error) {
@@ -2566,8 +2610,9 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
2566
2610
  }
2567
2611
  const messageIds = [...(this.interactionCardMessageIds.get(interactionId) ?? [])];
2568
2612
  for (const messageId of messageIds) {
2613
+ const channelId = this.cardMessageIdMap.get(messageId)?.channelId;
2569
2614
  this.forgetInteractionCard(messageId, interactionId);
2570
- await this.recallInteractionCard(messageId);
2615
+ await this.recallInteractionCard(messageId, channelId);
2571
2616
  }
2572
2617
  }
2573
2618
  forgetInteractionCard(messageId, interactionId) {
@@ -2577,13 +2622,14 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
2577
2622
  if (ids && ids.size === 0)
2578
2623
  this.interactionCardMessageIds.delete(interactionId);
2579
2624
  }
2580
- registerCardPostSend(messageId, action) {
2625
+ registerCardPostSend(messageId, action, channelId) {
2581
2626
  if (action.type !== 'register_interaction_card')
2582
2627
  return;
2583
2628
  this.cardMessageIdMap.set(messageId, {
2584
2629
  requestId: action.requestId,
2585
2630
  isCommandCard: action.isCommandCard,
2586
2631
  initiatorAid: action.initiatorAid,
2632
+ channelId,
2587
2633
  });
2588
2634
  this.ownedCardMsgIds.add(messageId);
2589
2635
  let messageIds = this.interactionCardMessageIds.get(action.requestId);
@@ -2595,7 +2641,7 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
2595
2641
  const now = Date.now();
2596
2642
  const mapTtl = action.expiresAt && action.expiresAt > now
2597
2643
  ? action.expiresAt - now
2598
- : 20 * 60 * 1000;
2644
+ : AUN_INTERACTION_CARD_TTL_MS;
2599
2645
  const mapTimer = setTimeout(() => {
2600
2646
  this.cardMessageIdMap.delete(messageId);
2601
2647
  const ids = this.interactionCardMessageIds.get(action.requestId);
@@ -2609,14 +2655,14 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
2609
2655
  const invalidationReason = this.invalidatedInteractions.get(action.requestId);
2610
2656
  if (invalidationReason) {
2611
2657
  this.cardMessageIdMap.delete(messageId);
2612
- void this.recallInteractionCard(messageId);
2658
+ void this.recallInteractionCard(messageId, channelId);
2613
2659
  }
2614
2660
  }
2615
2661
  runPostSend(entry, messageId) {
2616
2662
  if (!entry.postSend)
2617
2663
  return;
2618
2664
  if (entry.postSend.type === 'register_interaction_card') {
2619
- this.registerCardPostSend(messageId, entry.postSend);
2665
+ this.registerCardPostSend(messageId, entry.postSend, entry.channelId);
2620
2666
  }
2621
2667
  }
2622
2668
  async sendAunPayload(channelId, payload, context, label) {
@@ -2931,7 +2977,7 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
2931
2977
  finalPayload._evolcore_causation_ref = causationRef;
2932
2978
  registerAunCausation(causationRef, this.config.aid, args.to, outboundCausation);
2933
2979
  }
2934
- const encrypt = args.encrypt === true;
2980
+ const encrypt = args.encrypt ?? this.shouldEncrypt(args.to);
2935
2981
  const sendParams = {
2936
2982
  to: args.to,
2937
2983
  payload: this.truncatePayloadIfNeeded(finalPayload, 'msg-send-ipc'),
@@ -3036,7 +3082,7 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
3036
3082
  const finalPayload = this.stripUndefinedDeep({ ...args.payload });
3037
3083
  if (args.mentions?.length)
3038
3084
  finalPayload.mentions = args.mentions;
3039
- const encrypt = args.encrypt === true;
3085
+ const encrypt = args.encrypt ?? this.shouldEncrypt(args.groupId);
3040
3086
  try {
3041
3087
  const result = await this.callAndTrace('group.send', {
3042
3088
  group_id: args.groupId,
@@ -3529,6 +3575,117 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
3529
3575
  outbox.remove(this.config.aid, entry.id);
3530
3576
  }
3531
3577
  }
3578
+ async sendImage(channelId, data, mimeType, alt, context) {
3579
+ if (!Buffer.isBuffer(data)) {
3580
+ throw new Error('result.image data must be a Buffer');
3581
+ }
3582
+ if (data.length === 0) {
3583
+ throw new Error('result.image data cannot be empty');
3584
+ }
3585
+ if (data.length > MAX_AUN_ATTACHMENT_SIZE) {
3586
+ throw new Error(`result.image is too large (${formatSize(data.length)}, max ${formatSize(MAX_AUN_ATTACHMENT_SIZE)})`);
3587
+ }
3588
+ let normalizedMimeType = normalizeImageMimeType(mimeType);
3589
+ if (!normalizedMimeType) {
3590
+ const { default: imageType } = await import('image-type');
3591
+ const detected = await imageType(data).catch(() => undefined);
3592
+ normalizedMimeType = detected?.mime;
3593
+ if (!normalizedMimeType) {
3594
+ throw new Error('result.image requires a valid image MIME type or recognizable image data');
3595
+ }
3596
+ }
3597
+ const logText = alt ? `[image] ${alt}` : '[image]';
3598
+ const entry = outbox.enqueue(this.config.aid, {
3599
+ channelId,
3600
+ type: 'image',
3601
+ contentKind: 'image',
3602
+ image: { dataBase64: data.toString('base64'), mimeType: normalizedMimeType, alt },
3603
+ context,
3604
+ logText,
3605
+ });
3606
+ logger.debug(`${this.logPrefix()} Outbox enqueued image: id=${entry.id} channel=${channelId} bytes=${data.length}`);
3607
+ if (!this.connected || !this.client) {
3608
+ logger.warn(`${this.logPrefix()} Not connected, image send queued in outbox (id=${entry.id}). Triggering reconnect.`);
3609
+ if (!this.reconnectTimer && !this.client) {
3610
+ this.initClient().catch(e => logger.error(`${this.logPrefix()} Reconnect from sendImage failed: ${e}`));
3611
+ }
3612
+ return;
3613
+ }
3614
+ const ok = await this.withOutboxInFlight(entry, () => this.deliverImageEntry(entry), false);
3615
+ if (ok)
3616
+ outbox.remove(this.config.aid, entry.id);
3617
+ }
3618
+ async buildUploadedImagePayload(data, mimeType, alt) {
3619
+ if (!this.connected || !this.client) {
3620
+ throw new Error('AUN channel is not connected; image cannot be uploaded');
3621
+ }
3622
+ let contentType = normalizeImageMimeType(mimeType);
3623
+ let extension;
3624
+ if (!contentType) {
3625
+ const { default: imageType } = await import('image-type');
3626
+ const detected = await imageType(data).catch(() => undefined);
3627
+ contentType = detected?.mime;
3628
+ extension = detected?.ext;
3629
+ }
3630
+ if (!contentType) {
3631
+ throw new Error('result.image requires a valid image MIME type or recognizable image data');
3632
+ }
3633
+ if (!extension) {
3634
+ const subtype = contentType.slice('image/'.length);
3635
+ extension = subtype === 'jpeg'
3636
+ ? 'jpg'
3637
+ : subtype === 'svg+xml'
3638
+ ? 'svg'
3639
+ : subtype.replace(/[^a-z0-9]/g, '') || 'img';
3640
+ }
3641
+ const digest = crypto.createHash('sha256').update(data).digest('hex').slice(0, 12);
3642
+ const filename = `image-${digest}.${extension}`;
3643
+ const connection = {
3644
+ call: (method, params) => this.callAndTrace(method, params),
3645
+ close: async () => { },
3646
+ };
3647
+ const built = await uploadBufferAndBuildPayload(connection, this.config.aid, data, filename, { as: 'image', contentType });
3648
+ const imagePayload = { ...built.payload };
3649
+ setIfDefined(imagePayload, 'alt', alt);
3650
+ return imagePayload;
3651
+ }
3652
+ async deliverImageEntry(entry) {
3653
+ const image = entry.image;
3654
+ if (!image || typeof image.dataBase64 !== 'string') {
3655
+ logger.warn(`${this.logPrefix()} deliverImageEntry: missing image data (outbox id=${entry.id})`);
3656
+ return true;
3657
+ }
3658
+ const data = Buffer.from(image.dataBase64, 'base64');
3659
+ if (data.length === 0) {
3660
+ logger.warn(`${this.logPrefix()} deliverImageEntry: invalid image data (outbox id=${entry.id})`);
3661
+ return true;
3662
+ }
3663
+ const imagePayload = await this.buildUploadedImagePayload(data, image.mimeType, image.alt);
3664
+ entry.type = 'payload';
3665
+ entry.contentKind = 'image';
3666
+ entry.payload = this.applyReplyContextToPayload(imagePayload, entry.context);
3667
+ entry.logText ??= image.alt ? `[image] ${image.alt}` : '[image]';
3668
+ delete entry.image;
3669
+ // Persist the attachment reference before message.send. A failed send then
3670
+ // retries the compact wire payload without re-uploading the same image.
3671
+ let payloadEntry = entry;
3672
+ if (!outbox.replace(this.config.aid, entry)) {
3673
+ payloadEntry = outbox.enqueue(this.config.aid, {
3674
+ channelId: entry.channelId,
3675
+ type: 'payload',
3676
+ contentKind: 'image',
3677
+ payload: entry.payload,
3678
+ context: entry.context,
3679
+ logText: entry.logText,
3680
+ ttl: entry.ttl,
3681
+ });
3682
+ }
3683
+ const sent = await this.deliverPayloadEntry(payloadEntry);
3684
+ if (sent.ok && payloadEntry.id !== entry.id) {
3685
+ outbox.remove(this.config.aid, payloadEntry.id);
3686
+ }
3687
+ return sent.ok;
3688
+ }
3532
3689
  async deliverFileEntry(entry) {
3533
3690
  const channelId = entry.channelId;
3534
3691
  const absPath = entry.filePath;
@@ -3715,6 +3872,9 @@ EvolCore AI Agent 网关,支持多项目会话管理和多 AI 后端切换。
3715
3872
  else if (entry.type === 'file') {
3716
3873
  return this.withOutboxInFlight(entry, () => this.deliverFileEntry(entry), false);
3717
3874
  }
3875
+ else if (entry.type === 'image') {
3876
+ return this.withOutboxInFlight(entry, () => this.deliverImageEntry(entry), false);
3877
+ }
3718
3878
  else if (entry.type === 'payload') {
3719
3879
  const sent = await this.withOutboxInFlight(entry, () => this.deliverPayloadEntry(entry), { ok: false });
3720
3880
  return sent.ok;
@@ -4021,6 +4181,7 @@ export class AUNChannelPlugin {
4021
4181
  aid,
4022
4182
  keystorePath: inst.keystorePath,
4023
4183
  gatewayUrl: inst.gatewayUrl,
4184
+ defaultEncrypt: ctx.aunDefaultEncrypt,
4024
4185
  accessToken: inst.accessToken,
4025
4186
  flushDelay: inst.flushDelay,
4026
4187
  agentName: ctx.agentName,
@@ -4087,16 +4248,7 @@ export class AUNChannelPlugin {
4087
4248
  return;
4088
4249
  }
4089
4250
  case 'result.image': {
4090
- const buf = payload.data;
4091
- const b64 = buf.toString('base64');
4092
- const imagePayload = { type: 'image', data_base64: b64 };
4093
- setIfDefined(imagePayload, 'alt', payload.alt);
4094
- setIfDefined(imagePayload, 'mime_type', payload.mimeType);
4095
- await channel.sendContentPayload(channelId, imagePayload, {
4096
- contentKind: 'image',
4097
- context: replyCtx,
4098
- logText: payload.alt ? `[image] ${payload.alt}` : '[image]',
4099
- });
4251
+ await channel.sendImage(channelId, payload.data, payload.mimeType, payload.alt, replyCtx);
4100
4252
  return;
4101
4253
  }
4102
4254
  case 'activity.batch': {
@@ -4147,7 +4299,7 @@ export class AUNChannelPlugin {
4147
4299
  return;
4148
4300
  case 'interaction': {
4149
4301
  const req = payload.interaction;
4150
- const cardTtlMs = 20 * 60 * 1000;
4302
+ const cardTtlMs = AUN_INTERACTION_CARD_TTL_MS;
4151
4303
  if (req.kind.kind === 'action') {
4152
4304
  const action = req.kind;
4153
4305
  const aunCard = {
@@ -4204,6 +4356,8 @@ export class AUNChannelPlugin {
4204
4356
  aunCard.text = card.body;
4205
4357
  setIfDefined(aunCard, 'format', card.bodyFormat);
4206
4358
  }
4359
+ if (req.initiatorId && channel.isGroupId(channelId))
4360
+ aunCard.initiator = req.initiatorId;
4207
4361
  if (replyCtx?.threadId)
4208
4362
  aunCard.thread_id = replyCtx.threadId;
4209
4363
  await channel.sendContentPayload(channelId, aunCard, {
@@ -808,7 +808,7 @@ Options:
808
808
  --app <name> 指定应用 slot(独立消费通道,不影响 daemon)
809
809
  --aun-path <path> 指定 AUN keystore 根
810
810
  --format json 输出 JSON 格式
811
- --encrypt 启用端到端加密(密文发送)
811
+ --encrypt 强制端到端加密(未指定时使用 daemon 默认值)
812
812
  --no-encrypt 强制明文发送(优先于 --encrypt)
813
813
  --thread <id> 指定话题 ID(用于多话题路由)
814
814
  --session <latest|all|id> 按 EvolCore 逻辑会话过滤历史(默认 latest)
@@ -1048,9 +1048,10 @@ Options:
1048
1048
  }
1049
1049
  body = { mode: 'text', text };
1050
1050
  }
1051
- // 加密态:--encrypt 密文,--no-encrypt 明文,都不带默认明文(人类终端直用即此)。
1052
- // 模型自主发送时由系统提示规则要求按入站消息加密态显式带参。--no-encrypt 优先于 --encrypt
1053
- const encrypt = args.includes('--encrypt') && !args.includes('--no-encrypt');
1051
+ // 显式 flag 覆盖 daemon 默认值;未指定时保留 undefined。
1052
+ const encrypt = args.includes('--no-encrypt')
1053
+ ? false
1054
+ : args.includes('--encrypt') ? true : undefined;
1054
1055
  const thread = getArgValue(args, '--thread');
1055
1056
  const returnPolicyRaw = getArgValue(args, '--return');
1056
1057
  if (returnPolicyRaw && returnPolicyRaw !== 'required' && returnPolicyRaw !== 'none') {
@@ -1292,7 +1293,7 @@ Options:
1292
1293
  --app <name> 指定应用 slot(独立消费通道,不影响 daemon)
1293
1294
  --aun-path <path> 指定 AUN keystore 根
1294
1295
  --format json 输出 JSON 格式
1295
- --encrypt 启用端到端加密(仅 send)
1296
+ --encrypt 强制端到端加密(未指定时使用 daemon 默认值;仅 send)
1296
1297
  --no-encrypt 强制明文发送(优先于 --encrypt;仅 send)
1297
1298
  --thread <id> 指定话题 ID(仅 send)
1298
1299
  --return <none|required> 跨会话发送必填(仅 send;Trigger 只能使用 none)
@@ -1469,8 +1470,10 @@ Options:
1469
1470
  body = { mode: 'text', text };
1470
1471
  }
1471
1472
  const mentions = collectMentions();
1472
- // --encrypt 密文,--no-encrypt 明文,都不带默认明文。--no-encrypt 优先。
1473
- const encryptGroup = args.includes('--encrypt') && !args.includes('--no-encrypt');
1473
+ // 显式 flag 覆盖 daemon 默认值;未指定时保留 undefined。
1474
+ const encryptGroup = args.includes('--no-encrypt')
1475
+ ? false
1476
+ : args.includes('--encrypt') ? true : undefined;
1474
1477
  const thread = getArgValue(args, '--thread');
1475
1478
  const returnPolicyRaw = getArgValue(args, '--return');
1476
1479
  if (returnPolicyRaw && returnPolicyRaw !== 'required' && returnPolicyRaw !== 'none') {
package/dist/cli/bench.js CHANGED
@@ -5,9 +5,10 @@ import os from 'os';
5
5
  import { execFile } from 'child_process';
6
6
  import { promisify } from 'util';
7
7
  import { aidList, aidCreate } from '../aun/aid/identity.js';
8
- import { resolveControlIssuer } from '../aun/aid/control-aid.js';
8
+ import { resolveControlAidDomain } from '../aun/aid/control-aid.js';
9
9
  import { msgSend, msgPull } from '../aun/msg/index.js';
10
10
  import { getPackageRoot, aunPath as defaultAunPath } from '../paths.js';
11
+ import { loadDaemonConfig } from '../config-store.js';
11
12
  import { getAidStore, loadClient, SLOT } from '../aun/aid/store.js';
12
13
  import { isHelpFlag, wantsHelp, getArgValue } from './help.js';
13
14
  const execFileAsync = promisify(execFile);
@@ -476,10 +477,10 @@ Options:
476
477
  const need = numAids - usableAids.length;
477
478
  if (!formatJson)
478
479
  console.log(warn(`仅 ${usableAids.length} 个可用,需创建 ${need} 个新 AID`));
479
- const issuer = resolveControlIssuer();
480
+ const aidDomain = resolveControlAidDomain(loadDaemonConfig().aun?.defaultAidDomain);
480
481
  for (let i = 0; i < need; i++) {
481
482
  const hex = crypto.randomBytes(4).toString('hex');
482
- const newAid = `bench-${hex}.${issuer}`;
483
+ const newAid = `bench-${hex}.${aidDomain}`;
483
484
  try {
484
485
  await aidCreate(newAid, { aunPath });
485
486
  aids.push(newAid);