dominds 1.23.8 → 1.23.10

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 (166) hide show
  1. package/dist/docs/dialog-system.md +2 -2
  2. package/dist/docs/dialog-system.zh.md +2 -2
  3. package/dist/docs/dominds-terminology.md +2 -2
  4. package/dist/docs/tellask-collab.md +4 -2
  5. package/dist/docs/tellask-collab.zh.md +4 -2
  6. package/dist/llm/defaults.yaml +3 -0
  7. package/dist/llm/gen/codex.js +26 -5
  8. package/dist/llm/gen/openai-compatible.js +0 -2
  9. package/dist/llm/gen/openai.js +36 -4
  10. package/dist/llm/kernel-driver/drive.js +2 -2
  11. package/dist/llm/kernel-driver/events.js +6 -3
  12. package/dist/minds/system-prompt-parts.js +2 -2
  13. package/dist/minds/system-prompt.js +8 -4
  14. package/dist/persistence.d.ts +1 -0
  15. package/dist/persistence.js +44 -43
  16. package/dist/priming.js +39 -2
  17. package/dist/tools/pending-tellask-reminder.js +6 -6
  18. package/dist/tools/prompts/control/en/principles.md +1 -0
  19. package/dist/tools/prompts/control/zh/principles.md +1 -0
  20. package/package.json +3 -3
  21. package/webapp/dist/assets/{_basePickBy-BKcCOLIM.js → _basePickBy-CBh9Agsi.js} +3 -3
  22. package/webapp/dist/assets/_basePickBy-CBh9Agsi.js.map +1 -0
  23. package/webapp/dist/assets/{_baseUniq-7-u-sxFw.js → _baseUniq-D2UXV506.js} +2 -2
  24. package/webapp/dist/assets/_baseUniq-D2UXV506.js.map +1 -0
  25. package/webapp/dist/assets/{arc-d4KSm3Dw.js → arc-CmeRUuzC.js} +2 -2
  26. package/webapp/dist/assets/arc-CmeRUuzC.js.map +1 -0
  27. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-BRszd4pF.js → architectureDiagram-VXUJARFQ-D5hfsb4A.js} +8 -26
  28. package/webapp/dist/assets/architectureDiagram-VXUJARFQ-D5hfsb4A.js.map +1 -0
  29. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-BCleQsi6.js → blockDiagram-VD42YOAC-BVswEa9D.js} +170 -187
  30. package/webapp/dist/assets/blockDiagram-VD42YOAC-BVswEa9D.js.map +1 -0
  31. package/webapp/dist/assets/{c4Diagram-IC4MRINW-CIPOdGL1.js → c4Diagram-YG6GDRKO-Bgm6yzGX.js} +4 -4
  32. package/webapp/dist/assets/c4Diagram-YG6GDRKO-Bgm6yzGX.js.map +1 -0
  33. package/webapp/dist/assets/{channel-D-m6pRdq.js → channel-CDo0v82C.js} +2 -2
  34. package/webapp/dist/assets/channel-CDo0v82C.js.map +1 -0
  35. package/webapp/dist/assets/{chunk-4BX2VUAB-BWYOOC08.js → chunk-4BX2VUAB-DMqSdYxu.js} +2 -2
  36. package/webapp/dist/assets/chunk-4BX2VUAB-DMqSdYxu.js.map +1 -0
  37. package/webapp/dist/assets/{chunk-55IACEB6-DXMYVodl.js → chunk-55IACEB6-CudmE3Fx.js} +2 -2
  38. package/webapp/dist/assets/chunk-55IACEB6-CudmE3Fx.js.map +1 -0
  39. package/webapp/dist/assets/{chunk-WL4C6EOR-BH9YAFjs.js → chunk-B4BG7PRW-d5dfiagO.js} +121 -171
  40. package/webapp/dist/assets/chunk-B4BG7PRW-d5dfiagO.js.map +1 -0
  41. package/webapp/dist/assets/{chunk-NQ4KR5QH-Ct6A6c5Z.js → chunk-DI55MBZ5-CZCetJxI.js} +7 -9
  42. package/webapp/dist/assets/chunk-DI55MBZ5-CZCetJxI.js.map +1 -0
  43. package/webapp/dist/assets/{chunk-FMBD7UC4-ryTUBUk6.js → chunk-FMBD7UC4-BSVSuNxy.js} +2 -2
  44. package/webapp/dist/assets/chunk-FMBD7UC4-BSVSuNxy.js.map +1 -0
  45. package/webapp/dist/assets/{chunk-KX2RTZJC-DHmRW8Fy.js → chunk-QN33PNHL-Cbf-pIxI.js} +2 -2
  46. package/webapp/dist/assets/chunk-QN33PNHL-Cbf-pIxI.js.map +1 -0
  47. package/webapp/dist/assets/{chunk-QZHKN3VN-J-aYTkDG.js → chunk-QZHKN3VN-DYyIY8_q.js} +2 -2
  48. package/webapp/dist/assets/chunk-QZHKN3VN-DYyIY8_q.js.map +1 -0
  49. package/webapp/dist/assets/{chunk-JSJVCQXG-DBdXbF3A.js → chunk-TZMSLE5B-aW2uEdtS.js} +6 -14
  50. package/webapp/dist/assets/chunk-TZMSLE5B-aW2uEdtS.js.map +1 -0
  51. package/webapp/dist/assets/{classDiagram-VBA2DB6C-6_iFdvnA.js → classDiagram-2ON5EDUG-C4-5PgVL.js} +6 -7
  52. package/webapp/dist/assets/classDiagram-2ON5EDUG-C4-5PgVL.js.map +1 -0
  53. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-6_iFdvnA.js → classDiagram-v2-WZHVMYZB-C4-5PgVL.js} +6 -7
  54. package/webapp/dist/assets/classDiagram-v2-WZHVMYZB-C4-5PgVL.js.map +1 -0
  55. package/webapp/dist/assets/{clone-CB_At6rt.js → clone-DivPByZ0.js} +2 -2
  56. package/webapp/dist/assets/clone-DivPByZ0.js.map +1 -0
  57. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-Cd8UzjNB.js → cose-bilkent-S5V4N54A-CwBAjMT3.js} +2 -2
  58. package/webapp/dist/assets/cose-bilkent-S5V4N54A-CwBAjMT3.js.map +1 -0
  59. package/webapp/dist/assets/cytoscape.esm-Bm8DJGmZ.js.map +1 -1
  60. package/webapp/dist/assets/{dagre-KLK3FWXG-CdwYIQOJ.js → dagre-6UL2VRFP-tC56AIio.js} +7 -7
  61. package/webapp/dist/assets/dagre-6UL2VRFP-tC56AIio.js.map +1 -0
  62. package/webapp/dist/assets/defaultLocale-B2RvLBDe.js.map +1 -1
  63. package/webapp/dist/assets/{diagram-E7M64L7V-Cst9U1IU.js → diagram-PSM6KHXK-dEF_O6uj.js} +10 -10
  64. package/webapp/dist/assets/diagram-PSM6KHXK-dEF_O6uj.js.map +1 -0
  65. package/webapp/dist/assets/{diagram-IFDJBPK2-DbpZNhXp.js → diagram-QEK2KX5R-BC3CyB81.js} +8 -9
  66. package/webapp/dist/assets/diagram-QEK2KX5R-BC3CyB81.js.map +1 -0
  67. package/webapp/dist/assets/{diagram-P4PSJMXO-BrJUtC9e.js → diagram-S2PKOQOG-BV-YMbA_.js} +8 -8
  68. package/webapp/dist/assets/diagram-S2PKOQOG-BV-YMbA_.js.map +1 -0
  69. package/webapp/dist/assets/{erDiagram-INFDFZHY-CDgITFMs.js → erDiagram-Q2GNP2WA-DIgdtwce.js} +75 -96
  70. package/webapp/dist/assets/erDiagram-Q2GNP2WA-DIgdtwce.js.map +1 -0
  71. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-aFGKk-PM.js → flowDiagram-NV44I4VS-C7Mawlld.js} +81 -98
  72. package/webapp/dist/assets/flowDiagram-NV44I4VS-C7Mawlld.js.map +1 -0
  73. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-BZ_u2elV.js → ganttDiagram-JELNMOA3-DgaYLOeL.js} +3 -28
  74. package/webapp/dist/assets/ganttDiagram-JELNMOA3-DgaYLOeL.js.map +1 -0
  75. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-DH6bOdey.js → gitGraphDiagram-V2S2FVAM-Dwv1ZLFB.js} +46 -38
  76. package/webapp/dist/assets/gitGraphDiagram-V2S2FVAM-Dwv1ZLFB.js.map +1 -0
  77. package/webapp/dist/assets/graph-saC_350a.js +425 -0
  78. package/webapp/dist/assets/graph-saC_350a.js.map +1 -0
  79. package/webapp/dist/assets/{index-DZFkLLVz.css → index-BGdI3lWA.css} +1 -1
  80. package/webapp/dist/assets/{index--IEBo-K3.js → index-BsSFGqVX.js} +1353 -1091
  81. package/webapp/dist/assets/index-BsSFGqVX.js.map +1 -0
  82. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-Cwrydc6U.js → infoDiagram-HS3SLOUP-PDKRqD6y.js} +7 -7
  83. package/webapp/dist/assets/infoDiagram-HS3SLOUP-PDKRqD6y.js.map +1 -0
  84. package/webapp/dist/assets/init-ZxktEp_H.js.map +1 -1
  85. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-Dy7G86Ao.js → journeyDiagram-XKPGCS4Q-DDD6YlTa.js} +5 -5
  86. package/webapp/dist/assets/journeyDiagram-XKPGCS4Q-DDD6YlTa.js.map +1 -0
  87. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-C76eRxWS.js → kanban-definition-3W4ZIXB7-CK-CJzXm.js} +3 -5
  88. package/webapp/dist/assets/kanban-definition-3W4ZIXB7-CK-CJzXm.js.map +1 -0
  89. package/webapp/dist/assets/{layout-BImZEpEr.js → layout-DRs2ltCp.js} +5 -5
  90. package/webapp/dist/assets/layout-DRs2ltCp.js.map +1 -0
  91. package/webapp/dist/assets/{linear-DHdMAAzV.js → linear-CiMu0dYF.js} +2 -2
  92. package/webapp/dist/assets/linear-CiMu0dYF.js.map +1 -0
  93. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-GOhVsm4O.js → mindmap-definition-VGOIOE7T-C8yEoHXx.js} +5 -7
  94. package/webapp/dist/assets/mindmap-definition-VGOIOE7T-C8yEoHXx.js.map +1 -0
  95. package/webapp/dist/assets/ordinal-CxptdPJm.js.map +1 -1
  96. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-CZvk1jXC.js → pieDiagram-ADFJNKIX-BhtVILXQ.js} +8 -8
  97. package/webapp/dist/assets/pieDiagram-ADFJNKIX-BhtVILXQ.js.map +1 -0
  98. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-rREIz2-L.js → quadrantDiagram-AYHSOK5B-B7Xuuv_G.js} +3 -3
  99. package/webapp/dist/assets/quadrantDiagram-AYHSOK5B-B7Xuuv_G.js.map +1 -0
  100. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-C7Ko_VBz.js → requirementDiagram-UZGBJVZJ-DY6Q4U6l.js} +6 -16
  101. package/webapp/dist/assets/requirementDiagram-UZGBJVZJ-DY6Q4U6l.js.map +1 -0
  102. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-C4IvqC76.js → sankeyDiagram-TZEHDZUN-DZPox4PX.js} +2 -2
  103. package/webapp/dist/assets/sankeyDiagram-TZEHDZUN-DZPox4PX.js.map +1 -0
  104. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-BFvPV1wQ.js → sequenceDiagram-WL72ISMW-Bg6GPP0w.js} +201 -601
  105. package/webapp/dist/assets/sequenceDiagram-WL72ISMW-Bg6GPP0w.js.map +1 -0
  106. package/webapp/dist/assets/{stateDiagram-RAJIS63D-BcXbrOQl.js → stateDiagram-FKZM4ZOC-CcskYNpn.js} +9 -9
  107. package/webapp/dist/assets/stateDiagram-FKZM4ZOC-CcskYNpn.js.map +1 -0
  108. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-g15Y_50y.js → stateDiagram-v2-4FDKWEC3-Dja5UwuW.js} +5 -5
  109. package/webapp/dist/assets/stateDiagram-v2-4FDKWEC3-Dja5UwuW.js.map +1 -0
  110. package/webapp/dist/assets/{timeline-definition-YZTLITO2-CGP_BvY2.js → timeline-definition-IT6M3QCI-CA-Wvxg8.js} +3 -3
  111. package/webapp/dist/assets/timeline-definition-IT6M3QCI-CA-Wvxg8.js.map +1 -0
  112. package/webapp/dist/assets/{treemap-KZPCXAKY-B98r-m60.js → treemap-GDKQZRPO-CF_Fur4n.js} +24 -37
  113. package/webapp/dist/assets/treemap-GDKQZRPO-CF_Fur4n.js.map +1 -0
  114. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-CD7DBeTl.js → xychartDiagram-PRI3JC2R-CYc3vOkZ.js} +4 -4
  115. package/webapp/dist/assets/xychartDiagram-PRI3JC2R-CYc3vOkZ.js.map +1 -0
  116. package/webapp/dist/index.html +2 -2
  117. package/webapp/dist/assets/_basePickBy-BKcCOLIM.js.map +0 -1
  118. package/webapp/dist/assets/_baseUniq-7-u-sxFw.js.map +0 -1
  119. package/webapp/dist/assets/arc-d4KSm3Dw.js.map +0 -1
  120. package/webapp/dist/assets/architectureDiagram-2XIMDMQ5-BRszd4pF.js.map +0 -1
  121. package/webapp/dist/assets/blockDiagram-WCTKOSBZ-BCleQsi6.js.map +0 -1
  122. package/webapp/dist/assets/c4Diagram-IC4MRINW-CIPOdGL1.js.map +0 -1
  123. package/webapp/dist/assets/channel-D-m6pRdq.js.map +0 -1
  124. package/webapp/dist/assets/chunk-4BX2VUAB-BWYOOC08.js.map +0 -1
  125. package/webapp/dist/assets/chunk-55IACEB6-DXMYVodl.js.map +0 -1
  126. package/webapp/dist/assets/chunk-FMBD7UC4-ryTUBUk6.js.map +0 -1
  127. package/webapp/dist/assets/chunk-JSJVCQXG-DBdXbF3A.js.map +0 -1
  128. package/webapp/dist/assets/chunk-KX2RTZJC-DHmRW8Fy.js.map +0 -1
  129. package/webapp/dist/assets/chunk-NQ4KR5QH-Ct6A6c5Z.js.map +0 -1
  130. package/webapp/dist/assets/chunk-QZHKN3VN-J-aYTkDG.js.map +0 -1
  131. package/webapp/dist/assets/chunk-WL4C6EOR-BH9YAFjs.js.map +0 -1
  132. package/webapp/dist/assets/classDiagram-VBA2DB6C-6_iFdvnA.js.map +0 -1
  133. package/webapp/dist/assets/classDiagram-v2-RAHNMMFH-6_iFdvnA.js.map +0 -1
  134. package/webapp/dist/assets/clone-CB_At6rt.js.map +0 -1
  135. package/webapp/dist/assets/cose-bilkent-S5V4N54A-Cd8UzjNB.js.map +0 -1
  136. package/webapp/dist/assets/dagre-KLK3FWXG-CdwYIQOJ.js.map +0 -1
  137. package/webapp/dist/assets/diagram-E7M64L7V-Cst9U1IU.js.map +0 -1
  138. package/webapp/dist/assets/diagram-IFDJBPK2-DbpZNhXp.js.map +0 -1
  139. package/webapp/dist/assets/diagram-P4PSJMXO-BrJUtC9e.js.map +0 -1
  140. package/webapp/dist/assets/erDiagram-INFDFZHY-CDgITFMs.js.map +0 -1
  141. package/webapp/dist/assets/flowDiagram-PKNHOUZH-aFGKk-PM.js.map +0 -1
  142. package/webapp/dist/assets/ganttDiagram-A5KZAMGK-BZ_u2elV.js.map +0 -1
  143. package/webapp/dist/assets/gitGraphDiagram-K3NZZRJ6-DH6bOdey.js.map +0 -1
  144. package/webapp/dist/assets/graph-CvVYx_lD.js +0 -782
  145. package/webapp/dist/assets/graph-CvVYx_lD.js.map +0 -1
  146. package/webapp/dist/assets/index--IEBo-K3.js.map +0 -1
  147. package/webapp/dist/assets/infoDiagram-LFFYTUFH-Cwrydc6U.js.map +0 -1
  148. package/webapp/dist/assets/ishikawaDiagram-PHBUUO56-PAaQGWUX.js +0 -966
  149. package/webapp/dist/assets/ishikawaDiagram-PHBUUO56-PAaQGWUX.js.map +0 -1
  150. package/webapp/dist/assets/journeyDiagram-4ABVD52K-Dy7G86Ao.js.map +0 -1
  151. package/webapp/dist/assets/kanban-definition-K7BYSVSG-C76eRxWS.js.map +0 -1
  152. package/webapp/dist/assets/layout-BImZEpEr.js.map +0 -1
  153. package/webapp/dist/assets/linear-DHdMAAzV.js.map +0 -1
  154. package/webapp/dist/assets/mindmap-definition-YRQLILUH-GOhVsm4O.js.map +0 -1
  155. package/webapp/dist/assets/pieDiagram-SKSYHLDU-CZvk1jXC.js.map +0 -1
  156. package/webapp/dist/assets/quadrantDiagram-337W2JSQ-rREIz2-L.js.map +0 -1
  157. package/webapp/dist/assets/requirementDiagram-Z7DCOOCP-C7Ko_VBz.js.map +0 -1
  158. package/webapp/dist/assets/sankeyDiagram-WA2Y5GQK-C4IvqC76.js.map +0 -1
  159. package/webapp/dist/assets/sequenceDiagram-2WXFIKYE-BFvPV1wQ.js.map +0 -1
  160. package/webapp/dist/assets/stateDiagram-RAJIS63D-BcXbrOQl.js.map +0 -1
  161. package/webapp/dist/assets/stateDiagram-v2-FVOUBMTO-g15Y_50y.js.map +0 -1
  162. package/webapp/dist/assets/timeline-definition-YZTLITO2-CGP_BvY2.js.map +0 -1
  163. package/webapp/dist/assets/treemap-KZPCXAKY-B98r-m60.js.map +0 -1
  164. package/webapp/dist/assets/vennDiagram-LZ73GAT5-BO_64ARK.js +0 -2487
  165. package/webapp/dist/assets/vennDiagram-LZ73GAT5-BO_64ARK.js.map +0 -1
  166. package/webapp/dist/assets/xychartDiagram-JWTSCODW-CD7DBeTl.js.map +0 -1
@@ -396,8 +396,8 @@ Result (second call):
396
396
 
397
397
  - **No registry lookup** - always creates a new sideDialog
398
398
  - **Not registered** - no persistence across Tellasks
399
- - **No assignment-update channel** - once emitted, it cannot be updated in place like Type B
400
- - Another `tellaskSessionless` creates **another new transient sideDialog**; it does not update, stop, or tell the earlier Type C Side Dialog to stop
399
+ - Cannot continue or change the earlier task like Type B can
400
+ - Another `tellaskSessionless` is another independent task; it does not update or stop the earlier Type C task
401
401
  - If later correction, scope change, or earlier wrap-up may be needed, choose Type B `tellask` with `sessionSlug` from the start
402
402
  - The sideDialog itself is fully capable **except** for `freshBootsReasoning({ tellaskContent: "..." })` FBR, which is tool-less and tellask-free (see `fbr.md`).
403
403
  - Only difference from TYPE B: no registry lookup/resume capability
@@ -379,8 +379,8 @@ LLM 再次发出:tellask({ targetAgentId: "researcher", sessionSlug: "market-a
379
379
 
380
380
  - **无注册表查找** - 总是创建新的支线对话
381
381
  - **不注册** - 在各次诉请之间不持久化
382
- - **无任务安排更新通道** - 发出后不能像 TYPE B 那样就地更新同一路诉请要求
383
- - 再次发起 `tellaskSessionless` 只会创建**另一条新的瞬态支线对话**,不会更新、更不会要求先前那条 TYPE C 支线停止
382
+ - 不能像 TYPE B 那样接着同一件事说、更新同一件正在做的事
383
+ - 再次发起 `tellaskSessionless` 是另一件独立任务,不会更新、更不会要求先前那条 TYPE C 任务停止
384
384
  - 若你后续可能需要改要求、纠偏或提前收口,应该从一开始就选择带 `sessionSlug` 的 TYPE B `tellask`
385
385
  - 支线对话本身一般是“完整能力”的;但 `freshBootsReasoning({ tellaskContent: "..." })` FBR 是特例:无工具且禁止任何诉请(见 `fbr.zh.md`)。
386
386
  - 与 TYPE B 的唯一区别:无注册表查找/恢复能力
@@ -212,8 +212,8 @@ tellask({
212
212
  - EN (key property): “Fresh/one-shot” is not only “new context”; it also means **no continuation semantics** — later Tellasks are not expected to resume the same session context.
213
213
  - ZH(关键性质): “Fresh/一次性”不仅表示“新开上下文”,更表示:**没有后续续话语义** —— 后续诉请不应被期待能自动续接本次一次性诉请的上下文。
214
214
 
215
- - EN (operational consequence): A Fresh Tellask has **no assignment-update channel**. Another `tellaskSessionless` creates a new transient Side Dialog; it does not update or tell the earlier one to stop.
216
- - ZH(操作后果): 一次性诉请**没有任务安排更新通道**。再次发起 `tellaskSessionless` 只会新建另一条瞬态支线,不会更新、更不会要求先前那条支线停止。
215
+ - EN (operational consequence): A Fresh Tellask cannot continue or change the earlier task. Another `tellaskSessionless` is another independent task; it does not update or stop the earlier one.
216
+ - ZH(操作后果): 一次性诉请不能接着旧任务改要求。再次发起 `tellaskSessionless` 是另一件独立任务,不会更新、更不会要求先前那条任务停止。
217
217
 
218
218
  - EN (practical guidance): If you need a follow-up after a Fresh Tellask, treat it as a new request and restate necessary context; if you need iterative follow-ups, use `Tellask Session` with `sessionSlug`.
219
219
  - ZH(实践建议): 如果你在一次性诉请后还要追问,应当把追问当作全新请求并补齐必要上下文;如果你需要可迭代的追问/推进,请使用 `Tellask Session` 并提供 `sessionSlug`。
@@ -35,9 +35,10 @@ These points reflect current behavior in `dialog-system.md`, `fbr.md`, and `dili
35
35
 
36
36
  Important addition:
37
37
 
38
- - Only `Tellask Session` has an assignment-update channel.
39
- - `Fresh Tellask` has no such channel; another `tellaskSessionless` only creates another transient Side Dialog and does not affect or tell the earlier owner to stop.
38
+ - Only `Tellask Session` can continue the same task and update that task.
39
+ - `Fresh Tellask` cannot continue or change an earlier task; another `tellaskSessionless` is another independent task and does not affect or stop the earlier task.
40
40
  - If later correction, earlier wrap-up, or scope change may be needed, do not choose `Fresh Tellask`; use `tellask` with `sessionSlug` from the start.
41
+ - Do not treat an agent teammate like a human coworker who can only handle one conversation at a time. Same teammate + same `sessionSlug` = continue the same task and update that task; `tellaskSessionless` or a different `sessionSlug` = another independent task.
41
42
 
42
43
  ### 2.2 What `Tellask Session` really means
43
44
 
@@ -139,6 +140,7 @@ For teammate Tellasks (non-`freshBootsReasoning({ tellaskContent: "..." })`), al
139
140
  Hard rule:
140
141
 
141
142
  - You can only claim “waiting for result” if there is an explicit pending Tellask and known acceptance evidence.
143
+ - If several independent tasks should go to the same teammate, do not queue them: send separate `tellaskSessionless` calls, or use different `sessionSlug` values with `tellask`.
142
144
 
143
145
  ### 4.2 Always continue via explicit re-Tellask
144
146
 
@@ -35,9 +35,10 @@
35
35
 
36
36
  关键补充:
37
37
 
38
- - 只有长线诉请有“更新任务安排”的通道。
39
- - 一次性诉请没有这个通道;后续再开一个 `tellaskSessionless` 只会创建新的瞬态支线,不会影响旧支线继续执行,更不能要求旧主理人停止。
38
+ - 只有长线诉请能接着同一件事说、更新那件正在做的事。
39
+ - 一次性诉请不能接着旧任务改要求;后续再开一个 `tellaskSessionless` 只是另一件独立任务,不会影响旧任务继续执行,更不能要求旧主理人停止。
40
40
  - 如果你后来可能需要改要求、提前收口或纠偏,就不该使用一次性诉请,而应从一开始就用带 `sessionSlug` 的长线诉请。
41
+ - 不要把智能体队友当成真人同事:祂不会因为你又发一条诉请而被打扰。同一个队友 + 同一个 `sessionSlug` = 接着同一件事说,并更新那件正在做的事;`tellaskSessionless` 或不同 `sessionSlug` = 另一件独立任务。
41
42
 
42
43
  ### 2.2 长线诉请的真实语义
43
44
 
@@ -136,6 +137,7 @@
136
137
 
137
138
  - 任何“等待结果/等待回贴”表述,必须能指向**刚刚已发出的具体诉请**与**等待的验收证据**。
138
139
  - 若没有已发出的待回贴诉请,就不能写“等待”;应立刻发诉请或改为本地执行。
140
+ - 若有多件独立工作要交给同一队友,不需要排队、不需要担心打扰:分别发起 `tellaskSessionless`,或用不同 `sessionSlug` 发起 `tellask`。
139
141
 
140
142
  ### 4.2 续推时必须显式“再诉请”
141
143
 
@@ -484,6 +484,9 @@ providers:
484
484
  min: 0
485
485
  max: 1
486
486
  description: Nucleus sampling parameter.
487
+ parallel_tool_calls:
488
+ type: boolean
489
+ description: Allow the model to emit parallel tool calls.
487
490
  models:
488
491
  kimi-for-coding:
489
492
  name: Kimi For Coding
@@ -263,8 +263,23 @@ function extractReasoningPayload(item) {
263
263
  reasoning.content = content;
264
264
  if (encrypted)
265
265
  reasoning.encrypted_content = encrypted;
266
+ const hasReasoningData = summary.length > 0 || (content?.length ?? 0) > 0 || encrypted !== undefined;
267
+ if (hasReasoningData) {
268
+ reasoning.metadata = {
269
+ itemType: item.type,
270
+ };
271
+ if (typeof item.id === 'string' && item.id.length > 0) {
272
+ reasoning.metadata.itemId = item.id;
273
+ }
274
+ }
266
275
  return reasoning;
267
276
  }
277
+ function hasReasoningPayloadSignals(payload) {
278
+ return (payload.summary.length > 0 ||
279
+ (payload.content?.length ?? 0) > 0 ||
280
+ (payload.encrypted_content?.length ?? 0) > 0 ||
281
+ payload.metadata !== undefined);
282
+ }
268
283
  function buildReasoningPayloadFromText(text) {
269
284
  if (text.trim().length === 0)
270
285
  return undefined;
@@ -932,7 +947,7 @@ class CodexGen {
932
947
  : sawReasoningDeltaWithoutItemId;
933
948
  if (!sawReasoningDelta) {
934
949
  const text = extractReasoningText(event.item);
935
- if (text.length > 0) {
950
+ if (text.length > 0 || hasReasoningPayloadSignals(payloadFromItem)) {
936
951
  if (activeStream === 'saying') {
937
952
  const detail = 'CODEX stream overlap violation: received reasoning while saying stream still active';
938
953
  log.error(detail, new Error('codex_stream_overlap_violation'));
@@ -951,9 +966,11 @@ class CodexGen {
951
966
  await receiver.thinkingStart();
952
967
  activeStream = 'thinking';
953
968
  }
954
- currentThinkingContent += text;
955
- await receiver.thinkingChunk(text);
956
- await receiver.thinkingFinish(payloadFromItem ?? buildReasoningPayloadFromText(currentThinkingContent));
969
+ if (text.length > 0) {
970
+ currentThinkingContent += text;
971
+ await receiver.thinkingChunk(text);
972
+ }
973
+ await receiver.thinkingFinish(payloadFromItem);
957
974
  thinkingStarted = false;
958
975
  currentThinkingContent = '';
959
976
  if (activeStream === 'thinking')
@@ -961,12 +978,16 @@ class CodexGen {
961
978
  }
962
979
  }
963
980
  else if (thinkingStarted) {
964
- await receiver.thinkingFinish(payloadFromItem ?? buildReasoningPayloadFromText(currentThinkingContent));
981
+ await receiver.thinkingFinish(payloadFromItem);
965
982
  thinkingStarted = false;
966
983
  currentThinkingContent = '';
967
984
  if (activeStream === 'thinking')
968
985
  activeStream = 'idle';
969
986
  }
987
+ else if (hasReasoningPayloadSignals(payloadFromItem)) {
988
+ await receiver.thinkingStart();
989
+ await receiver.thinkingFinish(payloadFromItem);
990
+ }
970
991
  return;
971
992
  }
972
993
  case 'local_shell_call':
@@ -117,8 +117,6 @@ function resolveOpenAiCompatibleParallelToolCalls(args) {
117
117
  if (args.openAiParams.parallel_tool_calls !== undefined) {
118
118
  return args.openAiParams.parallel_tool_calls;
119
119
  }
120
- if (isKimiCodeProvider(args.providerConfig))
121
- return undefined;
122
120
  return true;
123
121
  }
124
122
  function isOpenAiCompatibleSseCaptureEnabled() {
@@ -1135,8 +1135,28 @@ function extractReasoningPayload(item) {
1135
1135
  out.content = content;
1136
1136
  if (encrypted)
1137
1137
  out.encrypted_content = encrypted;
1138
+ const hasReasoningData = summary.length > 0 || content.length > 0 || encrypted !== undefined;
1139
+ if (hasReasoningData) {
1140
+ const metadata = { itemType: item.type };
1141
+ if (typeof item.id === 'string' && item.id.length > 0) {
1142
+ metadata.itemId = item.id;
1143
+ }
1144
+ if (item.status === 'in_progress' ||
1145
+ item.status === 'completed' ||
1146
+ item.status === 'incomplete') {
1147
+ metadata.status = item.status;
1148
+ }
1149
+ out.metadata = metadata;
1150
+ }
1138
1151
  return out;
1139
1152
  }
1153
+ function hasReasoningPayloadSignals(payload) {
1154
+ return (payload !== null &&
1155
+ (payload.summary.length > 0 ||
1156
+ (payload.content?.length ?? 0) > 0 ||
1157
+ (payload.encrypted_content?.length ?? 0) > 0 ||
1158
+ payload.metadata !== undefined));
1159
+ }
1140
1160
  function openAiResponseToBatchOutputs(response, genseq) {
1141
1161
  const outputs = [];
1142
1162
  const output = response.output;
@@ -1149,7 +1169,7 @@ function openAiResponseToBatchOutputs(response, genseq) {
1149
1169
  if (item.type === 'reasoning') {
1150
1170
  const reasoning = extractReasoningPayload(item);
1151
1171
  const content = extractReasoningText(item);
1152
- if (content.length > 0 || reasoning !== null) {
1172
+ if (content.length > 0 || hasReasoningPayloadSignals(reasoning)) {
1153
1173
  outputs.push({
1154
1174
  kind: 'message',
1155
1175
  message: {
@@ -1157,7 +1177,7 @@ function openAiResponseToBatchOutputs(response, genseq) {
1157
1177
  role: 'assistant',
1158
1178
  genseq,
1159
1179
  content,
1160
- reasoning: reasoning ?? undefined,
1180
+ ...(reasoning !== null ? { reasoning } : {}),
1161
1181
  },
1162
1182
  });
1163
1183
  }
@@ -1655,6 +1675,7 @@ class OpenAiGen {
1655
1675
  const sawReasoningDelta = itemId !== null
1656
1676
  ? streamedReasoningItemIds.has(itemId)
1657
1677
  : sawReasoningDeltaWithoutItemId;
1678
+ const payload = extractReasoningPayload(item);
1658
1679
  if (sawReasoningDelta) {
1659
1680
  if (itemId !== null) {
1660
1681
  streamedReasoningItemIds.delete(itemId);
@@ -1662,9 +1683,20 @@ class OpenAiGen {
1662
1683
  else {
1663
1684
  sawReasoningDeltaWithoutItemId = false;
1664
1685
  }
1686
+ if (thinkingStarted) {
1687
+ await receiver.thinkingFinish(payload ?? buildReasoningPayloadFromText(currentThinkingContent));
1688
+ thinkingStarted = false;
1689
+ currentThinkingContent = '';
1690
+ if (activeStream === 'thinking')
1691
+ activeStream = 'idle';
1692
+ break;
1693
+ }
1694
+ if (hasReasoningPayloadSignals(payload)) {
1695
+ await receiver.thinkingStart();
1696
+ await receiver.thinkingFinish(payload);
1697
+ }
1665
1698
  break;
1666
1699
  }
1667
- const payload = extractReasoningPayload(item);
1668
1700
  const text = extractReasoningText(item);
1669
1701
  if (thinkingStarted) {
1670
1702
  if (currentThinkingContent.length === 0 && text.length > 0) {
@@ -1678,7 +1710,7 @@ class OpenAiGen {
1678
1710
  activeStream = 'idle';
1679
1711
  break;
1680
1712
  }
1681
- if (text.length > 0 || payload !== null) {
1713
+ if (text.length > 0 || hasReasoningPayloadSignals(payload)) {
1682
1714
  if (activeStream === 'saying') {
1683
1715
  if (sayingStarted) {
1684
1716
  await receiver.sayingFinish();
@@ -431,7 +431,7 @@ const TELLASK_SPECIAL_VIRTUAL_TOOLS = [
431
431
  {
432
432
  type: 'func',
433
433
  name: 'tellask',
434
- description: 'Create or resume a teammate Side Dialog with sessionSlug.',
434
+ description: 'Ask a teammate to work on a task. Same targetAgentId + same sessionSlug continues the same task and updates it; a different sessionSlug is another independent task and will not affect other work for that teammate.',
435
435
  parameters: {
436
436
  type: 'object',
437
437
  properties: {
@@ -449,7 +449,7 @@ const TELLASK_SPECIAL_VIRTUAL_TOOLS = [
449
449
  {
450
450
  type: 'func',
451
451
  name: 'tellaskSessionless',
452
- description: 'Create a one-shot teammate Side Dialog with no assignment-update channel; later tellaskSessionless calls create new dialogs rather than updating or stopping this one.',
452
+ description: 'Ask a teammate to do a one-shot independent task. It does not update, affect, or stop earlier tasks.',
453
453
  parameters: {
454
454
  type: 'object',
455
455
  properties: {
@@ -3,10 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.emitThinkingEvents = emitThinkingEvents;
4
4
  exports.emitSayingEvents = emitSayingEvents;
5
5
  async function emitThinkingEvents(dlg, content, reasoning) {
6
- if (!content.trim())
7
- return undefined;
6
+ const hasContent = content.trim().length > 0;
7
+ if (!hasContent && reasoning === undefined)
8
+ return;
8
9
  await dlg.thinkingStart();
9
- await dlg.thinkingChunk(content);
10
+ if (hasContent) {
11
+ await dlg.thinkingChunk(content);
12
+ }
10
13
  await dlg.thinkingFinish(reasoning);
11
14
  }
12
15
  async function emitSayingEvents(dlg, content) {
@@ -196,7 +196,7 @@ function getMemoryPromptCopy(ctx) {
196
196
  ? `你当前处于支线对话:此处不允许 \`do_mind\` / \`mind_more\` / \`change_mind\` / \`never_mind\`。当你判断需要更新差遣牒(尤其是 progress 公告牌)时,请在合适时机直接诉请差遣牒维护人 \`@${ctx.taskdocMaintainerId}\` 执行更新,并给出要新增的章节、要追加的条目、已合并好的“新全文/替换稿”,或要删除的章节。不要声称已更新,除非看到回执。`
197
197
  : '你当前处于支线对话,且上下文已进入吃紧/告急处置态:本程不要维护差遣牒,也不要整理差遣牒更新提案。请把下一程需要恢复的讨论细节、定位、验证方式和临时信息写入足够详尽的接续包提醒项。',
198
198
  mainDialogDutyLine: '你当前处于主线对话:你负责综合维护全队共享差遣牒(尤其是 progress 公告牌)。当队友/支线对话提出更新建议时,及时合并、压缩并保持清晰。',
199
- teammateTellaskRoundDoneLine: `队友诉请重要语义:当你在诉请者上下文中收到带${runtimeMarkers.finalCompleted}标记的回贴,表示该轮诉请已经结束;对方不会继续执行同一轮诉请。此时如果目标未达成,“等待”是错误的:必须显式发起新一轮 tellask 才能继续推进。`,
199
+ teammateTellaskRoundDoneLine: `队友诉请重要语义:当你在诉请者上下文中收到带${runtimeMarkers.finalCompleted}标记的回贴,表示该轮诉请已经结束;对方不会继续执行同一轮诉请。此时如果目标未达成,“等待”是错误的:必须显式发起新一轮 tellask 才能继续推进。并行语义:不要把智能体队友当成真人同事;祂不会因为你又发一条诉请而被打扰。同一个队友 + 同一个 sessionSlug = 接着同一件事说,并更新那件正在做的事;tellaskSessionless 或不同 sessionSlug = 另一件独立任务。`,
200
200
  teamMemoryHintLine: '提示:你具备团队记忆工具(`add_team_memory` / `replace_team_memory` / `drop_team_memory` / `clear_team_memory`),可在必要时维护团队记忆(谨慎、少量、只写稳定约定)。',
201
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\` 更新。`,
202
202
  sideDialogWorkflowLine: ctx.contextHealthPromptMode === 'normal'
@@ -230,7 +230,7 @@ function getMemoryPromptCopy(ctx) {
230
230
  ? `You are currently in a Side Dialog: \`do_mind\` / \`mind_more\` / \`change_mind\` / \`never_mind\` are not allowed here. When Taskdoc should be updated (especially the shared progress bulletin board), tellask the Taskdoc maintainer \`@${ctx.taskdocMaintainerId}\` with the new section to create, entries to append, a fully merged replacement draft, or the section to delete. Do not claim it is updated until you see a receipt.`
231
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.',
232
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.',
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.`,
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. Parallel semantics: do not treat an agent teammate like a human coworker who can only handle one conversation at a time. Same teammate + same sessionSlug = continue the same task and update that task; tellaskSessionless or a different sessionSlug = another independent task.`,
234
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.',
235
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.`,
236
236
  sideDialogWorkflowLine: ctx.contextHealthPromptMode === 'normal'
@@ -101,7 +101,8 @@ function buildTeammateTellaskPhaseContract(language) {
101
101
  '- 若被诉请者在回贴送达前因 `clear_mind` 开启新一程,同一进行中诉请默认继续有效;新一程会自然承接,直到产生回贴或明确失败。不要仅因对方换程就把该轮诉请当作失效重发。',
102
102
  '- 只有在存在明确进行中诉请时,才可声明“等待回贴/等待结果”(通常应可在“⏳ 进行中诉请(共 N 路,自动维护;仅 0 路时可手动删除)”这类提醒项中观测到);若该提醒项不存在,或提醒项已明确“当前没有执行中的诉请”,则“等待”是错误动作,必须执行下一动作(直接诉请或本地执行)。',
103
103
  '- “⏳ 进行中诉请”提醒项只是系统状态窗,不是控制面:内容不可手改;当存在非 0 路进行中诉请时,不可删除,误删会被拒绝并返回引导文案。若某一路诉请需要改要求、提前收口或纠偏,只能更新那一路诉请的“任务安排”(对长线诉请通常复用同一 `sessionSlug` 再发 `tellask`),让对应主理人按最新安排自行最终回复并自然结束。',
104
- '- 只有长线诉请(`tellask` + `sessionSlug`)才有“更新任务安排”的通道;一次性诉请(`tellaskSessionless`)没有这个通道。再次发起 `tellaskSessionless` 只会创建新的瞬态支线,不会更新、更不会要求旧支线主理人停止;若你后来发现可能需要改要求/提前收口,一开始就不该选择 `tellaskSessionless`。',
104
+ '- 只有长线诉请(`tellask` + `sessionSlug`)能接着同一件事说、更新同一件正在做的事;一次性诉请(`tellaskSessionless`)做不到。再次发起 `tellaskSessionless` 只是另一件独立任务,不会更新、更不会要求旧任务停止;若你后来发现可能需要改要求/提前收口,一开始就不该选择 `tellaskSessionless`。',
105
+ '- 不要把智能体队友当成真人同事:祂不会因为你又发一条诉请而被打扰。同一个队友可以同时做多件独立任务,系统会分开处理。记住这个简单规则:同一个队友 + 同一个 `sessionSlug` = 接着同一件事说,并更新那件正在做的事;`tellaskSessionless` 或不同 `sessionSlug` = 另一件独立任务。只要任务独立、目标清楚,就直接并行诉请。',
105
106
  '- 能由队友诉请完成的执行性工作,禁止转交 `askHuman` 做“转发员”;当你写“让 @X 执行 Y”时,必须在同一回复内直接发出 `tellask` 或 `tellaskSessionless`。',
106
107
  `- 当你在诉请正文里定义“回贴格式/交付格式”时,只写业务交付结构即可;不要要求被诉请者手写 \`${runtimeMarkers.finalCompleted}\` / \`${runtimeMarkers.tellaskBack}\` / FBR 标记(\`${runtimeMarkers.fbrDirectReply}\` / \`${runtimeMarkers.fbrReasoningOnly}\`),这些标记由 Dominds 运行时自动注入。`,
107
108
  '- 当你处于队友诉请触发的支线时,不要把“阻塞/不确定”默认等同于 `tellaskBack`:若按当前团队规程/SOP/职责卡已能明确判定执行负责人,直接用 `tellask` / `tellaskSessionless` 诉请对应负责人;只有确实需要诉请者补充需求、做裁决、澄清验收口径、提供缺失输入,或现有规程无法明确判责时,才使用 `tellaskBack`。`tellaskBack` 不携带 `sessionSlug`。',
@@ -113,7 +114,8 @@ function buildTeammateTellaskPhaseContract(language) {
113
114
  '- If the tellaskee starts a new course via `clear_mind` before delivering the reply, the same in-flight Tellask stays live by default; the new course naturally continues it until a reply is delivered or an explicit failure is returned. Do not re-tellask solely because the tellaskee changed course.',
114
115
  '- You may claim “waiting for reply/result” only when a concrete pending Tellask exists (normally observable in a “⏳ In-flight Tellasks (N total, auto-maintained; manually deletable only at zero in-flight)” reminder). If that reminder is absent, or it explicitly states there are no in-flight Tellasks, waiting is a wrong action; execute the next action now (direct Tellask or local action).',
115
116
  '- The “⏳ In-flight Tellasks” reminder is only a system status window, not a control surface: its content is not hand-editable; while any Tellask is still active, it is not deletable, and mistaken deletion will be rejected with guidance. If one Tellask needs a changed scope, earlier closure, or correction, update that Tellask’s assignment instead (for a sessioned Tellask, usually send another `tellask` with the same `sessionSlug`) so the tellaskee can deliver a final reply naturally under the latest assignment.',
116
- '- Only a sessioned Tellask (`tellask` + `sessionSlug`) has an assignment-update channel. A one-shot Tellask (`tellaskSessionless`) has no such channel: another `tellaskSessionless` creates a new transient Side Dialog and does not update, stop, or instruct the earlier one to stop. If you may need later correction or earlier wrap-up, do not choose `tellaskSessionless` in the first place.',
117
+ '- Only a sessioned Tellask (`tellask` + `sessionSlug`) can continue the same task and update that task. A one-shot Tellask (`tellaskSessionless`) cannot: another `tellaskSessionless` is a separate task and does not update, stop, or instruct the earlier task to stop. If you may need later correction or earlier wrap-up, do not choose `tellaskSessionless` in the first place.',
118
+ '- Do not treat an agent teammate like a human coworker who can only handle one conversation at a time. The same teammate can work on several independent tasks at once, and the system keeps them separate. Simple rule: same teammate + same `sessionSlug` = continue the same task and update that task; `tellaskSessionless` or a different `sessionSlug` = another independent task. When tasks are independent and clear, tellask in parallel.',
117
119
  '- Do not use `askHuman` as a relay for executable teammate work. If you write “ask @X to do Y”, emit `tellask` or `tellaskSessionless` in the same response.',
118
120
  `- When you define a “reply/delivery format” inside tellask body, keep it to the business delivery structure; do not require the tellaskee to hand-write \`${runtimeMarkers.finalCompleted}\` / \`${runtimeMarkers.tellaskBack}\` / FBR markers (\`${runtimeMarkers.fbrDirectReply}\` / \`${runtimeMarkers.fbrReasoningOnly}\`), because Dominds runtime injects those markers automatically.`,
119
121
  '- In a teammate-triggered Side Dialog, do not treat “blocked / uncertain” as an automatic `tellaskBack`: if current team SOP / role ownership already identifies the responsible executor, directly use `tellask` / `tellaskSessionless` for that owner; use `tellaskBack` only when you truly need the tellasker to clarify, decide, confirm acceptance criteria, provide missing input, or when existing SOP cannot determine ownership. `tellaskBack` must not carry `sessionSlug`.',
@@ -197,11 +199,13 @@ function buildTellaskCollaborationProtocol(language, dialogScope) {
197
199
  zh: [
198
200
  '- Tellask 统一走函数工具通道:`tellaskBack` / `tellask` / `tellaskSessionless` / `askHuman` / `freshBootsReasoning`。',
199
201
  '- 对队友诉请默认使用 `tellask` 并复用 `sessionSlug`;仅在确认一次性诉请足够、且后续不需要更新任务安排/提前收口时才使用 `tellaskSessionless`,并需说明理由。',
202
+ '- 并行协调默认允许:不要把智能体队友当成真人同事;祂不会因为你又发一条诉请而被打扰。同一个队友 + 同一个 `sessionSlug` = 接着同一件事说;`tellaskSessionless` 或不同 `sessionSlug` = 另一件独立任务。',
200
203
  '- 例外优先级(强制):`tellaskBack` 仅用于回问诉请者,不适用队友长线默认规则,也不携带 `sessionSlug`。',
201
204
  ],
202
205
  en: [
203
206
  '- Tellask must use the function-tool channel: `tellaskBack` / `tellask` / `tellaskSessionless` / `askHuman` / `freshBootsReasoning`.',
204
207
  '- For teammate tellasks, default to `tellask` and continue with the same `sessionSlug`; use `tellaskSessionless` only when a one-shot is truly sufficient and later assignment updates / early wrap-up are not needed.',
208
+ '- Parallel coordination is allowed by default: do not treat an agent teammate like a human coworker who can only handle one conversation at a time. Same teammate + same `sessionSlug` = continue the same task; `tellaskSessionless` or a different `sessionSlug` = another independent task.',
205
209
  '- Mandatory exception precedence: `tellaskBack` is ask-back-only and outside the teammate-session default; it does not carry `sessionSlug`.',
206
210
  ],
207
211
  }),
@@ -266,14 +270,14 @@ function buildTellaskInteractionRules(language) {
266
270
  zh: [
267
271
  '- `tellaskBack`:仅用于支线回问诉请者。',
268
272
  '- `tellask`:用于可恢复的长线诉请(必须提供 `targetAgentId` / `sessionSlug` / `tellaskContent`)。',
269
- '- `tellaskSessionless`:用于一次性诉请(必须提供 `targetAgentId` / `tellaskContent`);它不会建立可更新的任务安排通道,后续再次调用只会新开支线,不会影响旧支线继续执行。',
273
+ '- `tellaskSessionless`:用于一次性诉请(必须提供 `targetAgentId` / `tellaskContent`);它不能接着旧任务改要求,后续再次调用只是另一件独立任务,不会影响旧任务继续执行,也不会打扰同一队友正在执行的其它独立诉请。不要把智能体队友当成需要排队说话的真人同事。',
270
274
  '- `askHuman`:用于 Q4H(向人类请求必要澄清/决策/授权/缺失输入)。',
271
275
  '- `freshBootsReasoning`:用于发起扪心自问(FBR)支线(`tellaskContent` 必填,`effort` 可选)。',
272
276
  ],
273
277
  en: [
274
278
  '- `tellaskBack`: ask back to tellasker from a Side Dialog only.',
275
279
  '- `tellask`: resumable tellask (requires `targetAgentId` / `sessionSlug` / `tellaskContent`).',
276
- '- `tellaskSessionless`: one-shot tellask (requires `targetAgentId` / `tellaskContent`); it does not create an assignment-update channel, and later calls create new Side Dialogs instead of affecting the earlier one.',
280
+ '- `tellaskSessionless`: one-shot tellask (requires `targetAgentId` / `tellaskContent`); it cannot continue an earlier task or change its requirements. Later calls are separate tasks and do not affect earlier work for the same teammate. Do not treat agent teammates like human coworkers who need you to wait in line to talk.',
277
281
  '- `askHuman`: Q4H for necessary clarification/decision/authorization/missing input.',
278
282
  '- `freshBootsReasoning`: starts an FBR Side Dialog (requires `tellaskContent`, optional `effort`).',
279
283
  ],
@@ -97,6 +97,7 @@ export declare class DiskFileDialogStore extends DialogStore {
97
97
  private sayingContent;
98
98
  private thinkingContent;
99
99
  private thinkingReasoning;
100
+ private thinkingStarted;
100
101
  sayingStart(dialog: Dialog): Promise<void>;
101
102
  sayingChunk(dialog: Dialog, chunk: string): Promise<void>;
102
103
  sayingFinish(dialog: Dialog): Promise<void>;
@@ -1816,6 +1816,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
1816
1816
  this.sayingContent = '';
1817
1817
  this.thinkingContent = '';
1818
1818
  this.thinkingReasoning = undefined;
1819
+ this.thinkingStarted = false;
1819
1820
  this.dialogId = dialogId;
1820
1821
  }
1821
1822
  // === DialogStore interface methods ===
@@ -2261,6 +2262,7 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
2261
2262
  // Reset thinking content tracker
2262
2263
  this.thinkingContent = '';
2263
2264
  this.thinkingReasoning = undefined;
2265
+ this.thinkingStarted = true;
2264
2266
  const thinkingStartEvt = {
2265
2267
  type: 'thinking_start_evt',
2266
2268
  course,
@@ -2286,13 +2288,13 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
2286
2288
  if (reasoning)
2287
2289
  this.thinkingReasoning = reasoning;
2288
2290
  const thinkingContent = this.thinkingContent;
2289
- if (thinkingContent || this.thinkingReasoning) {
2291
+ if (this.thinkingStarted || thinkingContent || this.thinkingReasoning) {
2290
2292
  const thinkingMessageEvent = {
2291
2293
  ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
2292
2294
  type: 'agent_thought_record',
2293
2295
  genseq: dialog.activeGenSeq,
2294
2296
  content: thinkingContent,
2295
- reasoning: this.thinkingReasoning,
2297
+ ...(this.thinkingReasoning !== undefined ? { reasoning: this.thinkingReasoning } : {}),
2296
2298
  };
2297
2299
  await this.appendEvent(dialog, course, thinkingMessageEvent);
2298
2300
  }
@@ -2300,8 +2302,10 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
2300
2302
  type: 'thinking_finish_evt',
2301
2303
  course,
2302
2304
  genseq: dialog.activeGenSeq,
2305
+ ...(this.thinkingReasoning !== undefined ? { reasoning: this.thinkingReasoning } : {}),
2303
2306
  };
2304
2307
  (0, evt_registry_1.postDialogEvent)(dialog, thinkingFinishEvt);
2308
+ this.thinkingStarted = false;
2305
2309
  }
2306
2310
  async markdownStart(dialog) {
2307
2311
  const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
@@ -2805,8 +2809,8 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
2805
2809
  type: 'agent_thought_record',
2806
2810
  genseq,
2807
2811
  content: content || '',
2808
- reasoning,
2809
- provider_data,
2812
+ ...(reasoning !== undefined ? { reasoning } : {}),
2813
+ ...(provider_data !== undefined ? { provider_data } : {}),
2810
2814
  }
2811
2815
  : {
2812
2816
  ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
@@ -3319,43 +3323,26 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
3319
3323
  break;
3320
3324
  }
3321
3325
  case 'agent_thought_record': {
3322
- // Replay thinking content as thinking events
3326
+ // Replay persisted thinking records as substream boundaries, with chunks when content exists.
3323
3327
  const content = event.content || '';
3324
- if (content) {
3325
- // Start thinking phase
3326
- const thinkingStartEvent = {
3327
- type: 'thinking_start_evt',
3328
- course,
3329
- genseq: event.genseq,
3330
- dialog: {
3331
- selfId: dialog.id.selfId,
3332
- rootId: dialog.id.rootId,
3333
- },
3334
- timestamp: event.ts,
3335
- };
3336
- if (ws.readyState === 1) {
3337
- ws.send(JSON.stringify(thinkingStartEvent));
3338
- }
3339
- const thinkingChunks = this.createOptimalChunks(content);
3340
- for (const chunk of thinkingChunks) {
3341
- const thinkingChunkEvent = {
3342
- type: 'thinking_chunk_evt',
3343
- chunk,
3344
- course,
3345
- genseq: event.genseq,
3346
- dialog: {
3347
- selfId: dialog.id.selfId,
3348
- rootId: dialog.id.rootId,
3349
- },
3350
- timestamp: event.ts,
3351
- };
3352
- if (ws.readyState === 1) {
3353
- ws.send(JSON.stringify(thinkingChunkEvent));
3354
- }
3355
- }
3356
- // Finish thinking phase
3357
- const thinkingFinishEvent = {
3358
- type: 'thinking_finish_evt',
3328
+ const thinkingStartEvent = {
3329
+ type: 'thinking_start_evt',
3330
+ course,
3331
+ genseq: event.genseq,
3332
+ dialog: {
3333
+ selfId: dialog.id.selfId,
3334
+ rootId: dialog.id.rootId,
3335
+ },
3336
+ timestamp: event.ts,
3337
+ };
3338
+ if (ws.readyState === 1) {
3339
+ ws.send(JSON.stringify(thinkingStartEvent));
3340
+ }
3341
+ const thinkingChunks = this.createOptimalChunks(content);
3342
+ for (const chunk of thinkingChunks) {
3343
+ const thinkingChunkEvent = {
3344
+ type: 'thinking_chunk_evt',
3345
+ chunk,
3359
3346
  course,
3360
3347
  genseq: event.genseq,
3361
3348
  dialog: {
@@ -3365,9 +3352,23 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
3365
3352
  timestamp: event.ts,
3366
3353
  };
3367
3354
  if (ws.readyState === 1) {
3368
- ws.send(JSON.stringify(thinkingFinishEvent));
3355
+ ws.send(JSON.stringify(thinkingChunkEvent));
3369
3356
  }
3370
3357
  }
3358
+ const thinkingFinishEvent = {
3359
+ type: 'thinking_finish_evt',
3360
+ course,
3361
+ genseq: event.genseq,
3362
+ ...(event.reasoning !== undefined ? { reasoning: event.reasoning } : {}),
3363
+ dialog: {
3364
+ selfId: dialog.id.selfId,
3365
+ rootId: dialog.id.rootId,
3366
+ },
3367
+ timestamp: event.ts,
3368
+ };
3369
+ if (ws.readyState === 1) {
3370
+ ws.send(JSON.stringify(thinkingFinishEvent));
3371
+ }
3371
3372
  break;
3372
3373
  }
3373
3374
  case 'agent_words_record': {
@@ -6933,8 +6934,8 @@ class DialogPersistence {
6933
6934
  role: 'assistant',
6934
6935
  genseq: event.genseq,
6935
6936
  content: event.content,
6936
- reasoning: event.reasoning,
6937
- provider_data: event.provider_data,
6937
+ ...(event.reasoning !== undefined ? { reasoning: event.reasoning } : {}),
6938
+ ...(event.provider_data !== undefined ? { provider_data: event.provider_data } : {}),
6938
6939
  });
6939
6940
  break;
6940
6941
  }
package/dist/priming.js CHANGED
@@ -440,11 +440,48 @@ function parseOptionalReasoningPayload(value, context) {
440
440
  if (encryptedContentRaw !== undefined && typeof encryptedContentRaw !== 'string') {
441
441
  throw new Error(`${context}.reasoning.encrypted_content must be a string when provided`);
442
442
  }
443
+ const metadataRaw = value['metadata'];
444
+ let metadata;
445
+ if (metadataRaw !== undefined) {
446
+ if (!isRecord(metadataRaw)) {
447
+ throw new Error(`${context}.reasoning.metadata must be an object when provided`);
448
+ }
449
+ const itemIdRaw = metadataRaw['itemId'];
450
+ if (itemIdRaw !== undefined && typeof itemIdRaw !== 'string') {
451
+ throw new Error(`${context}.reasoning.metadata.itemId must be a string when provided`);
452
+ }
453
+ const itemTypeRaw = metadataRaw['itemType'];
454
+ if (itemTypeRaw !== undefined && itemTypeRaw !== 'reasoning') {
455
+ throw new Error(`${context}.reasoning.metadata.itemType must be 'reasoning' when provided`);
456
+ }
457
+ const statusRaw = metadataRaw['status'];
458
+ if (statusRaw !== undefined &&
459
+ statusRaw !== 'in_progress' &&
460
+ statusRaw !== 'completed' &&
461
+ statusRaw !== 'incomplete') {
462
+ throw new Error(`${context}.reasoning.metadata.status must be in_progress|completed|incomplete when provided`);
463
+ }
464
+ metadata = {};
465
+ if (typeof itemIdRaw === 'string')
466
+ metadata.itemId = itemIdRaw;
467
+ if (itemTypeRaw === 'reasoning')
468
+ metadata.itemType = itemTypeRaw;
469
+ if (statusRaw === 'in_progress' || statusRaw === 'completed' || statusRaw === 'incomplete') {
470
+ metadata.status = statusRaw;
471
+ }
472
+ if (metadata.itemId === undefined &&
473
+ metadata.itemType === undefined &&
474
+ metadata.status === undefined) {
475
+ metadata = undefined;
476
+ }
477
+ }
443
478
  const reasoning = { summary };
444
479
  if (content !== undefined)
445
480
  reasoning.content = content;
446
481
  if (typeof encryptedContentRaw === 'string')
447
482
  reasoning.encrypted_content = encryptedContentRaw;
483
+ if (metadata !== undefined)
484
+ reasoning.metadata = metadata;
448
485
  return reasoning;
449
486
  }
450
487
  function parseOptionalStringArray(record, key, context) {
@@ -1979,8 +2016,8 @@ function primingRecordToChatMessage(record) {
1979
2016
  role: 'assistant',
1980
2017
  genseq: record.genseq,
1981
2018
  content: record.content,
1982
- reasoning: record.reasoning,
1983
- provider_data: record.provider_data,
2019
+ ...(record.reasoning !== undefined ? { reasoning: record.reasoning } : {}),
2020
+ ...(record.provider_data !== undefined ? { provider_data: record.provider_data } : {}),
1984
2021
  };
1985
2022
  case 'agent_words_record':
1986
2023
  return {