evolcore 0.0.32 → 0.0.34

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 (214) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/bin/ec.js +3 -2
  3. package/bin/install-codex-managed-hooks.mjs +135 -37
  4. package/dist/agents/baseagent-availability.js +20 -36
  5. package/dist/agents/claude-runner.js +111 -15
  6. package/dist/agents/codex/app-server-client.js +3 -0
  7. package/dist/agents/codex/diagnostics.js +112 -54
  8. package/dist/agents/codex-runner.js +241 -63
  9. package/dist/agents/ecagent-runner.js +78 -33
  10. package/dist/agents/runner-types.js +5 -6
  11. package/dist/aun/aid/identity.js +1 -1
  12. package/dist/aun/group/operations.js +0 -1
  13. package/dist/aun/msg/history.js +1 -0
  14. package/dist/aun/msg/p2p.js +0 -1
  15. package/dist/aun/outbox.js +50 -1
  16. package/dist/channels/aun.js +44 -8
  17. package/dist/channels/daemon.js +261 -3
  18. package/dist/cli/agent-command.js +58 -24
  19. package/dist/cli/agent.js +1 -1
  20. package/dist/cli/aun-commands.js +368 -31
  21. package/dist/cli/contact.js +8 -2
  22. package/dist/cli/ctl-command.js +3 -1
  23. package/dist/cli/daemon-commands.js +197 -27
  24. package/dist/cli/debug-mode.js +154 -0
  25. package/dist/cli/fs-command.js +2 -1
  26. package/dist/cli/handoff-command.js +3 -0
  27. package/dist/cli/index.js +98 -67
  28. package/dist/cli/init.js +2 -2
  29. package/dist/cli/integrity-command.js +196 -0
  30. package/dist/cli/managed-command-guard.js +5 -0
  31. package/dist/cli/memory-command.js +166 -146
  32. package/dist/cli/queue-command.js +9 -4
  33. package/dist/cli/session-command.js +194 -0
  34. package/dist/cli/skill-command.js +78 -2
  35. package/dist/cli/task-context.js +1 -0
  36. package/dist/cli/thread-command.js +622 -0
  37. package/dist/cli/trigger-command.js +10 -3
  38. package/dist/config/builtin-roles.js +1 -0
  39. package/dist/config/config-field-policy.js +6 -3
  40. package/dist/config/config-manager.js +26 -2
  41. package/dist/config/contact-book-store.js +5 -0
  42. package/dist/config/resolved-config-op.js +3 -0
  43. package/dist/config/role-service.js +13 -0
  44. package/dist/config/runtime-env.js +16 -0
  45. package/dist/config-store.js +45 -0
  46. package/dist/core/audit/log-integrity.js +3 -1
  47. package/dist/core/auth/agent-delegation.js +133 -36
  48. package/dist/core/auth/debug-context.js +139 -0
  49. package/dist/core/auth/delegation-diagnostics.js +414 -0
  50. package/dist/core/auth/operation-authorizer.js +25 -2
  51. package/dist/core/auth/operation-catalog.js +49 -0
  52. package/dist/core/background-session/session-cleanup.js +212 -0
  53. package/dist/core/background-session/types.js +10 -0
  54. package/dist/core/bootstrap-messages.js +1 -1
  55. package/dist/core/bootstrap-service.js +6 -3
  56. package/dist/core/command/agent-control.js +18 -26
  57. package/dist/core/command/command-handler.js +197 -27
  58. package/dist/core/command/daemon-diagnostics.js +1 -0
  59. package/dist/core/command/memory-slash.js +6 -2
  60. package/dist/core/command/menu-catalog.js +51 -1
  61. package/dist/core/command/menu-handler.js +114 -23
  62. package/dist/core/command/menu-protocol.js +25 -1
  63. package/dist/core/command/skill-slash.js +322 -0
  64. package/dist/core/command/slash-gate.js +6 -4
  65. package/dist/core/command/slash-handler.js +195 -13
  66. package/dist/core/command/topic-slash.js +528 -0
  67. package/dist/core/daemon-bootstrap.js +4 -7
  68. package/dist/core/evolagent-registry.js +20 -5
  69. package/dist/core/file-integrity/read.js +61 -0
  70. package/dist/core/file-integrity/store.js +262 -0
  71. package/dist/core/handoff/runtime.js +5 -11
  72. package/dist/core/handoff/store.js +5 -0
  73. package/dist/core/ipc-registration.js +175 -3
  74. package/dist/core/memory/batch-meta.js +132 -0
  75. package/dist/core/memory/consolidation-context.js +83 -29
  76. package/dist/core/memory/consolidation-ops-records.js +49 -16
  77. package/dist/core/memory/consolidation-queue-format.js +21 -0
  78. package/dist/core/memory/consolidation.js +264 -205
  79. package/dist/core/memory/index-manager.js +19 -28
  80. package/dist/core/memory/memory-admin.js +19 -14
  81. package/dist/core/memory/memory-document.js +53 -9
  82. package/dist/core/memory/memory-writer.js +30 -15
  83. package/dist/core/message/aun-ipc-sender.js +161 -6
  84. package/dist/core/message/im-renderer.js +169 -10
  85. package/dist/core/message/message-bridge.js +15 -4
  86. package/dist/core/message/message-log.js +1 -0
  87. package/dist/core/message/peer-mode.js +6 -1
  88. package/dist/core/message/response-engine.js +929 -110
  89. package/dist/core/message/subtask-tool-projection.js +140 -0
  90. package/dist/core/model/catalog-service.js +17 -12
  91. package/dist/core/permission/ec-command-parser.js +217 -9
  92. package/dist/core/permission/protected-paths.js +5 -1
  93. package/dist/core/permission/readonly-shell-query.js +43 -5
  94. package/dist/core/permission/session-path-grants.js +334 -0
  95. package/dist/core/permission/tool-canonical.js +226 -0
  96. package/dist/core/permission/tool-policy.js +30 -62
  97. package/dist/core/role/runtime-policy.js +21 -10
  98. package/dist/core/session/session-fs-store.js +123 -8
  99. package/dist/core/session/session-idle-monitor.js +249 -22
  100. package/dist/core/session/session-manager.js +129 -14
  101. package/dist/core/skill/command-parser.js +13 -0
  102. package/dist/core/skill/index-generator.js +21 -4
  103. package/dist/core/skill/startup.js +41 -0
  104. package/dist/core/skill/switch-resolver.js +55 -29
  105. package/dist/core/system-session/grants.js +40 -0
  106. package/dist/core/system-session/memory.js +222 -0
  107. package/dist/core/system-session/registry.js +74 -0
  108. package/dist/core/system-session/types.js +14 -0
  109. package/dist/core/thread/command-parser.js +125 -0
  110. package/dist/core/thread/index.js +1 -0
  111. package/dist/core/thread/ipc-operation.js +95 -0
  112. package/dist/core/thread/thread-context-storage.js +131 -0
  113. package/dist/core/thread/thread-operation.js +258 -0
  114. package/dist/core/thread/thread-route.js +33 -0
  115. package/dist/core/thread/thread-service.js +770 -0
  116. package/dist/core/thread/types.js +1 -0
  117. package/dist/eck/kit-renderer.js +7 -2
  118. package/dist/eck/manifest-engine.js +24 -4
  119. package/dist/eck/message-renderer.js +35 -0
  120. package/dist/index.js +19 -7
  121. package/dist/ipc.js +140 -50
  122. package/dist/paths.js +93 -0
  123. package/dist/response-system/engines/v1/proactive-flow.js +169 -80
  124. package/dist/stats/billing.js +20 -8
  125. package/dist/trigger/authorization.js +57 -28
  126. package/dist/trigger/feedback.js +13 -2
  127. package/dist/trigger/parser.js +70 -1
  128. package/dist/trigger/system-definitions.js +3 -3
  129. package/dist/trigger/validation.js +14 -0
  130. package/dist/utils/cross-platform.js +11 -2
  131. package/dist/utils/error-dict.json +18 -4
  132. package/dist/utils/error-utils.js +143 -1
  133. package/dist/utils/instance-registry.js +13 -8
  134. package/dist/utils/log-writer.js +12 -0
  135. package/dist/utils/process-introspect.js +11 -0
  136. package/kits/docs/context-assembly.md +1 -1
  137. package/kits/docs/evolcore/INDEX.md +1 -0
  138. package/kits/docs/evolcore/agent-create.md +40 -28
  139. package/kits/docs/evolcore/agent.md +21 -6
  140. package/kits/docs/evolcore/config.md +2 -2
  141. package/kits/docs/evolcore/ctl.md +2 -2
  142. package/kits/docs/evolcore/ec-capabilities.md +5 -1
  143. package/kits/docs/evolcore/fs-architecture.md +4 -5
  144. package/kits/docs/evolcore/fs.md +1 -1
  145. package/kits/docs/evolcore/group-collaboration.md +4 -6
  146. package/kits/docs/evolcore/group.md +11 -12
  147. package/kits/docs/evolcore/memory-architecture.md +4 -5
  148. package/kits/docs/evolcore/memory-consolidation.md +19 -15
  149. package/kits/docs/evolcore/memory-tags.md +3 -1
  150. package/kits/docs/evolcore/memory.md +24 -12
  151. package/kits/docs/evolcore/menu-exec-schema-commands.md +2 -2
  152. package/kits/docs/evolcore/menu-protocol.md +7 -0
  153. package/kits/docs/evolcore/model.md +16 -0
  154. package/kits/docs/evolcore/msg.md +8 -11
  155. package/kits/docs/evolcore/thread-chain.md +267 -0
  156. package/kits/docs/prompt-loading-architecture.md +1 -1
  157. package/kits/eck_manifest.json +55 -40
  158. package/kits/eck_manifest.memory.json +0 -12
  159. package/kits/eck_message_manifest.json +169 -10
  160. package/kits/rules/01-overview.md +11 -0
  161. package/kits/rules/03-identity.md +6 -3
  162. package/kits/rules/05-venue.md +1 -1
  163. package/kits/rules/06-channel.md +1 -1
  164. package/kits/rules/07-memory-and-thread.md +199 -0
  165. package/kits/schemas/_meta.json +7 -1
  166. package/kits/schemas/agent-config.schema.13.json +1 -1
  167. package/kits/schemas/daemon.schema.7.json +140 -0
  168. package/kits/schemas/relation-config.schema.9.json +18 -3
  169. package/kits/schemas/role-config.schema.1.json +6 -6
  170. package/kits/schemas/single-session.schema.1.json +6 -6
  171. package/kits/schemas/single-session.schema.2.json +6 -6
  172. package/kits/schemas/single-session.schema.3.json +6 -6
  173. package/kits/skills/.switches.json +12 -1
  174. package/kits/skills/ec-group/SKILL.md +234 -0
  175. package/kits/skills/ec-skill/SKILL.md +10 -1
  176. package/kits/skills/ec-skill/scripts/cli.mjs +16 -2
  177. package/kits/skills/ec-skill/scripts/skill.mjs +1 -1
  178. package/kits/skills/scrapling-article-fetch/SKILL.md +128 -0
  179. package/kits/skills/scrapling-article-fetch/scripts/check_python_env.py +54 -0
  180. package/kits/skills/scrapling-article-fetch/scripts/render_markdown_reply.py +35 -0
  181. package/kits/skills/scrapling-article-fetch/scripts/run_pipeline.sh +16 -0
  182. package/kits/skills/scrapling-article-fetch/scripts/scrapling_fetch.py +344 -0
  183. package/kits/skills/thread-ops/SKILL.md +492 -0
  184. package/kits/skills/wechat-article-media-download/SKILL.md +65 -0
  185. package/kits/skills/wechat-article-media-download/scripts/download.py +163 -0
  186. package/kits/skills/wechat-article-reader/SKILL.md +97 -0
  187. package/kits/skills/wechat-article-reader/scripts/fetch.mjs +256 -0
  188. package/kits/templates/bootstrap-welcome.md +7 -7
  189. package/kits/templates/memory-consolidation/forget.md +7 -2
  190. package/kits/templates/memory-consolidation/generalize.md +9 -4
  191. package/kits/templates/memory-consolidation/notes.md +11 -11
  192. package/kits/templates/memory-consolidation/profile.md +8 -3
  193. package/kits/templates/memory-consolidation/promote.md +8 -3
  194. package/kits/templates/memory-consolidation/workflow.md +6 -6
  195. package/kits/templates/message-fragments/handoff-request-to-target.md +1 -1
  196. package/kits/templates/message-fragments/item.md +2 -1
  197. package/kits/templates/message-fragments/thread-context.md +6 -0
  198. package/kits/templates/message-fragments/trigger-session.md +2 -0
  199. package/kits/templates/message-fragments/trigger-thread-check.md +2 -0
  200. package/kits/templates/roles/member.json +2 -0
  201. package/kits/templates/roles/visitor.json +2 -0
  202. package/kits/templates/system-fragments/bootstrap.md +67 -72
  203. package/kits/templates/system-fragments/channel.md +3 -6
  204. package/kits/templates/system-fragments/commands.md +1 -0
  205. package/kits/templates/system-fragments/managed-runtime.md +15 -0
  206. package/kits/templates/system-fragments/memory.md +16 -9
  207. package/kits/templates/system-fragments/reply.md +7 -6
  208. package/kits/templates/system-fragments/session.md +5 -14
  209. package/package.json +6 -3
  210. package/dist/core/memory/memory-session-policy.js +0 -41
  211. package/dist/core/memory/memory-signature.js +0 -257
  212. package/kits/docs/evolcore/group-fs.md +0 -17
  213. package/kits/docs/venues/aun-group.md +0 -45
  214. package/kits/docs/venues/group.md +0 -43
@@ -1,9 +1,10 @@
1
1
  import { logger } from '../../utils/logger.js';
2
2
  import { summarizeToolInput, summarizeToolInputForDisplay, toolInputForDisplay } from '../../utils/tool-summary.js';
3
- import { getErrorMessage, isContextTooLongText } from '../../utils/error-utils.js';
3
+ import { getErrorMessage, getToolResultErrorText, isContextTooLongText } from '../../utils/error-utils.js';
4
4
  import { tagErrorTextWithEvolcoreVersion } from '../../utils/evolcore-version.js';
5
5
  import { DEFAULT_FLUSH_DELAY_MS } from '../../types.js';
6
6
  import { classifyAunToolErrorCode, normalizeToolErrorClassification } from '../permission/tool-error-code.js';
7
+ import { foldSubtaskTerminal } from './subtask-tool-projection.js';
7
8
  export class IMRenderer {
8
9
  opts;
9
10
  itemsQueue = [];
@@ -22,6 +23,16 @@ export class IMRenderer {
22
23
  syntheticCallSeq = 0;
23
24
  currentAssistantUuid;
24
25
  currentTextPhase;
26
+ /** 无来源工具时合成的子任务卡片;与 lifecycle 边界一样,不算抑制兜底错误的正文/过程内容。 */
27
+ subtaskItems = new WeakSet();
28
+ /** 本轮已投影的工具调用 call_id → 工具名;子任务只归拢到本轮可见的来源工具卡片。 */
29
+ toolCallNames = new Map();
30
+ /**
31
+ * 归拢到来源工具的子任务:call_id → 状态。
32
+ * running 期间到达的 tool_result(后台占位结果)先扣住,等终态合并后再发;
33
+ * 终态先到(前台)时记下终态,等真实 tool_result 到达时合并。
34
+ */
35
+ parentSubtasks = new Map();
25
36
  constructor(opts) {
26
37
  this.opts = opts;
27
38
  }
@@ -66,7 +77,8 @@ export class IMRenderer {
66
77
  /** 强制刷新所有 pending 事件 */
67
78
  async flush(isFinal, attention) {
68
79
  if (this.opts.envelope.chatmode === 'proactive') {
69
- // proactive 是 fire-and-forget,无 pending buffer
80
+ // proactive 是 fire-and-forget,无 pending buffer;只需放出仍被扣住的工具结果
81
+ this.releaseHeldToolResults();
70
82
  return;
71
83
  }
72
84
  return this.flushInternal(isFinal, attention);
@@ -79,16 +91,24 @@ export class IMRenderer {
79
91
  }
80
92
  /** 是否有 pending 内容 */
81
93
  hasContent() {
82
- return this.textBuffer.length > 0 || this.itemsQueue.some(it => it.kind !== 'text');
94
+ return this.textBuffer.length > 0 || this.itemsQueue.some(it => it.kind !== 'text') || this.hasHeldToolResults();
83
95
  }
84
96
  /** 是否有会抑制兜底错误消息的正文/过程内容;lifecycle 边界不算。 */
85
97
  hasNonLifecycleContent() {
86
- return this.textBuffer.trim().length > 0 || this.itemsQueue.some(it => {
98
+ return this.textBuffer.trim().length > 0 || this.hasHeldToolResults() || this.itemsQueue.some(it => {
87
99
  if (it.kind === 'text')
88
100
  return it.text.trim().length > 0;
101
+ if (this.subtaskItems.has(it))
102
+ return false;
89
103
  return it.kind !== 'started' && it.kind !== 'completed';
90
104
  });
91
105
  }
106
+ hasHeldToolResults() {
107
+ for (const state of this.parentSubtasks.values())
108
+ if (state.held)
109
+ return true;
110
+ return false;
111
+ }
92
112
  /** 是否有待发送的文本 */
93
113
  hasTextPending() {
94
114
  return this.textBuffer.length > 0;
@@ -234,6 +254,7 @@ export class IMRenderer {
234
254
  ...(evolCommand ? { evolCommand } : {}),
235
255
  ...(assistantUuid ? { forkAnchor: { assistantMessageId: assistantUuid } } : {}),
236
256
  };
257
+ this.toolCallNames.set(item.call_id, name);
237
258
  this.recordActivity(item);
238
259
  if (this.suppressActivityItems())
239
260
  return;
@@ -245,7 +266,6 @@ export class IMRenderer {
245
266
  addToolResult(name, ok, result, error, callId, durationMs, descText, classification, assistantUuid) {
246
267
  if (this.opts.envelope.chatmode === 'proactive')
247
268
  return;
248
- this.emitProgress('tool_result', undefined, undefined, { toolName: name, callId, ok, durationMs });
249
269
  const normalizedClassification = !ok
250
270
  ? normalizeToolErrorClassification(classification ?? {})
251
271
  : undefined;
@@ -255,7 +275,13 @@ export class IMRenderer {
255
275
  name,
256
276
  ok,
257
277
  ...(result !== undefined && { result }),
258
- ...(error !== undefined && { error }),
278
+ ...(!ok
279
+ ? { error: getToolResultErrorText({ name, result, error, exitCode: classification?.exitCode }) }
280
+ : error !== undefined ? { error } : {}),
281
+ ...(typeof classification?.exitCode === 'number' && Number.isInteger(classification.exitCode)
282
+ ? { exit_code: classification.exitCode }
283
+ : {}),
284
+ ...(classification?.outputKind ? { output_kind: classification.outputKind } : {}),
259
285
  ...(!ok && {
260
286
  error_code: classifyAunToolErrorCode({
261
287
  ...(classification ?? {}),
@@ -269,6 +295,22 @@ export class IMRenderer {
269
295
  ...(descText !== undefined && { text: descText }),
270
296
  ...(assistantUuid ? { forkAnchor: { assistantMessageId: assistantUuid } } : {}),
271
297
  };
298
+ const resolved = this.resolveParentToolResult(item);
299
+ if (!resolved)
300
+ return;
301
+ this.deliverToolResult(resolved);
302
+ }
303
+ /** 投递一条工具结果(interactive 入队 / proactive 直发),并记录任务活动。 */
304
+ deliverToolResult(item) {
305
+ if (item.kind !== 'tool_result')
306
+ return;
307
+ if (this.opts.envelope.chatmode === 'proactive') {
308
+ this.emitProactiveItem(item);
309
+ return;
310
+ }
311
+ this.emitProgress('tool_result', undefined, undefined, {
312
+ toolName: item.name, callId: item.call_id, ok: item.ok, durationMs: item.duration_ms,
313
+ });
272
314
  this.recordActivity(item);
273
315
  if (this.suppressActivityItems())
274
316
  return;
@@ -276,6 +318,73 @@ export class IMRenderer {
276
318
  this.messageTimestamps.push(Date.now());
277
319
  this.scheduleFlush();
278
320
  }
321
+ /**
322
+ * 工具结果与归拢子任务的会合点。
323
+ * - 无归拢子任务:原样放行
324
+ * - 子任务已终态(前台:通知先于真实结果到达):合并终态后放行
325
+ * - 子任务仍在跑(后台:先到的是占位结果):扣住,返回 null,等 endParentSubtask 合并后发出
326
+ */
327
+ resolveParentToolResult(item) {
328
+ if (item.kind !== 'tool_result')
329
+ return item;
330
+ const state = this.parentSubtasks.get(item.call_id);
331
+ if (!state)
332
+ return item;
333
+ if (state.terminal) {
334
+ this.parentSubtasks.delete(item.call_id);
335
+ return foldSubtaskTerminal(item, state.terminal);
336
+ }
337
+ state.held = item;
338
+ return null;
339
+ }
340
+ /**
341
+ * 子任务开始:若来源工具卡片在本轮可见,登记归拢,不另出卡片。
342
+ * 返回 false 表示无法归拢(无来源工具或卡片不在本轮),调用方应改发独立卡片。
343
+ */
344
+ beginParentSubtask(toolUseId) {
345
+ if (!toolUseId || !this.toolCallNames.has(toolUseId))
346
+ return false;
347
+ if (!this.parentSubtasks.has(toolUseId))
348
+ this.parentSubtasks.set(toolUseId, {});
349
+ return true;
350
+ }
351
+ /**
352
+ * 子任务终态:合并进来源工具的 tool_result。
353
+ * - 已扣住占位结果(后台):合并后立即发出
354
+ * - 结果尚未到达(前台):记下终态,等结果到达时合并
355
+ * 返回 false 表示本轮没有登记该归拢(卡片已提前释放或不在本轮),调用方应补发一条同 call_id 的终态结果。
356
+ */
357
+ endParentSubtask(toolUseId, terminal) {
358
+ if (!toolUseId)
359
+ return false;
360
+ const state = this.parentSubtasks.get(toolUseId);
361
+ if (!state)
362
+ return false;
363
+ if (state.held) {
364
+ this.parentSubtasks.delete(toolUseId);
365
+ this.deliverToolResult(foldSubtaskTerminal(state.held, terminal));
366
+ }
367
+ else {
368
+ state.terminal = terminal;
369
+ }
370
+ return true;
371
+ }
372
+ /** 来源工具的名称(本轮可见时);补发终态结果时用来对齐卡片名。 */
373
+ toolNameForCall(callId) {
374
+ return callId ? this.toolCallNames.get(callId) : undefined;
375
+ }
376
+ /**
377
+ * 放出仍被扣住的工具结果(不带子任务终态,原样发出)。
378
+ * 轮次结束或出错收尾时调用,避免来源工具卡片停在"执行中"。
379
+ */
380
+ releaseHeldToolResults() {
381
+ for (const [callId, state] of this.parentSubtasks) {
382
+ if (!state.held)
383
+ continue;
384
+ this.parentSubtasks.delete(callId);
385
+ this.deliverToolResult(state.held);
386
+ }
387
+ }
279
388
  /** 添加进度提示 */
280
389
  addProgress(text, opts = {}) {
281
390
  if (this.opts.envelope.chatmode === 'proactive')
@@ -348,6 +457,26 @@ export class IMRenderer {
348
457
  this.messageTimestamps.push(Date.now());
349
458
  this.scheduleFlush();
350
459
  }
460
+ /**
461
+ * 添加子任务活动(由 subtask-tool-projection 构造的 tool_call / tool_result)。
462
+ *
463
+ * 与 addToolCall/addToolResult 不同:不发 status.progress(子任务不是本轮模型正在发起的工具调用),
464
+ * 且 proactive 下照常投影为 thought(mapEventToItem 不处理 task_* 事件,不会重复)。
465
+ * 活动记录与 addToolCall 一致,在抑制前写入,保证任务活动 Menu 历史完整。
466
+ */
467
+ addSubtaskActivity(item) {
468
+ this.subtaskItems.add(item);
469
+ if (this.opts.envelope.chatmode === 'proactive') {
470
+ this.emitProactiveItem(item);
471
+ return;
472
+ }
473
+ this.recordActivity(item);
474
+ if (this.suppressActivityItems())
475
+ return;
476
+ this.itemsQueue.push(item);
477
+ this.messageTimestamps.push(Date.now());
478
+ this.scheduleFlush();
479
+ }
351
480
  /**
352
481
  * proactive 下放行为 thought 的 notice subtype 白名单——仅"真·终态错误":
353
482
  * - context-too-long:上下文超限且无法 auto-compact,任务到此终止
@@ -553,6 +682,16 @@ export class IMRenderer {
553
682
  clearTimeout(this.timer);
554
683
  this.timer = undefined;
555
684
  }
685
+ // 显式 flush(轮次结束、出错收尾)时放出被扣住的后台占位结果;定时 flush 不放,
686
+ // 否则长时间后台任务会在终态到达前就把占位结果发出去。放出的结果随本次 flush 一起发,
687
+ // 不需要它重新挂上的定时器。
688
+ if (!scheduled) {
689
+ this.releaseHeldToolResults();
690
+ if (this.timer) {
691
+ clearTimeout(this.timer);
692
+ this.timer = undefined;
693
+ }
694
+ }
556
695
  // 文件标记过滤:marker 任何时候都不该出现在用户文本里,必须在 *每次* flush
557
696
  // (含非最终的定时 flush)执行。否则文本块若滞留 buffer 后被定时器触发,会走
558
697
  // 下方非-final 的 result.text 路径,把 [SEND_FILE:...] 原样发给用户。
@@ -717,6 +856,16 @@ export class IMRenderer {
717
856
  if (item.kind === 'progress') {
718
857
  return;
719
858
  }
859
+ if (item.kind === 'tool_call') {
860
+ this.toolCallNames.set(item.call_id, item.name);
861
+ }
862
+ else if (item.kind === 'tool_result') {
863
+ const resolved = this.resolveParentToolResult(item);
864
+ if (!resolved)
865
+ return;
866
+ this.emitProactiveItem(resolved);
867
+ return;
868
+ }
720
869
  this.emitProactiveItem(item);
721
870
  }
722
871
  /** proactive 模式逐条投影:单个 ThoughtItem 包成 activity.batch[1] 发出(fire-and-forget)。 */
@@ -761,7 +910,13 @@ export class IMRenderer {
761
910
  item.arguments = toolInputForDisplay(event.name, event.input);
762
911
  return item;
763
912
  }
764
- case 'tool_result':
913
+ case 'tool_result': {
914
+ const executionFields = {
915
+ ...(typeof event.exitCode === 'number' && Number.isInteger(event.exitCode)
916
+ ? { exit_code: event.exitCode }
917
+ : {}),
918
+ ...(event.outputKind ? { output_kind: event.outputKind } : {}),
919
+ };
765
920
  if (event.isError) {
766
921
  const classification = normalizeToolErrorClassification(event);
767
922
  return {
@@ -769,9 +924,11 @@ export class IMRenderer {
769
924
  call_id: event.callId || this.synthCallId(),
770
925
  name: event.name,
771
926
  ok: false,
927
+ ...executionFields,
928
+ ...(event.result !== undefined ? { result: event.result } : {}),
772
929
  error_code: classifyAunToolErrorCode({ ...event, ...classification }),
773
930
  ...(classification.errorDetailCode ? { detail_code: classification.errorDetailCode } : {}),
774
- error: event.error || (typeof event.result === 'string' ? event.result : '执行失败'),
931
+ error: getToolResultErrorText(event),
775
932
  ...(event.durationMs !== undefined && { duration_ms: event.durationMs }),
776
933
  };
777
934
  }
@@ -782,11 +939,13 @@ export class IMRenderer {
782
939
  call_id: event.callId || this.synthCallId(),
783
940
  name: event.name,
784
941
  ok: true,
942
+ ...executionFields,
785
943
  result: event.result,
786
944
  text: resultText,
787
945
  ...(event.durationMs !== undefined && { duration_ms: event.durationMs }),
788
946
  };
789
947
  }
948
+ }
790
949
  case 'compact':
791
950
  return {
792
951
  kind: 'notice',
@@ -814,7 +973,7 @@ export class IMRenderer {
814
973
  // 上下文过长错误不输出(留给外层 auto-compact 处理)
815
974
  if (isContextTooLongText(event.error || ''))
816
975
  return null;
817
- const text = getErrorMessage(new Error(event.error || '任务执行失败'), undefined, false);
976
+ const text = getErrorMessage(new Error(event.error), undefined, false);
818
977
  return { kind: 'notice', text: tagErrorTextWithEvolcoreVersion(text), severity: 'warn' };
819
978
  }
820
979
  case 'complete': {
@@ -828,7 +987,7 @@ export class IMRenderer {
828
987
  return null;
829
988
  }
830
989
  if (event.isError) {
831
- const errText = event.errors?.join('; ') || event.result || '任务失败';
990
+ const errText = event.errors?.join('; ') || event.result || '';
832
991
  const text = getErrorMessage(new Error(errText), event.terminalReason, false);
833
992
  const item = {
834
993
  kind: 'summary',
@@ -137,7 +137,8 @@ export class MessageBridge {
137
137
  logger.debug(`[MessageBridge] Decision context group rules unavailable: ${String(error)}`);
138
138
  }
139
139
  }
140
- const personalPath = path.join(agentDir(item.selfAid), 'personal', 'personal.md');
140
+ // persona.md 是唯一的人格/个人资料文件(personal.md 已废弃并入)
141
+ const personalPath = path.join(agentDir(item.selfAid), 'personal', 'persona.md');
141
142
  if (fs.existsSync(personalPath))
142
143
  resources.personal = fs.readFileSync(personalPath, 'utf8');
143
144
  if (item.projectPath) {
@@ -1895,9 +1896,19 @@ export class MessageBridge {
1895
1896
  case 'menu.list':
1896
1897
  if (args?.view === 'catalog') {
1897
1898
  validateMenuCatalogArgs(args);
1898
- const data = await this.cmdHandler.getMenuCatalog(channel, msg.channelId, authSubject, args.context, msg.isControlChannel ? 'control' : 'agent', !msg.isControlChannel || (msg.encrypted === true
1899
- && msg.protectedHeaders?.auth_method !== 'remote-access-token'
1900
- && msg.protectedHeaders?.auth_method !== 'ecweb-token'));
1899
+ const catalogArgs = [
1900
+ channel,
1901
+ msg.channelId,
1902
+ authSubject,
1903
+ args.context,
1904
+ msg.isControlChannel ? 'control' : 'agent',
1905
+ !msg.isControlChannel || (msg.encrypted === true
1906
+ && msg.protectedHeaders?.auth_method !== 'remote-access-token'
1907
+ && msg.protectedHeaders?.auth_method !== 'ecweb-token'),
1908
+ ];
1909
+ const data = msg.threadId
1910
+ ? await this.cmdHandler.getMenuCatalog(...catalogArgs, transportReplyContext)
1911
+ : await this.cmdHandler.getMenuCatalog(...catalogArgs);
1901
1912
  return menuSuccess(header, data);
1902
1913
  }
1903
1914
  if (args?.view !== undefined) {
@@ -20,6 +20,7 @@ const TRANSIENT_PROTOCOL_TYPES = new Set([
20
20
  'thought',
21
21
  'handoff_state',
22
22
  'handoff_result',
23
+ 'topic-created', // 话题创建系统消息,不进大模型上下文
23
24
  ]);
24
25
  const KNOWN_AUN_PAYLOAD_TYPES = new Set([
25
26
  'text',
@@ -14,8 +14,11 @@ export function resolveChatMode(params) {
14
14
  configured = undefined;
15
15
  }
16
16
  const kind = normalizePeerType(params.peerType);
17
+ // 运行时硬约束(非配置项):system/service 始终 interactive;agent 始终 proactive
17
18
  if (kind === 'system' || kind === 'service')
18
19
  return 'interactive';
20
+ if (kind === 'agent')
21
+ return 'proactive';
19
22
  const field = chatmodeFieldForPeer(params.chatType, params.peerType);
20
23
  const decision = resolveRuntimeStringField({
21
24
  selfAid: params.self,
@@ -70,9 +73,11 @@ export function isSystemOrServicePeer(peerType) {
70
73
  */
71
74
  export function resolveChatModeForPeer(params) {
72
75
  const kind = normalizePeerType(params.peerType);
73
- // 运行时硬约束(非配置项):system/service 对端始终同步交互
76
+ // 运行时硬约束(非配置项):system/service 对端始终同步交互;agent 对端始终主动响应
74
77
  if (kind === 'system' || kind === 'service')
75
78
  return 'interactive';
79
+ if (kind === 'agent')
80
+ return 'proactive';
76
81
  // 合并后的场景表 → 出厂默认表
77
82
  const field = chatmodeFieldForPeer(params.chatType, params.peerType);
78
83
  return params.configured?.[field] ?? chatmodeFactoryDefaults()[field];