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
@@ -65,6 +65,7 @@ const dialog_run_state_1 = require("../dialog-run-state");
65
65
  const evt_registry_1 = require("../evt-registry");
66
66
  const log_1 = require("../log");
67
67
  const load_1 = require("../minds/load");
68
+ const system_prompt_parts_1 = require("../minds/system-prompt-parts");
68
69
  const persistence_1 = require("../persistence");
69
70
  const problems_1 = require("../problems");
70
71
  const async_fifo_mutex_1 = require("../shared/async-fifo-mutex");
@@ -77,6 +78,7 @@ const time_1 = require("../shared/utils/time");
77
78
  const team_1 = require("../team");
78
79
  const tellask_1 = require("../tellask");
79
80
  const tool_1 = require("../tool");
81
+ const pending_tellask_reminder_1 = require("../tools/pending-tellask-reminder");
80
82
  const id_2 = require("../utils/id");
81
83
  const taskdoc_1 = require("../utils/taskdoc");
82
84
  const client_1 = require("./client");
@@ -93,6 +95,22 @@ function resolveMemberDiligencePushMax(team, agentId) {
93
95
  }
94
96
  return DEFAULT_KEEP_GOING_MAX_NUM_PROMPTS;
95
97
  }
98
+ async function syncPendingTellaskReminderBestEffort(dlg, where) {
99
+ try {
100
+ const changed = await (0, pending_tellask_reminder_1.syncPendingTellaskReminderState)(dlg);
101
+ if (!changed)
102
+ return;
103
+ await dlg.processReminderUpdates();
104
+ }
105
+ catch (err) {
106
+ log_1.log.warn('Failed to sync pending tellask reminder', {
107
+ where,
108
+ dialogId: dlg.id.selfId,
109
+ rootId: dlg.id.rootId,
110
+ error: err instanceof Error ? err.message : String(err),
111
+ });
112
+ }
113
+ }
96
114
  function stripMarkdownFrontmatter(raw) {
97
115
  // We no longer honor frontmatter config in diligence files.
98
116
  // If frontmatter exists, strip it to preserve backward compatibility with old files.
@@ -148,7 +166,7 @@ async function maybePrepareDiligenceAutoContinuePrompt(options) {
148
166
  if (!options.isRootDialog) {
149
167
  return { kind: 'disabled', nextRemainingBudget: options.remainingBudget };
150
168
  }
151
- if (options.dlg.disableDiligencePush) {
169
+ if (options.dlg.disableDiligencePush || options.suppressDiligencePush === true) {
152
170
  const normalizedRemaining = typeof options.remainingBudget === 'number' && Number.isFinite(options.remainingBudget)
153
171
  ? Math.max(0, Math.floor(options.remainingBudget))
154
172
  : 0;
@@ -838,6 +856,22 @@ async function withSuspensionStateLock(dialogId, fn) {
838
856
  release();
839
857
  }
840
858
  }
859
+ async function hasQueuedSubdialogResponses(dialogId) {
860
+ try {
861
+ const queued = await withSuspensionStateLock(dialogId, async () => {
862
+ return await persistence_1.DialogPersistence.loadSubdialogResponsesQueue(dialogId);
863
+ });
864
+ return queued.length > 0;
865
+ }
866
+ catch (err) {
867
+ log_1.log.warn('Failed to check queued subdialog responses; suppressing diligence as safe default', {
868
+ dialogId: dialogId.valueOf(),
869
+ error: err,
870
+ });
871
+ // Fail safe: if we cannot verify queue emptiness, do not inject diligence prompts.
872
+ return true;
873
+ }
874
+ }
841
875
  // TODO: certain scenarios should pass `waitInQue=true`:
842
876
  // - supdialog call for clarification
843
877
  /**
@@ -875,7 +909,7 @@ async function withSuspensionStateLock(dialogId, fn) {
875
909
  * - Continue loop if new function calls or tool outputs exist
876
910
  * - Break and release lock when complete
877
911
  */
878
- async function driveDialogStream(dlg, humanPrompt, waitInQue = false) {
912
+ async function driveDialogStream(dlg, humanPrompt, waitInQue = false, driveOptions) {
879
913
  if (!waitInQue && dlg.isLocked()) {
880
914
  throw new Error(`Dialog busy driven, see how it proceeded and try again.`);
881
915
  }
@@ -905,7 +939,7 @@ async function driveDialogStream(dlg, humanPrompt, waitInQue = false) {
905
939
  if (effectivePrompt && effectivePrompt.userLanguageCode) {
906
940
  dlg.setLastUserLanguageCode(effectivePrompt.userLanguageCode);
907
941
  }
908
- driveResult = await _driveDialogStream(dlg, effectivePrompt);
942
+ driveResult = await _driveDialogStream(dlg, effectivePrompt, driveOptions);
909
943
  // Do not auto-chain upNext when this drive ended in interrupted state
910
944
  // (user/emergency/system stop). upNext remains queued for explicit manual resume.
911
945
  if (!driveResult.interrupted) {
@@ -1047,7 +1081,8 @@ async function checkQ4HAnswered(dialogId) {
1047
1081
  return false;
1048
1082
  }
1049
1083
  }
1050
- async function _driveDialogStream(dlg, humanPrompt) {
1084
+ async function _driveDialogStream(dlg, humanPrompt, driveOptions) {
1085
+ const suppressDiligencePushForDrive = driveOptions?.suppressDiligencePush === true;
1051
1086
  const abortSignal = (0, dialog_run_state_1.createActiveRun)(dlg.id);
1052
1087
  let finalRunState;
1053
1088
  let shouldEmitResumedMarker = false;
@@ -1090,18 +1125,20 @@ async function _driveDialogStream(dlg, humanPrompt) {
1090
1125
  let systemPrompt = minds.systemPrompt;
1091
1126
  const memories = minds.memories;
1092
1127
  let agentTools = minds.agentTools;
1093
- const isToollessFbr = isToollessFbrSelfSubdialog(dlg);
1094
- if (isToollessFbr) {
1095
- // Tool-less FBR: technically supply zero tools to the LLM.
1096
- agentTools = [];
1097
- systemPrompt = withFbrToollessSystemPrompt(systemPrompt, (0, runtime_language_1.getWorkLanguage)());
1098
- // FBR-only model params override (deep merge onto effective member model_params).
1099
- if (agent.fbr_model_params) {
1100
- const fbrAgent = Object.create(agent);
1101
- fbrAgent.model_params = mergeModelParams(agent.model_params, agent.fbr_model_params);
1102
- agent = fbrAgent;
1103
- }
1128
+ const drivePolicy = buildDrivePolicy({
1129
+ dlg,
1130
+ agent,
1131
+ systemPrompt,
1132
+ agentTools,
1133
+ language: (0, runtime_language_1.getWorkLanguage)(),
1134
+ });
1135
+ const drivePolicyValidation = validateDrivePolicyInvariants(drivePolicy, (0, runtime_language_1.getWorkLanguage)());
1136
+ if (!drivePolicyValidation.ok) {
1137
+ throw new Error(`FBR policy isolation violation: ${drivePolicyValidation.detail}`);
1104
1138
  }
1139
+ agent = drivePolicy.effectiveAgent;
1140
+ systemPrompt = drivePolicy.effectiveSystemPrompt;
1141
+ agentTools = drivePolicy.effectiveAgentTools;
1105
1142
  // reload cfgs every course, in case it's been updated by human or ai meanwhile
1106
1143
  // Validate streaming configuration
1107
1144
  try {
@@ -1193,7 +1230,7 @@ async function _driveDialogStream(dlg, humanPrompt) {
1193
1230
  if (currentPrompt) {
1194
1231
  const promptOrigin = currentPrompt.origin ?? 'user';
1195
1232
  const isDiligencePrompt = promptOrigin === 'diligence_push';
1196
- if (isDiligencePrompt && dlg.disableDiligencePush) {
1233
+ if (isDiligencePrompt && (dlg.disableDiligencePush || suppressDiligencePushForDrive)) {
1197
1234
  log_1.log.info('Skip diligence prompt after disable toggle', {
1198
1235
  dialogId: dlg.id.valueOf(),
1199
1236
  msgId: currentPrompt.msgId,
@@ -1310,12 +1347,13 @@ async function _driveDialogStream(dlg, humanPrompt) {
1310
1347
  return false;
1311
1348
  return true;
1312
1349
  });
1313
- const ctxMsgs = [
1314
- ...memories,
1315
- ...(taskDocMsg ? [taskDocMsg] : []),
1316
- ...coursePrefixMsgs,
1317
- ...dialogMsgsForContext,
1318
- ];
1350
+ const ctxMsgs = buildDriveContextMessages({
1351
+ prependedContextMessages: drivePolicy.prependedContextMessages,
1352
+ memories,
1353
+ taskDocMsg,
1354
+ coursePrefixMsgs,
1355
+ dialogMsgsForContext,
1356
+ });
1319
1357
  if (genIterNo === 1 && takenSubdialogResponses.length > 0) {
1320
1358
  for (const response of takenSubdialogResponses) {
1321
1359
  ctxMsgs.push({
@@ -1495,34 +1533,27 @@ async function _driveDialogStream(dlg, humanPrompt) {
1495
1533
  }
1496
1534
  }
1497
1535
  }
1498
- if (isToollessFbr && collectedAssistantCalls.length > 0) {
1499
- const hasDisallowedTellask = collectedAssistantCalls.some((call) => {
1500
- if (call.validation.kind !== 'valid')
1501
- return true;
1502
- return call.validation.firstMention !== 'tellasker';
1536
+ const nonStreamingTellaskViolation = resolveDrivePolicyViolationKind({
1537
+ policy: drivePolicy,
1538
+ tellaskCalls: collectedAssistantCalls,
1539
+ functionCallCount: 0,
1540
+ });
1541
+ if (nonStreamingTellaskViolation === 'tellask') {
1542
+ const violationText = (0, driver_messages_1.formatDomindsNoteFbrToollessViolation)((0, runtime_language_1.getWorkLanguage)(), {
1543
+ kind: 'tellask',
1503
1544
  });
1504
- if (!hasDisallowedTellask) {
1505
- // Tool-less FBR: allow TellaskBack only (`!?@tellasker`) for critical clarification.
1506
- }
1507
- else {
1508
- const violationText = (0, driver_messages_1.formatDomindsNoteFbrToollessViolation)((0, runtime_language_1.getWorkLanguage)(), {
1509
- kind: 'tellask',
1510
- });
1511
- const genseq = dlg.activeGenSeq ?? 0;
1512
- await dlg.addChatMessages({
1513
- type: 'saying_msg',
1514
- role: 'assistant',
1515
- genseq,
1516
- content: violationText,
1517
- });
1518
- lastAssistantSayingContent = violationText;
1519
- await dlg.persistAgentMessage(violationText, genseq, 'saying_msg');
1520
- return { lastAssistantSayingContent, interrupted: false };
1521
- }
1545
+ const genseq = dlg.activeGenSeq ?? 0;
1546
+ await dlg.addChatMessages({
1547
+ type: 'saying_msg',
1548
+ role: 'assistant',
1549
+ genseq,
1550
+ content: violationText,
1551
+ });
1552
+ lastAssistantSayingContent = violationText;
1553
+ await dlg.persistAgentMessage(violationText, genseq, 'saying_msg');
1554
+ return { lastAssistantSayingContent, interrupted: false };
1522
1555
  }
1523
- let assistantValidCallCount = 0;
1524
1556
  if (collectedAssistantCalls.length > 0) {
1525
- assistantValidCallCount = collectedAssistantCalls.filter((call) => call.validation.kind === 'valid').length;
1526
1557
  throwIfAborted(abortSignal, dlg.id);
1527
1558
  const assistantResult = await executeTellaskCalls(dlg, agent, collectedAssistantCalls);
1528
1559
  if (dlg.hasUpNext()) {
@@ -1536,7 +1567,12 @@ async function _driveDialogStream(dlg, humanPrompt) {
1536
1567
  }
1537
1568
  }
1538
1569
  const funcCalls = nonStreamMsgs.filter((m) => m.type === 'func_call_msg');
1539
- if (isToollessFbr && funcCalls.length > 0) {
1570
+ const nonStreamingToolViolation = resolveDrivePolicyViolationKind({
1571
+ policy: drivePolicy,
1572
+ tellaskCalls: [],
1573
+ functionCallCount: funcCalls.length,
1574
+ });
1575
+ if (nonStreamingToolViolation === 'tool') {
1540
1576
  const violationText = (0, driver_messages_1.formatDomindsNoteFbrToollessViolation)((0, runtime_language_1.getWorkLanguage)(), {
1541
1577
  kind: 'tool',
1542
1578
  });
@@ -1694,11 +1730,9 @@ async function _driveDialogStream(dlg, humanPrompt) {
1694
1730
  }
1695
1731
  break;
1696
1732
  }
1697
- // Continue only when the assistant actually emitted executable calls this round.
1698
- // Do not auto-continue on malformed tellask diagnostics alone.
1699
- const shouldContinue = funcCalls.length > 0 ||
1700
- assistantValidCallCount > 0 ||
1701
- (funcResults.length > 0 && funcCalls.length === 0);
1733
+ // Continue only when this round executed function tools.
1734
+ // Tellask-only rounds must stop and wait for sideline/backfill feedback.
1735
+ const shouldContinue = funcCalls.length > 0 || (funcResults.length > 0 && funcCalls.length === 0);
1702
1736
  if (!shouldContinue) {
1703
1737
  // Diligence Push (root dialog only): prevent ALL stopping except legitimate suspension.
1704
1738
  // If disabled (empty diligence file) or budget exhausted, we suspend via Q4H.
@@ -1722,11 +1756,19 @@ async function _driveDialogStream(dlg, humanPrompt) {
1722
1756
  }
1723
1757
  break;
1724
1758
  }
1759
+ const hasQueuedResponses = await hasQueuedSubdialogResponses(dlg.id);
1760
+ if (hasQueuedResponses) {
1761
+ log_1.log.info('Skip diligence prompt while subdialog responses are still queued', {
1762
+ dialogId: dlg.id.valueOf(),
1763
+ });
1764
+ break;
1765
+ }
1725
1766
  const prepared = await maybePrepareDiligenceAutoContinuePrompt({
1726
1767
  dlg,
1727
1768
  isRootDialog: true,
1728
1769
  remainingBudget: dlg.diligencePushRemainingBudget,
1729
1770
  diligencePushMax: resolveMemberDiligencePushMax(team, dlg.agentId),
1771
+ suppressDiligencePush: suppressDiligencePushForDrive,
1730
1772
  });
1731
1773
  dlg.diligencePushRemainingBudget = prepared.nextRemainingBudget;
1732
1774
  void persistence_1.DialogPersistence.mutateDialogLatest(dlg.id, () => ({
@@ -1739,7 +1781,7 @@ async function _driveDialogStream(dlg, humanPrompt) {
1739
1781
  maxInjectCount: prepared.maxInjectCount,
1740
1782
  injectedCount: Math.max(0, prepared.maxInjectCount - prepared.nextRemainingBudget),
1741
1783
  remainingCount: Math.max(0, prepared.nextRemainingBudget),
1742
- disableDiligencePush: dlg.disableDiligencePush,
1784
+ disableDiligencePush: dlg.disableDiligencePush || suppressDiligencePushForDrive,
1743
1785
  });
1744
1786
  }
1745
1787
  if (prepared.kind === 'budget_exhausted') {
@@ -1892,6 +1934,11 @@ async function _driveDialogStream(dlg, humanPrompt) {
1892
1934
  arguments: args,
1893
1935
  });
1894
1936
  },
1937
+ webSearchCall: async (call) => {
1938
+ throwIfAborted(abortSignal, dlg.id);
1939
+ sawAnyStreamContent = true;
1940
+ await dlg.webSearchCall(call);
1941
+ },
1895
1942
  }, dlg.activeGenSeq, abortSignal);
1896
1943
  },
1897
1944
  });
@@ -1927,33 +1974,26 @@ async function _driveDialogStream(dlg, humanPrompt) {
1927
1974
  throw new Error('Collected calls missing callId - parser should have allocated one per call');
1928
1975
  }
1929
1976
  const validCalls = collectedCalls.filter((call) => call.validation.kind === 'valid');
1930
- if (isToollessFbr && (collectedCalls.length > 0 || streamedFuncCalls.length > 0)) {
1931
- const hasDisallowedTellask = collectedCalls.some((call) => {
1932
- if (call.validation.kind !== 'valid')
1933
- return true;
1934
- return call.validation.firstMention !== 'tellasker';
1977
+ const streamingPolicyViolation = resolveDrivePolicyViolationKind({
1978
+ policy: drivePolicy,
1979
+ tellaskCalls: collectedCalls,
1980
+ functionCallCount: streamedFuncCalls.length,
1981
+ });
1982
+ if (streamingPolicyViolation) {
1983
+ const violationText = (0, driver_messages_1.formatDomindsNoteFbrToollessViolation)((0, runtime_language_1.getWorkLanguage)(), {
1984
+ kind: streamingPolicyViolation,
1935
1985
  });
1936
- const shouldBlock = streamedFuncCalls.length > 0 || hasDisallowedTellask;
1937
- if (shouldBlock) {
1938
- const violationText = (0, driver_messages_1.formatDomindsNoteFbrToollessViolation)((0, runtime_language_1.getWorkLanguage)(), {
1939
- kind: collectedCalls.length > 0 && streamedFuncCalls.length > 0
1940
- ? 'tellask_and_tool'
1941
- : collectedCalls.length > 0
1942
- ? 'tellask'
1943
- : 'tool',
1944
- });
1945
- const genseq = dlg.activeGenSeq ?? 0;
1946
- newMsgs.push({
1947
- type: 'saying_msg',
1948
- role: 'assistant',
1949
- genseq,
1950
- content: violationText,
1951
- });
1952
- lastAssistantSayingContent = violationText;
1953
- await dlg.addChatMessages(...newMsgs);
1954
- await dlg.persistAgentMessage(violationText, genseq, 'saying_msg');
1955
- return { lastAssistantSayingContent, interrupted: false };
1956
- }
1986
+ const genseq = dlg.activeGenSeq ?? 0;
1987
+ newMsgs.push({
1988
+ type: 'saying_msg',
1989
+ role: 'assistant',
1990
+ genseq,
1991
+ content: violationText,
1992
+ });
1993
+ lastAssistantSayingContent = violationText;
1994
+ await dlg.addChatMessages(...newMsgs);
1995
+ await dlg.persistAgentMessage(violationText, genseq, 'saying_msg');
1996
+ return { lastAssistantSayingContent, interrupted: false };
1957
1997
  }
1958
1998
  throwIfAborted(abortSignal, dlg.id);
1959
1999
  const results = await Promise.all(validCalls.map((call) => executeTellaskCall(dlg, agent, call.validation.firstMention, call.tellaskHead, call.body, call.callId)));
@@ -2124,9 +2164,9 @@ async function _driveDialogStream(dlg, humanPrompt) {
2124
2164
  }
2125
2165
  break;
2126
2166
  }
2127
- // Continue only when this round had executable calls.
2128
- // Invalid/malformed tellask diagnostics should not trigger implicit extra generations.
2129
- const shouldContinue = validCalls.length > 0 || streamedFuncCalls.length > 0 || funcResults.length > 0;
2167
+ // Continue only when this round executed function tools.
2168
+ // Tellask-only rounds must stop and wait for sideline/backfill feedback.
2169
+ const shouldContinue = streamedFuncCalls.length > 0 || funcResults.length > 0;
2130
2170
  if (!shouldContinue) {
2131
2171
  // Diligence Push (root dialog only): prevent ALL stopping except legitimate suspension.
2132
2172
  if (dlg instanceof dialog_1.RootDialog) {
@@ -2149,11 +2189,19 @@ async function _driveDialogStream(dlg, humanPrompt) {
2149
2189
  }
2150
2190
  break;
2151
2191
  }
2192
+ const hasQueuedResponses = await hasQueuedSubdialogResponses(dlg.id);
2193
+ if (hasQueuedResponses) {
2194
+ log_1.log.info('Skip diligence prompt while subdialog responses are still queued', {
2195
+ dialogId: dlg.id.valueOf(),
2196
+ });
2197
+ break;
2198
+ }
2152
2199
  const prepared = await maybePrepareDiligenceAutoContinuePrompt({
2153
2200
  dlg,
2154
2201
  isRootDialog: true,
2155
2202
  remainingBudget: dlg.diligencePushRemainingBudget,
2156
2203
  diligencePushMax: resolveMemberDiligencePushMax(team, dlg.agentId),
2204
+ suppressDiligencePush: suppressDiligencePushForDrive,
2157
2205
  });
2158
2206
  dlg.diligencePushRemainingBudget = prepared.nextRemainingBudget;
2159
2207
  void persistence_1.DialogPersistence.mutateDialogLatest(dlg.id, () => ({
@@ -2166,7 +2214,7 @@ async function _driveDialogStream(dlg, humanPrompt) {
2166
2214
  maxInjectCount: prepared.maxInjectCount,
2167
2215
  injectedCount: Math.max(0, prepared.maxInjectCount - prepared.nextRemainingBudget),
2168
2216
  remainingCount: Math.max(0, prepared.nextRemainingBudget),
2169
- disableDiligencePush: dlg.disableDiligencePush,
2217
+ disableDiligencePush: dlg.disableDiligencePush || suppressDiligencePushForDrive,
2170
2218
  });
2171
2219
  }
2172
2220
  if (prepared.kind === 'budget_exhausted') {
@@ -2411,33 +2459,141 @@ function mergeModelParams(base, overlay) {
2411
2459
  anthropic: { ...(base.anthropic ?? {}), ...(overlay.anthropic ?? {}) },
2412
2460
  };
2413
2461
  }
2414
- function withFbrToollessSystemPrompt(systemPrompt, language) {
2462
+ function buildDrivePolicy(args) {
2463
+ const { dlg, agent, systemPrompt, agentTools, language } = args;
2464
+ if (!isToollessFbrSelfSubdialog(dlg)) {
2465
+ return {
2466
+ mode: 'default',
2467
+ effectiveAgent: agent,
2468
+ effectiveSystemPrompt: systemPrompt,
2469
+ effectiveAgentTools: agentTools,
2470
+ prependedContextMessages: [],
2471
+ tellaskPolicy: 'allow_any',
2472
+ allowFunctionCalls: true,
2473
+ };
2474
+ }
2475
+ const effectiveAgent = Object.assign(Object.create(agent), {
2476
+ model_params: mergeModelParams(agent.model_params, agent.fbr_model_params),
2477
+ });
2478
+ return {
2479
+ mode: 'fbr_toolless',
2480
+ effectiveAgent,
2481
+ effectiveSystemPrompt: buildFbrSystemPrompt(language),
2482
+ effectiveAgentTools: [],
2483
+ prependedContextMessages: [
2484
+ {
2485
+ type: 'environment_msg',
2486
+ role: 'user',
2487
+ content: (0, system_prompt_parts_1.buildNoToolsNotice)(language),
2488
+ },
2489
+ ],
2490
+ tellaskPolicy: 'tellasker_only',
2491
+ allowFunctionCalls: false,
2492
+ };
2493
+ }
2494
+ function buildDriveContextMessages(args) {
2495
+ return [
2496
+ ...args.prependedContextMessages,
2497
+ ...args.memories,
2498
+ ...(args.taskDocMsg ? [args.taskDocMsg] : []),
2499
+ ...args.coursePrefixMsgs,
2500
+ ...args.dialogMsgsForContext,
2501
+ ];
2502
+ }
2503
+ function hasTellaskPolicyViolation(policy, calls) {
2504
+ if (policy.tellaskPolicy === 'allow_any') {
2505
+ return false;
2506
+ }
2507
+ return calls.some((call) => {
2508
+ if (call.validation.kind !== 'valid') {
2509
+ return true;
2510
+ }
2511
+ return call.validation.firstMention !== 'tellasker';
2512
+ });
2513
+ }
2514
+ function resolveDrivePolicyViolationKind(args) {
2515
+ const tellaskViolation = hasTellaskPolicyViolation(args.policy, args.tellaskCalls);
2516
+ const toolViolation = !args.policy.allowFunctionCalls && args.functionCallCount > 0;
2517
+ if (tellaskViolation && toolViolation) {
2518
+ return 'tellask_and_tool';
2519
+ }
2520
+ if (tellaskViolation) {
2521
+ return 'tellask';
2522
+ }
2523
+ if (toolViolation) {
2524
+ return 'tool';
2525
+ }
2526
+ return null;
2527
+ }
2528
+ function validateDrivePolicyInvariants(policy, language) {
2529
+ if (policy.mode !== 'fbr_toolless') {
2530
+ return { ok: true };
2531
+ }
2532
+ const expectedSystemPrompt = buildFbrSystemPrompt(language);
2533
+ if (policy.effectiveSystemPrompt !== expectedSystemPrompt) {
2534
+ return {
2535
+ ok: false,
2536
+ detail: 'FBR must use buildFbrSystemPrompt(language) exactly.',
2537
+ };
2538
+ }
2539
+ if (policy.effectiveAgentTools.length > 0) {
2540
+ return {
2541
+ ok: false,
2542
+ detail: 'FBR effectiveAgentTools must be empty.',
2543
+ };
2544
+ }
2545
+ if (policy.allowFunctionCalls) {
2546
+ return {
2547
+ ok: false,
2548
+ detail: 'FBR allowFunctionCalls must be false.',
2549
+ };
2550
+ }
2551
+ if (policy.tellaskPolicy !== 'tellasker_only') {
2552
+ return {
2553
+ ok: false,
2554
+ detail: 'FBR tellaskPolicy must be tellasker_only.',
2555
+ };
2556
+ }
2557
+ const expectedNoToolsNotice = (0, system_prompt_parts_1.buildNoToolsNotice)(language);
2558
+ if (policy.prependedContextMessages.length !== 1) {
2559
+ return {
2560
+ ok: false,
2561
+ detail: 'FBR must prepend exactly one no-tools notice message.',
2562
+ };
2563
+ }
2564
+ const [notice] = policy.prependedContextMessages;
2565
+ if (!notice ||
2566
+ notice.type !== 'environment_msg' ||
2567
+ notice.role !== 'user' ||
2568
+ notice.content !== expectedNoToolsNotice) {
2569
+ return {
2570
+ ok: false,
2571
+ detail: 'FBR prepended notice must exactly match buildNoToolsNotice(language).',
2572
+ };
2573
+ }
2574
+ return { ok: true };
2575
+ }
2576
+ function buildFbrSystemPrompt(language) {
2415
2577
  const prefix = language === 'zh'
2416
2578
  ? [
2417
- '# 扪心自问(FBR)支线对话:无工具模式',
2418
- '',
2419
- '- 你正在处理一次 `!?@self` 扪心自问(FBR)诉请。',
2420
- '- **本对话无任何工具**:禁止函数工具调用;禁止除 `!?@tellasker` 外的一切队友诉请。',
2421
- '- 仅当你需要澄清关键上下文时,允许使用 `!?@tellasker` 向诉请者回问;除此之外不要发起任何诉请。',
2422
- '- 你只能基于诉请正文(以及本支线对话自身的会话历史,如有)进行推理与总结;不要假设你能访问诉请者线程的对话历史。',
2423
- '- 若上下文不足,请在输出中列出缺失信息与原因;必要时可用 `!?@tellasker` 回问澄清。除 `!?@tellasker` 外不要发起任何诉请/工具调用。',
2424
- '',
2425
- '---',
2579
+ '# 扪心自问(FBR)支线对话',
2426
2580
  '',
2581
+ '- 你正在处理一次由 `!?@self` 发起的 FBR 支线对话。',
2582
+ '- 诉请正文是主要任务上下文;不要假设能访问诉请者对话历史。',
2583
+ '- 若使用可恢复的 `!tellaskSession` 形式,你可以使用本支线对话自身的 `tellaskSession` 历史作为显式上下文。',
2584
+ '- 若诉请正文缺少关键上下文,请在输出中列出缺失信息与阻塞原因。',
2585
+ '- 仅当必须澄清关键缺失上下文时,允许用 `!?@tellasker` 回问诉请者;除此之外不要发起任何诉请。',
2427
2586
  ].join('\n')
2428
2587
  : [
2429
- '# Tool-less @self FBR sideline dialog',
2588
+ '# Fresh Boots Reasoning (FBR) sideline dialog',
2430
2589
  '',
2431
- '- This is a Fresh Boots Reasoning session created by `!?@self`.',
2432
- '- **No tools are available**: do not emit function tool calls; do not emit any tellasks except `!?@tellasker`.',
2590
+ '- This is an FBR sideline dialog created by `!?@self`.',
2591
+ '- The tellask body is the primary task context; do not assume access to tellasker dialog history.',
2592
+ '- If this is the resumable `!tellaskSession` form, you may use this sideline dialog’s own tellaskSession history as explicit context.',
2593
+ '- If the tellask body is missing critical context, list what is missing and why it blocks reasoning.',
2433
2594
  '- `!?@tellasker` is allowed only when you must clarify critical missing context; otherwise do not emit any tellasks.',
2434
- '- Use only the tellask body (and this sideline dialog’s own tellaskSession history, if any) as context. Do not assume access to the caller-thread dialog history.',
2435
- '- If the tellask body is missing critical context, list the missing info and why it blocks reasoning; if truly necessary you may ask back via `!?@tellasker` (and only that). Do not fetch via tools/other tellasks.',
2436
- '',
2437
- '---',
2438
- '',
2439
2595
  ].join('\n');
2440
- return `${prefix}${systemPrompt}`.trim();
2596
+ return prefix.trim();
2441
2597
  }
2442
2598
  function isToollessFbrSelfSubdialog(dlg) {
2443
2599
  return dlg instanceof dialog_1.SubDialog && isFbrSelfTellaskHeadLine(dlg.assignmentFromSup.tellaskHead);
@@ -2707,6 +2863,7 @@ async function createSubdialogForSupdialog(supdialog, targetAgentId, tellaskHead
2707
2863
  await withSuspensionStateLock(supdialog.id, async () => {
2708
2864
  await persistence_1.DialogPersistence.appendPendingSubdialog(supdialog.id, pendingRecord);
2709
2865
  });
2866
+ await syncPendingTellaskReminderBestEffort(supdialog, 'createSubdialogForSupdialog:appendPending');
2710
2867
  // Drive the subdialog asynchronously
2711
2868
  void (async () => {
2712
2869
  try {
@@ -2862,6 +3019,7 @@ async function supplyResponseToSupdialog(parentDialog, subdialogId, responseText
2862
3019
  const resolvedAgentId = result.responderAgentId ?? result.responderId;
2863
3020
  const resolvedOriginMemberId = result.originMemberId ?? parentDialog.agentId;
2864
3021
  const resolvedCallId = callId ?? '';
3022
+ await syncPendingTellaskReminderBestEffort(parentDialog, 'supplyResponseToSupdialog:savePending');
2865
3023
  await parentDialog.receiveTeammateResponse(result.responderId, result.tellaskHead, status, subdialogId, {
2866
3024
  response: responseText,
2867
3025
  agentId: resolvedAgentId,
@@ -2873,7 +3031,10 @@ async function supplyResponseToSupdialog(parentDialog, subdialogId, responseText
2873
3031
  if (parentDialog instanceof dialog_1.RootDialog) {
2874
3032
  dialog_global_registry_1.globalDialogRegistry.markNeedsDrive(parentDialog.id.rootId);
2875
3033
  }
2876
- void driveDialogStream(parentDialog, undefined, true);
3034
+ const suppressDiligencePushForReviveDrive = parentDialog.disableDiligencePush;
3035
+ void driveDialogStream(parentDialog, undefined, true, {
3036
+ suppressDiligencePush: suppressDiligencePushForReviveDrive,
3037
+ });
2877
3038
  }
2878
3039
  }
2879
3040
  catch (error) {
@@ -2938,6 +3099,7 @@ async function incorporateSubdialogResponses(rootDialog) {
2938
3099
  const respondedIds = new Set(responses.map((r) => r.subdialogId));
2939
3100
  const filteredPending = pendingSubdialogs.filter((p) => !respondedIds.has(p.subdialogId));
2940
3101
  await persistence_1.DialogPersistence.savePendingSubdialogs(rootDialog.id, filteredPending);
3102
+ await syncPendingTellaskReminderBestEffort(rootDialog, 'incorporateSubdialogResponses:savePending');
2941
3103
  return responses;
2942
3104
  }
2943
3105
  catch (error) {
@@ -3127,6 +3289,15 @@ async function executeTellaskCall(dlg, agent, firstMention, tellaskHead, body, c
3127
3289
  }
3128
3290
  catch (q4hErr) {
3129
3291
  const errMsg = q4hErr instanceof Error ? q4hErr.message : String(q4hErr);
3292
+ const streamErr = `Q4H register invariant violation: dialog=${dlg.id.selfId} callId=${callId.trim()} reason=${errMsg}`;
3293
+ try {
3294
+ await dlg.streamError(streamErr);
3295
+ }
3296
+ catch (streamErrPost) {
3297
+ log_1.log.warn('Q4H: failed to emit stream_error_evt', streamErrPost, {
3298
+ dialogId: dlg.id.selfId,
3299
+ });
3300
+ }
3130
3301
  log_1.log.error('Q4H: Failed to register question', q4hErr, {
3131
3302
  dialogId: dlg.id.selfId,
3132
3303
  tellaskHead: tellaskHead.substring(0, 100),
@@ -3267,6 +3438,7 @@ async function executeTellaskCall(dlg, agent, firstMention, tellaskHead, body, c
3267
3438
  records: [...previous, ...pendingRecords],
3268
3439
  }));
3269
3440
  });
3441
+ await syncPendingTellaskReminderBestEffort(dlg, 'executeTellaskCall:FBR-TypeC:replacePending');
3270
3442
  for (const sub of createdSubs) {
3271
3443
  void (async () => {
3272
3444
  try {
@@ -3417,6 +3589,7 @@ async function executeTellaskCall(dlg, agent, firstMention, tellaskHead, body, c
3417
3589
  return { kind: 'replace', records: next };
3418
3590
  });
3419
3591
  });
3592
+ await syncPendingTellaskReminderBestEffort(pendingOwner, 'executeTellaskCall:FBR-TypeB:replacePending');
3420
3593
  for (const r of createdOrExisting) {
3421
3594
  void (async () => {
3422
3595
  try {
@@ -3592,6 +3765,7 @@ async function executeTellaskCall(dlg, agent, firstMention, tellaskHead, body, c
3592
3765
  await withSuspensionStateLock(dlg.id, async () => {
3593
3766
  await persistence_1.DialogPersistence.appendPendingSubdialog(dlg.id, pendingRecord);
3594
3767
  });
3768
+ await syncPendingTellaskReminderBestEffort(dlg, 'executeTellaskCall:TypeB-fallback:appendPending');
3595
3769
  const task = (async () => {
3596
3770
  try {
3597
3771
  const initPrompt = {
@@ -3673,6 +3847,7 @@ async function executeTellaskCall(dlg, agent, firstMention, tellaskHead, body, c
3673
3847
  return { kind: 'replace', records: next };
3674
3848
  });
3675
3849
  });
3850
+ await syncPendingTellaskReminderBestEffort(pendingOwner, 'executeTellaskCall:TypeB:replacePending');
3676
3851
  const task = (async () => {
3677
3852
  try {
3678
3853
  if (result.kind === 'existing') {
@@ -3745,6 +3920,7 @@ async function executeTellaskCall(dlg, agent, firstMention, tellaskHead, body, c
3745
3920
  await withSuspensionStateLock(dlg.id, async () => {
3746
3921
  await persistence_1.DialogPersistence.appendPendingSubdialog(dlg.id, pendingRecord);
3747
3922
  });
3923
+ await syncPendingTellaskReminderBestEffort(dlg, 'executeTellaskCall:TypeC:appendPending');
3748
3924
  const task = (async () => {
3749
3925
  try {
3750
3926
  const initPrompt = {