dominds 0.6.2 → 0.6.4

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 (149) hide show
  1. package/dist/access-control.js +2 -2
  2. package/dist/agent-priming.js +826 -92
  3. package/dist/cli/read.js +406 -12
  4. package/dist/dialog.js +4 -0
  5. package/dist/docs/design.md +1 -0
  6. package/dist/docs/design.zh.md +1 -0
  7. package/dist/docs/dialog-system.md +12 -7
  8. package/dist/docs/dialog-system.zh.md +7 -3
  9. package/dist/docs/dominds-agent-priming.md +10 -1
  10. package/dist/docs/dominds-agent-priming.zh.md +9 -1
  11. package/dist/docs/dominds-terminology.md +8 -8
  12. package/dist/docs/fbr-implementation.md +77 -0
  13. package/dist/docs/fbr-implementation.zh.md +77 -0
  14. package/dist/docs/fbr.md +142 -141
  15. package/dist/docs/fbr.zh.md +129 -123
  16. package/dist/docs/keep-going.zh.md +162 -0
  17. package/dist/docs/showing-by-doing.md +208 -0
  18. package/dist/docs/showing-by-doing.zh.md +177 -0
  19. package/dist/docs/tellask-collab.md +250 -0
  20. package/dist/docs/tellask-collab.zh.md +254 -0
  21. package/dist/docs/txt-editing-tools.md +2 -2
  22. package/dist/docs/txt-editing-tools.zh.md +2 -2
  23. package/dist/llm/defaults.yaml +82 -4
  24. package/dist/llm/driver.js +280 -104
  25. package/dist/llm/gen/codex.js +49 -2
  26. package/dist/log.js +385 -30
  27. package/dist/mcp/supervisor.js +113 -40
  28. package/dist/minds/builtin/pangu/persona.zh.md +2 -2
  29. package/dist/minds/load.js +49 -284
  30. package/dist/minds/minds-i18n.js +2 -2
  31. package/dist/minds/promptdocs.js +263 -0
  32. package/dist/minds/system-prompt-parts.js +231 -0
  33. package/dist/minds/system-prompt.js +190 -223
  34. package/dist/persistence.js +66 -1
  35. package/dist/server/websocket-handler.js +14 -0
  36. package/dist/shared/diligence.js +40 -6
  37. package/dist/shared/utils/inter-dialog-format.js +3 -5
  38. package/dist/showing-by-doing.js +34 -31
  39. package/dist/snippets/README.en.md +3 -0
  40. package/dist/static/assets/{_baseUniq-C9vbtHF9.js → _baseUniq-C7IpU2Uk.js} +2 -2
  41. package/dist/static/assets/{_baseUniq-C9vbtHF9.js.map → _baseUniq-C7IpU2Uk.js.map} +1 -1
  42. package/dist/static/assets/{arc-hulXG01i.js → arc-1bhQqjON.js} +2 -2
  43. package/dist/static/assets/{arc-hulXG01i.js.map → arc-1bhQqjON.js.map} +1 -1
  44. package/dist/static/assets/{architectureDiagram-VXUJARFQ-DdLIAMT5.js → architectureDiagram-VXUJARFQ-CkEi1QpB.js} +6 -6
  45. package/dist/static/assets/{architectureDiagram-VXUJARFQ-DdLIAMT5.js.map → architectureDiagram-VXUJARFQ-CkEi1QpB.js.map} +1 -1
  46. package/dist/static/assets/{blockDiagram-VD42YOAC-DACsx66C.js → blockDiagram-VD42YOAC-DaBQ5-pY.js} +7 -7
  47. package/dist/static/assets/{blockDiagram-VD42YOAC-DACsx66C.js.map → blockDiagram-VD42YOAC-DaBQ5-pY.js.map} +1 -1
  48. package/dist/static/assets/{c4Diagram-YG6GDRKO-Cd5xZlLy.js → c4Diagram-YG6GDRKO-ChUgpgkP.js} +3 -3
  49. package/dist/static/assets/{c4Diagram-YG6GDRKO-Cd5xZlLy.js.map → c4Diagram-YG6GDRKO-ChUgpgkP.js.map} +1 -1
  50. package/dist/static/assets/{channel-NQehis0Z.js → channel-CxvmwllM.js} +2 -2
  51. package/dist/static/assets/{channel-NQehis0Z.js.map → channel-CxvmwllM.js.map} +1 -1
  52. package/dist/static/assets/{chunk-4BX2VUAB-DZDPl76b.js → chunk-4BX2VUAB-CKsrU2yk.js} +2 -2
  53. package/dist/static/assets/{chunk-4BX2VUAB-DZDPl76b.js.map → chunk-4BX2VUAB-CKsrU2yk.js.map} +1 -1
  54. package/dist/static/assets/{chunk-55IACEB6-CFSRDUbl.js → chunk-55IACEB6-BAau9SFt.js} +2 -2
  55. package/dist/static/assets/{chunk-55IACEB6-CFSRDUbl.js.map → chunk-55IACEB6-BAau9SFt.js.map} +1 -1
  56. package/dist/static/assets/{chunk-B4BG7PRW-BqQQ9M_z.js → chunk-B4BG7PRW--IiJ7W1m.js} +5 -5
  57. package/dist/static/assets/{chunk-B4BG7PRW-BqQQ9M_z.js.map → chunk-B4BG7PRW--IiJ7W1m.js.map} +1 -1
  58. package/dist/static/assets/{chunk-DI55MBZ5-FiFzz1Gh.js → chunk-DI55MBZ5-B83KrPQj.js} +4 -4
  59. package/dist/static/assets/{chunk-DI55MBZ5-FiFzz1Gh.js.map → chunk-DI55MBZ5-B83KrPQj.js.map} +1 -1
  60. package/dist/static/assets/{chunk-FMBD7UC4-DqqtCyWK.js → chunk-FMBD7UC4-BlDXzeza.js} +2 -2
  61. package/dist/static/assets/{chunk-FMBD7UC4-DqqtCyWK.js.map → chunk-FMBD7UC4-BlDXzeza.js.map} +1 -1
  62. package/dist/static/assets/{chunk-QN33PNHL-F0laQQ-J.js → chunk-QN33PNHL-B596W_v7.js} +2 -2
  63. package/dist/static/assets/{chunk-QN33PNHL-F0laQQ-J.js.map → chunk-QN33PNHL-B596W_v7.js.map} +1 -1
  64. package/dist/static/assets/{chunk-QZHKN3VN-CWhEZPaV.js → chunk-QZHKN3VN-UBBCxgBb.js} +2 -2
  65. package/dist/static/assets/{chunk-QZHKN3VN-CWhEZPaV.js.map → chunk-QZHKN3VN-UBBCxgBb.js.map} +1 -1
  66. package/dist/static/assets/{chunk-TZMSLE5B-Dx9cnwUy.js → chunk-TZMSLE5B-D-wCX2wJ.js} +2 -2
  67. package/dist/static/assets/{chunk-TZMSLE5B-Dx9cnwUy.js.map → chunk-TZMSLE5B-D-wCX2wJ.js.map} +1 -1
  68. package/dist/static/assets/{classDiagram-2ON5EDUG-Dp-dyEGy.js → classDiagram-2ON5EDUG-DvtmzPcu.js} +6 -6
  69. package/dist/static/assets/{classDiagram-2ON5EDUG-Dp-dyEGy.js.map → classDiagram-2ON5EDUG-DvtmzPcu.js.map} +1 -1
  70. package/dist/static/assets/{classDiagram-v2-WZHVMYZB-Dp-dyEGy.js → classDiagram-v2-WZHVMYZB-DvtmzPcu.js} +6 -6
  71. package/dist/static/assets/{classDiagram-v2-WZHVMYZB-Dp-dyEGy.js.map → classDiagram-v2-WZHVMYZB-DvtmzPcu.js.map} +1 -1
  72. package/dist/static/assets/{clone-C6mKvxs5.js → clone-DgJ0ZR-k.js} +2 -2
  73. package/dist/static/assets/{clone-C6mKvxs5.js.map → clone-DgJ0ZR-k.js.map} +1 -1
  74. package/dist/static/assets/{cose-bilkent-S5V4N54A-Dbwh3GoX.js → cose-bilkent-S5V4N54A-DXMyFQvy.js} +2 -2
  75. package/dist/static/assets/{cose-bilkent-S5V4N54A-Dbwh3GoX.js.map → cose-bilkent-S5V4N54A-DXMyFQvy.js.map} +1 -1
  76. package/dist/static/assets/{dagre-6UL2VRFP-BD_6e0Uk.js → dagre-6UL2VRFP-BdaUG-j_.js} +7 -7
  77. package/dist/static/assets/{dagre-6UL2VRFP-BD_6e0Uk.js.map → dagre-6UL2VRFP-BdaUG-j_.js.map} +1 -1
  78. package/dist/static/assets/{diagram-PSM6KHXK-BWt7Q59-.js → diagram-PSM6KHXK-NLiqKBzn.js} +7 -7
  79. package/dist/static/assets/{diagram-PSM6KHXK-BWt7Q59-.js.map → diagram-PSM6KHXK-NLiqKBzn.js.map} +1 -1
  80. package/dist/static/assets/{diagram-QEK2KX5R-D0BvBR_a.js → diagram-QEK2KX5R-D-0fyvY_.js} +6 -6
  81. package/dist/static/assets/{diagram-QEK2KX5R-D0BvBR_a.js.map → diagram-QEK2KX5R-D-0fyvY_.js.map} +1 -1
  82. package/dist/static/assets/{diagram-S2PKOQOG-D8uRdKXp.js → diagram-S2PKOQOG-BQ_FU59m.js} +6 -6
  83. package/dist/static/assets/{diagram-S2PKOQOG-D8uRdKXp.js.map → diagram-S2PKOQOG-BQ_FU59m.js.map} +1 -1
  84. package/dist/static/assets/{erDiagram-Q2GNP2WA-CQoifjFq.js → erDiagram-Q2GNP2WA-DyftKeuC.js} +5 -5
  85. package/dist/static/assets/{erDiagram-Q2GNP2WA-CQoifjFq.js.map → erDiagram-Q2GNP2WA-DyftKeuC.js.map} +1 -1
  86. package/dist/static/assets/{flowDiagram-NV44I4VS-CGhdeaG8.js → flowDiagram-NV44I4VS-9SGefONA.js} +6 -6
  87. package/dist/static/assets/{flowDiagram-NV44I4VS-CGhdeaG8.js.map → flowDiagram-NV44I4VS-9SGefONA.js.map} +1 -1
  88. package/dist/static/assets/{ganttDiagram-JELNMOA3-D8W0wb9H.js → ganttDiagram-JELNMOA3-k_WLhf-r.js} +3 -3
  89. package/dist/static/assets/{ganttDiagram-JELNMOA3-D8W0wb9H.js.map → ganttDiagram-JELNMOA3-k_WLhf-r.js.map} +1 -1
  90. package/dist/static/assets/{gitGraphDiagram-NY62KEGX-ChHni_jP.js → gitGraphDiagram-NY62KEGX-3eoLlCOY.js} +7 -7
  91. package/dist/static/assets/{gitGraphDiagram-NY62KEGX-ChHni_jP.js.map → gitGraphDiagram-NY62KEGX-3eoLlCOY.js.map} +1 -1
  92. package/dist/static/assets/{graph-BWoi_FgC.js → graph-vUevIs4s.js} +3 -3
  93. package/dist/static/assets/{graph-BWoi_FgC.js.map → graph-vUevIs4s.js.map} +1 -1
  94. package/dist/static/assets/{index-th_praGg.js → index-BNBG2CE1.js} +399 -68
  95. package/dist/static/assets/index-BNBG2CE1.js.map +1 -0
  96. package/dist/static/assets/{infoDiagram-WHAUD3N6-B_XKKZTV.js → infoDiagram-WHAUD3N6-CwEhVxkU.js} +5 -5
  97. package/dist/static/assets/{infoDiagram-WHAUD3N6-B_XKKZTV.js.map → infoDiagram-WHAUD3N6-CwEhVxkU.js.map} +1 -1
  98. package/dist/static/assets/{journeyDiagram-XKPGCS4Q-ChGuQ6T9.js → journeyDiagram-XKPGCS4Q-Dtdq4G4Q.js} +5 -5
  99. package/dist/static/assets/{journeyDiagram-XKPGCS4Q-ChGuQ6T9.js.map → journeyDiagram-XKPGCS4Q-Dtdq4G4Q.js.map} +1 -1
  100. package/dist/static/assets/{kanban-definition-3W4ZIXB7-BjWe623u.js → kanban-definition-3W4ZIXB7-Bli-AycJ.js} +3 -3
  101. package/dist/static/assets/{kanban-definition-3W4ZIXB7-BjWe623u.js.map → kanban-definition-3W4ZIXB7-Bli-AycJ.js.map} +1 -1
  102. package/dist/static/assets/{layout-BPyT310w.js → layout-CGlA8c09.js} +5 -5
  103. package/dist/static/assets/{layout-BPyT310w.js.map → layout-CGlA8c09.js.map} +1 -1
  104. package/dist/static/assets/{linear-xUsVjXWq.js → linear-Da2jDWL3.js} +2 -2
  105. package/dist/static/assets/{linear-xUsVjXWq.js.map → linear-Da2jDWL3.js.map} +1 -1
  106. package/dist/static/assets/{min-xFt7zeOd.js → min-Co741hTV.js} +3 -3
  107. package/dist/static/assets/{min-xFt7zeOd.js.map → min-Co741hTV.js.map} +1 -1
  108. package/dist/static/assets/{mindmap-definition-VGOIOE7T-DT_dvf2c.js → mindmap-definition-VGOIOE7T-DvkIjoq8.js} +4 -4
  109. package/dist/static/assets/{mindmap-definition-VGOIOE7T-DT_dvf2c.js.map → mindmap-definition-VGOIOE7T-DvkIjoq8.js.map} +1 -1
  110. package/dist/static/assets/{pieDiagram-ADFJNKIX-B1DQ-OaG.js → pieDiagram-ADFJNKIX-BGuGhTu8.js} +7 -7
  111. package/dist/static/assets/{pieDiagram-ADFJNKIX-B1DQ-OaG.js.map → pieDiagram-ADFJNKIX-BGuGhTu8.js.map} +1 -1
  112. package/dist/static/assets/{quadrantDiagram-AYHSOK5B-IHqyr3iT.js → quadrantDiagram-AYHSOK5B-DAZcrJMg.js} +3 -3
  113. package/dist/static/assets/{quadrantDiagram-AYHSOK5B-IHqyr3iT.js.map → quadrantDiagram-AYHSOK5B-DAZcrJMg.js.map} +1 -1
  114. package/dist/static/assets/{requirementDiagram-UZGBJVZJ-CKBpht7B.js → requirementDiagram-UZGBJVZJ-CXN0DxZs.js} +4 -4
  115. package/dist/static/assets/{requirementDiagram-UZGBJVZJ-CKBpht7B.js.map → requirementDiagram-UZGBJVZJ-CXN0DxZs.js.map} +1 -1
  116. package/dist/static/assets/{sankeyDiagram-TZEHDZUN-D2uGjv3i.js → sankeyDiagram-TZEHDZUN-B7-yAePZ.js} +2 -2
  117. package/dist/static/assets/{sankeyDiagram-TZEHDZUN-D2uGjv3i.js.map → sankeyDiagram-TZEHDZUN-B7-yAePZ.js.map} +1 -1
  118. package/dist/static/assets/{sequenceDiagram-WL72ISMW-wLFRhAKd.js → sequenceDiagram-WL72ISMW-DfBNY6h_.js} +4 -4
  119. package/dist/static/assets/{sequenceDiagram-WL72ISMW-wLFRhAKd.js.map → sequenceDiagram-WL72ISMW-DfBNY6h_.js.map} +1 -1
  120. package/dist/static/assets/{stateDiagram-FKZM4ZOC-BFGQTbx5.js → stateDiagram-FKZM4ZOC-BLo1xRVY.js} +9 -9
  121. package/dist/static/assets/{stateDiagram-FKZM4ZOC-BFGQTbx5.js.map → stateDiagram-FKZM4ZOC-BLo1xRVY.js.map} +1 -1
  122. package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-DF7AjJuk.js → stateDiagram-v2-4FDKWEC3-Dq7MAD0I.js} +5 -5
  123. package/dist/static/assets/{stateDiagram-v2-4FDKWEC3-DF7AjJuk.js.map → stateDiagram-v2-4FDKWEC3-Dq7MAD0I.js.map} +1 -1
  124. package/dist/static/assets/{timeline-definition-IT6M3QCI-ChHFOb0o.js → timeline-definition-IT6M3QCI-ySWyBF3b.js} +3 -3
  125. package/dist/static/assets/{timeline-definition-IT6M3QCI-ChHFOb0o.js.map → timeline-definition-IT6M3QCI-ySWyBF3b.js.map} +1 -1
  126. package/dist/static/assets/{treemap-KMMF4GRG-BxaNvQU4.js → treemap-KMMF4GRG-DOp4sqOh.js} +4 -4
  127. package/dist/static/assets/{treemap-KMMF4GRG-BxaNvQU4.js.map → treemap-KMMF4GRG-DOp4sqOh.js.map} +1 -1
  128. package/dist/static/assets/{xychartDiagram-PRI3JC2R-CrNKeY_-.js → xychartDiagram-PRI3JC2R-vkmh67qb.js} +3 -3
  129. package/dist/static/assets/{xychartDiagram-PRI3JC2R-CrNKeY_-.js.map → xychartDiagram-PRI3JC2R-vkmh67qb.js.map} +1 -1
  130. package/dist/static/index.html +1 -1
  131. package/dist/team.js +29 -6
  132. package/dist/tool.js +56 -0
  133. package/dist/tools/builtins.js +4 -2
  134. package/dist/tools/context-health.js +7 -7
  135. package/dist/tools/os.js +267 -30
  136. package/dist/tools/pending-tellask-reminder.js +185 -0
  137. package/dist/tools/plan.js +1 -0
  138. package/dist/tools/ripgrep.js +145 -4
  139. package/dist/tools/shell-tools.js +21 -0
  140. package/dist/tools/team-mgmt.js +4 -4
  141. package/dist/tools/toolset-manual.js +74 -0
  142. package/dist/utils/task-doc.js +16 -16
  143. package/package.json +1 -1
  144. package/dist/minds/builtin/cmdr/persona.md +0 -3
  145. package/dist/minds/builtin/dijiang/knowledge.md +0 -287
  146. package/dist/minds/builtin/dijiang/persona.md +0 -7
  147. package/dist/static/assets/index-th_praGg.js.map +0 -1
  148. package/dist/static/testing/dom-observation-utils.js +0 -425
  149. package/dist/static/testing/e2e-test-helper.js +0 -3119
@@ -35,7 +35,90 @@ function formatTeamIntro(team, selfAgentId, language) {
35
35
  .join('\n');
36
36
  }
37
37
  function buildSystemPrompt(input) {
38
- const fbrEnabled = (input.agent.fbr_effort ?? 0) >= 1;
38
+ const fbrScopeRuleZh = input.dialogScope === 'mainline'
39
+ ? '- 每次扪心自问(FBR)之前,务必先基于当前可观测事实调用 \\`change_mind\\` 更新差遣牒,体现任务最新进展情况。\\`!?@self\\` 自诉请正文不要冗余包含差遣牒已有信息。'
40
+ : '- 每次扪心自问(FBR)之前,务必先基于当前可观测事实分析是否与差遣牒内容存在差异,并将发现的情况包含在 \\`!?@self\\` 自诉请正文中。';
41
+ const fbrScopeRuleEn = input.dialogScope === 'mainline'
42
+ ? '- Before every FBR, first call \\`change_mind\\` based on currently observable facts to update the Taskdoc with the latest task progress, do not redundantly include information already present in the Taskdoc in the \\`!?@self\\` tellask body.'
43
+ : '- Before every FBR, first analyze whether currently observable facts differ from the Taskdoc, and include the findings in the \\`!?@self\\` tellask body.';
44
+ const fbrPhaseContractZh = [
45
+ '- FBR 必须按“发起 → 等待回贴 → 综合决策”三段执行:\\`!?@self\\` 只代表发起,不代表你已完成这轮推理。',
46
+ '- 发出 \\`!?@self\\` 后必须进入等待态:在该次 FBR 支线回贴返回前,不得给出“最终下一步行动决策”。',
47
+ '- 若 \\`fbr-effort = N\\`,必须等待全部 N 条回贴后再综合;不得基于部分回贴提前定稿。',
48
+ '- 综合阶段必须显式区分“证据(FBR 回贴事实)”与“决策(下一步行动)”;若关键事实仍缺失,先补事实再迭代 FBR。',
49
+ ].join('\n');
50
+ const fbrPhaseContractEn = [
51
+ '- FBR MUST follow three phases: “initiate -> wait for feedback -> synthesize and decide”. \\`!?@self\\` means initiation only, not completed reasoning.',
52
+ '- After emitting \\`!?@self\\`, enter wait state: do not output a final next-action decision before feedback from that FBR sideline returns.',
53
+ '- If \\`fbr-effort = N\\`, wait for all N feedback drafts before synthesis; do not finalize based on partial drafts.',
54
+ '- During synthesis, explicitly separate “evidence (FBR feedback facts)” from “decision (next action)”; if key facts are still missing, collect facts first and iterate FBR.',
55
+ ].join('\n');
56
+ const teammatePhaseContractZh = [
57
+ '- 队友诉请必须遵循“发起 → 等待 → 判定 → 续推”四段协议:若目标未达成,立即发出下一轮诉请推进。',
58
+ '- 对队友诉请而言,收到回贴即表示该轮调用已结束;不存在“对方仍在后台继续执行同一诉请”的默认语义。要继续必须显式再发一轮诉请(通常沿用同一 \\`!tellaskSession <slug>\\`)。',
59
+ '- 只有在存在明确 pending tellask 时,才可声明“等待回贴/等待结果”;否则必须执行下一动作(直接诉请或本地执行)。',
60
+ '- 能由队友诉请完成的执行性工作,禁止转交 @human 做“转发员”;当你写“让 @X 执行 Y”时,必须在同一回复内直接发出 \\`!?@X ...\\`。',
61
+ ].join('\n');
62
+ const teammatePhaseContractEn = [
63
+ '- Teammate Tellasks MUST follow four phases: “initiate -> wait -> judge -> continue”. If the objective is not met, immediately send the next Tellask round.',
64
+ '- For teammate Tellasks, a delivered response closes that call round; there is no default “still running in background” state for the same Tellask. To continue, emit a new Tellask explicitly (usually reusing the same \\`!tellaskSession <slug>\\`).',
65
+ '- You may claim “waiting for reply/result” only when a concrete pending Tellask exists; otherwise execute the next action now (direct Tellask or local action).',
66
+ '- Do not use @human as a relay for executable teammate work. If you write “ask @X to do Y”, emit \\`!?@X ...\\` in the same response.',
67
+ ].join('\n');
68
+ const collaborationProtocolZh = [
69
+ '- \\`!?@...\\` 仅用于诉请队友/@self/@human,不是函数工具调用通道。',
70
+ '- 函数工具只能通过原生 function-calling 调用;不要把工具名写进 \\`!?@...\\` 诉请头。',
71
+ '- 对队友诉请(非 \\`!?@self\\`)默认带 \\`!tellaskSession <slug>\\` 并在同一会话续推;仅在确认一次性诉请足够时才可省略,且需说明理由。',
72
+ '- 队友诉请阶段协议(强制):',
73
+ teammatePhaseContractZh,
74
+ ].join('\n');
75
+ const collaborationProtocolEn = [
76
+ '- \\`!?@...\\` is only for tellasking teammates/@self/@human; it is not a function-tool invocation channel.',
77
+ '- Function tools must be invoked through native function-calling only; do not put tool names in \\`!?@...\\` tellask headlines.',
78
+ '- For teammate tellasks (non-\\`!?@self\\`), default to \\`!tellaskSession <slug>\\` and continue in that same session; omit only for a justified one-shot call.',
79
+ '- Teammate Tellask phase contract (mandatory):',
80
+ teammatePhaseContractEn,
81
+ ].join('\n');
82
+ const fbrGuidelinesZh = [
83
+ '- \\`!?@self\\` 是 FBR 特有机制,不属于“队友诉请”分类;请按本节规则执行,不要套用“队友诉请默认带 \\`!tellaskSession\\`”的规则。',
84
+ '- 当用户明确要求“做一次 FBR/扪心自问”,对话主理人必须用 \\`!?@self\\` 发起。',
85
+ fbrScopeRuleZh,
86
+ '- FBR 的默认入口是瞬态 \\`!?@self\\`(不带 \\`!tellaskSession\\`);仅当明确需要可恢复的长期 FBR 会话时,才使用 \\`!?@self !tellaskSession <slug>\\`,并说明理由。',
87
+ '- 即使用户未明确要求,在诉诸 @human(Q4H)之前,若感觉目标不够清晰或难以决定下一步行动,应首先发起一次扪心自问,充分总结当前对话上下文的事实情况作为 FBR 正文;在收到该次 FBR 回贴前,不要提前下最终行动决策。',
88
+ '- FBR 阶段协议(强制):',
89
+ fbrPhaseContractZh,
90
+ '- 鼓励 FBR 自我建议立即获取哪些未明事实,得到建议利用当前对话工具获取,再补足上下文迭代 FBR 直到获得清晰的下一步行动思路。',
91
+ ].join('\n');
92
+ const fbrGuidelinesEn = [
93
+ '- \\`!?@self\\` is an FBR-specific mechanism, not part of the teammate-tellask category; follow this section’s rules instead of teammate-tellask defaults.',
94
+ '- When the user explicitly requests “do an FBR / fresh boots reasoning”, the Dialog Responder must initiate \\`!?@self\\`.',
95
+ fbrScopeRuleEn,
96
+ '- The default FBR entry is transient \\`!?@self\\` (without \\`!tellaskSession\\`); use \\`!?@self !tellaskSession <slug>\\` only when you explicitly need a resumable long-lived FBR thread, and explain why.',
97
+ '- Even without an explicit request, before resorting to @human (Q4H), if the goal is unclear or deciding the next action is difficult, you should first initiate FBR and summarize current dialog facts as the FBR body; do not finalize the next action before that FBR feedback returns.',
98
+ '- FBR phase contract (mandatory):',
99
+ fbrPhaseContractEn,
100
+ '- Encourage FBR to recommend which missing facts to obtain immediately; then use the current dialog’s tools to fetch them, update context, and iterate FBR until a clear next action emerges.',
101
+ ].join('\n');
102
+ const tellaskInteractionRulesZh = [
103
+ '- 诉请(tellask)使用逐行前缀语法:只有第 0 列以 \\`!?\\` 开头的行才会被当作诉请行。',
104
+ '- 诉请块以连续 \\`!?...\\` 行组成;遇到第一行普通行即结束。',
105
+ '- 一个诉请块的第一行必须是 \\`!?@<name> ...\\`。',
106
+ ].join('\n');
107
+ const tellaskInteractionRulesEn = [
108
+ '- Tellask uses a line-prefix grammar: only lines starting at column 0 with \\`!?\\` are tellask lines.',
109
+ '- A tellask block is a consecutive run of \\`!?...\\` lines; the first non-\\`!?\\` line ends the block.',
110
+ '- The first tellask line in a block must start with \\`!?@<name> ...\\`.',
111
+ ].join('\n');
112
+ const functionToolRulesZh = [
113
+ '- 回答必须基于可观测事实;为获取事实优先使用可用工具,缺乏观测事实时明确说明并请求/补充获取,不得臆测。',
114
+ `- 你必须通过原生 function-calling 发起函数工具调用。请提供严格的 JSON 参数对象,并尽量匹配工具 schema。Dominds 会对 schema 做 best-effort 校验(例如 required / additionalProperties:false / 基础 type / primitive enum / primitive const);其余复杂关键字(pattern/format/min/max/oneOf 等)与语义约束以工具报错为准。${input.funcToolRulesText}`,
115
+ '- 若遇到权限/沙盒/工具不可用:按要求申请升级或发起 Q4H;禁止编造结果。',
116
+ ].join('\n');
117
+ const functionToolRulesEn = [
118
+ '- Answers must be grounded in observed facts. Use available tools to obtain facts; if facts are missing, say so and request/obtain them—do not guess.',
119
+ `- You must invoke function tools via native function-calling. Provide a valid JSON object for the tool's arguments and match the tool schema as closely as possible. Dominds performs best-effort schema validation (for example required / additionalProperties:false / basic types / primitive enum / primitive const); other complex keywords (pattern/format/min/max/oneOf etc.) and semantic constraints are enforced via tool errors.${input.funcToolRulesText}`,
120
+ '- If a tool is unavailable due to permissions/sandboxing, request escalation or ask Q4H; do not fabricate results.',
121
+ ].join('\n');
39
122
  if (input.language === 'zh') {
40
123
  return `
41
124
  # Agent 系统提示
@@ -52,16 +135,41 @@ function buildSystemPrompt(input) {
52
135
  - 以 \`[系统通知]\` 或 \`[System notification]\` 开头的消息是**系统通知**,不是用户输入。
53
136
  - 系统通知不需要你直接回复给用户,但需要你根据通知内容执行相应的操作(如维护提醒项、调用 clear_mind 等)。
54
137
 
138
+ ## 指令优先级与冲突处理
139
+ - 优先级:系统 > 差遣牒 > 用户 > 工具回执。
140
+ - 发生冲突时:说明冲突并优先执行高优先级;若需要决策/授权/缺失输入,发起 Q4H。
141
+
142
+ ## 术语表
143
+
144
+ - 诉请(Tellask):对智能体的结构化请求。
145
+ - 诉请头(Tellask headline):诉请块第一行,形如 \`!?@<name> ...\`,结构化指令(如 \`!tellaskSession <slug>\`)写在这里。
146
+ - 诉请正文(Tellask body):诉请块内以 \`!?\` 开头但不以 \`!?@\` 开头的行,用于承载上下文/约束/验收。
147
+ - 对话主理人(Dialog Responder):负责当前对话推进与输出的智能体。
148
+ - 诉请者(tellasker):发出诉请的对话主理人。
149
+ - 被诉请者(tellaskee):接收诉请的对话主理人/队友。
150
+ - 回问诉请(TellaskBack):支线对话用 \`!?@tellasker\` 回问诉请者以澄清。
151
+ - 扪心自问(FBR):仅由 \`!?@self\` 触发的“无工具”支线推理机制。
152
+ - Q4H(Question for Human):通过 \`!?@human\` 向人类请求必要的澄清/决策/授权/缺失输入。
153
+ - 长线诉请(Tellask Session):使用 \`!tellaskSession <slug>\` 的可恢复多轮协作。
154
+ - 一次性诉请(Fresh Tellask):一次性、不可恢复的诉请。
155
+ - 主线对话(Mainline dialog):承载共享差遣牒并负责整体推进的对话。
156
+ - 支线对话(Sideline dialog):为分项任务临时创建的工作对话。
157
+ - 差遣牒(Taskdoc):共享任务契约,包含必要的 goals/constraints/progress 章节以及可选更多的额外章节。
158
+
55
159
  ## 角色设定
160
+
56
161
  ${input.persona}
57
162
 
58
163
  ## 知识
164
+
59
165
  ${input.knowledge}
60
166
 
61
167
  ## 经验
168
+
62
169
  ${input.lessons}
63
170
 
64
171
  ## 运行环境
172
+
65
173
  ${input.envIntro}
66
174
 
67
175
  ## 团队目录
@@ -69,137 +177,38 @@ ${input.envIntro}
69
177
  **特殊成员**:人类(@human)是特殊团队成员。你可以使用 \`!?@human ...\` 发起 Q4H(Question for Human),用于请求必要的澄清/决策/授权/提供缺失输入,或汇报当前环境中无法由智能体自主完成的阻塞事项。
70
178
  **注意**:不要把可由智能体完成的执行性工作外包给 @human。向 @human 的请求应尽量最小化、可验证(给出需要的具体信息、预期格式/选项),并在得到答复后继续由智能体自主完成后续工作。
71
179
  **补充**:像“发起队友诉请/推进迭代/收集回贴”这类常规协作动作属于智能体的自主工作流,不要向 @human 询问“是否要执行”;直接执行并在必要时汇报进度即可。
72
- **常见坑(协作推进)**:如果你需要队友执行某项工作,不要“口头等待”或假设对方会自动行动:应立即发起队友诉请并明确验收口径;当你说“等待回贴/等待结果”时,也要说明你已经发出哪条诉请(含 \`!tellaskSession\`)以及你在等什么验收证据。
73
180
 
74
181
  你与以下智能体队友协作。使用他们的呼号与其交流、安排分项工作。
75
182
 
76
183
  ${input.teamIntro}
77
184
 
78
- ## 交互能力
79
- 你与队友的诉请(tellask)交互,使用一种极简的逐行前缀语法,在任意分片的流式输出场景下都能稳定工作。
80
-
81
- ### 诉请(tellask)语法(务必精确遵守)
82
- **要点(最重要的 6 条硬规则)**
83
- 1) 只有“第 0 列以 \`!?\` 开头”的行才会被当作诉请行;其余都是普通 markdown。
84
- 2) 一个诉请块会持续收集 \`!?...\` 行,直到遇到第一行“不以 \`!?\` 开头”的普通行才结束(推荐用空行分隔诉请块)。
85
- 3) 一个诉请块的第一行必须是 \`!?@<name> ...\`(否则为格式不正确)。
86
- 4) 同一诉请块内:
87
- - 第一行是诉请头;后续任何以 \`!?@\` 开头的行会继续追加到诉请头(不会触发新的诉请)。
88
- - 以 \`!?\` 开头但不以 \`!?@\` 开头的行会进入诉请正文。
89
- 5) **同一条消息里发起多个诉请:必须写多个诉请块,并用至少一行普通行分隔。**
90
- 6) **给队友发诉请(@tooling/@server/...)且需要跨轮协作:强烈建议带稳定的 \`!tellaskSession <tellaskSession>\`。**
91
-
92
- **补充规则:多人集体诉请(队友诉请一对多拆分)**
93
- - 单个诉请块的诉请头(含多行诉请头)里若出现多个队友呼号,Dominds 会将其视为“一对多诉请”,并对每个目标队友执行“一对多拆分”(为每个目标生成一条队友诉请;诉请头与诉请正文保持一致)。
94
- - 若诉请头包含 \`!tellaskSession <tellaskSession>\`,它最多出现一次,并对所有被拆分的目标队友生效。
95
- - 若你想发起多条彼此独立的诉请(例如给不同队友不同内容),仍必须写多个诉请块,并用至少一行普通行分隔。
96
-
97
- **\`!tellaskSession\`(跨轮协作的默认做法)**
98
- - 用途:让同一条工作流在多轮对话中可追踪,避免对方“每次像新工单”丢上下文。
99
- - 只写在诉请头:\`!?@ux !tellaskSession ux-checklist ...\`(每个诉请块最多一次)。
100
- - 命名建议:\`<owner>-<area>-<short>\`,例如 \`tooling-read-file-options\`、\`server-ws-schema-v2\`。
101
- - 不要用于 \`!?@tellasker\`(规则:\`@tellasker\` 必须不带 \`!tellaskSession\`)。
102
-
103
- **关键易错点:当你需要在队友诉请中携带正文(步骤/上下文/验收标准等)时,正文每行也必须以 \`!?\` 开头,否则会被当作普通 markdown 分隔符导致诉请正文为空。**
104
-
105
- **常见坑(我们已经踩过)**
106
- - 空行/普通行会立刻结束当前诉请块:一旦你在一段 \`!?...\` 行中插入了普通行(包括空行),该诉请块立即结束;后续再出现的 \`!?...\` 会被当作**新的诉请块**,因此其第一行必须是 \`!?@<name> ...\`,否则会触发格式不正确。
107
- - 若你想在同一诉请块中表达“空行效果”,请写一行只有前缀的 \`!?\`(即 body 为空的一行),不要写真正的空行。
108
- - 连续写两行 \`!?@...\`:第二行不会触发第二个工具,会被并入同一诉请块诉请头,导致“多余参数/格式不正确”等误导性错误。
109
- - 不要把多个工具调用写在同一个诉请块里:请用空行分隔成多个诉请块(空行本身就是普通行分隔符)。
110
-
111
- 反例(会被合并成一个诉请块诉请头):
112
- \`\`\`plain-text
113
- !?@cmdr run lint:types
114
- !?@cmdr then run build
115
- \`\`\`
116
-
117
- 正例(两个诉请块,用空行分隔):
118
- \`\`\`plain-text
119
- !?@cmdr run lint:types
120
-
121
- !?@cmdr run build
122
- \`\`\`
123
-
124
- **复制即用模板**
125
- - 队友诉请(带话题):
126
- \`\`\`plain-text
127
- !?@ux !tellaskSession ux-checklist
128
- !?请修复 read_file 的 parseReadFileOptions,并按验收用例回贴输出。
129
- \`\`\`
130
- - 队友诉请(带正文):
131
- \`\`\`plain-text
132
- !?@ux !tellaskSession ws-mod-guardrails
133
- !?请在 rtws(运行时工作区)内定位所有仍在使用 tellask 工具语法(!?@tool)的地方,并迁移到函数工具调用;同时更新文档与测试故事。
134
- \`\`\`
135
- ### 函数工具
136
- - 你必须通过原生 function-calling 发起函数工具调用。请提供严格的 JSON 参数对象,并且严格匹配工具 schema(不允许额外字段,必须包含所有 required 字段)。${input.funcToolRulesText}
137
-
138
- ${input.funcToolUsageText || '没有可用的函数工具。'}
139
-
140
- ### 函数工具调用 vs 诉请
141
- - 原生 function-calling 不能用于队友诉请:队友诉请必须使用 tellask。
142
- - tellask 文本不能用于函数工具调用:函数工具(包括对话控制/文件/文本编辑等)一律使用原生 function-calling。
143
- ### 语法小抄(反模式)
144
- - 不要在 \`!?\` 前加项目符号、引用、编号或缩进(例如 \`- !?@ux\`、\`> !?@ux\`、\` !?@ux\`)。
145
- - 当你只是提到呼号/工具名而不是发起诉请:不要让该行以 \`!?\` 开头;必要时用反引号包裹(例如 \`\`!?@ux\`\`)。
146
- - mention ID 允许包含点号用于命名空间(例如 \`@team.lead\`)。末尾的点号视为标点并忽略(例如 \`@team.lead.\` 仍然指向 \`@team.lead\`)。
147
-
148
- ### 特殊队友别名
149
- ${fbrEnabled
150
- ? `- \`!?@self\`:扪心自问(FBR)自诉请。目标是当前对话的应答者标识,并创建一个新的、短暂的支线对话(默认;最常用)。
151
- - \`!?@self !tellaskSession <tellaskSession>\`:带 tellaskSession 的 FBR 自诉请(少用)。仅当你明确需要可恢复的长期初心会话时使用。`
152
- : ''}
153
- - \`!?@tellasker\`:回问诉请(TellaskBack)。只在**支线对话**内有效;用于向“诉请者”(发起本次诉请的对话)回问澄清,避免自行猜测。必须**不带** \`!tellaskSession\`。
154
-
155
- ${fbrEnabled
156
- ? `### 扪心自问(FBR)建议
157
- - 当你遇到“难题/硬决策/强不确定性/多约束”,**或你发现自己“越想越自洽,但缺少外部验证”**时,优先考虑发起 !?@self 扪心自问:这些情形值得投入更多推理精力。把问题拆成一个清晰的子问题,让“初心版本的你”指出哪些只是自洽推演、哪些需要证据/实验/日志验证,并给出可执行的验证计划;再把结论整合回当前对话继续推进。
158
- - 重要:FBR 支线对话是**无工具**的;不要假设它能读文件/查网页/跑命令。诉请正文里必须给足上下文(必要日志/片段/约束/目标/验收口径)。
159
- - 当运行时因 \`fbr-effort\` 生成多份 FBR 草稿时,把它理解为“付出努力的倍数”,而不是“某个固定自我在说话”。这些输出**没有稳定映射关系**,不要用序号称呼/追问某一份草稿。
160
- - 你必须做“综合整理”而不是“逐条复述”:去重、对比分歧、提炼共识,取各自精华去各自糟粕,并给出一个统一的可执行结论与验证计划。
161
- - 若诉请正文包含 \`uname -a\` 等环境快照,请将其理解为**当前 Dominds 运行时的真实环境信息**(不是“某台机器的猜测”),并据此做出环境相关判断与建议。`
162
- : ''}
163
-
164
- ### 工具集提示与队友诉请(tellask)
165
-
166
- ${input.toolUsageText}${input.intrinsicToolInstructions
167
- ? `\n### 对话控制工具\n${input.intrinsicToolInstructions}`
168
- : '\n'}
169
- ### 示例
170
- - 队友诉请:让 shell 专员运行命令(推荐写法)
171
- \`\`\`plain-text
172
- !?@<shell-specialist> !tellaskSession lint-types
173
- !?请在 repo root 执行:pnpm -C dominds lint:types
174
- !?回贴:exit_code + stdout/stderr(可截断,但需包含所有 TS error 行)
175
- \`\`\`
176
-
177
- - 队友诉请:带正文(普通行会自动结束该诉请块)
178
- \`\`\`plain-text
179
- !?@ux !tellaskSession ux-checklist
180
- !?请基于本 PR 的改动给出手工验收清单(严重度 + 复现步骤)。
181
- OK —— 我会等待你的结果,然后继续推进。
182
- \`\`\`
183
-
184
- - 反例:只写“我会请 shell 专员运行”,但没有诉请块(不会触发执行)
185
- \`\`\`plain-text
186
- 我会请 shell 专员运行 pnpm -C dominds lint:types。
187
- \`\`\`
188
-
189
- - 反例:声称“已运行/已通过”,但没有看到回执(禁止)
190
- \`\`\`plain-text
191
- 我已经让 shell 专员跑过了,lint:types 没问题。
192
- \`\`\`
193
-
194
- ### 并发与编排
195
- - 同一条回复中的所有诉请会并发执行;在同一轮中,它们无法看到彼此的输出。
196
- - 让每个诉请都自给自足。
197
- - 需要前后依赖的步骤,请拆分到多轮,或使用编排器工具强制顺序。
198
-
199
- ### 防止意外触发
200
- - 只有第 0 列以 \`!?\` 开头的行才会被解释为诉请行。
201
- - 行内的 \`!?\` 与 \`@\` 没有特殊含义。
202
- - 不确定时,不要在行首写 \`!?\`;需要展示字面量时用反引号包裹。
185
+ ## 全局策略
186
+
187
+ ${input.policyText}
188
+
189
+ ## 协作协议(Tellask 与函数工具边界)
190
+
191
+ ${collaborationProtocolZh}
192
+
193
+ ## FBR 使用准则
194
+
195
+ ${fbrGuidelinesZh}
196
+
197
+ ## 内置工具
198
+
199
+ ${input.intrinsicToolUsageText}
200
+
201
+ ## 工具集手册
202
+
203
+ ${input.toolsetManualIntro}
204
+
205
+ ## 交互协议
206
+
207
+ ### Tellask(仅用于队友/@self/@human)
208
+ ${tellaskInteractionRulesZh}
209
+
210
+ ### 函数工具(仅原生 function-calling)
211
+ ${functionToolRulesZh}
203
212
  `;
204
213
  }
205
214
  return `
@@ -209,7 +218,7 @@ OK —— 我会等待你的结果,然后继续推进。
209
218
  - Member ID: \`${input.agent.id}\`
210
219
  - Full Name: ${input.agent.name}
211
220
 
212
- ## Language Mode
221
+ ## Language Model
213
222
  - Your internal working language is English (system prompt, tool rules, teammate/sideline-dialog narrative formatting).
214
223
  - You may receive a short guide message like "User-visible response language: X". When replying to the user, follow that guide; if absent, respond in the working language.
215
224
 
@@ -217,121 +226,79 @@ OK —— 我会等待你的结果,然后继续推进。
217
226
  - Messages starting with \`[系统通知]\` or \`[System notification]\` are **system notifications**, not user input.
218
227
  System notifications convey important state changes (e.g., context caution/critical, Diligence Push triggered). Read carefully and follow the instructions.
219
228
 
229
+ ## Instruction Priority & Conflicts
230
+ - Priority order: system > taskdoc > user > tool outputs.
231
+ - On conflict: state the conflict and follow the higher-priority instruction; if a decision/authorization/input is needed, ask Q4H.
232
+
233
+ ## Glossary
234
+
235
+ - Tellask: a structured request addressed to an agent.
236
+ - Tellask headline: the first line of a Tellask block, e.g. \`!?@<name> ...\`; directives like \`!tellaskSession <slug>\` go here.
237
+ - Tellask body: lines starting with \`!?\` but not \`!?@\`, carrying context/constraints/acceptance.
238
+ - Dialog Responder: the role responsible for driving a dialog and producing responses.
239
+ - tellasker: the Dialog Responder that issued the Tellask.
240
+ - tellaskee: the Dialog Responder/agent that receives the Tellask.
241
+ - TellaskBack: a sideline uses \`!?@tellasker\` to ask the tellasker for clarification.
242
+ - Fresh Boots Reasoning (FBR): a tool-less sideline reasoning mechanism triggered only by \`!?@self\`.
243
+ - Q4H (Question for Human): use \`!?@human\` to request necessary clarification/decision/authorization/missing input from a human.
244
+ - Tellask Session: resumable multi-turn work using \`!tellaskSession <slug>\`.
245
+ - Fresh Tellask: a one-shot, non-resumable Tellask.
246
+ - Mainline dialog: the dialog that owns the shared Taskdoc and overall progress.
247
+ - Sideline dialog: a temporary dialog for a subtask.
248
+ - Taskdoc: the shared task contract with required goals/constraints/progress sections plus optional extra sections.
249
+
220
250
  ## Persona
251
+
221
252
  ${input.persona}
222
253
 
223
254
  ## Knowledge
255
+
224
256
  ${input.knowledge}
225
257
 
226
258
  ## Lessons
259
+
227
260
  ${input.lessons}
228
261
 
229
262
  ## Runtime Environment
263
+
230
264
  ${input.envIntro}
231
265
 
232
266
  ## Team Directory
267
+
233
268
  **Special member**: Human (@human) is a special team member. You may use \`!?@human ...\` to ask a Q4H (Question for Human) when you need necessary clarification/decision/authorization/missing inputs, or to report blockers that cannot be completed autonomously in the current environment.
234
269
  **Note**: Do not outsource executable work to @human. Keep Q4H requests minimal and verifiable (ask for specific info, expected format/options), then continue the remaining work autonomously after receiving the answer.
235
270
  **Addendum**: Routine coordination actions (e.g., tellasking teammates, driving iterations, collecting replies) are part of the agent’s autonomous workflow; do not ask @human for permission to do them. Execute and report progress when needed.
236
- **Common pitfall (coordination)**: If you need a teammate to do something, do not “wait verbally” or assume it will happen automatically. Send a tellask immediately with explicit acceptance criteria. When you say you are “waiting for a reply/result”, also state which tellask (including \`!tellaskSession\`) you already sent and what acceptance evidence you are waiting for.
237
271
 
238
272
  You collaborate with the following teammates. Use their call signs to address them.
239
273
 
240
274
  ${input.teamIntro}
241
275
 
242
- ## Interaction Abilities
243
- You interact with teammates via the tellask mechanism using a primitive line-prefix grammar designed to be robust under arbitrary streaming chunk boundaries.
244
-
245
- ### Tellask Grammar
246
- - A tellask block consists of lines; every tellask line MUST begin at column 0 with literal \`!?\`. The \`!?\` prefix is not part of the payload.
247
- - Any line not starting with \`!?\` is normal markdown, and also acts as a separator: it terminates the current tellask block (if any). Therefore there is no explicit terminator.
248
- - The first tellask line in a block MUST start with \`!?@<name>\` to be considered valid. Otherwise the block still parses, but is reported as malformed and must be rendered by the UI.
249
- - Within a tellask block:
250
- - Headline: starts from the first tellask line (after removing \`!?\`); subsequent lines starting with \`!?@\` extend the headline (multiline headline).
251
- - Body: all tellask lines that start with \`!?\` but NOT \`!?@\` compose the body in order.
252
- - **Collective teammate tellask (one-to-many split)**: If multiple teammate call signs appear in the tellask headline (including multiline headlines), Dominds treats this as a one-to-many tellask and **splits** it into one teammate tellask per target teammate, using the same headline/body payload for each.
253
- - If you include \`!tellaskSession <tellaskSession>\`, it must appear at most once in the headline and applies to all split targets.
254
- - If you want multiple independent tellasks with different content, write multiple tellask blocks separated by normal lines.
255
-
256
- ### Function Tools
257
- - You must invoke function tools via native function-calling. Provide a valid JSON object for the tool's arguments that strictly matches the tool schema (no extra fields, include all required fields).${input.funcToolRulesText}
258
-
259
- ${input.funcToolUsageText || 'No function tools available.'}
260
-
261
- ### Function Calling vs Tellask
262
- - Native function-calling cannot be used to tellask teammates: teammate tellasks must use tellask.
263
- - Tellask text cannot invoke function tools: all tools (including dialog control) must use native function-calling.
264
-
265
- ### Anti-pattern Cheat Sheet
266
- - Do NOT prefix tellask lines with bullets, blockquotes, numbering, or indentation (e.g., \`- !?@ux\`, \`> !?@ux\`, \` !?@ux\`).
267
- - Normal/blank lines terminate the current tellask block immediately. If you later write another tellask line, it starts a NEW tellask block, so its first line must be \`!?@<name> ...\` (otherwise it's malformed).
268
- - If you want an “empty line” inside a tellask body, write a tellask body line with empty payload: a line containing only \`!?\`.
269
- - When you are only mentioning a call sign/tool name and not making a tellask call, do not start the line with \`!?\`; wrap it in backticks if needed (e.g., \`\`!?@ux\`\`).
270
- - Mention IDs may include dots for namespacing (e.g., \`@team.lead\`). A trailing dot is treated as punctuation and ignored (e.g., \`@team.lead.\` still targets \`@team.lead\`).
271
-
272
- ### Teammate Tellasks
273
- - Prefer multi-teammate tellasks for parallel expertise. Keep requests specific and role-aware.
274
-
275
- ### Special Teammate Aliases
276
- ${fbrEnabled
277
- ? `- \`!?@self\`: Fresh Boots Reasoning (FBR) self-tellask. Targets your current dialog responder (\`agentId\`) and creates a NEW ephemeral sideline dialog (default; most common).
278
- - \`!?@self !tellaskSession <tellaskSession>\`: FBR self-tellask with a registered tellask session (rare). Use only when you explicitly want a resumable long-lived fresh-boots session.`
279
- : ''}
280
- - \`!?@tellasker\`: TellaskBack (ask the tellasker dialog for clarification). Only valid inside a **sideline dialog**; tellasks back to the tellasker (the dialog that issued the current Tellask). Must be used with NO \`!tellaskSession\`.
281
-
282
- ${fbrEnabled
283
- ? `### Fresh Boots Reasoning (FBR) Guidance
284
- - In hard situations (high uncertainty, complex trade-offs, many constraints, or when facing tough decisions) — **or when your reasoning feels increasingly self-consistent but lacks external verification** — proactively do a tool-less !?@self FBR. Isolate a single sub-question; ask your “fresh boots” self to separate coherent speculation from evidence-backed claims, propose concrete verification steps (tests/logs/experiments to run later), then integrate the conclusion back and keep driving the main work.
285
- - Important: the FBR sideline dialog is **tool-less**. Do not assume it can read files, browse, run shell, or fetch rtws (runtime workspace) state. Put all required context into the tellask body (relevant snippets/logs/constraints/acceptance criteria).
286
- - When the runtime produces multiple FBR drafts due to \`fbr-effort\`, treat it as an “effort multiplier”, not as stable personas. There is **no stable mapping** between drafts; do not number them or continue a thread with a specific draft.
287
- - You must *synthesize*, not *repeat*: dedupe, reconcile disagreements, extract the best parts, then deliver one coherent decision and an actionable verification plan.
288
- - If the tellask body contains an environment snapshot (e.g. \`uname -a\`), treat it as **real environment info for the current Dominds runtime**, not “some machine”. Ground your advice in it.`
289
- : ''}
290
-
291
- ### Toolset Prompts & Teammate Tellasks (Tellask)
292
-
293
- ${input.toolUsageText}${input.intrinsicToolInstructions
294
- ? `\n### Dialog Control Tools\n${input.intrinsicToolInstructions}`
295
- : '\n'}
296
- ### Examples
297
- - Single tellask call (no body)
298
- \`\`\`plain-text
299
- !?@ux Please review the UX and report issues.
300
- \`\`\`
301
-
302
- - Tellask call with a body (a normal line ends the block automatically)
303
- \`\`\`plain-text
304
- !?@cmdr !tellaskSession fix-ws-mod
305
- !?1) Run lint/types
306
- !?2) Report errors and proposed fixes
307
- OK — I will wait for your results and then proceed.
308
- \`\`\`
309
-
310
- - Multiline headline + body
311
- \`\`\`plain-text
312
- !?@ux Please do the following:
313
- !?@ux And keep the output concise
314
- !?1) Check logs/error.log
315
- !?2) Propose a fix
316
- \`\`\`
317
-
318
- - Multi-call (separate blocks)
319
- \`\`\`plain-text
320
- !?@ux !tellaskSession ux-checklist
321
- !?Please review the UX flow and report issues.
322
-
323
- !?@cmdr !tellaskSession lint-types
324
- !?Please run lint:types and report TypeScript errors.
325
- \`\`\`
326
-
327
- ### Concurrency & Orchestration
328
- - All calls in one response run concurrently; they cannot see each other's outputs in the same turn.
329
- - Design each call to be self-sufficient.
330
- - For dependent steps, split across turns or use an orchestrator tool to enforce sequencing.
331
-
332
- ### Safety Against Accidental Mentions
333
- - Only lines beginning with \`!?\` at column 0 are interpreted as tellask lines.
334
- - Inline \`!?\` and \`@\` have no special meaning.
335
- - When in doubt, do not place \`!?\` at column 0; wrap literal examples in backticks.
276
+ ## Global Policies
277
+
278
+ ${input.policyText}
279
+
280
+ ## Collaboration Protocol (Tellask vs Function Tools)
281
+
282
+ ${collaborationProtocolEn}
283
+
284
+ ## FBR Usage Guidelines
285
+
286
+ ${fbrGuidelinesEn}
287
+
288
+ ## Intrinsic Tools
289
+
290
+ ${input.intrinsicToolUsageText}
291
+
292
+ ## Toolset Manuals
293
+
294
+ ${input.toolsetManualIntro}
295
+
296
+ ## Interaction Protocols
297
+
298
+ ### Tellask (teammates/@self/@human only)
299
+ ${tellaskInteractionRulesEn}
300
+
301
+ ### Function Tools (native function-calling only)
302
+ ${functionToolRulesEn}
336
303
  `;
337
304
  }
@@ -771,6 +771,29 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
771
771
  };
772
772
  (0, evt_registry_1.postDialogEvent)(dialog, funcCallEvt);
773
773
  }
774
+ async webSearchCall(dialog, payload) {
775
+ const course = dialog.activeGenCourseOrUndefined ?? dialog.currentCourse;
776
+ const record = {
777
+ ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
778
+ type: 'web_search_call_record',
779
+ genseq: dialog.activeGenSeq,
780
+ phase: payload.phase,
781
+ itemId: payload.itemId,
782
+ status: payload.status,
783
+ action: payload.action,
784
+ };
785
+ await this.appendEvent(course, record);
786
+ const evt = {
787
+ type: 'web_search_call_evt',
788
+ course,
789
+ genseq: dialog.activeGenSeq,
790
+ phase: payload.phase,
791
+ itemId: payload.itemId,
792
+ status: payload.status,
793
+ action: payload.action,
794
+ };
795
+ (0, evt_registry_1.postDialogEvent)(dialog, evt);
796
+ }
774
797
  /**
775
798
  * Emit stream error for current generation lifecycle (uses active genseq when present)
776
799
  */
@@ -1517,6 +1540,26 @@ class DiskFileDialogStore extends dialog_1.DialogStore {
1517
1540
  }
1518
1541
  break;
1519
1542
  }
1543
+ case 'web_search_call_record': {
1544
+ const webSearchCall = {
1545
+ type: 'web_search_call_evt',
1546
+ phase: event.phase,
1547
+ itemId: event.itemId,
1548
+ status: event.status,
1549
+ action: event.action,
1550
+ course,
1551
+ genseq: event.genseq,
1552
+ dialog: {
1553
+ selfId: dialog.id.selfId,
1554
+ rootId: dialog.id.rootId,
1555
+ },
1556
+ timestamp: event.ts,
1557
+ };
1558
+ if (ws.readyState === 1) {
1559
+ ws.send(JSON.stringify(webSearchCall));
1560
+ }
1561
+ break;
1562
+ }
1520
1563
  case 'func_result_record': {
1521
1564
  // Handle function result events from persistence
1522
1565
  const funcResult = {
@@ -2369,7 +2412,25 @@ class DialogPersistence {
2369
2412
  }
2370
2413
  }
2371
2414
  static async appendQuestion4HumanState(dialogId, question, status = 'running') {
2372
- await this.mutateQuestions4HumanState(dialogId, () => ({ kind: 'append', question }), status);
2415
+ const questionId = question.id;
2416
+ const normalizedCallId = typeof question.callId === 'string' && question.callId.trim() !== ''
2417
+ ? question.callId.trim()
2418
+ : null;
2419
+ await this.mutateQuestions4HumanState(dialogId, (previousQuestions) => {
2420
+ const byId = previousQuestions.find((q) => q.id === questionId);
2421
+ if (byId) {
2422
+ throw new Error(`Q4H duplicate question id violation: dialog=${dialogId.valueOf()} status=${status} questionId=${questionId} existingAskedAt=${byId.askedAt} incomingAskedAt=${question.askedAt}`);
2423
+ }
2424
+ if (normalizedCallId) {
2425
+ const byCallId = previousQuestions.find((q) => {
2426
+ return typeof q.callId === 'string' && q.callId.trim() === normalizedCallId;
2427
+ });
2428
+ if (byCallId) {
2429
+ throw new Error(`Q4H duplicate call id violation: dialog=${dialogId.valueOf()} status=${status} callId=${normalizedCallId} existingQuestionId=${byCallId.id} incomingQuestionId=${questionId} existingAskedAt=${byCallId.askedAt} incomingAskedAt=${question.askedAt}`);
2430
+ }
2431
+ }
2432
+ return { kind: 'append', question };
2433
+ }, status);
2373
2434
  }
2374
2435
  static async removeQuestion4HumanState(dialogId, questionId, status = 'running') {
2375
2436
  const out = await this.mutateQuestions4HumanState(dialogId, () => ({ kind: 'remove', questionId }), status);
@@ -3571,6 +3632,10 @@ class DialogPersistence {
3571
3632
  });
3572
3633
  break;
3573
3634
  }
3635
+ case 'web_search_call_record':
3636
+ // UI-only timeline event for native web_search tool call visualization.
3637
+ // Must not be injected into LLM context reconstruction.
3638
+ break;
3574
3639
  case 'func_result_record': {
3575
3640
  // Convert function result to ChatMessage
3576
3641
  messages.push({
@@ -21,6 +21,7 @@ const language_1 = require("../shared/types/language");
21
21
  const time_1 = require("../shared/utils/time");
22
22
  const team_1 = require("../team");
23
23
  const team_config_updates_1 = require("../team-config-updates");
24
+ const pending_tellask_reminder_1 = require("../tools/pending-tellask-reminder");
24
25
  const id_1 = require("../utils/id");
25
26
  const auth_1 = require("./auth");
26
27
  const create_dialog_contract_1 = require("./create-dialog-contract");
@@ -41,6 +42,17 @@ const wsLiveDlg = new WeakMap();
41
42
  const wsSub = new WeakMap();
42
43
  const wsUiLanguage = new WeakMap();
43
44
  let broadcastDialogsIndexMessage = null;
45
+ async function syncPendingTellaskReminderBestEffort(dialog, where) {
46
+ try {
47
+ await (0, pending_tellask_reminder_1.syncPendingTellaskReminderState)(dialog);
48
+ }
49
+ catch (err) {
50
+ log.warn(`Failed to sync pending tellask reminder at ${where}`, err, {
51
+ dialogId: dialog.id.selfId,
52
+ rootId: dialog.id.rootId,
53
+ });
54
+ }
55
+ }
44
56
  function resolveUserLanguageCode(ws, raw, fallbackDialog) {
45
57
  if (typeof raw === 'string') {
46
58
  const parsed = (0, language_1.normalizeLanguageCode)(raw);
@@ -690,6 +702,7 @@ async function handleDisplayDialog(ws, packet) {
690
702
  // Proactively emit reminders for the newly active dialog
691
703
  // todo: maybe emit only to the requestiong websocket, not publish via PubChan as curr impl
692
704
  try {
705
+ await syncPendingTellaskReminderBestEffort(dialog, 'handleDisplayDialog');
693
706
  await dialog.processReminderUpdates();
694
707
  }
695
708
  catch (err) {
@@ -748,6 +761,7 @@ async function handleDisplayReminders(ws, packet) {
748
761
  log.warn(`Dialog ${packet.dialog} for reminders is not current live (live dialog is ${live.id})`);
749
762
  return;
750
763
  }
764
+ await syncPendingTellaskReminderBestEffort(live, 'handleDisplayReminders');
751
765
  await live.processReminderUpdates();
752
766
  }
753
767
  catch (error) {