dominds 1.19.3 → 1.20.2

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 (195) hide show
  1. package/README.md +1 -0
  2. package/dist/access-control.js +2 -2
  3. package/dist/dialog.d.ts +6 -1
  4. package/dist/dialog.js +13 -4
  5. package/dist/docs/context-health.md +39 -13
  6. package/dist/docs/context-health.zh.md +14 -7
  7. package/dist/docs/idle-reminder-wake.md +227 -0
  8. package/dist/docs/idle-reminder-wake.zh.md +227 -0
  9. package/dist/llm/client.d.ts +2 -0
  10. package/dist/llm/client.js +32 -2
  11. package/dist/llm/defaults.yaml +51 -10
  12. package/dist/llm/gen/codex.js +15 -0
  13. package/dist/llm/gen/failure-classifier.js +22 -1
  14. package/dist/llm/kernel-driver/drive.js +6 -0
  15. package/dist/llm/kernel-driver/flow.js +9 -0
  16. package/dist/llm/kernel-driver/idle-reminder-wake.d.ts +4 -0
  17. package/dist/llm/kernel-driver/idle-reminder-wake.js +351 -0
  18. package/dist/llm/kernel-driver/types.d.ts +1 -1
  19. package/dist/minds/load.js +2 -1
  20. package/dist/minds/minds-i18n.js +2 -2
  21. package/dist/minds/system-prompt-parts.js +56 -20
  22. package/dist/minds/system-prompt.js +10 -10
  23. package/dist/persistence.js +1 -1
  24. package/dist/runtime/driver-messages.d.ts +3 -0
  25. package/dist/runtime/driver-messages.js +91 -8
  26. package/dist/server/setup-routes.js +5 -5
  27. package/dist/tool.d.ts +8 -0
  28. package/dist/tools/builtins.js +4 -2
  29. package/dist/tools/ctrl.d.ts +2 -0
  30. package/dist/tools/ctrl.js +255 -68
  31. package/dist/tools/os.js +198 -0
  32. package/dist/tools/prompts/control/en/errors.md +2 -2
  33. package/dist/tools/prompts/control/en/index.md +1 -1
  34. package/dist/tools/prompts/control/en/principles.md +21 -14
  35. package/dist/tools/prompts/control/en/scenarios.md +12 -4
  36. package/dist/tools/prompts/control/en/tools.md +45 -5
  37. package/dist/tools/prompts/control/zh/errors.md +2 -2
  38. package/dist/tools/prompts/control/zh/index.md +1 -1
  39. package/dist/tools/prompts/control/zh/principles.md +21 -14
  40. package/dist/tools/prompts/control/zh/scenarios.md +10 -4
  41. package/dist/tools/prompts/control/zh/tools.md +40 -5
  42. package/dist/tools/prompts/personal_memory/en/principles.md +1 -1
  43. package/dist/tools/prompts/personal_memory/zh/principles.md +1 -1
  44. package/dist/tools/prompts/team_memory/en/principles.md +1 -1
  45. package/dist/tools/prompts/team_memory/zh/principles.md +1 -1
  46. package/dist/tools/team_mgmt.js +5 -8
  47. package/dist/utils/task-package.d.ts +7 -0
  48. package/dist/utils/task-package.js +65 -28
  49. package/dist/utils/taskdoc.js +21 -17
  50. package/package.json +4 -4
  51. package/webapp/dist/assets/{_basePickBy-Dnh413xT.js → _basePickBy-B7M9Q0Fa.js} +3 -3
  52. package/webapp/dist/assets/_basePickBy-B7M9Q0Fa.js.map +1 -0
  53. package/webapp/dist/assets/{_baseUniq-DWzYqpN_.js → _baseUniq-DAeYoL6j.js} +2 -2
  54. package/webapp/dist/assets/_baseUniq-DAeYoL6j.js.map +1 -0
  55. package/webapp/dist/assets/{arc-vfBkNCOx.js → arc-Bh4nDbNR.js} +2 -2
  56. package/webapp/dist/assets/arc-Bh4nDbNR.js.map +1 -0
  57. package/webapp/dist/assets/{architectureDiagram-VXUJARFQ-DiUEBXOa.js → architectureDiagram-2XIMDMQ5-CxqmdsIm.js} +26 -8
  58. package/webapp/dist/assets/architectureDiagram-2XIMDMQ5-CxqmdsIm.js.map +1 -0
  59. package/webapp/dist/assets/{blockDiagram-VD42YOAC-BqK1KM2m.js → blockDiagram-WCTKOSBZ-CxIWLtpt.js} +187 -170
  60. package/webapp/dist/assets/blockDiagram-WCTKOSBZ-CxIWLtpt.js.map +1 -0
  61. package/webapp/dist/assets/{c4Diagram-YG6GDRKO-ClHNu1Uo.js → c4Diagram-IC4MRINW-1qErOIgG.js} +4 -4
  62. package/webapp/dist/assets/c4Diagram-IC4MRINW-1qErOIgG.js.map +1 -0
  63. package/webapp/dist/assets/{channel-BbWLVc8W.js → channel-DkgZHNUe.js} +2 -2
  64. package/webapp/dist/assets/channel-DkgZHNUe.js.map +1 -0
  65. package/webapp/dist/assets/{chunk-4BX2VUAB-CItdSmZH.js → chunk-4BX2VUAB-BmdMbU9v.js} +2 -2
  66. package/webapp/dist/assets/chunk-4BX2VUAB-BmdMbU9v.js.map +1 -0
  67. package/webapp/dist/assets/{chunk-55IACEB6-DSCX9WCf.js → chunk-55IACEB6-D6LDTDBy.js} +2 -2
  68. package/webapp/dist/assets/chunk-55IACEB6-D6LDTDBy.js.map +1 -0
  69. package/webapp/dist/assets/{chunk-FMBD7UC4-BJ1vT2se.js → chunk-FMBD7UC4-C-BdCe4C.js} +2 -2
  70. package/webapp/dist/assets/chunk-FMBD7UC4-C-BdCe4C.js.map +1 -0
  71. package/webapp/dist/assets/{chunk-TZMSLE5B-D2g6Tj7Z.js → chunk-JSJVCQXG-WA_BLIm9.js} +14 -6
  72. package/webapp/dist/assets/chunk-JSJVCQXG-WA_BLIm9.js.map +1 -0
  73. package/webapp/dist/assets/{chunk-QN33PNHL-CGyezTSD.js → chunk-KX2RTZJC-CA7sDJO5.js} +2 -2
  74. package/webapp/dist/assets/chunk-KX2RTZJC-CA7sDJO5.js.map +1 -0
  75. package/webapp/dist/assets/{chunk-DI55MBZ5-CRMf6XZu.js → chunk-NQ4KR5QH-wlvxalE3.js} +9 -7
  76. package/webapp/dist/assets/chunk-NQ4KR5QH-wlvxalE3.js.map +1 -0
  77. package/webapp/dist/assets/{chunk-QZHKN3VN-9xs15j8C.js → chunk-QZHKN3VN-Bo1VMcph.js} +2 -2
  78. package/webapp/dist/assets/chunk-QZHKN3VN-Bo1VMcph.js.map +1 -0
  79. package/webapp/dist/assets/{chunk-B4BG7PRW-5CRXFeD9.js → chunk-WL4C6EOR-B-Pk44be.js} +171 -121
  80. package/webapp/dist/assets/chunk-WL4C6EOR-B-Pk44be.js.map +1 -0
  81. package/webapp/dist/assets/{classDiagram-2ON5EDUG-BQFGGJNm.js → classDiagram-VBA2DB6C-BqKuyb49.js} +7 -6
  82. package/webapp/dist/assets/classDiagram-VBA2DB6C-BqKuyb49.js.map +1 -0
  83. package/webapp/dist/assets/{classDiagram-v2-WZHVMYZB-BQFGGJNm.js → classDiagram-v2-RAHNMMFH-BqKuyb49.js} +7 -6
  84. package/webapp/dist/assets/classDiagram-v2-RAHNMMFH-BqKuyb49.js.map +1 -0
  85. package/webapp/dist/assets/{clone-DOfPd4cz.js → clone-BX5z8WVZ.js} +2 -2
  86. package/webapp/dist/assets/clone-BX5z8WVZ.js.map +1 -0
  87. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-BYN-vqm8.js → cose-bilkent-S5V4N54A-B-s11SgN.js} +2 -2
  88. package/webapp/dist/assets/cose-bilkent-S5V4N54A-B-s11SgN.js.map +1 -0
  89. package/webapp/dist/assets/cytoscape.esm-Bm8DJGmZ.js.map +1 -1
  90. package/webapp/dist/assets/{dagre-6UL2VRFP-ClEaFABE.js → dagre-KLK3FWXG-DmQFV2qK.js} +7 -7
  91. package/webapp/dist/assets/dagre-KLK3FWXG-DmQFV2qK.js.map +1 -0
  92. package/webapp/dist/assets/defaultLocale-B2RvLBDe.js.map +1 -1
  93. package/webapp/dist/assets/{diagram-PSM6KHXK-CM4hLE_0.js → diagram-E7M64L7V-QRaBfST8.js} +10 -10
  94. package/webapp/dist/assets/diagram-E7M64L7V-QRaBfST8.js.map +1 -0
  95. package/webapp/dist/assets/{diagram-QEK2KX5R-BZjGFX-2.js → diagram-IFDJBPK2-lrWn1Obo.js} +9 -8
  96. package/webapp/dist/assets/diagram-IFDJBPK2-lrWn1Obo.js.map +1 -0
  97. package/webapp/dist/assets/{diagram-S2PKOQOG-Bvw01OOG.js → diagram-P4PSJMXO-sTU7Hh-Y.js} +8 -8
  98. package/webapp/dist/assets/diagram-P4PSJMXO-sTU7Hh-Y.js.map +1 -0
  99. package/webapp/dist/assets/{erDiagram-Q2GNP2WA-ctHu5zQL.js → erDiagram-INFDFZHY-Cx6jc9Wq.js} +96 -75
  100. package/webapp/dist/assets/erDiagram-INFDFZHY-Cx6jc9Wq.js.map +1 -0
  101. package/webapp/dist/assets/{flowDiagram-NV44I4VS-m7ofIhri.js → flowDiagram-PKNHOUZH-DfGI49Dz.js} +98 -81
  102. package/webapp/dist/assets/flowDiagram-PKNHOUZH-DfGI49Dz.js.map +1 -0
  103. package/webapp/dist/assets/{ganttDiagram-JELNMOA3-D9wS5Veb.js → ganttDiagram-A5KZAMGK-nrcHWWaM.js} +28 -3
  104. package/webapp/dist/assets/ganttDiagram-A5KZAMGK-nrcHWWaM.js.map +1 -0
  105. package/webapp/dist/assets/{gitGraphDiagram-V2S2FVAM-B86qqJx7.js → gitGraphDiagram-K3NZZRJ6-D8ivAqd6.js} +38 -46
  106. package/webapp/dist/assets/gitGraphDiagram-K3NZZRJ6-D8ivAqd6.js.map +1 -0
  107. package/webapp/dist/assets/graph-R5G-y8tB.js +782 -0
  108. package/webapp/dist/assets/graph-R5G-y8tB.js.map +1 -0
  109. package/webapp/dist/assets/{index-tinPEZoH.js → index--fy89xGh.js} +1034 -1059
  110. package/webapp/dist/assets/{index-tinPEZoH.js.map → index--fy89xGh.js.map} +1 -1
  111. package/webapp/dist/assets/{index-BGdI3lWA.css → index-DZFkLLVz.css} +1 -1
  112. package/webapp/dist/assets/{infoDiagram-HS3SLOUP-DwRPUctP.js → infoDiagram-LFFYTUFH-PIoZHr7s.js} +7 -7
  113. package/webapp/dist/assets/infoDiagram-LFFYTUFH-PIoZHr7s.js.map +1 -0
  114. package/webapp/dist/assets/init-ZxktEp_H.js.map +1 -1
  115. package/webapp/dist/assets/ishikawaDiagram-PHBUUO56-oCM-LYk1.js +966 -0
  116. package/webapp/dist/assets/ishikawaDiagram-PHBUUO56-oCM-LYk1.js.map +1 -0
  117. package/webapp/dist/assets/{journeyDiagram-XKPGCS4Q-B91ZO-ec.js → journeyDiagram-4ABVD52K-C2qidjQ5.js} +5 -5
  118. package/webapp/dist/assets/journeyDiagram-4ABVD52K-C2qidjQ5.js.map +1 -0
  119. package/webapp/dist/assets/{kanban-definition-3W4ZIXB7-CoogrZ07.js → kanban-definition-K7BYSVSG-Du0TC8WS.js} +5 -3
  120. package/webapp/dist/assets/kanban-definition-K7BYSVSG-Du0TC8WS.js.map +1 -0
  121. package/webapp/dist/assets/{layout-BrzQmqFJ.js → layout-VmEo1OEB.js} +5 -5
  122. package/webapp/dist/assets/layout-VmEo1OEB.js.map +1 -0
  123. package/webapp/dist/assets/{linear-C6H7K9Zy.js → linear-B662YHAc.js} +2 -2
  124. package/webapp/dist/assets/linear-B662YHAc.js.map +1 -0
  125. package/webapp/dist/assets/{mindmap-definition-VGOIOE7T-UDHZQkNZ.js → mindmap-definition-YRQLILUH-D7arZj95.js} +7 -5
  126. package/webapp/dist/assets/mindmap-definition-YRQLILUH-D7arZj95.js.map +1 -0
  127. package/webapp/dist/assets/ordinal-CxptdPJm.js.map +1 -1
  128. package/webapp/dist/assets/{pieDiagram-ADFJNKIX-M81uyQ1J.js → pieDiagram-SKSYHLDU-DvjPP4PA.js} +8 -8
  129. package/webapp/dist/assets/pieDiagram-SKSYHLDU-DvjPP4PA.js.map +1 -0
  130. package/webapp/dist/assets/{quadrantDiagram-AYHSOK5B-ClzIh9Gb.js → quadrantDiagram-337W2JSQ-B_JUGMj_.js} +3 -3
  131. package/webapp/dist/assets/quadrantDiagram-337W2JSQ-B_JUGMj_.js.map +1 -0
  132. package/webapp/dist/assets/{requirementDiagram-UZGBJVZJ-DLK3A-pn.js → requirementDiagram-Z7DCOOCP-DF0mpvE3.js} +16 -6
  133. package/webapp/dist/assets/requirementDiagram-Z7DCOOCP-DF0mpvE3.js.map +1 -0
  134. package/webapp/dist/assets/{sankeyDiagram-TZEHDZUN-CYqju8I1.js → sankeyDiagram-WA2Y5GQK-CoXlxv00.js} +2 -2
  135. package/webapp/dist/assets/sankeyDiagram-WA2Y5GQK-CoXlxv00.js.map +1 -0
  136. package/webapp/dist/assets/{sequenceDiagram-WL72ISMW-2guv6eOd.js → sequenceDiagram-2WXFIKYE-DYqT5Pg7.js} +601 -201
  137. package/webapp/dist/assets/sequenceDiagram-2WXFIKYE-DYqT5Pg7.js.map +1 -0
  138. package/webapp/dist/assets/{stateDiagram-FKZM4ZOC-iujqSp0X.js → stateDiagram-RAJIS63D-D9b1mN8-.js} +9 -9
  139. package/webapp/dist/assets/stateDiagram-RAJIS63D-D9b1mN8-.js.map +1 -0
  140. package/webapp/dist/assets/{stateDiagram-v2-4FDKWEC3-BxzY81ky.js → stateDiagram-v2-FVOUBMTO-DNzgudL_.js} +5 -5
  141. package/webapp/dist/assets/stateDiagram-v2-FVOUBMTO-DNzgudL_.js.map +1 -0
  142. package/webapp/dist/assets/{timeline-definition-IT6M3QCI-DjCFSC8d.js → timeline-definition-YZTLITO2-CkyKUY7A.js} +3 -3
  143. package/webapp/dist/assets/timeline-definition-YZTLITO2-CkyKUY7A.js.map +1 -0
  144. package/webapp/dist/assets/{treemap-GDKQZRPO-iaBzDWCP.js → treemap-KZPCXAKY-CZd09kF-.js} +37 -24
  145. package/webapp/dist/assets/treemap-KZPCXAKY-CZd09kF-.js.map +1 -0
  146. package/webapp/dist/assets/vennDiagram-LZ73GAT5-BxVF5Olo.js +2487 -0
  147. package/webapp/dist/assets/vennDiagram-LZ73GAT5-BxVF5Olo.js.map +1 -0
  148. package/webapp/dist/assets/{xychartDiagram-PRI3JC2R-R6Jl1c89.js → xychartDiagram-JWTSCODW-BRwRloPc.js} +4 -4
  149. package/webapp/dist/assets/xychartDiagram-JWTSCODW-BRwRloPc.js.map +1 -0
  150. package/webapp/dist/index.html +2 -2
  151. package/webapp/dist/assets/_basePickBy-Dnh413xT.js.map +0 -1
  152. package/webapp/dist/assets/_baseUniq-DWzYqpN_.js.map +0 -1
  153. package/webapp/dist/assets/arc-vfBkNCOx.js.map +0 -1
  154. package/webapp/dist/assets/architectureDiagram-VXUJARFQ-DiUEBXOa.js.map +0 -1
  155. package/webapp/dist/assets/blockDiagram-VD42YOAC-BqK1KM2m.js.map +0 -1
  156. package/webapp/dist/assets/c4Diagram-YG6GDRKO-ClHNu1Uo.js.map +0 -1
  157. package/webapp/dist/assets/channel-BbWLVc8W.js.map +0 -1
  158. package/webapp/dist/assets/chunk-4BX2VUAB-CItdSmZH.js.map +0 -1
  159. package/webapp/dist/assets/chunk-55IACEB6-DSCX9WCf.js.map +0 -1
  160. package/webapp/dist/assets/chunk-B4BG7PRW-5CRXFeD9.js.map +0 -1
  161. package/webapp/dist/assets/chunk-DI55MBZ5-CRMf6XZu.js.map +0 -1
  162. package/webapp/dist/assets/chunk-FMBD7UC4-BJ1vT2se.js.map +0 -1
  163. package/webapp/dist/assets/chunk-QN33PNHL-CGyezTSD.js.map +0 -1
  164. package/webapp/dist/assets/chunk-QZHKN3VN-9xs15j8C.js.map +0 -1
  165. package/webapp/dist/assets/chunk-TZMSLE5B-D2g6Tj7Z.js.map +0 -1
  166. package/webapp/dist/assets/classDiagram-2ON5EDUG-BQFGGJNm.js.map +0 -1
  167. package/webapp/dist/assets/classDiagram-v2-WZHVMYZB-BQFGGJNm.js.map +0 -1
  168. package/webapp/dist/assets/clone-DOfPd4cz.js.map +0 -1
  169. package/webapp/dist/assets/cose-bilkent-S5V4N54A-BYN-vqm8.js.map +0 -1
  170. package/webapp/dist/assets/dagre-6UL2VRFP-ClEaFABE.js.map +0 -1
  171. package/webapp/dist/assets/diagram-PSM6KHXK-CM4hLE_0.js.map +0 -1
  172. package/webapp/dist/assets/diagram-QEK2KX5R-BZjGFX-2.js.map +0 -1
  173. package/webapp/dist/assets/diagram-S2PKOQOG-Bvw01OOG.js.map +0 -1
  174. package/webapp/dist/assets/erDiagram-Q2GNP2WA-ctHu5zQL.js.map +0 -1
  175. package/webapp/dist/assets/flowDiagram-NV44I4VS-m7ofIhri.js.map +0 -1
  176. package/webapp/dist/assets/ganttDiagram-JELNMOA3-D9wS5Veb.js.map +0 -1
  177. package/webapp/dist/assets/gitGraphDiagram-V2S2FVAM-B86qqJx7.js.map +0 -1
  178. package/webapp/dist/assets/graph-u844GGQC.js +0 -425
  179. package/webapp/dist/assets/graph-u844GGQC.js.map +0 -1
  180. package/webapp/dist/assets/infoDiagram-HS3SLOUP-DwRPUctP.js.map +0 -1
  181. package/webapp/dist/assets/journeyDiagram-XKPGCS4Q-B91ZO-ec.js.map +0 -1
  182. package/webapp/dist/assets/kanban-definition-3W4ZIXB7-CoogrZ07.js.map +0 -1
  183. package/webapp/dist/assets/layout-BrzQmqFJ.js.map +0 -1
  184. package/webapp/dist/assets/linear-C6H7K9Zy.js.map +0 -1
  185. package/webapp/dist/assets/mindmap-definition-VGOIOE7T-UDHZQkNZ.js.map +0 -1
  186. package/webapp/dist/assets/pieDiagram-ADFJNKIX-M81uyQ1J.js.map +0 -1
  187. package/webapp/dist/assets/quadrantDiagram-AYHSOK5B-ClzIh9Gb.js.map +0 -1
  188. package/webapp/dist/assets/requirementDiagram-UZGBJVZJ-DLK3A-pn.js.map +0 -1
  189. package/webapp/dist/assets/sankeyDiagram-TZEHDZUN-CYqju8I1.js.map +0 -1
  190. package/webapp/dist/assets/sequenceDiagram-WL72ISMW-2guv6eOd.js.map +0 -1
  191. package/webapp/dist/assets/stateDiagram-FKZM4ZOC-iujqSp0X.js.map +0 -1
  192. package/webapp/dist/assets/stateDiagram-v2-4FDKWEC3-BxzY81ky.js.map +0 -1
  193. package/webapp/dist/assets/timeline-definition-IT6M3QCI-DjCFSC8d.js.map +0 -1
  194. package/webapp/dist/assets/treemap-GDKQZRPO-iaBzDWCP.js.map +0 -1
  195. package/webapp/dist/assets/xychartDiagram-PRI3JC2R-R6Jl1c89.js.map +0 -1
@@ -0,0 +1,351 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cancelIdleReminderWake = cancelIdleReminderWake;
4
+ exports.maybeStartIdleReminderWake = maybeStartIdleReminderWake;
5
+ const id_1 = require("@longrun-ai/kernel/utils/id");
6
+ const time_1 = require("@longrun-ai/kernel/utils/time");
7
+ const dialog_display_state_1 = require("../../dialog-display-state");
8
+ const log_1 = require("../../log");
9
+ const persistence_1 = require("../../persistence");
10
+ const driver_messages_1 = require("../../runtime/driver-messages");
11
+ const work_language_1 = require("../../runtime/work-language");
12
+ const shared_reminders_1 = require("../../shared-reminders");
13
+ const tool_1 = require("../../tool");
14
+ const IDLE_WAKE_AGGREGATION_WINDOW_MS = 500;
15
+ const idleReminderWakeTasks = new Map();
16
+ function normalizeWakeEvents(result) {
17
+ if (result === null)
18
+ return [];
19
+ if (Array.isArray(result)) {
20
+ return result.map(assertWakeEventShape);
21
+ }
22
+ const event = result;
23
+ return [assertWakeEventShape(event)];
24
+ }
25
+ function assertWakeEventShape(event) {
26
+ if (event.eventId.trim() === '') {
27
+ throw new Error('idle reminder wake invariant violation: empty eventId');
28
+ }
29
+ if (event.reminderId.trim() === '') {
30
+ throw new Error(`idle reminder wake invariant violation: empty reminderId (${event.eventId})`);
31
+ }
32
+ if (event.content.trim() === '') {
33
+ throw new Error(`idle reminder wake invariant violation: empty content (${event.eventId})`);
34
+ }
35
+ if (!event.content.startsWith('【系统提示】') && !event.content.startsWith('[System notice]')) {
36
+ throw new Error(`idle reminder wake invariant violation: wake event content must start with a system notice prefix (${event.eventId})`);
37
+ }
38
+ return event;
39
+ }
40
+ function sleep(ms, signal) {
41
+ return new Promise((resolve) => {
42
+ if (signal?.aborted) {
43
+ resolve();
44
+ return;
45
+ }
46
+ let timeout;
47
+ let settled = false;
48
+ const finish = () => {
49
+ if (settled)
50
+ return;
51
+ settled = true;
52
+ clearTimeout(timeout);
53
+ signal?.removeEventListener('abort', onAbort);
54
+ resolve();
55
+ };
56
+ const onAbort = () => {
57
+ finish();
58
+ };
59
+ timeout = setTimeout(finish, ms);
60
+ signal?.addEventListener('abort', onAbort, { once: true });
61
+ });
62
+ }
63
+ function isCurrentTask(dialogId, task) {
64
+ return idleReminderWakeTasks.get(dialogId.key()) === task;
65
+ }
66
+ function isAbortLikeError(error) {
67
+ return error instanceof Error && (error.name === 'AbortError' || error.message === 'aborted');
68
+ }
69
+ function stripSystemNoticePrefix(content, prefix) {
70
+ const normalized = content.trim();
71
+ if (normalized.startsWith(prefix)) {
72
+ return normalized.slice(prefix.length).trim();
73
+ }
74
+ return normalized;
75
+ }
76
+ function buildAggregatedWakePromptContent(events) {
77
+ if (events.length === 1) {
78
+ const only = events[0];
79
+ if (!only) {
80
+ throw new Error('idle reminder wake invariant violation: missing first event');
81
+ }
82
+ return only.content;
83
+ }
84
+ const language = (0, work_language_1.getWorkLanguage)();
85
+ const prefix = (0, driver_messages_1.formatSystemNoticePrefix)(language);
86
+ const body = events
87
+ .map((event, index) => {
88
+ const eventText = stripSystemNoticePrefix(event.content, prefix);
89
+ return `${String(index + 1)}. ${eventText}`;
90
+ })
91
+ .join('\n\n');
92
+ return language === 'zh'
93
+ ? `${prefix}
94
+ 以下是对话空闲期间发生的 runtime 环境事件。这些事件不是新的用户指令。
95
+
96
+ ${body}
97
+
98
+ 请结合当前任务上下文继续推进;若这些事件不影响当前工作,不要发送占位式确认。`
99
+ : `${prefix}
100
+ The following runtime environment events happened while the dialog was idle. These events are not new user instructions.
101
+
102
+ ${body}
103
+
104
+ Continue according to the current task context; if these events do not affect the work, do not send a placeholder acknowledgement.`;
105
+ }
106
+ async function applyWakeEventUpdates(dialog, events) {
107
+ const eventsWithUpdates = events.filter((event) => event.updatedContent !== undefined || event.updatedMeta !== undefined);
108
+ if (eventsWithUpdates.length === 0)
109
+ return;
110
+ const byReminderId = new Map();
111
+ for (const event of eventsWithUpdates) {
112
+ const existing = byReminderId.get(event.reminderId);
113
+ if (existing && existing.eventId !== event.eventId) {
114
+ throw new Error(`idle reminder wake invariant violation: multiple wake updates for reminder ${event.reminderId}`);
115
+ }
116
+ byReminderId.set(event.reminderId, event);
117
+ }
118
+ const targets = await dialog.listVisibleReminderTargets();
119
+ const appliedReminderIds = new Set();
120
+ for (const target of targets) {
121
+ const event = byReminderId.get(target.reminder.id);
122
+ if (!event)
123
+ continue;
124
+ appliedReminderIds.add(event.reminderId);
125
+ const nextContent = event.updatedContent ?? target.reminder.content;
126
+ const nextMeta = event.updatedMeta !== undefined ? event.updatedMeta : target.reminder.meta;
127
+ if (target.source === 'dialog') {
128
+ dialog.updateReminder(target.index, nextContent, nextMeta, {
129
+ renderMode: target.reminder.renderMode,
130
+ });
131
+ continue;
132
+ }
133
+ await (0, shared_reminders_1.mutateAgentSharedReminders)(target.agentId, (reminders) => {
134
+ const index = reminders.findIndex((reminder) => reminder.id === target.reminder.id);
135
+ if (index < 0) {
136
+ throw new Error(`idle reminder wake invariant violation: shared reminder ${target.reminder.id} disappeared before update`);
137
+ }
138
+ const previous = reminders[index];
139
+ if (!previous) {
140
+ throw new Error(`idle reminder wake invariant violation: shared reminder ${target.reminder.id} missing at resolved index`);
141
+ }
142
+ reminders[index] = (0, tool_1.materializeReminder)({
143
+ id: previous.id,
144
+ content: nextContent,
145
+ owner: previous.owner,
146
+ meta: nextMeta,
147
+ echoback: previous.echoback,
148
+ scope: previous.scope,
149
+ createdAt: previous.createdAt,
150
+ priority: previous.priority,
151
+ renderMode: previous.renderMode,
152
+ });
153
+ });
154
+ dialog.touchReminders();
155
+ }
156
+ for (const reminderId of byReminderId.keys()) {
157
+ if (appliedReminderIds.has(reminderId))
158
+ continue;
159
+ throw new Error(`idle reminder wake invariant violation: reminder update target disappeared before apply (${reminderId})`);
160
+ }
161
+ await dialog.processReminderUpdates();
162
+ }
163
+ async function loadFreshIdleWakeEligibility(dialog) {
164
+ if ((0, dialog_display_state_1.hasActiveRun)(dialog.id))
165
+ return false;
166
+ const latest = await persistence_1.DialogPersistence.loadDialogLatest(dialog.id, 'running');
167
+ if (!latest)
168
+ return false;
169
+ if (latest.displayState?.kind !== 'idle_waiting_user')
170
+ return false;
171
+ if (latest.executionMarker?.kind === 'dead')
172
+ return false;
173
+ if (latest.executionMarker?.kind === 'interrupted')
174
+ return false;
175
+ const q4h = await persistence_1.DialogPersistence.loadQuestions4HumanState(dialog.id, dialog.status);
176
+ if (q4h.length > 0)
177
+ return false;
178
+ const pendingSideDialogs = await persistence_1.DialogPersistence.loadPendingSideDialogs(dialog.id, dialog.status);
179
+ return pendingSideDialogs.length === 0;
180
+ }
181
+ function collectWakeCapableReminders(reminders) {
182
+ const result = [];
183
+ for (const reminder of reminders) {
184
+ if (!reminder.owner?.waitForReminderWakeEvent)
185
+ continue;
186
+ result.push({ ownerName: reminder.owner.name, reminder });
187
+ }
188
+ return result;
189
+ }
190
+ function dedupeAndSortWakeEvents(events) {
191
+ const byId = new Map();
192
+ for (const event of events) {
193
+ const existing = byId.get(event.eventId);
194
+ if (existing) {
195
+ if (existing.content !== event.content ||
196
+ existing.reminderId !== event.reminderId ||
197
+ existing.updatedContent !== event.updatedContent ||
198
+ JSON.stringify(existing.updatedMeta ?? null) !== JSON.stringify(event.updatedMeta ?? null)) {
199
+ throw new Error(`idle reminder wake invariant violation: conflicting duplicate eventId ${event.eventId}`);
200
+ }
201
+ continue;
202
+ }
203
+ byId.set(event.eventId, event);
204
+ }
205
+ return [...byId.values()].sort((left, right) => left.eventId.localeCompare(right.eventId));
206
+ }
207
+ async function runIdleReminderWakeTask(dialog, callbacks, task) {
208
+ if (!(await loadFreshIdleWakeEligibility(dialog)))
209
+ return;
210
+ const targets = collectWakeCapableReminders(await dialog.listVisibleReminders());
211
+ if (targets.length === 0)
212
+ return;
213
+ const waitController = new AbortController();
214
+ task.controller.signal.addEventListener('abort', () => {
215
+ waitController.abort();
216
+ }, { once: true });
217
+ if (task.controller.signal.aborted) {
218
+ waitController.abort();
219
+ }
220
+ const collected = [];
221
+ let pending = targets.length;
222
+ let resolveFirstEvent;
223
+ const firstEvent = new Promise((resolve) => {
224
+ resolveFirstEvent = resolve;
225
+ });
226
+ const settleOne = () => {
227
+ pending -= 1;
228
+ if (pending === 0 && collected.length === 0) {
229
+ resolveFirstEvent?.();
230
+ }
231
+ };
232
+ for (const target of targets) {
233
+ const owner = target.reminder.owner;
234
+ if (!owner?.waitForReminderWakeEvent) {
235
+ settleOne();
236
+ continue;
237
+ }
238
+ void owner
239
+ .waitForReminderWakeEvent(dialog, [target.reminder], waitController.signal)
240
+ .then((result) => {
241
+ const events = normalizeWakeEvents(result);
242
+ if (events.length > 0) {
243
+ collected.push(...events);
244
+ resolveFirstEvent?.();
245
+ }
246
+ })
247
+ .catch((error) => {
248
+ if (!waitController.signal.aborted && !isAbortLikeError(error)) {
249
+ log_1.log.warn('idle reminder wake owner wait failed', error, {
250
+ dialogId: dialog.id.valueOf(),
251
+ rootId: dialog.id.rootId,
252
+ selfId: dialog.id.selfId,
253
+ ownerName: target.ownerName,
254
+ reminderId: target.reminder.id,
255
+ });
256
+ }
257
+ })
258
+ .finally(() => {
259
+ settleOne();
260
+ });
261
+ }
262
+ await firstEvent;
263
+ if (task.controller.signal.aborted || collected.length === 0)
264
+ return;
265
+ await sleep(IDLE_WAKE_AGGREGATION_WINDOW_MS, task.controller.signal);
266
+ if (task.controller.signal.aborted || !isCurrentTask(dialog.id, task))
267
+ return;
268
+ waitController.abort();
269
+ const events = dedupeAndSortWakeEvents(collected);
270
+ if (events.length === 0)
271
+ return;
272
+ await applyWakeEventUpdates(dialog, events);
273
+ if (task.controller.signal.aborted || !isCurrentTask(dialog.id, task))
274
+ return;
275
+ if (!(await loadFreshIdleWakeEligibility(dialog))) {
276
+ log_1.log.debug('idle reminder wake dropped because dialog is no longer eligible', undefined, {
277
+ dialogId: dialog.id.valueOf(),
278
+ rootId: dialog.id.rootId,
279
+ selfId: dialog.id.selfId,
280
+ eventIds: events.map((event) => event.eventId),
281
+ });
282
+ return;
283
+ }
284
+ const prompt = {
285
+ content: buildAggregatedWakePromptContent(events),
286
+ msgId: (0, id_1.generateShortId)(),
287
+ grammar: 'markdown',
288
+ origin: 'runtime',
289
+ };
290
+ await callbacks.driveDialog(dialog, {
291
+ humanPrompt: prompt,
292
+ waitInQue: true,
293
+ driveOptions: {
294
+ source: 'kernel_driver_idle_reminder_wake',
295
+ reason: 'idle_reminder_wake',
296
+ },
297
+ });
298
+ }
299
+ function cancelIdleReminderWake(dialogId, reason) {
300
+ const task = idleReminderWakeTasks.get(dialogId.key());
301
+ if (!task)
302
+ return;
303
+ idleReminderWakeTasks.delete(dialogId.key());
304
+ task.controller.abort();
305
+ log_1.log.debug('idle reminder wake task canceled', undefined, {
306
+ dialogId: dialogId.valueOf(),
307
+ rootId: dialogId.rootId,
308
+ selfId: dialogId.selfId,
309
+ reason,
310
+ startedAt: task.startedAt,
311
+ });
312
+ }
313
+ function maybeStartIdleReminderWake(dialog, callbacks, reason) {
314
+ cancelIdleReminderWake(dialog.id, `replace:${reason}`);
315
+ const task = {
316
+ dialogKey: dialog.id.key(),
317
+ controller: new AbortController(),
318
+ startedAt: (0, time_1.formatUnifiedTimestamp)(new Date()),
319
+ };
320
+ idleReminderWakeTasks.set(dialog.id.key(), task);
321
+ log_1.log.debug('idle reminder wake task started', undefined, {
322
+ dialogId: dialog.id.valueOf(),
323
+ rootId: dialog.id.rootId,
324
+ selfId: dialog.id.selfId,
325
+ reason,
326
+ startedAt: task.startedAt,
327
+ });
328
+ void (async () => {
329
+ try {
330
+ if (!(await loadFreshIdleWakeEligibility(dialog)))
331
+ return;
332
+ if (task.controller.signal.aborted || !isCurrentTask(dialog.id, task))
333
+ return;
334
+ await runIdleReminderWakeTask(dialog, callbacks, task);
335
+ }
336
+ catch (error) {
337
+ if (!task.controller.signal.aborted && !isAbortLikeError(error)) {
338
+ log_1.log.warn('idle reminder wake task failed', error, {
339
+ dialogId: dialog.id.valueOf(),
340
+ rootId: dialog.id.rootId,
341
+ selfId: dialog.id.selfId,
342
+ });
343
+ }
344
+ }
345
+ finally {
346
+ if (isCurrentTask(dialog.id, task)) {
347
+ idleReminderWakeTasks.delete(dialog.id.key());
348
+ }
349
+ }
350
+ })();
351
+ }
@@ -2,7 +2,7 @@ import type { DialogDisplayState, DialogInterruptionReason } from '@longrun-ai/k
2
2
  import type { DialogDiligencePrompt, DialogPrompt, DialogRunControlSpec, DialogRuntimeGuidePrompt, DialogRuntimePrompt, DialogRuntimeReplyPrompt, DialogRuntimeSideDialogPrompt, DialogUserPrompt } from '@longrun-ai/kernel/types/drive-intent';
3
3
  import type { Dialog, DialogID } from '../../dialog';
4
4
  export type KernelDriverRunControl = DialogRunControlSpec;
5
- export type KernelDriverDriveSource = 'unspecified' | 'ws_user_message' | 'ws_user_answer' | 'ws_diligence_push' | 'ws_resume_dialog' | 'ws_resume_all' | 'kernel_driver_backend_loop' | 'kernel_driver_follow_up' | 'kernel_driver_sideDialog_init' | 'kernel_driver_sideDialog_resume' | 'kernel_driver_fbr_sideDialog_round' | 'kernel_driver_type_a_askerDialog_call' | 'kernel_driver_supply_response_parent_revive';
5
+ export type KernelDriverDriveSource = 'unspecified' | 'ws_user_message' | 'ws_user_answer' | 'ws_diligence_push' | 'ws_resume_dialog' | 'ws_resume_all' | 'kernel_driver_backend_loop' | 'kernel_driver_follow_up' | 'kernel_driver_sideDialog_init' | 'kernel_driver_sideDialog_resume' | 'kernel_driver_fbr_sideDialog_round' | 'kernel_driver_type_a_askerDialog_call' | 'kernel_driver_supply_response_parent_revive' | 'kernel_driver_idle_reminder_wake';
6
6
  export type KernelDriverDriveOptions = Readonly<{
7
7
  suppressDiligencePush?: boolean;
8
8
  allowResumeFromInterrupted?: boolean;
@@ -218,8 +218,9 @@ async function loadAgentMinds(agentId, dialog, options) {
218
218
  ctrl_1.clearMindTool,
219
219
  ctrl_1.recallTaskdocTool,
220
220
  ];
221
- // change_mind is only available in main dialogs (not sideDialogs).
221
+ // Taskdoc mutation tools are only available in main dialogs (not sideDialogs).
222
222
  if (dialog === undefined || dialog.askerDialog === undefined) {
223
+ intrinsicFuncTools.push(ctrl_1.mindMoreTool);
223
224
  intrinsicFuncTools.push(ctrl_1.changeMindTool);
224
225
  }
225
226
  const agentTools = (() => {
@@ -54,7 +54,7 @@ function taskdocCanonicalCopy(language) {
54
54
  '**Taskdoc 封装与访问限制**',
55
55
  '',
56
56
  '- 任何 `.tsk/` 目录及其子路径(`**/*.tsk/**`)都是封装状态:禁止使用任何通用文件工具读取/写入/列目录(例如 `read_file` / `write_file` / `list_dir` 等)。',
57
- '- 更新 Taskdoc 只能使用函数工具 `change_mind`(按章节整段替换;顶层用 `selector`,额外章节用 `category + selector`)。',
57
+ '- 更新 Taskdoc 只能使用函数工具 `mind_more` / `change_mind`:少量新增用 `mind_more` 追加(默认 progress),需要删除陈旧项、重排或压缩时用 `change_mind` 整章替换。',
58
58
  '- 读取“不会自动注入上下文”的额外章节,只能使用函数工具 `recall_taskdoc({ category, selector })`。',
59
59
  '',
60
60
  '**Taskdoc 自动注入规则(系统提示)**',
@@ -70,7 +70,7 @@ function taskdocCanonicalCopy(language) {
70
70
  '**Taskdoc encapsulation & access restrictions**',
71
71
  '',
72
72
  '- Any `.tsk/` directory and its subpaths (`**/*.tsk/**`) are encapsulated state: general file tools MUST NOT read/write/list them (e.g. `read_file` / `write_file` / `list_dir`).',
73
- '- Taskdoc updates MUST go through the function tool `change_mind` (whole-section replace; use top-level `selector`, or `category + selector` for extra sections).',
73
+ '- Taskdoc updates MUST go through `mind_more` / `change_mind`: use `mind_more` for small append-only additions (defaults to progress), and use `change_mind` for full-section replacement when cleanup, reordering, or compression is needed.',
74
74
  '- To read extra sections that are NOT auto-injected, use the function tool `recall_taskdoc({ category, selector })`.',
75
75
  '',
76
76
  '**Taskdoc auto-injection rules (system prompt)**',
@@ -137,24 +137,40 @@ function buildShellPolicyPrompt(ctx) {
137
137
  function getMemoryPromptCopy(ctx) {
138
138
  const runtimeMarkers = (0, inter_dialog_format_1.getRuntimeTransferMarkers)(ctx.language);
139
139
  const contextHealthLineZh = ctx.contextHealthPromptMode === 'critical'
140
- ? '当前上下文处于系统告急处置态:立即停止继续大实现/大阅读。本程只做保信息、提醒项提炼与 `clear_mind`。'
140
+ ? ctx.isSideDialog
141
+ ? '当前上下文处于系统告急处置态:立即停止继续大实现/大阅读。你当前处于支线对话;本程不维护差遣牒,也不整理差遣牒更新提案,只维护足够详尽的接续包提醒项并 `clear_mind`。提醒项长度没有技术限制。'
142
+ : '当前上下文处于系统告急处置态:立即停止继续大实现/大阅读。本程只做保信息:先把当前对话历史中尚未落实到文档、且下一程需要知会的讨论细节落到差遣牒合适章节,再提炼接续包提醒项并 `clear_mind`。'
141
143
  : ctx.contextHealthPromptMode === 'caution'
142
- ? '当前上下文处于系统吃紧处置态:不要继续扩张上下文。本程优先提炼提醒项并尽快 `clear_mind`,不要继续大实现/大阅读。'
144
+ ? ctx.isSideDialog
145
+ ? '当前上下文处于系统吃紧处置态:不要继续扩张上下文。你当前处于支线对话;本程不维护差遣牒,也不整理差遣牒更新提案,优先维护足够详尽的接续包提醒项并尽快 `clear_mind`。提醒项长度没有技术限制。'
146
+ : '当前上下文处于系统吃紧处置态:不要继续扩张上下文。本程优先把尚未落实到文档、且下一程需要知会的讨论细节落到差遣牒合适章节,再提炼提醒项并尽快 `clear_mind`,不要继续大实现/大阅读。'
143
147
  : '当前没有生效中的上下文健康处置指令,按正常工作流推进。';
144
148
  const taskdocLogLineZh = ctx.contextHealthPromptMode === 'critical'
145
- ? '不要把长日志/大段 tool output 直接塞进差遣牒;差遣牒只写结论+下一步;提醒项也只留可扫读摘录。当前是告急处置态:本程允许先保留多条粗略提醒项求稳,但不要在当前程提前做“新一程清醒复核”。系统真正开启新一程后,第一步再复核整理:删除冗余、纠正偏激/失真思路,再收敛成高质量提醒项。'
149
+ ? ctx.isSideDialog
150
+ ? '当前是告急处置态:支线对话不要维护差遣牒,也不要整理差遣牒更新提案;把当前对话历史中下一程需要知道的讨论细节、下一步、关键定位、运行/验证信息、临时路径/ID/样例输入和恢复依据写入接续包提醒项。提醒项长度没有技术限制,宁可完整一些;允许多条粗略提醒项求稳,但不要在当前程提前做“新一程清醒复核”。系统真正开启新一程后,第一步再复核整理:删除冗余、纠正偏激/失真思路,再收敛成高质量提醒项。'
151
+ : '不要把长日志/大段 tool output 直接塞进差遣牒;差遣牒只写结论+下一步。当前是告急处置态:先检查当前对话历史里尚未落文档的讨论细节;能作为全队共享状态/决策/约束/目标的,主线直接用 `mind_more`/`change_mind` 写入差遣牒合适章节。接续包提醒项只留差遣牒仍未覆盖、但恢复工作容易丢的细节;本程允许先保留多条粗略提醒项求稳,但不要在当前程提前做“新一程清醒复核”。系统真正开启新一程后,第一步再复核整理:删除冗余、纠正偏激/失真思路,再收敛成高质量提醒项。'
146
152
  : ctx.contextHealthPromptMode === 'caution'
147
- ? '不要把长日志/大段 tool output 直接塞进差遣牒;差遣牒只写结论+下一步;提醒项也只留可扫读摘录。当前是吃紧处置态:本程优先压缩/提炼提醒项并尽快 `clear_mind`;若一时来不及,可先保留多条粗略提醒项过桥,但不要在当前程提前做“新一程清醒复核”。系统真正开启新一程后,第一步再复核整理:删除冗余、纠正偏激/失真思路,再收敛成高质量提醒项。'
153
+ ? ctx.isSideDialog
154
+ ? '当前是吃紧处置态:支线对话不要维护差遣牒,也不要整理差遣牒更新提案;把当前对话历史中下一程需要知道的讨论细节、下一步、关键定位、运行/验证信息、临时路径/ID/样例输入和恢复依据写入接续包提醒项。提醒项长度没有技术限制,宁可完整一些;若一时来不及,可先保留多条粗略提醒项过桥,但不要在当前程提前做“新一程清醒复核”。系统真正开启新一程后,第一步再复核整理:删除冗余、纠正偏激/失真思路,再收敛成高质量提醒项。'
155
+ : '不要把长日志/大段 tool output 直接塞进差遣牒;差遣牒只写结论+下一步。当前是吃紧处置态:先检查当前对话历史里尚未落文档的讨论细节;能作为全队共享状态/决策/约束/目标的,主线直接用 `mind_more`/`change_mind` 写入差遣牒合适章节。接续包提醒项只留差遣牒仍未覆盖、但恢复工作容易丢的细节;若一时来不及,可先保留多条粗略提醒项过桥,但不要在当前程提前做“新一程清醒复核”。系统真正开启新一程后,第一步再复核整理:删除冗余、纠正偏激/失真思路,再收敛成高质量提醒项。'
148
156
  : '不要把长日志/大段 tool output 直接塞进差遣牒;差遣牒只写结论+下一步;提醒项也只留可扫读摘录。接续包提醒项默认应保持结构化、便于快速恢复。';
149
157
  const contextHealthLineEn = ctx.contextHealthPromptMode === 'critical'
150
- ? 'Current context is under system critical remediation: stop large implementations/reads immediately. In this course, do only preserve-info work, reminder distillation, and `clear_mind`.'
158
+ ? ctx.isSideDialog
159
+ ? 'Current context is under system critical remediation: stop large implementations/reads immediately. You are in a Side Dialog; in this course, do not maintain Taskdoc and do not draft Taskdoc update proposals. Only maintain sufficiently detailed continuation-package reminders and `clear_mind`. Reminder length has no technical limit.'
160
+ : 'Current context is under system critical remediation: stop large implementations/reads immediately. In this course, only preserve information: first record current-dialog discussion details that are not yet documented but the next course needs to know into the appropriate Taskdoc sections, then distill continuation-package reminders and `clear_mind`.'
151
161
  : ctx.contextHealthPromptMode === 'caution'
152
- ? 'Current context is under system caution remediation: do not keep expanding context. In this course, prioritize reminder distillation and `clear_mind`; do not continue large implementations/reads.'
162
+ ? ctx.isSideDialog
163
+ ? 'Current context is under system caution remediation: do not keep expanding context. You are in a Side Dialog; in this course, do not maintain Taskdoc and do not draft Taskdoc update proposals. Prioritize sufficiently detailed continuation-package reminders and `clear_mind`. Reminder length has no technical limit.'
164
+ : 'Current context is under system caution remediation: do not keep expanding context. In this course, first record undocumented discussion details that the next course needs to know into the appropriate Taskdoc sections, then distill reminders and `clear_mind`; do not continue large implementations/reads.'
153
165
  : 'There is no active context-health remediation instruction in effect right now; proceed with the normal workflow.';
154
166
  const taskdocLogLineEn = ctx.contextHealthPromptMode === 'critical'
155
- ? 'Do not paste long logs/tool outputs into Taskdoc; Taskdoc should record decisions + next steps; reminders should also keep only scannable excerpts. Current mode is critical remediation: in this course, rough multi-reminder bridge notes are acceptable, but do not perform the new-course “clear-headed review” early. Once the system actually starts the new course, the first step is to review/rewrite them: remove redundancy, correct biased or distorted bridge notes, then compress them into high-quality reminders.'
167
+ ? ctx.isSideDialog
168
+ ? 'Current mode is critical remediation: in a Side Dialog, do not maintain Taskdoc and do not draft Taskdoc update proposals. Put discussion details from current dialog history that the next course needs to know, next actions, key pointers, run/verify info, volatile paths/IDs/sample inputs, and resume reasoning into continuation-package reminders. Reminder length has no technical limit, so prefer being complete. Rough multi-reminder bridge notes are acceptable in this course, but do not perform the new-course “clear-headed review” early. Once the system actually starts the new course, the first step is to review/rewrite them: remove redundancy, correct biased or distorted bridge notes, then compress them into high-quality reminders.'
169
+ : 'Do not paste long logs/tool outputs into Taskdoc; Taskdoc should record decisions + next steps. Current mode is critical remediation: first review current-dialog discussion details not yet written into documentation. If they belong to team-shared state, decisions, constraints, or goals, write them to the appropriate Taskdoc section with `mind_more`/`change_mind`. Continuation-package reminders should keep only details still not covered by Taskdoc but easy to lose during resume. Rough multi-reminder bridge notes are acceptable in this course, but do not perform the new-course “clear-headed review” early. Once the system actually starts the new course, the first step is to review/rewrite them: remove redundancy, correct biased or distorted bridge notes, then compress them into high-quality reminders.'
156
170
  : ctx.contextHealthPromptMode === 'caution'
157
- ? 'Do not paste long logs/tool outputs into Taskdoc; Taskdoc should record decisions + next steps; reminders should also keep only scannable excerpts. Current mode is caution remediation: in this course, prioritize compressing/distilling reminders and clearing soon; if needed, rough multi-reminder bridge notes are acceptable, but do not perform the new-course “clear-headed review” early. Once the system actually starts the new course, the first step is to review/rewrite them: remove redundancy, correct biased or distorted bridge notes, then compress them into high-quality reminders.'
171
+ ? ctx.isSideDialog
172
+ ? 'Current mode is caution remediation: in a Side Dialog, do not maintain Taskdoc and do not draft Taskdoc update proposals. Put discussion details from current dialog history that the next course needs to know, next actions, key pointers, run/verify info, volatile paths/IDs/sample inputs, and resume reasoning into continuation-package reminders. Reminder length has no technical limit, so prefer being complete. If needed, rough multi-reminder bridge notes are acceptable, but do not perform the new-course “clear-headed review” early. Once the system actually starts the new course, the first step is to review/rewrite them: remove redundancy, correct biased or distorted bridge notes, then compress them into high-quality reminders.'
173
+ : 'Do not paste long logs/tool outputs into Taskdoc; Taskdoc should record decisions + next steps. Current mode is caution remediation: first review current-dialog discussion details not yet written into documentation. If they belong to team-shared state, decisions, constraints, or goals, write them to the appropriate Taskdoc section with `mind_more`/`change_mind`. Continuation-package reminders should keep only details still not covered by Taskdoc but easy to lose during resume. If needed, rough multi-reminder bridge notes are acceptable, but do not perform the new-course “clear-headed review” early. Once the system actually starts the new course, the first step is to review/rewrite them: remove redundancy, correct biased or distorted bridge notes, then compress them into high-quality reminders.'
158
174
  : 'Do not paste long logs/tool outputs into Taskdoc; Taskdoc should record decisions + next steps; reminders should also keep only scannable excerpts. Keep continuation-package reminders structured and fast to resume from by default.';
159
175
  if (ctx.language === 'zh') {
160
176
  return {
@@ -163,20 +179,30 @@ function getMemoryPromptCopy(ctx) {
163
179
  clearMindLine: '`clear_mind` 会开启新一程对话(保留差遣牒、提醒项与记忆层),从而卸掉这部分认知负载并继续推进。因此你必须先把关键信息提炼到高价值载体:',
164
180
  taskdocContractLine: '- 差遣牒(`*.tsk/`):全队共享的任务契约(goals/constraints/progress);不是个人笔记,保持足够短,每轮都应可通读。',
165
181
  taskdocSemanticsLine: '- 章节语义约定:`progress` 是全队共享、准实时、可扫读的任务公告牌,用来记录当前有效状态、关键决策、下一步与仍成立阻塞;不是流水账,也不是个人工作记录。`goals` / `constraints` 是较稳定的任务契约;每次更新都必须保留仍然有效的他人条目。',
166
- taskdocSectionReplaceLine: `- 更新差遣牒的任意分段时:每次调用会替换该分段全文;你必须先对照“上下文中注入的当前内容”做合并/压缩;禁止覆盖/抹掉他人条目;自己负责维护的条目必须标注责任人(例如 \`- [owner:@${ctx.agentId}] ...\` 或用 \`### @${ctx.agentId}\` 分块)。`,
167
- progressLine: '- 更新 `progress` 时:它必须始终是可供全队扫读的完整当前快照,而不是只追加自己这一轮的零散笔记。',
182
+ taskdocSectionReplaceLine: ctx.isSideDialog && ctx.contextHealthPromptMode !== 'normal'
183
+ ? '- 当前处于支线对话的上下文健康处置态:本程不要维护差遣牒,也不要整理差遣牒更新提案;把下一程需要恢复的细节写入足够详尽的接续包提醒项。'
184
+ : `- 更新差遣牒时:少量新增条目可用 \`mind_more\` 追加(默认 progress);需要删除陈旧项、重排结构或压缩时,用 \`change_mind\` 整章替换并先对照“上下文中注入的当前内容”做合并;禁止覆盖/抹掉他人条目;自己负责维护的条目必须标注责任人(例如 \`- [owner:@${ctx.agentId}] ...\` 或用 \`### @${ctx.agentId}\` 分块)。`,
185
+ progressLine: ctx.isSideDialog && ctx.contextHealthPromptMode !== 'normal'
186
+ ? '- 当前处于支线对话的上下文健康处置态:本程不更新 `progress`;只把下一程接续所需信息写入提醒项。'
187
+ : '- 更新 `progress` 时:它必须始终是可供全队扫读的完整当前快照,而不是只追加自己这一轮的零散笔记。',
168
188
  injectedTaskdocLine: '- 重要:差遣牒内容会被系统以内联形式注入到上下文中(本轮生成视角下即为最新;注入内容不包括全局约束)。需要回顾时请直接基于上下文里的差遣牒内容回顾与决策,不要试图用通用文件工具读取 `*.tsk/` 下的文件(会被拒绝)。',
169
189
  constraintsLine: '- 约定:`constraints` 只写任务特有的硬要求,不得写入系统提示/工具文档里已明确且由系统强制执行的通用规则(例如 `*.tsk/` 封装禁止通用文件工具)。一经发现重复,必须删除并告知用户。',
170
- remindersLine: '- 提醒项(以 `reminder_id` 标识,工作集):当前对话的高频工作记录/关键细节(偏私有,不作为全队公告);默认保持少量(常见 1–3 条),优先 `update_reminder` 压缩/合并,不再需要就 `delete_reminder`。准备 `clear_mind` 开启新一程对话时,默认整理成“结构化接续包提醒项”;其中只保留差遣牒未覆盖、但恢复工作容易丢的细节(如第一步、关键定位、运行/验证信息、临时 ids/路径)。若系统已把当前程切到吃紧/告急处置态,则允许先保留多条粗略提醒项把信息带过桥;当前程只做保信息 + clear_mind;只有系统实际开启新一程后,第一步才是以清醒头脑复核并整理这些接续包/粗略提醒项:删除冗余、纠正偏激或失真的过桥思路、压缩成高质量提醒项。',
190
+ remindersLine: ctx.isSideDialog
191
+ ? '- 提醒项(以 `reminder_id` 标识,工作集):当前对话的高频工作记录/关键细节(偏私有,不作为全队公告);默认保持少量(常见 1–3 条),优先 `update_reminder` 压缩/合并,不再需要就 `delete_reminder`。准备 `clear_mind` 开启新一程对话时,整理“结构化接续包提醒项”;提醒项保留恢复工作容易丢的细节(如第一步、关键定位、运行/验证信息、临时 ids/路径)。若系统已把当前程切到吃紧/告急处置态,支线对话不要维护差遣牒,也不要整理差遣牒更新提案;只维护足够详尽的接续包提醒项,提醒项长度没有技术限制,允许先保留多条粗略提醒项把信息带过桥;当前程只做保信息 + clear_mind;只有系统实际开启新一程后,第一步才是以清醒头脑复核并整理这些接续包/粗略提醒项:删除冗余、纠正偏激或失真的过桥思路、压缩成高质量提醒项。'
192
+ : '- 提醒项(以 `reminder_id` 标识,工作集):当前对话的高频工作记录/关键细节(偏私有,不作为全队公告);默认保持少量(常见 1–3 条),优先 `update_reminder` 压缩/合并,不再需要就 `delete_reminder`。准备 `clear_mind` 开启新一程对话时,先把尚未落实到文档、且下一程需要知会的讨论细节落到差遣牒合适章节,再整理“结构化接续包提醒项”;提醒项只保留差遣牒仍未覆盖、但恢复工作容易丢的细节(如第一步、关键定位、运行/验证信息、临时 ids/路径)。若系统已把当前程切到吃紧/告急处置态,则允许先保留多条粗略提醒项把信息带过桥;当前程只做落文档、保信息 + clear_mind;只有系统实际开启新一程后,第一步才是以清醒头脑复核并整理这些接续包/粗略提醒项:删除冗余、纠正偏激或失真的过桥思路、压缩成高质量提醒项。',
171
193
  teamMemoryLine: '- 团队记忆:稳定的团队约定/工程规约(跨任务共享)。',
172
194
  personalMemoryLine: '- 个人记忆:稳定的个人习惯/偏好与职责域知识;记忆会在每次生成时自动注入上下文,应保持少量且准确(关键文档/代码的精确路径 + 最小必要事实)。不要记录具体任务状态。',
173
- sideDialogDutyLine: `你当前处于支线对话:此处不允许 \`change_mind\`。当你判断需要更新差遣牒(尤其是 progress 公告牌)时,请在合适时机直接诉请差遣牒维护人 \`@${ctx.taskdocMaintainerId}\` 执行更新,并给出你已合并好的“新全文/替换稿”(用于替换对应章节全文)。不要声称已更新,除非看到回执。`,
195
+ sideDialogDutyLine: ctx.contextHealthPromptMode === 'normal'
196
+ ? `你当前处于支线对话:此处不允许 \`mind_more\` / \`change_mind\`。当你判断需要更新差遣牒(尤其是 progress 公告牌)时,请在合适时机直接诉请差遣牒维护人 \`@${ctx.taskdocMaintainerId}\` 执行更新,并给出要追加的条目或已合并好的“新全文/替换稿”。不要声称已更新,除非看到回执。`
197
+ : '你当前处于支线对话,且上下文已进入吃紧/告急处置态:本程不要维护差遣牒,也不要整理差遣牒更新提案。请把下一程需要恢复的讨论细节、定位、验证方式和临时信息写入足够详尽的接续包提醒项。',
174
198
  mainDialogDutyLine: '你当前处于主线对话:你负责综合维护全队共享差遣牒(尤其是 progress 公告牌)。当队友/支线对话提出更新建议时,及时合并、压缩并保持清晰。',
175
199
  teammateTellaskRoundDoneLine: `队友诉请重要语义:当你在诉请者上下文中收到带${runtimeMarkers.finalCompleted}标记的回贴,表示该轮诉请已经结束;对方不会继续执行同一轮诉请。此时如果目标未达成,“等待”是错误的:必须显式发起新一轮 tellask 才能继续推进。`,
176
200
  teamMemoryHintLine: '提示:你具备团队记忆工具(`add_team_memory` / `replace_team_memory` / `drop_team_memory` / `clear_team_memory`),可在必要时维护团队记忆(谨慎、少量、只写稳定约定)。',
177
201
  personalMemoryHintLine: `提示:你具备个人记忆工具(\`add_personal_memory\` / \`replace_personal_memory\` / \`drop_personal_memory\` / \`clear_personal_memory\`)。个人记忆仅对当前智能体可见,且系统会自动按成员隔离到 \`.minds/memory/individual/<member-id>/...\`;因此 \`path\` 不应包含你的成员 id(不要写 \`${ctx.agentId}/...\`)。首次创建时直接用 \`add_personal_memory\` 即可,目录会由系统自动创建。记忆会在每次生成时自动注入上下文:保持少量、保持准确、按“未来会一起更新的内容”合并;写稳定事实(关键路径 + 最小必要约定),不要写任务进度/当天状态;一旦你修改了相关文件或发现记忆过期/冲突,立刻用 \`replace_personal_memory\` 更新。`,
178
- sideDialogWorkflowLine: `工作流:先做事 → 再提炼(\`update_reminder\`;必要时整理差遣牒更新提案并诉请 \`@${ctx.taskdocMaintainerId}\` 合并写入)→ 然后 \`clear_mind\` 清空噪音。`,
179
- mainDialogWorkflowLine: '工作流:先做事再提炼(`update_reminder` + `change_mind(progress)`)→ 然后 `clear_mind` 清空噪音。',
202
+ sideDialogWorkflowLine: ctx.contextHealthPromptMode === 'normal'
203
+ ? `工作流:先做事再提炼(\`update_reminder\`;必要时整理差遣牒追加条目/更新提案并诉请 \`@${ctx.taskdocMaintainerId}\` 合并写入)→ 然后 \`clear_mind\` 清空噪音。`
204
+ : '工作流:停止扩张上下文 → 维护足够详尽的接续包提醒项(`add_reminder` 或 `update_reminder`,长度没有技术限制)→ 然后 `clear_mind` 开启新一程。',
205
+ mainDialogWorkflowLine: '工作流:先做事 → 再提炼(`update_reminder` + `mind_more(progress)`;需要压缩/删旧时用 `change_mind(progress)`)→ 然后 `clear_mind` 清空噪音。',
180
206
  contextHealthLine: contextHealthLineZh,
181
207
  taskdocLogLine: taskdocLogLineZh,
182
208
  };
@@ -187,20 +213,30 @@ function getMemoryPromptCopy(ctx) {
187
213
  clearMindLine: '`clear_mind` starts a new course while preserving Taskdoc, reminders, and memory layers. Therefore, before clearing, distill key information into durable layers:',
188
214
  taskdocContractLine: '- Taskdoc (`*.tsk/`): the team-shared task contract (goals/constraints/progress). It is not a personal notebook; keep it small enough to read every course.',
189
215
  taskdocSemanticsLine: '- Section semantics: `progress` is the team-shared, quasi-real-time, scannable task bulletin board for current effective state, key decisions, next steps, and still-active blockers; it is not a raw log or personal work record. `goals` / `constraints` are the more stable task contract; every update must preserve still-valid entries from others.',
190
- taskdocSectionReplaceLine: `- When updating any Taskdoc section: each call replaces the entire section; always start from the current injected content and merge/compress; do not overwrite other contributors; add an explicit owner tag for entries you maintain (e.g., \`- [owner:@${ctx.agentId}] ...\` or a \`### @${ctx.agentId}\` block).`,
191
- progressLine: '- When updating `progress`, keep it as a complete, team-scannable current snapshot instead of appending only your own latest notes.',
216
+ taskdocSectionReplaceLine: ctx.isSideDialog && ctx.contextHealthPromptMode !== 'normal'
217
+ ? '- Current mode is context-health remediation in a Side Dialog: do not maintain Taskdoc and do not draft Taskdoc update proposals in this course; put resume-critical details into sufficiently detailed continuation-package reminders.'
218
+ : `- When updating Taskdoc: use \`mind_more\` for small append-only additions (defaults to progress); when stale entries must be removed, reordered, or compressed, use \`change_mind\` for a full-section replacement based on the current injected content; do not overwrite other contributors; add an explicit owner tag for entries you maintain (e.g., \`- [owner:@${ctx.agentId}] ...\` or a \`### @${ctx.agentId}\` block).`,
219
+ progressLine: ctx.isSideDialog && ctx.contextHealthPromptMode !== 'normal'
220
+ ? '- Current mode is context-health remediation in a Side Dialog: do not update `progress` in this course; put resume-critical information into reminders only.'
221
+ : '- When updating `progress`, keep it as a complete, team-scannable current snapshot instead of appending only your own latest notes.',
192
222
  injectedTaskdocLine: '- Important: the Taskdoc content is injected inline into the context (the latest as of this generation; injected content excludes global constraints). Review the injected Taskdoc instead of trying to read files under `*.tsk/` via general file tools (they will be rejected).',
193
223
  constraintsLine: '- Convention: Taskdoc `constraints` must contain task-specific requirements only; do not include global, system-enforced rules already stated in system prompt/tool docs (e.g. `.tsk/` encapsulation bans general file tools). If duplication is found, you MUST remove it and notify the user.',
194
- remindersLine: '- Reminders (addressed by `reminder_id`, working set): your high-frequency per-dialog worklog + critical details (not a team bulletin board); keep it small by default (often 1–3 items), prefer `update_reminder` to compress/merge, and delete when obsolete. When preparing `clear_mind` to start a new course, default to a structured continuation-package reminder that keeps only details not already covered by Taskdoc but easy to lose during resume (first step, key pointers, run/verify info, volatile ids/paths). If the system has already put the current course into caution/critical remediation, rough multi-reminder bridge notes are acceptable; in the current course, only preserve volatile information and clear_mind. Only after the system actually starts the new course does the mandatory first step become reviewing and rewriting those continuation/rough reminders with a clear head: remove redundancy, correct biased or distorted bridge notes, and compress them into high-quality reminders.',
224
+ remindersLine: ctx.isSideDialog
225
+ ? '- Reminders (addressed by `reminder_id`, working set): your high-frequency per-dialog worklog + critical details (not a team bulletin board); keep it small by default (often 1–3 items), prefer `update_reminder` to compress/merge, and delete when obsolete. When preparing `clear_mind` to start a new course, create a structured continuation-package reminder that preserves details easy to lose during resume (first step, key pointers, run/verify info, volatile ids/paths). If the system has already put the current course into caution/critical remediation, you are in a Side Dialog: do not maintain Taskdoc and do not draft Taskdoc update proposals; only maintain sufficiently detailed continuation-package reminders. Reminder length has no technical limit, rough multi-reminder bridge notes are acceptable, and in the current course you should only preserve volatile information and clear_mind. Only after the system actually starts the new course does the mandatory first step become reviewing and rewriting those continuation/rough reminders with a clear head: remove redundancy, correct biased or distorted bridge notes, and compress them into high-quality reminders.'
226
+ : '- Reminders (addressed by `reminder_id`, working set): your high-frequency per-dialog worklog + critical details (not a team bulletin board); keep it small by default (often 1–3 items), prefer `update_reminder` to compress/merge, and delete when obsolete. When preparing `clear_mind` to start a new course, first record undocumented discussion details that the next course needs to know into the appropriate Taskdoc sections, then create a structured continuation-package reminder. Reminders should keep only details still not covered by Taskdoc but easy to lose during resume (first step, key pointers, run/verify info, volatile ids/paths). If the system has already put the current course into caution/critical remediation, rough multi-reminder bridge notes are acceptable; in the current course, only document missing details, preserve volatile information, and clear_mind. Only after the system actually starts the new course does the mandatory first step become reviewing and rewriting those continuation/rough reminders with a clear head: remove redundancy, correct biased or distorted bridge notes, and compress them into high-quality reminders.',
195
227
  teamMemoryLine: '- Team memory: stable shared conventions (cross-task).',
196
228
  personalMemoryLine: '- Personal memory: stable personal habits/preferences and responsibility-scope knowledge. Memory is automatically injected into context on each generation: keep it small and accurate (exact key doc/code paths + minimal key facts); do not store per-task state.',
197
- sideDialogDutyLine: `You are currently in a Side Dialog: \`change_mind\` is not allowed here. When Taskdoc should be updated (especially the shared progress bulletin board), tellask the Taskdoc maintainer \`@${ctx.taskdocMaintainerId}\` with a fully merged replacement draft (full-section replacement). Do not claim it is updated until you see a receipt.`,
229
+ sideDialogDutyLine: ctx.contextHealthPromptMode === 'normal'
230
+ ? `You are currently in a Side Dialog: \`mind_more\` / \`change_mind\` are not allowed here. When Taskdoc should be updated (especially the shared progress bulletin board), tellask the Taskdoc maintainer \`@${ctx.taskdocMaintainerId}\` with entries to append or a fully merged replacement draft. Do not claim it is updated until you see a receipt.`
231
+ : 'You are currently in a Side Dialog under caution/critical context-health remediation: do not maintain Taskdoc and do not draft Taskdoc update proposals in this course. Put discussion details, pointers, verification method, and volatile resume information into sufficiently detailed continuation-package reminders.',
198
232
  mainDialogDutyLine: 'You are currently in the Main Dialog: you are responsible for keeping the team-shared Taskdoc coherent and up to date (especially the progress bulletin board). Merge proposals from teammates/Side Dialogs promptly and keep it concise.',
199
233
  teammateTellaskRoundDoneLine: `Teammate Tellask semantics: when you receive a tellasker reply with the ${runtimeMarkers.finalCompleted} marker, that Tellask round is finished; the tellaskee will not keep executing the same call in the background. If the objective is not met, “waiting” is wrong: you must explicitly start a new Tellask round to continue.`,
200
234
  teamMemoryHintLine: 'Hint: you have team-memory tools (`add_team_memory` / `replace_team_memory` / `drop_team_memory` / `clear_team_memory`) and may maintain team memory when it is truly stable and worth sharing.',
201
235
  personalMemoryHintLine: `Hint: you have personal-memory tools (\`add_personal_memory\` / \`replace_personal_memory\` / \`drop_personal_memory\` / \`clear_personal_memory\`). Personal memory is private to the current agent and is automatically isolated under \`.minds/memory/individual/<member-id>/...\`; therefore \`path\` MUST NOT include your member id (do not write \`${ctx.agentId}/...\`). For first-time setup, just call \`add_personal_memory\`—the directory will be created automatically. Memory is automatically injected into context on each generation: keep it small, keep it accurate, and group facts that are updated together. Store stable facts (exact key paths + minimal contracts), not daily state/progress. If you changed those files or detect staleness/conflicts, immediately \`replace_personal_memory\` to keep it accurate.`,
202
- sideDialogWorkflowLine: `Workflow: do work → distill (\`update_reminder\`; when Taskdoc needs updates, draft a merged replacement and ask \`@${ctx.taskdocMaintainerId}\`) then \`clear_mind\` to drop noise.`,
203
- mainDialogWorkflowLine: 'Workflow: do work → distill (`update_reminder` + `change_mind(progress)`) → then `clear_mind` to drop noise.',
236
+ sideDialogWorkflowLine: ctx.contextHealthPromptMode === 'normal'
237
+ ? `Workflow: do work → distill (\`update_reminder\`; when Taskdoc needs updates, draft append entries or a merged replacement and ask \`@${ctx.taskdocMaintainerId}\`) → then \`clear_mind\` to drop noise.`
238
+ : 'Workflow: stop expanding context → maintain sufficiently detailed continuation-package reminders (`add_reminder` or `update_reminder`, with no technical length limit) → then `clear_mind` to start a new course.',
239
+ mainDialogWorkflowLine: 'Workflow: do work → distill (`update_reminder` + `mind_more(progress)`; use `change_mind(progress)` when compression/deletion is needed) → then `clear_mind` to drop noise.',
204
240
  contextHealthLine: contextHealthLineEn,
205
241
  taskdocLogLine: taskdocLogLineEn,
206
242
  };
@@ -47,27 +47,27 @@ function buildFbrContextHealthScopeRule(scope, language, contextHealthPromptMode
47
47
  if (contextHealthPromptMode === 'critical') {
48
48
  return pickLocalized(language, {
49
49
  zh: scope === 'mainDialog'
50
- ? '- 当前上下文处于系统告急处置态:本程禁止发起 FBR。先按处置要求保信息、维护提醒项,并立即 `clear_mind`;系统真正开启新一程并完成接续包复核后,再恢复 FBR 与差遣牒更新。'
51
- : '- 当前上下文处于系统告急处置态:本程禁止发起 FBR。先按处置要求保信息、维护提醒项,并立即 `clear_mind`;系统真正开启新一程并完成接续包复核后,再恢复 FBR。',
50
+ ? '- 当前上下文处于系统告急处置态:本程禁止发起 FBR。先按处置要求把尚未落实到差遣牒、且下一程需要知会的讨论细节写入合适章节,再维护接续包提醒项,并立即 `clear_mind`;系统真正开启新一程并完成接续包复核后,再恢复 FBR'
51
+ : '- 当前上下文处于系统告急处置态:本程禁止发起 FBR。你当前处于支线对话:不要维护差遣牒,也不要整理差遣牒更新提案;先按处置要求维护足够详尽的接续包提醒项,并立即 `clear_mind`;系统真正开启新一程并完成接续包复核后,再恢复 FBR。',
52
52
  en: scope === 'mainDialog'
53
- ? '- Current context is under system critical remediation: do not start FBR in this course. Preserve volatile information, maintain reminders, and clear immediately; resume FBR and Taskdoc updates only after the system starts the new course and the continuation package has been reviewed.'
54
- : '- Current context is under system critical remediation: do not start FBR in this course. Preserve volatile information, maintain reminders, and clear immediately; resume FBR only after the system starts the new course and the continuation package has been reviewed.',
53
+ ? '- Current context is under system critical remediation: do not start FBR in this course. First write discussion details not yet in Taskdoc but needed by the next course into the appropriate sections, then maintain continuation-package reminders and clear immediately; resume FBR only after the system starts the new course and the continuation package has been reviewed.'
54
+ : '- Current context is under system critical remediation: do not start FBR in this course. You are in a Side Dialog: do not maintain Taskdoc and do not draft Taskdoc update proposals; first maintain sufficiently detailed continuation-package reminders, then clear immediately. Resume FBR only after the system starts the new course and the continuation package has been reviewed.',
55
55
  });
56
56
  }
57
57
  if (contextHealthPromptMode === 'caution') {
58
58
  return pickLocalized(language, {
59
59
  zh: scope === 'mainDialog'
60
- ? '- 当前上下文处于系统吃紧处置态:本程不要发起 FBR。先按处置要求提炼提醒项并尽快 `clear_mind`;系统真正开启新一程并完成接续包复核后,再恢复 FBR 与差遣牒更新。'
61
- : '- 当前上下文处于系统吃紧处置态:本程不要发起 FBR。先按处置要求提炼提醒项并尽快 `clear_mind`;系统真正开启新一程并完成接续包复核后,再恢复 FBR。',
60
+ ? '- 当前上下文处于系统吃紧处置态:本程不要发起 FBR。先按处置要求把尚未落实到差遣牒、且下一程需要知会的讨论细节写入合适章节,再提炼提醒项并尽快 `clear_mind`;系统真正开启新一程并完成接续包复核后,再恢复 FBR'
61
+ : '- 当前上下文处于系统吃紧处置态:本程不要发起 FBR。你当前处于支线对话:不要维护差遣牒,也不要整理差遣牒更新提案;先按处置要求维护足够详尽的接续包提醒项并尽快 `clear_mind`;系统真正开启新一程并完成接续包复核后,再恢复 FBR。',
62
62
  en: scope === 'mainDialog'
63
- ? '- Current context is under system caution remediation: do not start FBR in this course. Distill reminders and clear soon; resume FBR and Taskdoc updates only after the system starts the new course and the continuation package has been reviewed.'
64
- : '- Current context is under system caution remediation: do not start FBR in this course. Distill reminders and clear soon; resume FBR only after the system starts the new course and the continuation package has been reviewed.',
63
+ ? '- Current context is under system caution remediation: do not start FBR in this course. First write discussion details not yet in Taskdoc but needed by the next course into the appropriate sections, then distill reminders and clear soon; resume FBR only after the system starts the new course and the continuation package has been reviewed.'
64
+ : '- Current context is under system caution remediation: do not start FBR in this course. You are in a Side Dialog: do not maintain Taskdoc and do not draft Taskdoc update proposals; first maintain sufficiently detailed continuation-package reminders, then clear soon. Resume FBR only after the system starts the new course and the continuation package has been reviewed.',
65
65
  });
66
66
  }
67
67
  if (scope === 'mainDialog') {
68
68
  return pickLocalized(language, {
69
- zh: '- 当前没有生效中的上下文健康处置指令,可以按正常流程进行 FBR。完成 FBR 后,基于当前可观测事实调用 `change_mind` 更新差遣牒,体现任务最新进展情况。FBR 自诉请正文不要冗余包含差遣牒已有信息。',
70
- en: '- There is no active context-health remediation instruction in effect, so FBR may proceed normally. After FBR, call `change_mind` based on currently observable facts to update the Taskdoc with the latest progress; do not redundantly include information already present in the Taskdoc in the FBR body.',
69
+ zh: '- 当前没有生效中的上下文健康处置指令,可以按正常流程进行 FBR。完成 FBR 后,基于当前可观测事实调用 `mind_more` 或 `change_mind` 更新差遣牒,体现任务最新进展情况。FBR 自诉请正文不要冗余包含差遣牒已有信息。',
70
+ en: '- There is no active context-health remediation instruction in effect, so FBR may proceed normally. After FBR, call `mind_more` or `change_mind` based on currently observable facts to update the Taskdoc with the latest progress; do not redundantly include information already present in the Taskdoc in the FBR body.',
71
71
  });
72
72
  }
73
73
  return pickLocalized(language, {
@@ -4709,7 +4709,7 @@ class DialogPersistence {
4709
4709
  genseq,
4710
4710
  content,
4711
4711
  };
4712
- await this.appendEvent(dialog.id, course, ev, dialog.status);
4712
+ await this.appendEvent(dialog.id, course, attachRootGenerationRef(dialog, ev), dialog.status);
4713
4713
  }
4714
4714
  /**
4715
4715
  * Capture the current byte offset of a course JSONL file.