dominds 1.23.4 → 1.23.6

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 (113) hide show
  1. package/dist/dialog-display-state.js +79 -30
  2. package/dist/dialog-interruption.js +2 -0
  3. package/dist/dialog.d.ts +20 -0
  4. package/dist/dialog.js +60 -0
  5. package/dist/llm/kernel-driver/flow.js +177 -39
  6. package/dist/minds/system-prompt.js +4 -4
  7. package/dist/persistence.d.ts +1 -0
  8. package/dist/persistence.js +112 -14
  9. package/dist/runtime/driver-messages.js +12 -8
  10. package/dist/runtime/inter-dialog-format.js +4 -4
  11. package/dist/runtime/reply-prompt-copy.js +4 -4
  12. package/dist/tools/prompts/control/en/principles.md +1 -1
  13. package/dist/tools/prompts/control/en/scenarios.md +1 -1
  14. package/dist/tools/prompts/control/en/tools.md +1 -1
  15. package/dist/tools/prompts/control/zh/principles.md +1 -1
  16. package/dist/tools/prompts/control/zh/scenarios.md +1 -1
  17. package/dist/tools/prompts/control/zh/tools.md +1 -1
  18. package/package.json +3 -3
  19. package/webapp/dist/assets/{_basePickBy-DMD1UhXs.js → _basePickBy-528dB5Tu.js} +3 -3
  20. package/webapp/dist/assets/{_basePickBy-DMD1UhXs.js.map → _basePickBy-528dB5Tu.js.map} +1 -1
  21. package/webapp/dist/assets/{_baseUniq-CsE8Qvwt.js → _baseUniq-DkdKmFUs.js} +2 -2
  22. package/webapp/dist/assets/{_baseUniq-CsE8Qvwt.js.map → _baseUniq-DkdKmFUs.js.map} +1 -1
  23. package/webapp/dist/assets/{arc-0h8sV6e1.js → arc-BXvXVeL_.js} +2 -2
  24. package/webapp/dist/assets/{arc-0h8sV6e1.js.map → arc-BXvXVeL_.js.map} +1 -1
  25. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-BbMESECO.js → architectureDiagram-2XIMDMQ5-Ck1IMDXl.js} +7 -7
  26. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-BbMESECO.js.map → architectureDiagram-2XIMDMQ5-Ck1IMDXl.js.map} +1 -1
  27. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-DwkN-9a4.js → blockDiagram-WCTKOSBZ-DLRhkTKE.js} +7 -7
  28. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-DwkN-9a4.js.map → blockDiagram-WCTKOSBZ-DLRhkTKE.js.map} +1 -1
  29. package/webapp/dist/assets/{c4Diagram-IC4MRINW-CGYONEh1.js → c4Diagram-IC4MRINW-D2Hc1l7q.js} +3 -3
  30. package/webapp/dist/assets/{c4Diagram-IC4MRINW-CGYONEh1.js.map → c4Diagram-IC4MRINW-D2Hc1l7q.js.map} +1 -1
  31. package/webapp/dist/assets/{channel-DbSJhm5-.js → channel-DuagLVFr.js} +2 -2
  32. package/webapp/dist/assets/{channel-DbSJhm5-.js.map → channel-DuagLVFr.js.map} +1 -1
  33. package/webapp/dist/assets/{chunk-4BX2VUAB-D1inRfgf.js → chunk-4BX2VUAB-BVowxdVQ.js} +2 -2
  34. package/webapp/dist/assets/{chunk-4BX2VUAB-D1inRfgf.js.map → chunk-4BX2VUAB-BVowxdVQ.js.map} +1 -1
  35. package/webapp/dist/assets/{chunk-55IACEB6-DL1IDg_h.js → chunk-55IACEB6-DOqixome.js} +2 -2
  36. package/webapp/dist/assets/{chunk-55IACEB6-DL1IDg_h.js.map → chunk-55IACEB6-DOqixome.js.map} +1 -1
  37. package/webapp/dist/assets/{chunk-FMBD7UC4-CugIlRDV.js → chunk-FMBD7UC4-BQE3IRbI.js} +2 -2
  38. package/webapp/dist/assets/{chunk-FMBD7UC4-CugIlRDV.js.map → chunk-FMBD7UC4-BQE3IRbI.js.map} +1 -1
  39. package/webapp/dist/assets/{chunk-JSJVCQXG-DKHSdeu1.js → chunk-JSJVCQXG-BWvy_u2h.js} +2 -2
  40. package/webapp/dist/assets/{chunk-JSJVCQXG-DKHSdeu1.js.map → chunk-JSJVCQXG-BWvy_u2h.js.map} +1 -1
  41. package/webapp/dist/assets/{chunk-KX2RTZJC-DCU9tkq6.js → chunk-KX2RTZJC-DsSmqNSf.js} +2 -2
  42. package/webapp/dist/assets/{chunk-KX2RTZJC-DCU9tkq6.js.map → chunk-KX2RTZJC-DsSmqNSf.js.map} +1 -1
  43. package/webapp/dist/assets/{chunk-NQ4KR5QH-DN3O2s2M.js → chunk-NQ4KR5QH-B3jQt0DX.js} +4 -4
  44. package/webapp/dist/assets/{chunk-NQ4KR5QH-DN3O2s2M.js.map → chunk-NQ4KR5QH-B3jQt0DX.js.map} +1 -1
  45. package/webapp/dist/assets/{chunk-QZHKN3VN-e3ztIJg0.js → chunk-QZHKN3VN-CWST9WcY.js} +2 -2
  46. package/webapp/dist/assets/{chunk-QZHKN3VN-e3ztIJg0.js.map → chunk-QZHKN3VN-CWST9WcY.js.map} +1 -1
  47. package/webapp/dist/assets/{chunk-WL4C6EOR-Dv907NPM.js → chunk-WL4C6EOR-DjGCVqJN.js} +6 -6
  48. package/webapp/dist/assets/{chunk-WL4C6EOR-Dv907NPM.js.map → chunk-WL4C6EOR-DjGCVqJN.js.map} +1 -1
  49. package/webapp/dist/assets/{classDiagram-VBA2DB6C-DOTXtxYZ.js → classDiagram-VBA2DB6C-BnjkPcus.js} +7 -7
  50. package/webapp/dist/assets/{classDiagram-VBA2DB6C-DOTXtxYZ.js.map → classDiagram-VBA2DB6C-BnjkPcus.js.map} +1 -1
  51. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-DOTXtxYZ.js → classDiagram-v2-RAHNMMFH-BnjkPcus.js} +7 -7
  52. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-DOTXtxYZ.js.map → classDiagram-v2-RAHNMMFH-BnjkPcus.js.map} +1 -1
  53. package/webapp/dist/assets/{clone-6lYQMWpu.js → clone-BlToIURl.js} +2 -2
  54. package/webapp/dist/assets/{clone-6lYQMWpu.js.map → clone-BlToIURl.js.map} +1 -1
  55. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-DoJeDXV0.js → cose-bilkent-S5V4N54A-BDVnPWt2.js} +2 -2
  56. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-DoJeDXV0.js.map → cose-bilkent-S5V4N54A-BDVnPWt2.js.map} +1 -1
  57. package/webapp/dist/assets/{dagre-KLK3FWXG-F_n_vhV9.js → dagre-KLK3FWXG-aEZUtpHt.js} +7 -7
  58. package/webapp/dist/assets/{dagre-KLK3FWXG-F_n_vhV9.js.map → dagre-KLK3FWXG-aEZUtpHt.js.map} +1 -1
  59. package/webapp/dist/assets/{diagram-E7M64L7V-Crwhgyjv.js → diagram-E7M64L7V-CvNVSxxk.js} +8 -8
  60. package/webapp/dist/assets/{diagram-E7M64L7V-Crwhgyjv.js.map → diagram-E7M64L7V-CvNVSxxk.js.map} +1 -1
  61. package/webapp/dist/assets/{diagram-IFDJBPK2-CIt1nnn5.js → diagram-IFDJBPK2-Cvwaoava.js} +7 -7
  62. package/webapp/dist/assets/{diagram-IFDJBPK2-CIt1nnn5.js.map → diagram-IFDJBPK2-Cvwaoava.js.map} +1 -1
  63. package/webapp/dist/assets/{diagram-P4PSJMXO-qowipEfV.js → diagram-P4PSJMXO-ffnT7Lr_.js} +7 -7
  64. package/webapp/dist/assets/{diagram-P4PSJMXO-qowipEfV.js.map → diagram-P4PSJMXO-ffnT7Lr_.js.map} +1 -1
  65. package/webapp/dist/assets/{erDiagram-INFDFZHY-DV2BcYNa.js → erDiagram-INFDFZHY-DvGIVeJS.js} +5 -5
  66. package/webapp/dist/assets/{erDiagram-INFDFZHY-DV2BcYNa.js.map → erDiagram-INFDFZHY-DvGIVeJS.js.map} +1 -1
  67. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-CAbWV161.js → flowDiagram-PKNHOUZH-BkQUpSc9.js} +7 -7
  68. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-CAbWV161.js.map → flowDiagram-PKNHOUZH-BkQUpSc9.js.map} +1 -1
  69. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-CfdR7FRr.js → ganttDiagram-A5KZAMGK-BlG96EZZ.js} +3 -3
  70. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-CfdR7FRr.js.map → ganttDiagram-A5KZAMGK-BlG96EZZ.js.map} +1 -1
  71. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-DuJFTELz.js → gitGraphDiagram-K3NZZRJ6-CnyjUBR4.js} +8 -8
  72. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-DuJFTELz.js.map → gitGraphDiagram-K3NZZRJ6-CnyjUBR4.js.map} +1 -1
  73. package/webapp/dist/assets/{graph-cjRyzujT.js → graph-D-OO7MVR.js} +3 -3
  74. package/webapp/dist/assets/{graph-cjRyzujT.js.map → graph-D-OO7MVR.js.map} +1 -1
  75. package/webapp/dist/assets/{index-DgfF56L4.js → index-DvqI98wY.js} +39 -33
  76. package/webapp/dist/assets/{index-DgfF56L4.js.map → index-DvqI98wY.js.map} +1 -1
  77. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-3wx-7AdD.js → infoDiagram-LFFYTUFH-Bid564Un.js} +6 -6
  78. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-3wx-7AdD.js.map → infoDiagram-LFFYTUFH-Bid564Un.js.map} +1 -1
  79. package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-g6CMb1Qc.js → ishikawaDiagram-PHBUUO56-BoU1GXkx.js} +2 -2
  80. package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-g6CMb1Qc.js.map → ishikawaDiagram-PHBUUO56-BoU1GXkx.js.map} +1 -1
  81. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-DdCcmOBO.js → journeyDiagram-4ABVD52K-C-JJRe4y.js} +5 -5
  82. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-DdCcmOBO.js.map → journeyDiagram-4ABVD52K-C-JJRe4y.js.map} +1 -1
  83. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-BFw2emGl.js → kanban-definition-K7BYSVSG-BPGHC2fL.js} +3 -3
  84. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-BFw2emGl.js.map → kanban-definition-K7BYSVSG-BPGHC2fL.js.map} +1 -1
  85. package/webapp/dist/assets/{layout-Clazq06r.js → layout-BFpoiNr0.js} +5 -5
  86. package/webapp/dist/assets/{layout-Clazq06r.js.map → layout-BFpoiNr0.js.map} +1 -1
  87. package/webapp/dist/assets/{linear-jdsBGgvD.js → linear-BwnDVwt9.js} +2 -2
  88. package/webapp/dist/assets/{linear-jdsBGgvD.js.map → linear-BwnDVwt9.js.map} +1 -1
  89. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-DLSZrW6l.js → mindmap-definition-YRQLILUH-D4aHh1Ye.js} +4 -4
  90. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-DLSZrW6l.js.map → mindmap-definition-YRQLILUH-D4aHh1Ye.js.map} +1 -1
  91. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-Uj-Zpci6.js → pieDiagram-SKSYHLDU-DIp7yy6V.js} +8 -8
  92. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-Uj-Zpci6.js.map → pieDiagram-SKSYHLDU-DIp7yy6V.js.map} +1 -1
  93. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-DO7Sl1nV.js → quadrantDiagram-337W2JSQ-uKOhvCPR.js} +3 -3
  94. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-DO7Sl1nV.js.map → quadrantDiagram-337W2JSQ-uKOhvCPR.js.map} +1 -1
  95. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-WrurrDKQ.js → requirementDiagram-Z7DCOOCP-Da_5DlcQ.js} +4 -4
  96. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-WrurrDKQ.js.map → requirementDiagram-Z7DCOOCP-Da_5DlcQ.js.map} +1 -1
  97. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-gcxbxuZB.js → sankeyDiagram-WA2Y5GQK-P3UD1XYS.js} +2 -2
  98. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-gcxbxuZB.js.map → sankeyDiagram-WA2Y5GQK-P3UD1XYS.js.map} +1 -1
  99. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-B98U2Npa.js → sequenceDiagram-2WXFIKYE-jY-eNlAg.js} +4 -4
  100. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-B98U2Npa.js.map → sequenceDiagram-2WXFIKYE-jY-eNlAg.js.map} +1 -1
  101. package/webapp/dist/assets/{stateDiagram-RAJIS63D-BUgfHMbd.js → stateDiagram-RAJIS63D-HMXNbLUd.js} +9 -9
  102. package/webapp/dist/assets/{stateDiagram-RAJIS63D-BUgfHMbd.js.map → stateDiagram-RAJIS63D-HMXNbLUd.js.map} +1 -1
  103. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-C8gH0rSW.js → stateDiagram-v2-FVOUBMTO-C-50Qbn8.js} +5 -5
  104. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-C8gH0rSW.js.map → stateDiagram-v2-FVOUBMTO-C-50Qbn8.js.map} +1 -1
  105. package/webapp/dist/assets/{timeline-definition-YZTLITO2-DnVikX3B.js → timeline-definition-YZTLITO2-CkiLYjSG.js} +3 -3
  106. package/webapp/dist/assets/{timeline-definition-YZTLITO2-DnVikX3B.js.map → timeline-definition-YZTLITO2-CkiLYjSG.js.map} +1 -1
  107. package/webapp/dist/assets/{treemap-KZPCXAKY-BjhjT1IM.js → treemap-KZPCXAKY-DKYYu8t-.js} +5 -5
  108. package/webapp/dist/assets/{treemap-KZPCXAKY-BjhjT1IM.js.map → treemap-KZPCXAKY-DKYYu8t-.js.map} +1 -1
  109. package/webapp/dist/assets/{vennDiagram-LZ73GAT5-CXjPMxrl.js → vennDiagram-LZ73GAT5-n9k6D3Up.js} +2 -2
  110. package/webapp/dist/assets/{vennDiagram-LZ73GAT5-CXjPMxrl.js.map → vennDiagram-LZ73GAT5-n9k6D3Up.js.map} +1 -1
  111. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-ByKmk3Cb.js → xychartDiagram-JWTSCODW-DJZb5SW1.js} +3 -3
  112. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-ByKmk3Cb.js.map → xychartDiagram-JWTSCODW-DJZb5SW1.js.map} +1 -1
  113. package/webapp/dist/index.html +1 -1
@@ -96,6 +96,25 @@ function isSideDialogResponseAnchor(record) {
96
96
  function isNonIdleDisplayProjection(state) {
97
97
  return state !== undefined && state.kind !== 'idle_waiting_user';
98
98
  }
99
+ function pendingReplyObligationDisplayState() {
100
+ return {
101
+ kind: 'stopped',
102
+ reason: { kind: 'pending_reply_obligation' },
103
+ continueEnabled: true,
104
+ };
105
+ }
106
+ function blockerDisplayState(args) {
107
+ if (args.hasQ4H && args.hasSideDialogs) {
108
+ return { kind: 'blocked', reason: { kind: 'needs_human_input_and_sideDialogs' } };
109
+ }
110
+ if (args.hasQ4H) {
111
+ return { kind: 'blocked', reason: { kind: 'needs_human_input' } };
112
+ }
113
+ if (args.hasSideDialogs) {
114
+ return { kind: 'blocked', reason: { kind: 'waiting_for_sideDialogs' } };
115
+ }
116
+ return undefined;
117
+ }
99
118
  async function hasSideDialogFinalResponseAnchor(dialogId, latest) {
100
119
  if (dialogId.selfId === dialogId.rootId) {
101
120
  return false;
@@ -111,6 +130,35 @@ async function hasSideDialogFinalResponseAnchor(dialogId, latest) {
111
130
  }
112
131
  return false;
113
132
  }
133
+ async function hasActiveSideDialogReplyObligation(dialogId) {
134
+ if (dialogId.selfId === dialogId.rootId) {
135
+ return false;
136
+ }
137
+ const activeObligation = await persistence_1.DialogPersistence.loadActiveTellaskReplyObligation(dialogId, 'running');
138
+ return activeObligation !== undefined;
139
+ }
140
+ async function coerceIdleDisplayStateForActiveSideDialogReplyObligation(dialogId, displayState) {
141
+ if (displayState.kind !== 'idle_waiting_user') {
142
+ return displayState;
143
+ }
144
+ if (!(await hasActiveSideDialogReplyObligation(dialogId))) {
145
+ return displayState;
146
+ }
147
+ const q4h = await persistence_1.DialogPersistence.loadQuestions4HumanState(dialogId, 'running');
148
+ const pendingSideDialogs = await persistence_1.DialogPersistence.loadPendingSideDialogs(dialogId, 'running');
149
+ const blocked = blockerDisplayState({
150
+ hasQ4H: q4h.length > 0,
151
+ hasSideDialogs: pendingSideDialogs.length > 0,
152
+ });
153
+ const healedDisplayState = blocked ?? pendingReplyObligationDisplayState();
154
+ log.warn('Prevented sideDialog with active reply obligation from entering idle display state', new Error('sideDialog idle display-state invariant violation'), {
155
+ dialogId: dialogId.valueOf(),
156
+ rootId: dialogId.rootId,
157
+ selfId: dialogId.selfId,
158
+ healedDisplayState,
159
+ });
160
+ return healedDisplayState;
161
+ }
114
162
  function classifyRunControlBucket(state) {
115
163
  if (!state)
116
164
  return 'none';
@@ -345,6 +393,7 @@ async function clearDialogInterruptedExecutionMarker(dialogId) {
345
393
  await setDialogExecutionMarker(dialogId, undefined);
346
394
  }
347
395
  async function setDialogDisplayState(dialogId, displayState) {
396
+ displayState = await coerceIdleDisplayStateForActiveSideDialogReplyObligation(dialogId, displayState);
348
397
  if (displayState.kind === 'dead' && dialogId.selfId === dialogId.rootId) {
349
398
  log.warn('Rejecting dead displayState for main dialog (main dialogs must not be dead)', undefined, {
350
399
  dialogId: dialogId.valueOf(),
@@ -441,7 +490,8 @@ async function computeIdleDisplayState(dlg) {
441
490
  latest.executionMarker.kind === 'dead') {
442
491
  return { kind: 'dead', reason: latest.executionMarker.reason };
443
492
  }
444
- if (latest?.executionMarker?.kind === 'interrupted') {
493
+ if (latest?.executionMarker?.kind === 'interrupted' &&
494
+ latest.executionMarker.reason.kind !== 'pending_reply_obligation') {
445
495
  return {
446
496
  kind: 'stopped',
447
497
  reason: latest.executionMarker.reason,
@@ -457,14 +507,12 @@ async function computeIdleDisplayState(dlg) {
457
507
  }
458
508
  const hasQ4H = await dlg.hasPendingQ4H();
459
509
  const hasSideDialogs = await dlg.hasPendingSideDialogs();
460
- if (hasQ4H && hasSideDialogs) {
461
- return { kind: 'blocked', reason: { kind: 'needs_human_input_and_sideDialogs' } };
510
+ const blocked = blockerDisplayState({ hasQ4H, hasSideDialogs });
511
+ if (blocked) {
512
+ return blocked;
462
513
  }
463
- if (hasQ4H) {
464
- return { kind: 'blocked', reason: { kind: 'needs_human_input' } };
465
- }
466
- if (hasSideDialogs) {
467
- return { kind: 'blocked', reason: { kind: 'waiting_for_sideDialogs' } };
514
+ if (await hasActiveSideDialogReplyObligation(dlg.id)) {
515
+ return pendingReplyObligationDisplayState();
468
516
  }
469
517
  return { kind: 'idle_waiting_user' };
470
518
  }
@@ -480,7 +528,8 @@ async function computeIdleDisplayStateFromPersistence(dialogId) {
480
528
  latest.executionMarker.kind === 'dead') {
481
529
  return { kind: 'dead', reason: latest.executionMarker.reason };
482
530
  }
483
- if (latest?.executionMarker?.kind === 'interrupted') {
531
+ if (latest?.executionMarker?.kind === 'interrupted' &&
532
+ latest.executionMarker.reason.kind !== 'pending_reply_obligation') {
484
533
  return {
485
534
  kind: 'stopped',
486
535
  reason: latest.executionMarker.reason,
@@ -494,21 +543,19 @@ async function computeIdleDisplayStateFromPersistence(dialogId) {
494
543
  continueEnabled: true,
495
544
  };
496
545
  }
497
- if (latest && (await hasSideDialogFinalResponseAnchor(dialogId, latest))) {
498
- return { kind: 'idle_waiting_user' };
499
- }
500
546
  const q4h = await persistence_1.DialogPersistence.loadQuestions4HumanState(dialogId, 'running');
501
547
  const pendingSideDialogs = await persistence_1.DialogPersistence.loadPendingSideDialogs(dialogId, 'running');
502
548
  const hasQ4H = q4h.length > 0;
503
549
  const hasSideDialogs = pendingSideDialogs.length > 0;
504
- if (hasQ4H && hasSideDialogs) {
505
- return { kind: 'blocked', reason: { kind: 'needs_human_input_and_sideDialogs' } };
550
+ const blocked = blockerDisplayState({ hasQ4H, hasSideDialogs });
551
+ if (blocked) {
552
+ return blocked;
506
553
  }
507
- if (hasQ4H) {
508
- return { kind: 'blocked', reason: { kind: 'needs_human_input' } };
554
+ if (await hasActiveSideDialogReplyObligation(dialogId)) {
555
+ return pendingReplyObligationDisplayState();
509
556
  }
510
- if (hasSideDialogs) {
511
- return { kind: 'blocked', reason: { kind: 'waiting_for_sideDialogs' } };
557
+ if (latest && (await hasSideDialogFinalResponseAnchor(dialogId, latest))) {
558
+ return { kind: 'idle_waiting_user' };
512
559
  }
513
560
  return { kind: 'idle_waiting_user' };
514
561
  }
@@ -602,23 +649,22 @@ async function refreshRunControlProjectionFromPersistenceFacts(dialogId, trigger
602
649
  continueEnabled: true,
603
650
  };
604
651
  }
605
- if (await hasSideDialogFinalResponseAnchor(dialogId, latest)) {
606
- return { kind: 'idle_waiting_user' };
607
- }
608
652
  const q4h = await persistence_1.DialogPersistence.loadQuestions4HumanState(dialogId, 'running');
609
653
  const pendingSideDialogs = await persistence_1.DialogPersistence.loadPendingSideDialogs(dialogId, 'running');
610
654
  const hasQ4H = q4h.length > 0;
611
655
  const hasSideDialogs = pendingSideDialogs.length > 0;
612
- if (hasQ4H && hasSideDialogs) {
613
- return { kind: 'blocked', reason: { kind: 'needs_human_input_and_sideDialogs' } };
656
+ const blocked = blockerDisplayState({ hasQ4H, hasSideDialogs });
657
+ if (blocked) {
658
+ return blocked;
614
659
  }
615
- if (hasQ4H) {
616
- return { kind: 'blocked', reason: { kind: 'needs_human_input' } };
660
+ if (await hasActiveSideDialogReplyObligation(dialogId)) {
661
+ return pendingReplyObligationDisplayState();
617
662
  }
618
- if (hasSideDialogs) {
619
- return { kind: 'blocked', reason: { kind: 'waiting_for_sideDialogs' } };
663
+ if (await hasSideDialogFinalResponseAnchor(dialogId, latest)) {
664
+ return { kind: 'idle_waiting_user' };
620
665
  }
621
- if (latest.executionMarker?.kind === 'interrupted') {
666
+ if (latest.executionMarker?.kind === 'interrupted' &&
667
+ latest.executionMarker.reason.kind !== 'pending_reply_obligation') {
622
668
  return {
623
669
  kind: 'stopped',
624
670
  reason: latest.executionMarker.reason,
@@ -673,7 +719,9 @@ function isRecoverableGeneratingLatest(latest) {
673
719
  if (marker.kind === 'dead') {
674
720
  return false;
675
721
  }
676
- return marker.kind !== 'interrupted' || marker.reason.kind === 'pending_course_start';
722
+ return (marker.kind !== 'interrupted' ||
723
+ marker.reason.kind === 'pending_course_start' ||
724
+ marker.reason.kind === 'pending_reply_obligation');
677
725
  }
678
726
  async function reconcileDisplayStatesAfterRestart() {
679
727
  const dialogIds = await persistence_1.DialogPersistence.listAllDialogIds('running');
@@ -743,7 +791,8 @@ async function reconcileDisplayStatesAfterRestart() {
743
791
  needsDrive: true,
744
792
  displayState: { kind: 'proceeding' },
745
793
  executionMarker: existingMarker?.kind === 'interrupted' &&
746
- existingMarker.reason.kind === 'pending_course_start'
794
+ (existingMarker.reason.kind === 'pending_course_start' ||
795
+ existingMarker.reason.kind === 'pending_reply_obligation')
747
796
  ? undefined
748
797
  : existingMarker,
749
798
  },
@@ -24,6 +24,7 @@ function isInterruptionReasonManualResumeEligible(reason) {
24
24
  case 'emergency_stop':
25
25
  case 'server_restart':
26
26
  case 'pending_course_start':
27
+ case 'pending_reply_obligation':
27
28
  case 'fork_continue_ready':
28
29
  case 'system_stop':
29
30
  case 'llm_retry_stopped':
@@ -37,6 +38,7 @@ function isInterruptionReasonManualResumeEligible(reason) {
37
38
  function doesInterruptionReasonRequireExplicitResume(reason) {
38
39
  switch (reason.kind) {
39
40
  case 'pending_course_start':
41
+ case 'pending_reply_obligation':
40
42
  return false;
41
43
  case 'user_stop':
42
44
  case 'emergency_stop':
package/dist/dialog.d.ts CHANGED
@@ -354,6 +354,25 @@ export declare abstract class Dialog {
354
354
  skipTaskdoc?: boolean;
355
355
  sideDialogReplyTarget: DialogSideDialogReplyTarget;
356
356
  }): DialogQueuedPromptState;
357
+ private persistPendingRuntimePrompt;
358
+ private runtimePromptCommon;
359
+ queueRuntimeReplyPrompt(options: {
360
+ prompt: string;
361
+ msgId: string;
362
+ grammar: 'markdown';
363
+ userLanguageCode?: LanguageCode;
364
+ tellaskReplyDirective: TellaskReplyDirective;
365
+ skipTaskdoc?: boolean;
366
+ }): Promise<DialogQueuedPromptState>;
367
+ queueRuntimeSideDialogPrompt(options: {
368
+ prompt: string;
369
+ msgId: string;
370
+ grammar: 'markdown';
371
+ userLanguageCode?: LanguageCode;
372
+ tellaskReplyDirective: TellaskReplyDirective;
373
+ skipTaskdoc?: boolean;
374
+ sideDialogReplyTarget: DialogSideDialogReplyTarget;
375
+ }): Promise<DialogQueuedPromptState>;
357
376
  hasUpNext(): boolean;
358
377
  peekUpNext(): DialogQueuedPromptState | undefined;
359
378
  takeUpNext(): DialogQueuedPromptState | undefined;
@@ -678,6 +697,7 @@ export declare abstract class DialogStore {
678
697
  * Start a new course in storage
679
698
  */
680
699
  startNewCourse(_dialog: Dialog, _newCoursePrompt: DialogRuntimePrompt): Promise<void>;
700
+ persistPendingRuntimePrompt(_dialog: Dialog, _prompt: DialogRuntimePrompt): Promise<void>;
681
701
  /**
682
702
  * Handle stream error
683
703
  */
package/dist/dialog.js CHANGED
@@ -1018,6 +1018,65 @@ class Dialog {
1018
1018
  this._updatedAt = (0, time_1.formatUnifiedTimestamp)(new Date());
1019
1019
  return merged;
1020
1020
  }
1021
+ async persistPendingRuntimePrompt(prompt) {
1022
+ await this.dlgStore.persistPendingRuntimePrompt(this, prompt);
1023
+ }
1024
+ runtimePromptCommon(options) {
1025
+ const trimmed = options.prompt.trim();
1026
+ if (!trimmed) {
1027
+ throw new Error('Prompt is required to queue runtime prompt');
1028
+ }
1029
+ return {
1030
+ prompt: trimmed,
1031
+ msgId: options.msgId,
1032
+ grammar: options.grammar,
1033
+ userLanguageCode: options.userLanguageCode ?? this._lastUserLanguageCode,
1034
+ origin: 'runtime',
1035
+ runControl: undefined,
1036
+ };
1037
+ }
1038
+ async queueRuntimeReplyPrompt(options) {
1039
+ const common = this.runtimePromptCommon(options);
1040
+ const created = {
1041
+ ...common,
1042
+ kind: 'new_course_runtime_reply',
1043
+ tellaskReplyDirective: options.tellaskReplyDirective,
1044
+ skipTaskdoc: options.skipTaskdoc,
1045
+ };
1046
+ this.enqueueQueuedPromptState(created);
1047
+ await this.persistPendingRuntimePrompt({
1048
+ content: created.prompt,
1049
+ msgId: created.msgId,
1050
+ grammar: created.grammar ?? 'markdown',
1051
+ userLanguageCode: created.userLanguageCode,
1052
+ origin: 'runtime',
1053
+ tellaskReplyDirective: created.tellaskReplyDirective,
1054
+ skipTaskdoc: created.skipTaskdoc,
1055
+ });
1056
+ return created;
1057
+ }
1058
+ async queueRuntimeSideDialogPrompt(options) {
1059
+ const common = this.runtimePromptCommon(options);
1060
+ const created = {
1061
+ ...common,
1062
+ kind: 'new_course_runtime_sideDialog',
1063
+ tellaskReplyDirective: options.tellaskReplyDirective,
1064
+ skipTaskdoc: options.skipTaskdoc,
1065
+ sideDialogReplyTarget: options.sideDialogReplyTarget,
1066
+ };
1067
+ this.enqueueQueuedPromptState(created);
1068
+ await this.persistPendingRuntimePrompt({
1069
+ content: created.prompt,
1070
+ msgId: created.msgId,
1071
+ grammar: created.grammar ?? 'markdown',
1072
+ userLanguageCode: created.userLanguageCode,
1073
+ origin: 'runtime',
1074
+ tellaskReplyDirective: created.tellaskReplyDirective,
1075
+ skipTaskdoc: created.skipTaskdoc,
1076
+ sideDialogReplyTarget: created.sideDialogReplyTarget,
1077
+ });
1078
+ return created;
1079
+ }
1021
1080
  hasUpNext() {
1022
1081
  return this._upNextQueue.length > 0;
1023
1082
  }
@@ -1905,6 +1964,7 @@ class DialogStore {
1905
1964
  * Start a new course in storage
1906
1965
  */
1907
1966
  async startNewCourse(_dialog, _newCoursePrompt) { }
1967
+ async persistPendingRuntimePrompt(_dialog, _prompt) { }
1908
1968
  /**
1909
1969
  * Handle stream error
1910
1970
  */
@@ -23,6 +23,48 @@ const idle_reminder_wake_1 = require("./idle-reminder-wake");
23
23
  const reply_guidance_1 = require("./reply-guidance");
24
24
  const sideDialog_1 = require("./sideDialog");
25
25
  const tellask_special_1 = require("./tellask-special");
26
+ function buildRuntimeReplyReminderFollowUp(args) {
27
+ const common = {
28
+ prompt: args.prompt,
29
+ msgId: (0, id_1.generateShortId)(),
30
+ grammar: 'markdown',
31
+ origin: 'runtime',
32
+ userLanguageCode: args.language,
33
+ tellaskReplyDirective: args.directive,
34
+ };
35
+ return args.sideDialogReplyTarget === undefined
36
+ ? {
37
+ kind: 'runtime_reply_reminder',
38
+ ...common,
39
+ }
40
+ : {
41
+ kind: 'runtime_sideDialog_reply_reminder',
42
+ ...common,
43
+ sideDialogReplyTarget: args.sideDialogReplyTarget,
44
+ };
45
+ }
46
+ async function queueReplyReminderFollowUp(args) {
47
+ if (args.followUp.kind === 'runtime_sideDialog_reply_reminder') {
48
+ await args.dialog.queueRuntimeSideDialogPrompt({
49
+ prompt: args.followUp.prompt,
50
+ msgId: args.followUp.msgId,
51
+ grammar: args.followUp.grammar ?? 'markdown',
52
+ userLanguageCode: args.followUp.userLanguageCode,
53
+ tellaskReplyDirective: args.followUp.tellaskReplyDirective,
54
+ skipTaskdoc: args.followUp.skipTaskdoc,
55
+ sideDialogReplyTarget: args.followUp.sideDialogReplyTarget,
56
+ });
57
+ return;
58
+ }
59
+ await args.dialog.queueRuntimeReplyPrompt({
60
+ prompt: args.followUp.prompt,
61
+ msgId: args.followUp.msgId,
62
+ grammar: args.followUp.grammar ?? 'markdown',
63
+ userLanguageCode: args.followUp.userLanguageCode,
64
+ tellaskReplyDirective: args.followUp.tellaskReplyDirective,
65
+ skipTaskdoc: args.followUp.skipTaskdoc,
66
+ });
67
+ }
26
68
  function isReplyToolReminderPrompt(prompt) {
27
69
  return typeof prompt?.content === 'string' && (0, reply_prompt_copy_1.isReplyToolReminderPromptContent)(prompt.content);
28
70
  }
@@ -52,6 +94,10 @@ function resolveDirectFallbackResponse(args) {
52
94
  source: 'saying',
53
95
  };
54
96
  }
97
+ // Thinking-only output is intentionally a fallback candidate: some providers/models can finish a
98
+ // Side Dialog with useful content in thinking and no public saying. This helper only extracts the
99
+ // candidate; callers below must still reject it when a same-round function/tellask call needs
100
+ // auto-continuation, when the dialog is suspended, or when another follow-up prompt is queued.
55
101
  if (args.driveResult.lastAssistantThinkingContent !== null &&
56
102
  args.driveResult.lastAssistantThinkingContent.trim() !== '') {
57
103
  if (typeof args.driveResult.lastAssistantThinkingGenseq !== 'number' ||
@@ -163,6 +209,79 @@ async function loadPendingDiagnosticsSnapshot(args) {
163
209
  };
164
210
  }
165
211
  }
212
+ async function hasAssistantOutputAfterAssignmentAnchor(args) {
213
+ const events = await persistence_1.DialogPersistence.loadCourseEvents(args.dialog.id, args.dialog.currentCourse, args.dialog.status);
214
+ let assignmentGenseq;
215
+ for (const event of events) {
216
+ if (event.type === 'tellask_anchor_record' &&
217
+ event.anchorRole === 'assignment' &&
218
+ event.callId === args.callId) {
219
+ assignmentGenseq = event.genseq;
220
+ continue;
221
+ }
222
+ if (assignmentGenseq !== undefined &&
223
+ (event.type === 'agent_thought_record' || event.type === 'agent_words_record') &&
224
+ event.genseq >= assignmentGenseq &&
225
+ event.content.trim() !== '') {
226
+ return true;
227
+ }
228
+ }
229
+ return false;
230
+ }
231
+ async function resolveStrandedSideDialogReplyReminderFollowUp(args) {
232
+ const latest = await persistence_1.DialogPersistence.loadDialogLatest(args.dialog.id, args.dialog.status);
233
+ const displayState = latest?.displayState;
234
+ const isRecoverableProjection = displayState?.kind === 'idle_waiting_user' ||
235
+ (displayState?.kind === 'stopped' && displayState.reason.kind === 'pending_reply_obligation');
236
+ if (!latest ||
237
+ !isRecoverableProjection ||
238
+ latest.pendingCourseStartPrompt !== undefined ||
239
+ latest.executionMarker?.kind === 'dead') {
240
+ return undefined;
241
+ }
242
+ const directive = await (0, tellask_special_1.loadActiveTellaskReplyDirective)(args.dialog);
243
+ if (!directive) {
244
+ return undefined;
245
+ }
246
+ const ownerDialogId = directive.targetDialogId.trim();
247
+ if (ownerDialogId === '') {
248
+ throw new Error(`stranded sideDialog reply recovery invariant violation: empty targetDialogId ` +
249
+ `(dialogId=${args.dialog.id.valueOf()}, targetCallId=${directive.targetCallId})`);
250
+ }
251
+ const pending = await persistence_1.DialogPersistence.loadPendingSideDialogs(new dialog_1.DialogID(ownerDialogId, args.dialog.id.rootId), args.dialog.status);
252
+ const pendingRecord = pending.find((record) => record.sideDialogId === args.dialog.id.selfId && record.callId === directive.targetCallId);
253
+ if (!pendingRecord) {
254
+ return undefined;
255
+ }
256
+ if (!(await hasAssistantOutputAfterAssignmentAnchor({
257
+ dialog: args.dialog,
258
+ callId: pendingRecord.callId,
259
+ }))) {
260
+ return undefined;
261
+ }
262
+ const language = (0, work_language_1.getWorkLanguage)();
263
+ const sideDialogReplyTarget = {
264
+ ownerDialogId,
265
+ callType: pendingRecord.callType,
266
+ callId: pendingRecord.callId,
267
+ callSiteCourse: pendingRecord.callSiteCourse,
268
+ callSiteGenseq: pendingRecord.callSiteGenseq,
269
+ };
270
+ return {
271
+ kind: 'runtime_sideDialog_reply_reminder',
272
+ prompt: await buildReplyToolReminderPrompt({
273
+ dlg: args.dialog,
274
+ directive,
275
+ language,
276
+ }),
277
+ msgId: (0, id_1.generateShortId)(),
278
+ grammar: 'markdown',
279
+ origin: 'runtime',
280
+ userLanguageCode: language,
281
+ tellaskReplyDirective: directive,
282
+ sideDialogReplyTarget,
283
+ };
284
+ }
166
285
  async function clearConsumedDeferredRootQueueIfIdle(dialog) {
167
286
  if (dialog.id.selfId !== dialog.id.rootId) {
168
287
  return;
@@ -344,6 +463,8 @@ async function inspectNoPromptSideDialogDrive(args) {
344
463
  const inProgressGenerationResumeAllowed = args.driveOptions?.resumeInProgressGeneration === true;
345
464
  const supplyResponseParentReviveAllowed = source === 'kernel_driver_supply_response_parent_revive' &&
346
465
  hasNoPromptSideDialogResumeEntitlement(args.dialog, args.driveOptions);
466
+ const pendingReplyObligationResumeAllowed = latest?.executionMarker?.kind === 'interrupted' &&
467
+ latest.executionMarker.reason.kind === 'pending_reply_obligation';
347
468
  if (lastEvent?.type === 'tellask_anchor_record' && lastEvent.anchorRole === 'response') {
348
469
  return {
349
470
  shouldReject: true,
@@ -356,7 +477,8 @@ async function inspectNoPromptSideDialogDrive(args) {
356
477
  }
357
478
  if (!explicitInterruptedResumeAllowed &&
358
479
  !inProgressGenerationResumeAllowed &&
359
- !supplyResponseParentReviveAllowed) {
480
+ !supplyResponseParentReviveAllowed &&
481
+ !pendingReplyObligationResumeAllowed) {
360
482
  return {
361
483
  shouldReject: true,
362
484
  source,
@@ -618,6 +740,29 @@ async function executeDriveRound(args) {
618
740
  // suspended by pending Q4H or sideDialogs. This prevents duplicate generations when
619
741
  // multiple wake-ups race around the same sideDialog completion boundary.
620
742
  if (!humanPrompt) {
743
+ if (dialog instanceof dialog_1.SideDialog && !dialog.hasUpNext()) {
744
+ const strandedReplyReminder = await resolveStrandedSideDialogReplyReminderFollowUp({
745
+ dialog,
746
+ });
747
+ if (strandedReplyReminder !== undefined) {
748
+ await queueReplyReminderFollowUp({ dialog, followUp: strandedReplyReminder });
749
+ args.scheduleDrive(dialog, {
750
+ waitInQue: true,
751
+ driveOptions: {
752
+ source: 'kernel_driver_follow_up',
753
+ reason: 'follow_up_prompt',
754
+ },
755
+ });
756
+ log_1.log.warn('kernel-driver recovered stranded sideDialog reply obligation by queueing reply reminder', undefined, {
757
+ dialogId: dialog.id.valueOf(),
758
+ rootId: dialog.id.rootId,
759
+ selfId: dialog.id.selfId,
760
+ targetCallId: strandedReplyReminder.tellaskReplyDirective.targetCallId,
761
+ targetOwnerDialogId: strandedReplyReminder.sideDialogReplyTarget.ownerDialogId,
762
+ });
763
+ return;
764
+ }
765
+ }
621
766
  if (dialog instanceof dialog_1.SideDialog && !dialog.hasUpNext()) {
622
767
  try {
623
768
  const inspection = await inspectNoPromptSideDialogDrive({ dialog, driveOptions });
@@ -894,8 +1039,10 @@ async function executeDriveRound(args) {
894
1039
  driveResult.lastFunctionCallGenseq > 0 &&
895
1040
  directFallbackResponse.responseGenseq <= driveResult.lastFunctionCallGenseq;
896
1041
  if (hasInProgressFunctionCall) {
897
- // Any function call means execution is still in-progress. Only supply when the tellaskee
898
- // has produced a newer assistant saying after the latest function call.
1042
+ // A candidate direct fallback, including thinking-only output, must be newer than the
1043
+ // latest same-round function/tellask call. Otherwise the call is still the active move
1044
+ // and may auto-continue; the candidate is merely pre-tool reasoning/progress, not final
1045
+ // tellasker delivery.
899
1046
  log_1.log.debug('kernel-driver skip sideDialog response supply because latest assistant output is not after function calls', undefined, {
900
1047
  rootId: dialog.id.rootId,
901
1048
  selfId: dialog.id.selfId,
@@ -926,35 +1073,16 @@ async function executeDriveRound(args) {
926
1073
  else {
927
1074
  if (!activePromptWasReplyToolReminder) {
928
1075
  const language = (0, work_language_1.getWorkLanguage)();
929
- followUp =
930
- sideDialogReplyTarget === undefined
931
- ? {
932
- kind: 'runtime_reply_reminder',
933
- prompt: await buildReplyToolReminderPrompt({
934
- dlg: dialog,
935
- directive: activeTellaskReplyDirective,
936
- language,
937
- }),
938
- msgId: (0, id_1.generateShortId)(),
939
- grammar: 'markdown',
940
- origin: 'runtime',
941
- userLanguageCode: language,
942
- tellaskReplyDirective: activeTellaskReplyDirective,
943
- }
944
- : {
945
- kind: 'runtime_sideDialog_reply_reminder',
946
- prompt: await buildReplyToolReminderPrompt({
947
- dlg: dialog,
948
- directive: activeTellaskReplyDirective,
949
- language,
950
- }),
951
- msgId: (0, id_1.generateShortId)(),
952
- grammar: 'markdown',
953
- origin: 'runtime',
954
- userLanguageCode: language,
955
- tellaskReplyDirective: activeTellaskReplyDirective,
956
- sideDialogReplyTarget,
957
- };
1076
+ followUp = buildRuntimeReplyReminderFollowUp({
1077
+ directive: activeTellaskReplyDirective,
1078
+ prompt: await buildReplyToolReminderPrompt({
1079
+ dlg: dialog,
1080
+ directive: activeTellaskReplyDirective,
1081
+ language,
1082
+ }),
1083
+ language,
1084
+ sideDialogReplyTarget,
1085
+ });
958
1086
  log_1.log.debug('kernel-driver queued sideDialog replyTellask reminder after plain reply', undefined, {
959
1087
  dialogId: dialog.id.valueOf(),
960
1088
  targetCallId: activeTellaskReplyDirective.targetCallId,
@@ -1042,6 +1170,8 @@ async function executeDriveRound(args) {
1042
1170
  Number.isFinite(driveResult.lastFunctionCallGenseq) &&
1043
1171
  driveResult.lastFunctionCallGenseq > 0 &&
1044
1172
  directFallbackResponse.responseGenseq <= driveResult.lastFunctionCallGenseq;
1173
+ // Same rule as Side Dialog final delivery: direct fallback is allowed only after the
1174
+ // candidate content is known to be post-tool and no same-round call is waiting to continue.
1045
1175
  if (!hasInProgressFunctionCall) {
1046
1176
  if (!activePromptWasReplyToolReminder) {
1047
1177
  const language = (0, work_language_1.getWorkLanguage)();
@@ -1084,6 +1214,18 @@ async function executeDriveRound(args) {
1084
1214
  }
1085
1215
  }
1086
1216
  if (followUp) {
1217
+ if (followUp.kind === 'runtime_reply_reminder' ||
1218
+ followUp.kind === 'runtime_sideDialog_reply_reminder') {
1219
+ await queueReplyReminderFollowUp({ dialog, followUp });
1220
+ args.scheduleDrive(dialog, {
1221
+ waitInQue: true,
1222
+ driveOptions: {
1223
+ source: 'kernel_driver_follow_up',
1224
+ reason: 'follow_up_prompt',
1225
+ },
1226
+ });
1227
+ return driveResult;
1228
+ }
1087
1229
  args.scheduleDrive(dialog, {
1088
1230
  waitInQue: true,
1089
1231
  driveOptions: {
@@ -1116,9 +1258,7 @@ async function executeDriveRound(args) {
1116
1258
  case 'registered_assignment_update':
1117
1259
  case 'new_course_runtime_guide':
1118
1260
  case 'new_course_runtime_reply':
1119
- case 'new_course_runtime_sideDialog':
1120
- case 'runtime_reply_reminder':
1121
- case 'runtime_sideDialog_reply_reminder': {
1261
+ case 'new_course_runtime_sideDialog': {
1122
1262
  const runtimeCommon = {
1123
1263
  ...common,
1124
1264
  origin: 'runtime',
@@ -1127,8 +1267,7 @@ async function executeDriveRound(args) {
1127
1267
  : { skipTaskdoc: followUp.skipTaskdoc }),
1128
1268
  };
1129
1269
  if (followUp.kind === 'registered_assignment_update' ||
1130
- followUp.kind === 'new_course_runtime_sideDialog' ||
1131
- followUp.kind === 'runtime_sideDialog_reply_reminder') {
1270
+ followUp.kind === 'new_course_runtime_sideDialog') {
1132
1271
  const prompt = {
1133
1272
  ...runtimeCommon,
1134
1273
  tellaskReplyDirective: followUp.tellaskReplyDirective,
@@ -1136,8 +1275,7 @@ async function executeDriveRound(args) {
1136
1275
  };
1137
1276
  return prompt;
1138
1277
  }
1139
- if (followUp.kind === 'new_course_runtime_reply' ||
1140
- followUp.kind === 'runtime_reply_reminder') {
1278
+ if (followUp.kind === 'new_course_runtime_reply') {
1141
1279
  const prompt = {
1142
1280
  ...runtimeCommon,
1143
1281
  tellaskReplyDirective: followUp.tellaskReplyDirective,