dominds 1.22.0 → 1.23.0

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 (145) hide show
  1. package/dist/access-control.js +2 -2
  2. package/dist/dialog-instance-registry.js +3 -4
  3. package/dist/dialog.d.ts +2 -2
  4. package/dist/dialog.js +3 -3
  5. package/dist/docs/dialog-system.md +3 -2
  6. package/dist/docs/dialog-system.zh.md +3 -2
  7. package/dist/docs/diligence-push.md +19 -12
  8. package/dist/docs/diligence-push.zh.md +11 -9
  9. package/dist/docs/dominds-terminology.md +3 -3
  10. package/dist/docs/encapsulated-taskdoc.md +11 -2
  11. package/dist/docs/encapsulated-taskdoc.zh.md +10 -1
  12. package/dist/docs/llm-provider-isolation.md +1 -1
  13. package/dist/docs/llm-provider-isolation.zh.md +1 -1
  14. package/dist/docs/team_mgmt-toolset.md +2 -1
  15. package/dist/docs/team_mgmt-toolset.zh.md +2 -1
  16. package/dist/docs/volcengine-coding-plan-openai-compatible.zh.md +11 -10
  17. package/dist/llm/api-quirks.d.ts +0 -2
  18. package/dist/llm/api-quirks.js +1 -3
  19. package/dist/llm/client.d.ts +1 -0
  20. package/dist/llm/defaults.yaml +45 -6
  21. package/dist/llm/gen/anthropic.d.ts +0 -6
  22. package/dist/llm/gen/anthropic.js +21 -468
  23. package/dist/llm/gen/openai-compatible.d.ts +14 -1
  24. package/dist/llm/gen/openai-compatible.js +482 -19
  25. package/dist/llm/gen.d.ts +4 -2
  26. package/dist/llm/kernel-driver/drive.js +164 -114
  27. package/dist/llm/kernel-driver/runtime.js +36 -11
  28. package/dist/llm/kernel-driver/tellask-special.js +12 -9
  29. package/dist/minds/system-prompt-parts.js +8 -8
  30. package/dist/persistence.d.ts +2 -3
  31. package/dist/persistence.js +53 -76
  32. package/dist/problems.js +2 -1
  33. package/dist/runtime/driver-messages.js +4 -4
  34. package/dist/server/websocket-handler.js +17 -3
  35. package/dist/team.d.ts +2 -1
  36. package/dist/team.js +11 -1
  37. package/dist/tools/ctrl.js +48 -11
  38. package/dist/tools/prompts/control/en/principles.md +3 -3
  39. package/dist/tools/prompts/control/en/scenarios.md +4 -0
  40. package/dist/tools/prompts/control/en/tools.md +6 -3
  41. package/dist/tools/prompts/control/zh/principles.md +3 -3
  42. package/dist/tools/prompts/control/zh/scenarios.md +4 -0
  43. package/dist/tools/prompts/control/zh/tools.md +6 -3
  44. package/dist/tools/team_mgmt-manual.js +4 -4
  45. package/dist/tools/team_mgmt.js +15 -5
  46. package/dist/utils/task-package.d.ts +16 -0
  47. package/dist/utils/task-package.js +132 -55
  48. package/dist/utils/taskdoc.js +21 -16
  49. package/package.json +3 -3
  50. package/webapp/dist/assets/{_basePickBy-BYnYcdaa.js → _basePickBy-CGhMqD96.js} +3 -3
  51. package/webapp/dist/assets/{_basePickBy-BYnYcdaa.js.map → _basePickBy-CGhMqD96.js.map} +1 -1
  52. package/webapp/dist/assets/{_baseUniq-CHLBB955.js → _baseUniq-XCMW7z1Y.js} +2 -2
  53. package/webapp/dist/assets/{_baseUniq-CHLBB955.js.map → _baseUniq-XCMW7z1Y.js.map} +1 -1
  54. package/webapp/dist/assets/{arc-DQXtgZdO.js → arc-B6fzk0T5.js} +2 -2
  55. package/webapp/dist/assets/{arc-DQXtgZdO.js.map → arc-B6fzk0T5.js.map} +1 -1
  56. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-CzP5Yf9x.js → architectureDiagram-2XIMDMQ5-DmSI_GUt.js} +7 -7
  57. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-CzP5Yf9x.js.map → architectureDiagram-2XIMDMQ5-DmSI_GUt.js.map} +1 -1
  58. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-sOx5Byq8.js → blockDiagram-WCTKOSBZ-Bp0nb8IZ.js} +7 -7
  59. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-sOx5Byq8.js.map → blockDiagram-WCTKOSBZ-Bp0nb8IZ.js.map} +1 -1
  60. package/webapp/dist/assets/{c4Diagram-IC4MRINW-D8-GiS6c.js → c4Diagram-IC4MRINW-gYpylqGb.js} +3 -3
  61. package/webapp/dist/assets/{c4Diagram-IC4MRINW-D8-GiS6c.js.map → c4Diagram-IC4MRINW-gYpylqGb.js.map} +1 -1
  62. package/webapp/dist/assets/{channel-Bvke0iMP.js → channel-BmQ3YyUn.js} +2 -2
  63. package/webapp/dist/assets/{channel-Bvke0iMP.js.map → channel-BmQ3YyUn.js.map} +1 -1
  64. package/webapp/dist/assets/{chunk-4BX2VUAB-C9pln2M7.js → chunk-4BX2VUAB-B5pwFRwA.js} +2 -2
  65. package/webapp/dist/assets/{chunk-4BX2VUAB-C9pln2M7.js.map → chunk-4BX2VUAB-B5pwFRwA.js.map} +1 -1
  66. package/webapp/dist/assets/{chunk-55IACEB6-BLDXNtAM.js → chunk-55IACEB6-CZf6oMWM.js} +2 -2
  67. package/webapp/dist/assets/{chunk-55IACEB6-BLDXNtAM.js.map → chunk-55IACEB6-CZf6oMWM.js.map} +1 -1
  68. package/webapp/dist/assets/{chunk-FMBD7UC4-dYd3QdHa.js → chunk-FMBD7UC4-yZWCDzVz.js} +2 -2
  69. package/webapp/dist/assets/{chunk-FMBD7UC4-dYd3QdHa.js.map → chunk-FMBD7UC4-yZWCDzVz.js.map} +1 -1
  70. package/webapp/dist/assets/{chunk-JSJVCQXG-SqHEmHHd.js → chunk-JSJVCQXG-Cg1ST73M.js} +2 -2
  71. package/webapp/dist/assets/{chunk-JSJVCQXG-SqHEmHHd.js.map → chunk-JSJVCQXG-Cg1ST73M.js.map} +1 -1
  72. package/webapp/dist/assets/{chunk-KX2RTZJC-CRXgzI2d.js → chunk-KX2RTZJC-ByGtlX9q.js} +2 -2
  73. package/webapp/dist/assets/{chunk-KX2RTZJC-CRXgzI2d.js.map → chunk-KX2RTZJC-ByGtlX9q.js.map} +1 -1
  74. package/webapp/dist/assets/{chunk-NQ4KR5QH-IMA2JZhH.js → chunk-NQ4KR5QH-DoXvfhSY.js} +4 -4
  75. package/webapp/dist/assets/{chunk-NQ4KR5QH-IMA2JZhH.js.map → chunk-NQ4KR5QH-DoXvfhSY.js.map} +1 -1
  76. package/webapp/dist/assets/{chunk-QZHKN3VN-DBaGWjY3.js → chunk-QZHKN3VN-2gX2qsHB.js} +2 -2
  77. package/webapp/dist/assets/{chunk-QZHKN3VN-DBaGWjY3.js.map → chunk-QZHKN3VN-2gX2qsHB.js.map} +1 -1
  78. package/webapp/dist/assets/{chunk-WL4C6EOR-QLmsLbcS.js → chunk-WL4C6EOR-L-9bPNxS.js} +6 -6
  79. package/webapp/dist/assets/{chunk-WL4C6EOR-QLmsLbcS.js.map → chunk-WL4C6EOR-L-9bPNxS.js.map} +1 -1
  80. package/webapp/dist/assets/{classDiagram-VBA2DB6C-jN4lhUtx.js → classDiagram-VBA2DB6C-B79Oe3Df.js} +7 -7
  81. package/webapp/dist/assets/{classDiagram-VBA2DB6C-jN4lhUtx.js.map → classDiagram-VBA2DB6C-B79Oe3Df.js.map} +1 -1
  82. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-jN4lhUtx.js → classDiagram-v2-RAHNMMFH-B79Oe3Df.js} +7 -7
  83. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-jN4lhUtx.js.map → classDiagram-v2-RAHNMMFH-B79Oe3Df.js.map} +1 -1
  84. package/webapp/dist/assets/{clone-DPC4Vt09.js → clone-DvlY9Sdn.js} +2 -2
  85. package/webapp/dist/assets/{clone-DPC4Vt09.js.map → clone-DvlY9Sdn.js.map} +1 -1
  86. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-BtVgObsc.js → cose-bilkent-S5V4N54A-CtkGd0W6.js} +2 -2
  87. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-BtVgObsc.js.map → cose-bilkent-S5V4N54A-CtkGd0W6.js.map} +1 -1
  88. package/webapp/dist/assets/{dagre-KLK3FWXG-Bv6mn-UV.js → dagre-KLK3FWXG-B3W6QTXQ.js} +7 -7
  89. package/webapp/dist/assets/{dagre-KLK3FWXG-Bv6mn-UV.js.map → dagre-KLK3FWXG-B3W6QTXQ.js.map} +1 -1
  90. package/webapp/dist/assets/{diagram-E7M64L7V-D2OPgDkq.js → diagram-E7M64L7V-B6-J_E5Q.js} +8 -8
  91. package/webapp/dist/assets/{diagram-E7M64L7V-D2OPgDkq.js.map → diagram-E7M64L7V-B6-J_E5Q.js.map} +1 -1
  92. package/webapp/dist/assets/{diagram-IFDJBPK2-CZpDu-e5.js → diagram-IFDJBPK2-C-PH_Yx3.js} +7 -7
  93. package/webapp/dist/assets/{diagram-IFDJBPK2-CZpDu-e5.js.map → diagram-IFDJBPK2-C-PH_Yx3.js.map} +1 -1
  94. package/webapp/dist/assets/{diagram-P4PSJMXO-BkMbbW0p.js → diagram-P4PSJMXO-CB5xXDup.js} +7 -7
  95. package/webapp/dist/assets/{diagram-P4PSJMXO-BkMbbW0p.js.map → diagram-P4PSJMXO-CB5xXDup.js.map} +1 -1
  96. package/webapp/dist/assets/{erDiagram-INFDFZHY-Kf17ek1z.js → erDiagram-INFDFZHY-CuAhTGVU.js} +5 -5
  97. package/webapp/dist/assets/{erDiagram-INFDFZHY-Kf17ek1z.js.map → erDiagram-INFDFZHY-CuAhTGVU.js.map} +1 -1
  98. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-Cort4hNL.js → flowDiagram-PKNHOUZH-D3cIOfGj.js} +7 -7
  99. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-Cort4hNL.js.map → flowDiagram-PKNHOUZH-D3cIOfGj.js.map} +1 -1
  100. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-DcXFKB1Y.js → ganttDiagram-A5KZAMGK-CSFhVYXV.js} +3 -3
  101. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-DcXFKB1Y.js.map → ganttDiagram-A5KZAMGK-CSFhVYXV.js.map} +1 -1
  102. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-BORnqZ0-.js → gitGraphDiagram-K3NZZRJ6-CiEaxACG.js} +8 -8
  103. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-BORnqZ0-.js.map → gitGraphDiagram-K3NZZRJ6-CiEaxACG.js.map} +1 -1
  104. package/webapp/dist/assets/{graph-D4Uth-MK.js → graph-CYGALRuy.js} +3 -3
  105. package/webapp/dist/assets/{graph-D4Uth-MK.js.map → graph-CYGALRuy.js.map} +1 -1
  106. package/webapp/dist/assets/{index-YBIJr7jH.js → index-BTazqQrV.js} +186 -58
  107. package/webapp/dist/assets/index-BTazqQrV.js.map +1 -0
  108. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-DDjsEPg3.js → infoDiagram-LFFYTUFH-CiWJjQyU.js} +6 -6
  109. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-DDjsEPg3.js.map → infoDiagram-LFFYTUFH-CiWJjQyU.js.map} +1 -1
  110. package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-Bb2sPnCX.js → ishikawaDiagram-PHBUUO56-MlIIUO7o.js} +2 -2
  111. package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-Bb2sPnCX.js.map → ishikawaDiagram-PHBUUO56-MlIIUO7o.js.map} +1 -1
  112. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-BtRY6eBa.js → journeyDiagram-4ABVD52K-BBqwkA3d.js} +5 -5
  113. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-BtRY6eBa.js.map → journeyDiagram-4ABVD52K-BBqwkA3d.js.map} +1 -1
  114. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-aGmxT2H9.js → kanban-definition-K7BYSVSG-BS4GzDbo.js} +3 -3
  115. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-aGmxT2H9.js.map → kanban-definition-K7BYSVSG-BS4GzDbo.js.map} +1 -1
  116. package/webapp/dist/assets/{layout-BuLicmwh.js → layout-DaJO-1DW.js} +5 -5
  117. package/webapp/dist/assets/{layout-BuLicmwh.js.map → layout-DaJO-1DW.js.map} +1 -1
  118. package/webapp/dist/assets/{linear-DIPh96mp.js → linear-SWy2Cl7G.js} +2 -2
  119. package/webapp/dist/assets/{linear-DIPh96mp.js.map → linear-SWy2Cl7G.js.map} +1 -1
  120. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-ofWsysn9.js → mindmap-definition-YRQLILUH-B_gNrT3l.js} +4 -4
  121. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-ofWsysn9.js.map → mindmap-definition-YRQLILUH-B_gNrT3l.js.map} +1 -1
  122. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-DQqCTITO.js → pieDiagram-SKSYHLDU-CVh3lLBA.js} +8 -8
  123. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-DQqCTITO.js.map → pieDiagram-SKSYHLDU-CVh3lLBA.js.map} +1 -1
  124. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-DxWc0avu.js → quadrantDiagram-337W2JSQ-D0zAkVD7.js} +3 -3
  125. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-DxWc0avu.js.map → quadrantDiagram-337W2JSQ-D0zAkVD7.js.map} +1 -1
  126. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-DHgYfzwt.js → requirementDiagram-Z7DCOOCP--CTFD60w.js} +4 -4
  127. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-DHgYfzwt.js.map → requirementDiagram-Z7DCOOCP--CTFD60w.js.map} +1 -1
  128. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-Cuhwe80W.js → sankeyDiagram-WA2Y5GQK-XZnViaAX.js} +2 -2
  129. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-Cuhwe80W.js.map → sankeyDiagram-WA2Y5GQK-XZnViaAX.js.map} +1 -1
  130. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-DqSNoro8.js → sequenceDiagram-2WXFIKYE-BWAMhn_x.js} +4 -4
  131. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-DqSNoro8.js.map → sequenceDiagram-2WXFIKYE-BWAMhn_x.js.map} +1 -1
  132. package/webapp/dist/assets/{stateDiagram-RAJIS63D-D1mvuJi6.js → stateDiagram-RAJIS63D--jsLD0Dg.js} +9 -9
  133. package/webapp/dist/assets/{stateDiagram-RAJIS63D-D1mvuJi6.js.map → stateDiagram-RAJIS63D--jsLD0Dg.js.map} +1 -1
  134. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-BCYX5Gy-.js → stateDiagram-v2-FVOUBMTO-DUG9vyI5.js} +5 -5
  135. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-BCYX5Gy-.js.map → stateDiagram-v2-FVOUBMTO-DUG9vyI5.js.map} +1 -1
  136. package/webapp/dist/assets/{timeline-definition-YZTLITO2-DDLYGao7.js → timeline-definition-YZTLITO2-BROLp1hL.js} +3 -3
  137. package/webapp/dist/assets/{timeline-definition-YZTLITO2-DDLYGao7.js.map → timeline-definition-YZTLITO2-BROLp1hL.js.map} +1 -1
  138. package/webapp/dist/assets/{treemap-KZPCXAKY-DXkv1e6y.js → treemap-KZPCXAKY-BXuIlbYo.js} +5 -5
  139. package/webapp/dist/assets/{treemap-KZPCXAKY-DXkv1e6y.js.map → treemap-KZPCXAKY-BXuIlbYo.js.map} +1 -1
  140. package/webapp/dist/assets/{vennDiagram-LZ73GAT5-DMxsg9P0.js → vennDiagram-LZ73GAT5-BXWd8gBB.js} +2 -2
  141. package/webapp/dist/assets/{vennDiagram-LZ73GAT5-DMxsg9P0.js.map → vennDiagram-LZ73GAT5-BXWd8gBB.js.map} +1 -1
  142. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-BJ2qipzT.js → xychartDiagram-JWTSCODW-DR5z9o6h.js} +3 -3
  143. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-BJ2qipzT.js.map → xychartDiagram-JWTSCODW-DR5z9o6h.js.map} +1 -1
  144. package/webapp/dist/index.html +1 -1
  145. package/webapp/dist/assets/index-YBIJr7jH.js.map +0 -1
@@ -148,11 +148,11 @@ function getMemoryPromptCopy(ctx) {
148
148
  const taskdocLogLineZh = ctx.contextHealthPromptMode === 'critical'
149
149
  ? ctx.isSideDialog
150
150
  ? '当前是告急处置态:支线对话不要维护差遣牒,也不要整理差遣牒更新提案;把当前对话历史中下一程需要知道的讨论细节、下一步、关键定位、运行/验证信息、临时路径/ID/样例输入和恢复依据写入接续包提醒项。提醒项长度没有技术限制,宁可完整一些;允许多条粗略提醒项求稳,但不要在当前程提前做“新一程清醒复核”。系统真正开启新一程后,第一步再复核整理:删除冗余、纠正偏激/失真思路,再收敛成高质量提醒项。'
151
- : '不要把长日志/大段 tool output 直接塞进差遣牒;差遣牒只写结论+下一步。当前是告急处置态:先检查当前对话历史里尚未落文档的讨论细节;能作为全队共享状态/决策/约束/目标的,主线优先用 `do_mind` 新增章节保存;只有在确实需要改写已有章节、且已完成合并时,才用 `change_mind`。接续包提醒项只留差遣牒仍未覆盖、但恢复工作容易丢的细节;本程允许先保留多条粗略提醒项求稳,但不要在当前程提前做“新一程清醒复核”。系统真正开启新一程后,第一步再复核整理:删除冗余、纠正偏激/失真思路,再收敛成高质量提醒项。'
151
+ : '不要把长日志/大段 tool output 直接塞进差遣牒;差遣牒只写结论+下一步。当前是告急处置态:先检查当前对话历史里尚未落文档的讨论细节;能作为全队共享状态/决策/约束/目标的,主线优先用 `do_mind` 新增章节保存;只有在确实需要改写已有章节、已完成合并且能带上当前 `content_hash` 作为 `previous_content_hash` 时,才用 `change_mind`。接续包提醒项只留差遣牒仍未覆盖、但恢复工作容易丢的细节;本程允许先保留多条粗略提醒项求稳,但不要在当前程提前做“新一程清醒复核”。系统真正开启新一程后,第一步再复核整理:删除冗余、纠正偏激/失真思路,再收敛成高质量提醒项。'
152
152
  : ctx.contextHealthPromptMode === 'caution'
153
153
  ? ctx.isSideDialog
154
154
  ? '当前是吃紧处置态:支线对话不要维护差遣牒,也不要整理差遣牒更新提案;把当前对话历史中下一程需要知道的讨论细节、下一步、关键定位、运行/验证信息、临时路径/ID/样例输入和恢复依据写入接续包提醒项。提醒项长度没有技术限制,宁可完整一些;若一时来不及,可先保留多条粗略提醒项过桥,但不要在当前程提前做“新一程清醒复核”。系统真正开启新一程后,第一步再复核整理:删除冗余、纠正偏激/失真思路,再收敛成高质量提醒项。'
155
- : '不要把长日志/大段 tool output 直接塞进差遣牒;差遣牒只写结论+下一步。当前是吃紧处置态:先检查当前对话历史里尚未落文档的讨论细节;能作为全队共享状态/决策/约束/目标的,主线优先用 `do_mind` 新增章节保存;只有在确实需要改写已有章节、且已完成合并时,才用 `change_mind`。接续包提醒项只留差遣牒仍未覆盖、但恢复工作容易丢的细节;若一时来不及,可先保留多条粗略提醒项过桥,但不要在当前程提前做“新一程清醒复核”。系统真正开启新一程后,第一步再复核整理:删除冗余、纠正偏激/失真思路,再收敛成高质量提醒项。'
155
+ : '不要把长日志/大段 tool output 直接塞进差遣牒;差遣牒只写结论+下一步。当前是吃紧处置态:先检查当前对话历史里尚未落文档的讨论细节;能作为全队共享状态/决策/约束/目标的,主线优先用 `do_mind` 新增章节保存;只有在确实需要改写已有章节、已完成合并且能带上当前 `content_hash` 作为 `previous_content_hash` 时,才用 `change_mind`。接续包提醒项只留差遣牒仍未覆盖、但恢复工作容易丢的细节;若一时来不及,可先保留多条粗略提醒项过桥,但不要在当前程提前做“新一程清醒复核”。系统真正开启新一程后,第一步再复核整理:删除冗余、纠正偏激/失真思路,再收敛成高质量提醒项。'
156
156
  : '不要把长日志/大段 tool output 直接塞进差遣牒;差遣牒只写结论+下一步;提醒项也只留可扫读摘录。接续包提醒项默认应保持结构化、便于快速恢复。';
157
157
  const contextHealthLineEn = ctx.contextHealthPromptMode === 'critical'
158
158
  ? ctx.isSideDialog
@@ -166,11 +166,11 @@ function getMemoryPromptCopy(ctx) {
166
166
  const taskdocLogLineEn = ctx.contextHealthPromptMode === 'critical'
167
167
  ? ctx.isSideDialog
168
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, prefer creating a new section with `do_mind`; use `change_mind` only when an existing section truly needs rewriting and you have merged against the current content. 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.'
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, prefer creating a new section with `do_mind`; use `change_mind` only when an existing section truly needs rewriting, you have merged against the current content, and you can pass the current `content_hash` as `previous_content_hash`. 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.'
170
170
  : ctx.contextHealthPromptMode === 'caution'
171
171
  ? ctx.isSideDialog
172
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, prefer creating a new section with `do_mind`; use `change_mind` only when an existing section truly needs rewriting and you have merged against the current content. 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.'
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, prefer creating a new section with `do_mind`; use `change_mind` only when an existing section truly needs rewriting, you have merged against the current content, and you can pass the current `content_hash` as `previous_content_hash`. 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.'
174
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.';
175
175
  if (ctx.language === 'zh') {
176
176
  return {
@@ -181,7 +181,7 @@ function getMemoryPromptCopy(ctx) {
181
181
  taskdocSemanticsLine: '- 章节语义约定:`progress` 是全队共享、准实时、可扫读的任务公告牌,用来记录当前有效状态、关键决策、下一步与仍成立阻塞;不是流水账,也不是个人工作记录。`goals` / `constraints` 是较稳定的任务契约;每次更新都必须保留仍然有效的他人条目。',
182
182
  taskdocSectionReplaceLine: ctx.isSideDialog && ctx.contextHealthPromptMode !== 'normal'
183
183
  ? '- 当前处于支线对话的上下文健康处置态:本程不要维护差遣牒,也不要整理差遣牒更新提案;把下一程需要恢复的细节写入足够详尽的接续包提醒项。'
184
- : `- 更新差遣牒时:少量新增条目可用 \`mind_more\` 追加(默认 progress);缺失章节用 \`do_mind\` 创建;需要删除陈旧项、重排结构或压缩时,用 \`change_mind\` 整章替换并先对照“上下文中注入的当前内容”做合并;需要删除整章文件时用 \`never_mind\`;禁止覆盖/抹掉他人条目;自己负责维护的条目必须标注责任人(例如 \`- [owner:@${ctx.agentId}] ...\` 或用 \`### @${ctx.agentId}\` 分块)。`,
184
+ : `- 更新差遣牒时:少量新增条目可用 \`mind_more\` 追加(默认 progress);缺失章节用 \`do_mind\` 创建;需要删除陈旧项、重排结构或压缩时,用 \`change_mind\` 整章替换并先对照“上下文中注入的当前内容”做合并,同时带上当前 \`content_hash\` 作为 \`previous_content_hash\`;需要删除整章文件时用 \`never_mind\`;禁止覆盖/抹掉他人条目;自己负责维护的条目必须标注责任人(例如 \`- [owner:@${ctx.agentId}] ...\` 或用 \`### @${ctx.agentId}\` 分块)。`,
185
185
  progressLine: ctx.isSideDialog && ctx.contextHealthPromptMode !== 'normal'
186
186
  ? '- 当前处于支线对话的上下文健康处置态:本程不更新 `progress`;只把下一程接续所需信息写入提醒项。'
187
187
  : '- 更新 `progress` 时:它必须始终是可供全队扫读的完整当前快照,而不是只追加自己这一轮的零散笔记。',
@@ -202,7 +202,7 @@ function getMemoryPromptCopy(ctx) {
202
202
  sideDialogWorkflowLine: ctx.contextHealthPromptMode === 'normal'
203
203
  ? `工作流:先做事 → 再提炼(\`update_reminder\`;必要时整理差遣牒追加条目/更新提案并诉请 \`@${ctx.taskdocMaintainerId}\` 合并写入)→ 然后 \`clear_mind\` 清空噪音。`
204
204
  : '工作流:停止扩张上下文 → 维护足够详尽的接续包提醒项(`add_reminder` 或 `update_reminder`,长度没有技术限制)→ 然后 `clear_mind` 开启新一程。',
205
- mainDialogWorkflowLine: '工作流:先做事 再提炼(`update_reminder` + `mind_more(progress)`;需要压缩/删旧时用 `change_mind(progress)`;要删除整章文件时用 `never_mind`)→ 然后 `clear_mind` 清空噪音。',
205
+ mainDialogWorkflowLine: '工作流:先做事 -> 再提炼(`update_reminder` + `mind_more(progress)`;需要压缩/删旧时用带 `previous_content_hash` 的 `change_mind`;要删除整章文件时用 `never_mind`)-> 然后 `clear_mind` 清空噪音。',
206
206
  contextHealthLine: contextHealthLineZh,
207
207
  taskdocLogLine: taskdocLogLineZh,
208
208
  };
@@ -215,7 +215,7 @@ function getMemoryPromptCopy(ctx) {
215
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.',
216
216
  taskdocSectionReplaceLine: ctx.isSideDialog && ctx.contextHealthPromptMode !== 'normal'
217
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); create missing sections with \`do_mind\`; when stale entries must be removed, reordered, or compressed, use \`change_mind\` for a full-section replacement based on the current injected content; when a whole section file should be removed, use \`never_mind\`; do not overwrite other contributors; add an explicit owner tag for entries you maintain (e.g., \`- [owner:@${ctx.agentId}] ...\` or a \`### @${ctx.agentId}\` block).`,
218
+ : `- When updating Taskdoc: use \`mind_more\` for small append-only additions (defaults to progress); create missing sections with \`do_mind\`; when stale entries must be removed, reordered, or compressed, use \`change_mind\` for a full-section replacement based on the current injected content and include the current \`content_hash\` as \`previous_content_hash\`; when a whole section file should be removed, use \`never_mind\`; 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
219
  progressLine: ctx.isSideDialog && ctx.contextHealthPromptMode !== 'normal'
220
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
221
  : '- When updating `progress`, keep it as a complete, team-scannable current snapshot instead of appending only your own latest notes.',
@@ -236,7 +236,7 @@ function getMemoryPromptCopy(ctx) {
236
236
  sideDialogWorkflowLine: ctx.contextHealthPromptMode === 'normal'
237
237
  ? `Workflow: do work → distill (\`update_reminder\`; when Taskdoc needs updates, draft append entries, a merged replacement, or a section deletion and ask \`@${ctx.taskdocMaintainerId}\`) → then \`clear_mind\` to drop noise.`
238
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; use `never_mind` when removing a whole section file) then `clear_mind` to drop noise.',
239
+ mainDialogWorkflowLine: 'Workflow: do work -> distill (`update_reminder` + `mind_more(progress)`; use `change_mind` with `previous_content_hash` when compression/deletion is needed; use `never_mind` when removing a whole section file) -> then `clear_mind` to drop noise.',
240
240
  contextHealthLine: contextHealthLineEn,
241
241
  taskdocLogLine: taskdocLogLineEn,
242
242
  };
@@ -75,8 +75,7 @@ export declare class DiskFileDialogStore extends DialogStore {
75
75
  * Ensure sideDialog directory exists (delegate to DialogPersistence)
76
76
  */
77
77
  private ensureSideDialogDirectory;
78
- private findExistingFuncResultRecord;
79
- private findExistingCallRecord;
78
+ private findExistingTellaskCallRecord;
80
79
  private findExistingTellaskResultRecord;
81
80
  private raiseDuplicateCallInvariantViolation;
82
81
  private raiseDuplicateCallResultInvariantViolation;
@@ -157,7 +156,7 @@ export declare class DiskFileDialogStore extends DialogStore {
157
156
  /**
158
157
  * Persist a function call to storage
159
158
  */
160
- persistFunctionCall(dialog: Dialog, id: string, name: string, rawArgumentsText: string, genseq: number): Promise<void>;
159
+ persistFunctionCall(dialog: Dialog, id: string, name: string, rawArgumentsText: string, genseq: number, rawId?: string): Promise<void>;
161
160
  persistTellaskCall(dialog: Dialog, id: string, name: 'tellaskBack' | 'tellask' | 'tellaskSessionless' | 'replyTellask' | 'replyTellaskSessionless' | 'replyTellaskBack' | 'askHuman' | 'freshBootsReasoning', rawArgumentsText: string, genseq: number, options?: {
162
161
  deliveryMode?: 'tellask_call_start' | 'func_call_requested';
163
162
  }): Promise<void>;
@@ -549,6 +549,8 @@ function buildFuncCallRecord(args) {
549
549
  ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
550
550
  type: 'func_call_record',
551
551
  genseq: args.genseq,
552
+ ...(args.rawId !== undefined ? { rawId: args.rawId } : {}),
553
+ ...(args.effectiveId !== undefined ? { effectiveId: args.effectiveId } : {}),
552
554
  id: args.id,
553
555
  name: args.name,
554
556
  rawArgumentsText: args.rawArgumentsText,
@@ -559,6 +561,8 @@ function buildFuncResultRecord(funcResult, genseq) {
559
561
  ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
560
562
  type: 'func_result_record',
561
563
  id: funcResult.id,
564
+ ...(funcResult.rawId !== undefined ? { rawId: funcResult.rawId } : {}),
565
+ ...(funcResult.effectiveId !== undefined ? { effectiveId: funcResult.effectiveId } : {}),
562
566
  name: funcResult.name,
563
567
  content: funcResult.content,
564
568
  contentItems: funcResult.contentItems,
@@ -1882,19 +1886,6 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
1882
1886
  if (!Number.isFinite(genseq) || genseq <= 0) {
1883
1887
  throw new Error(`receiveFuncResult invariant violation: missing valid genseq for func result ${funcResult.id}`);
1884
1888
  }
1885
- const existingFuncResult = await this.findExistingFuncResultRecord(dialog, funcResult.id);
1886
- if (existingFuncResult) {
1887
- await this.raiseDuplicateCallResultInvariantViolation({
1888
- dialog,
1889
- kind: 'func_result',
1890
- callId: funcResult.id,
1891
- callName: funcResult.name,
1892
- incomingCourse: course,
1893
- incomingGenseq: genseq,
1894
- existingCourse: existingFuncResult.course,
1895
- existingGenseq: existingFuncResult.record.genseq,
1896
- });
1897
- }
1898
1889
  const funcResultRecord = buildFuncResultRecord(funcResult, genseq);
1899
1890
  await this.appendEvent(dialog, course, funcResultRecord);
1900
1891
  // Send event to frontend
@@ -1905,6 +1896,8 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
1905
1896
  const funcResultEvt = {
1906
1897
  type: 'func_result_evt',
1907
1898
  id: funcResult.id,
1899
+ ...(funcResult.rawId !== undefined ? { rawId: funcResult.rawId } : {}),
1900
+ ...(funcResult.effectiveId !== undefined ? { effectiveId: funcResult.effectiveId } : {}),
1908
1901
  name: funcResult.name,
1909
1902
  content: funcResult.content,
1910
1903
  contentItems: funcResult.contentItems,
@@ -1916,7 +1909,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
1916
1909
  }
1917
1910
  async receiveTellaskResult(dialog, result) {
1918
1911
  const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
1919
- const existingTellaskResult = await this.findExistingTellaskResultRecord(dialog, result.callId);
1912
+ const existingTellaskResult = await this.findExistingTellaskResultRecord(dialog, course, result.callId);
1920
1913
  if (existingTellaskResult) {
1921
1914
  await this.raiseDuplicateCallResultInvariantViolation({
1922
1915
  dialog,
@@ -1925,7 +1918,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
1925
1918
  callName: result.callName,
1926
1919
  incomingCourse: course,
1927
1920
  incomingGenseq: undefined,
1928
- existingCourse: existingTellaskResult.course,
1921
+ existingCourse: course,
1929
1922
  existingGenseq: undefined,
1930
1923
  });
1931
1924
  }
@@ -1954,53 +1947,29 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
1954
1947
  async ensureSideDialogDirectory(dialogId) {
1955
1948
  return await DialogPersistence.ensureSideDialogDirectory(dialogId);
1956
1949
  }
1957
- async findExistingFuncResultRecord(dialog, callId) {
1958
- const latest = await DialogPersistence.loadDialogLatest(dialog.id, dialog.status);
1959
- const maxCourse = latest?.currentCourse ?? dialog.currentCourse;
1960
- for (let course = 1; course <= maxCourse; course += 1) {
1961
- const events = await DialogPersistence.loadCourseEvents(dialog.id, course, dialog.status);
1962
- for (const event of events) {
1963
- if (event.type !== 'func_result_record') {
1964
- continue;
1965
- }
1966
- if (event.id !== callId) {
1967
- continue;
1968
- }
1969
- return { course, record: event };
1950
+ async findExistingTellaskCallRecord(dialog, course, callId) {
1951
+ const events = await DialogPersistence.loadCourseEvents(dialog.id, course, dialog.status);
1952
+ for (const event of events) {
1953
+ if (event.type !== 'tellask_call_record') {
1954
+ continue;
1970
1955
  }
1971
- }
1972
- return undefined;
1973
- }
1974
- async findExistingCallRecord(dialog, callId) {
1975
- const latest = await DialogPersistence.loadDialogLatest(dialog.id, dialog.status);
1976
- const maxCourse = latest?.currentCourse ?? dialog.currentCourse;
1977
- for (let course = 1; course <= maxCourse; course += 1) {
1978
- const events = await DialogPersistence.loadCourseEvents(dialog.id, course, dialog.status);
1979
- for (const event of events) {
1980
- if (event.type === 'func_call_record' && event.id === callId) {
1981
- return { course, record: event };
1982
- }
1983
- if (event.type === 'tellask_call_record' && event.id === callId) {
1984
- return { course, record: event };
1985
- }
1956
+ if (event.id !== callId) {
1957
+ continue;
1986
1958
  }
1959
+ return event;
1987
1960
  }
1988
1961
  return undefined;
1989
1962
  }
1990
- async findExistingTellaskResultRecord(dialog, callId) {
1991
- const latest = await DialogPersistence.loadDialogLatest(dialog.id, dialog.status);
1992
- const maxCourse = latest?.currentCourse ?? dialog.currentCourse;
1993
- for (let course = 1; course <= maxCourse; course += 1) {
1994
- const events = await DialogPersistence.loadCourseEvents(dialog.id, course, dialog.status);
1995
- for (const event of events) {
1996
- if (event.type !== 'tellask_result_record') {
1997
- continue;
1998
- }
1999
- if (event.callId !== callId) {
2000
- continue;
2001
- }
2002
- return { course, record: event };
1963
+ async findExistingTellaskResultRecord(dialog, course, callId) {
1964
+ const events = await DialogPersistence.loadCourseEvents(dialog.id, course, dialog.status);
1965
+ for (const event of events) {
1966
+ if (event.type !== 'tellask_result_record') {
1967
+ continue;
1968
+ }
1969
+ if (event.callId !== callId) {
1970
+ continue;
2003
1971
  }
1972
+ return event;
2004
1973
  }
2005
1974
  return undefined;
2006
1975
  }
@@ -2763,30 +2732,26 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
2763
2732
  /**
2764
2733
  * Persist a function call to storage
2765
2734
  */
2766
- async persistFunctionCall(dialog, id, name, rawArgumentsText, genseq) {
2735
+ async persistFunctionCall(dialog, id, name, rawArgumentsText, genseq, rawId) {
2767
2736
  const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
2768
2737
  if (!Number.isFinite(genseq) || genseq <= 0) {
2769
2738
  throw new Error(`persistFunctionCall invariant violation: missing valid genseq for func call ${id}`);
2770
2739
  }
2771
- const existingCall = await this.findExistingCallRecord(dialog, id);
2772
- if (existingCall) {
2773
- await this.raiseDuplicateCallInvariantViolation({
2774
- dialog,
2775
- kind: 'func_call',
2776
- callId: id,
2777
- callName: name,
2778
- incomingCourse: course,
2779
- incomingGenseq: genseq,
2780
- existingCourse: existingCall.course,
2781
- existingGenseq: existingCall.record.genseq,
2782
- existingName: existingCall.record.name,
2783
- });
2784
- }
2785
- const funcCallEvent = buildFuncCallRecord({ id, name, rawArgumentsText, genseq });
2740
+ const normalizedRawId = typeof rawId === 'string' && rawId.trim() !== '' ? rawId : id;
2741
+ const funcCallEvent = buildFuncCallRecord({
2742
+ rawId: normalizedRawId,
2743
+ effectiveId: id,
2744
+ id,
2745
+ name,
2746
+ rawArgumentsText,
2747
+ genseq,
2748
+ });
2786
2749
  await this.appendEvent(dialog, course, funcCallEvent);
2787
2750
  const funcCallEvt = {
2788
2751
  type: 'func_call_requested_evt',
2789
2752
  funcId: id,
2753
+ rawFuncId: normalizedRawId,
2754
+ effectiveFuncId: id,
2790
2755
  funcName: name,
2791
2756
  arguments: rawArgumentsText,
2792
2757
  course,
@@ -2799,7 +2764,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
2799
2764
  if (!Number.isFinite(genseq) || genseq <= 0) {
2800
2765
  throw new Error(`persistTellaskCall invariant violation: missing valid genseq for tellask call ${id}`);
2801
2766
  }
2802
- const existingCall = await this.findExistingCallRecord(dialog, id);
2767
+ const existingCall = await this.findExistingTellaskCallRecord(dialog, course, id);
2803
2768
  if (existingCall) {
2804
2769
  await this.raiseDuplicateCallInvariantViolation({
2805
2770
  dialog,
@@ -2808,9 +2773,9 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
2808
2773
  callName: name,
2809
2774
  incomingCourse: course,
2810
2775
  incomingGenseq: genseq,
2811
- existingCourse: existingCall.course,
2812
- existingGenseq: existingCall.record.genseq,
2813
- existingName: existingCall.record.name,
2776
+ existingCourse: course,
2777
+ existingGenseq: existingCall.genseq,
2778
+ existingName: existingCall.name,
2814
2779
  });
2815
2780
  }
2816
2781
  const tellaskCallEvent = buildTellaskCallRecord({
@@ -2826,6 +2791,8 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
2826
2791
  const funcCallEvt = {
2827
2792
  type: 'func_call_requested_evt',
2828
2793
  funcId: id,
2794
+ rawFuncId: id,
2795
+ effectiveFuncId: id,
2829
2796
  funcName: name,
2830
2797
  arguments: formatTellaskCallArguments(tellaskCallEvent),
2831
2798
  course,
@@ -3373,6 +3340,8 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
3373
3340
  const funcCall = {
3374
3341
  type: 'func_call_requested_evt',
3375
3342
  funcId: event.id,
3343
+ rawFuncId: event.rawId,
3344
+ effectiveFuncId: event.effectiveId ?? event.id,
3376
3345
  funcName: event.name,
3377
3346
  arguments: event.rawArgumentsText,
3378
3347
  course,
@@ -3393,6 +3362,8 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
3393
3362
  const replyCall = {
3394
3363
  type: 'func_call_requested_evt',
3395
3364
  funcId: event.id,
3365
+ rawFuncId: event.id,
3366
+ effectiveFuncId: event.id,
3396
3367
  funcName: event.name,
3397
3368
  arguments: formatTellaskCallArguments(event),
3398
3369
  course,
@@ -3598,6 +3569,8 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
3598
3569
  const funcResult = {
3599
3570
  type: 'func_result_evt',
3600
3571
  id: event.id,
3572
+ rawId: event.rawId,
3573
+ effectiveId: event.effectiveId ?? event.id,
3601
3574
  name: event.name,
3602
3575
  content: event.content,
3603
3576
  contentItems: event.contentItems,
@@ -6894,6 +6867,8 @@ class DialogPersistence {
6894
6867
  role: 'assistant',
6895
6868
  genseq: event.genseq,
6896
6869
  id: event.id,
6870
+ ...(event.rawId !== undefined ? { rawId: event.rawId } : {}),
6871
+ ...(event.effectiveId !== undefined ? { effectiveId: event.effectiveId } : {}),
6897
6872
  name: event.name,
6898
6873
  arguments: event.rawArgumentsText,
6899
6874
  });
@@ -6933,6 +6908,8 @@ class DialogPersistence {
6933
6908
  role: 'tool',
6934
6909
  genseq: event.genseq,
6935
6910
  id: event.id,
6911
+ ...(event.rawId !== undefined ? { rawId: event.rawId } : {}),
6912
+ ...(event.effectiveId !== undefined ? { effectiveId: event.effectiveId } : {}),
6936
6913
  name: event.name,
6937
6914
  content: event.content,
6938
6915
  contentItems: event.contentItems,
package/dist/problems.js CHANGED
@@ -207,9 +207,10 @@ function getProblemPath(problem) {
207
207
  case 'mcp_tool_blacklisted':
208
208
  case 'mcp_tool_not_whitelisted':
209
209
  case 'mcp_tool_invalid_name':
210
- case 'llm_provider_rejected_request':
211
210
  case 'generic_problem':
212
211
  return null;
212
+ case 'llm_provider_rejected_request':
213
+ return problem.detail.requestPayloadPath ?? problem.detail.debugPath ?? null;
213
214
  }
214
215
  }
215
216
  function normalizeComparablePath(raw) {
@@ -407,7 +407,7 @@ function formatAgentFacingContextHealthV3RemediationGuide(language, args) {
407
407
  '',
408
408
  '操作:',
409
409
  '- 优先新增差遣牒章节保存讨论细节:do_mind({ "category": "<category>", "selector": "<selector>", "content": "..." })',
410
- '- 只有在确实需要改写已有章节、且已对照当前差遣牒内容完成合并时,才更新:change_mind({ ... })',
410
+ '- 只有在确实需要改写已有章节、且已对照当前差遣牒内容完成合并并带上 `previous_content_hash` 时,才更新:change_mind({"selector":"<selector>","content":"...","previous_content_hash":"sha256:..."})',
411
411
  '- 优先新增过桥提醒项:add_reminder({ "content": "..." })',
412
412
  '- 只有在确实能就地复用现有提醒项、且不会额外增加当前程认知负担时,才更新:update_reminder({ "reminder_id": "<现有 reminder_id>", "content": "..." })',
413
413
  ].join('\n');
@@ -443,7 +443,7 @@ function formatAgentFacingContextHealthV3RemediationGuide(language, args) {
443
443
  '',
444
444
  '操作:',
445
445
  '- 优先新增差遣牒章节保存讨论细节:do_mind({ "category": "<category>", "selector": "<selector>", "content": "..." })',
446
- '- 只有在确实需要改写已有章节、且已对照当前差遣牒内容完成合并时,才更新:change_mind({ ... })',
446
+ '- 只有在确实需要改写已有章节、且已对照当前差遣牒内容完成合并并带上 `previous_content_hash` 时,才更新:change_mind({"selector":"<selector>","content":"...","previous_content_hash":"sha256:..."})',
447
447
  '- 优先新增过桥提醒项:add_reminder({ "content": "..." })',
448
448
  '- 只有在确实能就地复用现有提醒项、且不会额外增加当前程认知负担时,才更新:update_reminder({ "reminder_id": "<现有 reminder_id>", "content": "..." })',
449
449
  '- clear_mind({})',
@@ -484,7 +484,7 @@ function formatAgentFacingContextHealthV3RemediationGuide(language, args) {
484
484
  '',
485
485
  'Operations:',
486
486
  '- Prefer creating a new Taskdoc section for discussion details: do_mind({ "category": "<category>", "selector": "<selector>", "content": "..." })',
487
- '- Only update when an existing section truly needs rewriting and you have merged against the current Taskdoc content: change_mind({ ... })',
487
+ '- Only update when an existing section truly needs rewriting and you have merged against the current Taskdoc content and can provide `previous_content_hash`: change_mind({"selector":"<selector>","content":"...","previous_content_hash":"sha256:..."})',
488
488
  '- Prefer adding a bridge reminder first: add_reminder({ "content": "..." })',
489
489
  '- Only if an existing reminder is clearly the right place, and updating it would not add extra cognitive load in the current course: update_reminder({ "reminder_id": "<existing reminder_id>", "content": "..." })',
490
490
  ].join('\n');
@@ -520,7 +520,7 @@ function formatAgentFacingContextHealthV3RemediationGuide(language, args) {
520
520
  '',
521
521
  'Operations:',
522
522
  '- Prefer creating a new Taskdoc section for discussion details: do_mind({ "category": "<category>", "selector": "<selector>", "content": "..." })',
523
- '- Only update when an existing section truly needs rewriting and you have merged against the current Taskdoc content: change_mind({ ... })',
523
+ '- Only update when an existing section truly needs rewriting and you have merged against the current Taskdoc content and can provide `previous_content_hash`: change_mind({"selector":"<selector>","content":"...","previous_content_hash":"sha256:..."})',
524
524
  '- Prefer adding a bridge reminder first: add_reminder({ "content": "..." })',
525
525
  '- Only if an existing reminder is clearly the right place, and updating it would not add extra cognitive load in the current course: update_reminder({ "reminder_id": "<existing reminder_id>", "content": "..." })',
526
526
  '- clear_mind({})',
@@ -717,11 +717,13 @@ async function maybeTriggerImmediateDiligencePrompt(mainDialog) {
717
717
  patch: { diligencePushRemainingBudget: mainDialog.diligencePushRemainingBudget },
718
718
  }));
719
719
  if (prepared.kind !== 'disabled') {
720
+ const maxInjectCount = Math.max(0, Math.floor(prepared.maxInjectCount));
721
+ const remainingCount = Math.max(0, Math.floor(prepared.nextRemainingBudget));
720
722
  (0, evt_registry_1.postDialogEvent)(mainDialog, {
721
723
  type: 'diligence_budget_evt',
722
- maxInjectCount: prepared.maxInjectCount,
723
- injectedCount: Math.max(0, prepared.maxInjectCount - prepared.nextRemainingBudget),
724
- remainingCount: Math.max(0, prepared.nextRemainingBudget),
724
+ maxInjectCount,
725
+ injectedCount: maxInjectCount > 0 ? Math.max(0, maxInjectCount - remainingCount) : 0,
726
+ remainingCount,
725
727
  disableDiligencePush: mainDialog.disableDiligencePush,
726
728
  });
727
729
  }
@@ -730,6 +732,18 @@ async function maybeTriggerImmediateDiligencePrompt(mainDialog) {
730
732
  source: 'ws_diligence_push',
731
733
  reason: 'enable_keep_going_immediate_prompt',
732
734
  });
735
+ return;
736
+ }
737
+ if (prepared.kind === 'budget_exhausted') {
738
+ await (0, runtime_2.suspendForKeepGoingBudgetExhausted)({
739
+ dlg: mainDialog,
740
+ maxInjectCount: prepared.maxInjectCount,
741
+ });
742
+ mainDialog.diligencePushRemainingBudget = 0;
743
+ await persistence_1.DialogPersistence.mutateDialogLatest(mainDialog.id, () => ({
744
+ kind: 'patch',
745
+ patch: { diligencePushRemainingBudget: mainDialog.diligencePushRemainingBudget },
746
+ }));
733
747
  }
734
748
  }
735
749
  catch (error) {
package/dist/team.d.ts CHANGED
@@ -55,6 +55,7 @@ export declare namespace Team {
55
55
  web_search_allowed_domains?: string[];
56
56
  web_search_include_sources?: boolean;
57
57
  };
58
+ type OpenAiCompatibleThinkingMode = 'auto' | 'off' | 'low' | 'medium' | 'high';
58
59
  type OpenAiCompatibleModelParams = {
59
60
  temperature?: number;
60
61
  service_tier?: 'auto' | 'default' | 'flex' | 'scale' | 'priority';
@@ -66,7 +67,7 @@ export declare namespace Team {
66
67
  text_format_json_schema?: string;
67
68
  text_format_json_schema_strict?: boolean;
68
69
  reasoning_effort?: 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';
69
- thinking?: boolean | Record<string, unknown>;
70
+ thinking?: boolean | OpenAiCompatibleThinkingMode | Record<string, unknown>;
70
71
  };
71
72
  type AnthropicThinkingConfig = {
72
73
  type: 'adaptive';
package/dist/team.js CHANGED
@@ -2322,7 +2322,17 @@ exports.Team = Team;
2322
2322
  asOptionalString(params.text_format_json_schema_name, `${at2}.text_format_json_schema_name`);
2323
2323
  asOptionalString(params.text_format_json_schema, `${at2}.text_format_json_schema`);
2324
2324
  asOptionalBoolean(params.text_format_json_schema_strict, `${at2}.text_format_json_schema_strict`);
2325
- validateOptionalBooleanOrObject(params.thinking, `${at2}.thinking`);
2325
+ const thinking = params.thinking;
2326
+ if (thinking !== undefined &&
2327
+ typeof thinking !== 'boolean' &&
2328
+ !isRecordValue(thinking) &&
2329
+ thinking !== 'auto' &&
2330
+ thinking !== 'off' &&
2331
+ thinking !== 'low' &&
2332
+ thinking !== 'medium' &&
2333
+ thinking !== 'high') {
2334
+ throw new Error(`Invalid ${at2}.thinking: expected boolean|object|auto|off|low|medium|high (got ${describeValueType(thinking)})`);
2335
+ }
2326
2336
  const serviceTier = params.service_tier;
2327
2337
  if (serviceTier !== undefined &&
2328
2338
  serviceTier !== 'auto' &&