dominds 1.25.14 → 1.25.16

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 (112) hide show
  1. package/dist/llm/kernel-driver/drive.js +85 -31
  2. package/dist/llm/kernel-driver/flow.js +142 -40
  3. package/dist/llm/kernel-driver/reply-guidance.d.ts +2 -1
  4. package/dist/llm/kernel-driver/reply-guidance.js +11 -6
  5. package/dist/llm/kernel-driver/types.d.ts +2 -1
  6. package/dist/mcp/supervisor.js +2 -4
  7. package/dist/minds/system-prompt.js +4 -4
  8. package/dist/persistence.js +50 -27
  9. package/dist/runtime/driver-messages.d.ts +5 -0
  10. package/dist/runtime/driver-messages.js +105 -59
  11. package/dist/runtime/reply-prompt-copy.js +8 -6
  12. package/dist/server/dominds-self-update.js +584 -106
  13. package/dist/tools/app-reminders.js +6 -6
  14. package/dist/tools/mcp.js +2 -8
  15. package/dist/tools/os.js +14 -14
  16. package/dist/tools/pending-tellask-reminder.js +10 -10
  17. package/package.json +3 -3
  18. package/webapp/dist/assets/{_basePickBy-xJw0ZLXb.js → _basePickBy-bB-pfQPi.js} +3 -3
  19. package/webapp/dist/assets/{_basePickBy-xJw0ZLXb.js.map → _basePickBy-bB-pfQPi.js.map} +1 -1
  20. package/webapp/dist/assets/{_baseUniq-BwH1mnxt.js → _baseUniq-CGrWBZre.js} +2 -2
  21. package/webapp/dist/assets/{_baseUniq-BwH1mnxt.js.map → _baseUniq-CGrWBZre.js.map} +1 -1
  22. package/webapp/dist/assets/{arc-CXDyEAks.js → arc-I9vbIaKk.js} +2 -2
  23. package/webapp/dist/assets/{arc-CXDyEAks.js.map → arc-I9vbIaKk.js.map} +1 -1
  24. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-CQfjSekJ.js → architectureDiagram-2XIMDMQ5-CrwjTxLz.js} +7 -7
  25. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-CQfjSekJ.js.map → architectureDiagram-2XIMDMQ5-CrwjTxLz.js.map} +1 -1
  26. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-DFTd-DGC.js → blockDiagram-WCTKOSBZ-DTm0qfvP.js} +7 -7
  27. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-DFTd-DGC.js.map → blockDiagram-WCTKOSBZ-DTm0qfvP.js.map} +1 -1
  28. package/webapp/dist/assets/{c4Diagram-IC4MRINW-DS_zRetl.js → c4Diagram-IC4MRINW-DwRQtzZF.js} +3 -3
  29. package/webapp/dist/assets/{c4Diagram-IC4MRINW-DS_zRetl.js.map → c4Diagram-IC4MRINW-DwRQtzZF.js.map} +1 -1
  30. package/webapp/dist/assets/{channel-BbTmwKgX.js → channel-BHLOwBnI.js} +2 -2
  31. package/webapp/dist/assets/{channel-BbTmwKgX.js.map → channel-BHLOwBnI.js.map} +1 -1
  32. package/webapp/dist/assets/{chunk-4BX2VUAB-CwosIBGF.js → chunk-4BX2VUAB-C-uXnDVV.js} +2 -2
  33. package/webapp/dist/assets/{chunk-4BX2VUAB-CwosIBGF.js.map → chunk-4BX2VUAB-C-uXnDVV.js.map} +1 -1
  34. package/webapp/dist/assets/{chunk-55IACEB6-Cwh90dP4.js → chunk-55IACEB6-Dq9BI2N6.js} +2 -2
  35. package/webapp/dist/assets/{chunk-55IACEB6-Cwh90dP4.js.map → chunk-55IACEB6-Dq9BI2N6.js.map} +1 -1
  36. package/webapp/dist/assets/{chunk-FMBD7UC4-BNnil15z.js → chunk-FMBD7UC4-DR9kFZOV.js} +2 -2
  37. package/webapp/dist/assets/{chunk-FMBD7UC4-BNnil15z.js.map → chunk-FMBD7UC4-DR9kFZOV.js.map} +1 -1
  38. package/webapp/dist/assets/{chunk-JSJVCQXG-DimIImfv.js → chunk-JSJVCQXG-xnc6SVE5.js} +2 -2
  39. package/webapp/dist/assets/{chunk-JSJVCQXG-DimIImfv.js.map → chunk-JSJVCQXG-xnc6SVE5.js.map} +1 -1
  40. package/webapp/dist/assets/{chunk-KX2RTZJC-iWTw8TpU.js → chunk-KX2RTZJC-rUxlh4aS.js} +2 -2
  41. package/webapp/dist/assets/{chunk-KX2RTZJC-iWTw8TpU.js.map → chunk-KX2RTZJC-rUxlh4aS.js.map} +1 -1
  42. package/webapp/dist/assets/{chunk-NQ4KR5QH-vej7OjjD.js → chunk-NQ4KR5QH-BGU4PhTQ.js} +4 -4
  43. package/webapp/dist/assets/{chunk-NQ4KR5QH-vej7OjjD.js.map → chunk-NQ4KR5QH-BGU4PhTQ.js.map} +1 -1
  44. package/webapp/dist/assets/{chunk-QZHKN3VN-UTOcRcah.js → chunk-QZHKN3VN-CAlu4xE7.js} +2 -2
  45. package/webapp/dist/assets/{chunk-QZHKN3VN-UTOcRcah.js.map → chunk-QZHKN3VN-CAlu4xE7.js.map} +1 -1
  46. package/webapp/dist/assets/{chunk-WL4C6EOR-BPG9Okux.js → chunk-WL4C6EOR-zZXRkBBY.js} +6 -6
  47. package/webapp/dist/assets/{chunk-WL4C6EOR-BPG9Okux.js.map → chunk-WL4C6EOR-zZXRkBBY.js.map} +1 -1
  48. package/webapp/dist/assets/{classDiagram-VBA2DB6C-BY0IlgU0.js → classDiagram-VBA2DB6C-DI1CfOtL.js} +7 -7
  49. package/webapp/dist/assets/{classDiagram-VBA2DB6C-BY0IlgU0.js.map → classDiagram-VBA2DB6C-DI1CfOtL.js.map} +1 -1
  50. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-BY0IlgU0.js → classDiagram-v2-RAHNMMFH-DI1CfOtL.js} +7 -7
  51. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-BY0IlgU0.js.map → classDiagram-v2-RAHNMMFH-DI1CfOtL.js.map} +1 -1
  52. package/webapp/dist/assets/{clone-HAPhhkfG.js → clone-quTqCNPA.js} +2 -2
  53. package/webapp/dist/assets/{clone-HAPhhkfG.js.map → clone-quTqCNPA.js.map} +1 -1
  54. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-BQlr3U5G.js → cose-bilkent-S5V4N54A-BY28yO7Y.js} +2 -2
  55. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-BQlr3U5G.js.map → cose-bilkent-S5V4N54A-BY28yO7Y.js.map} +1 -1
  56. package/webapp/dist/assets/{dagre-KLK3FWXG-DphPFDYz.js → dagre-KLK3FWXG-DLyZ54D-.js} +7 -7
  57. package/webapp/dist/assets/{dagre-KLK3FWXG-DphPFDYz.js.map → dagre-KLK3FWXG-DLyZ54D-.js.map} +1 -1
  58. package/webapp/dist/assets/{diagram-E7M64L7V-Bv4UxxXd.js → diagram-E7M64L7V-CD-HWZAJ.js} +8 -8
  59. package/webapp/dist/assets/{diagram-E7M64L7V-Bv4UxxXd.js.map → diagram-E7M64L7V-CD-HWZAJ.js.map} +1 -1
  60. package/webapp/dist/assets/{diagram-IFDJBPK2-y1CGHto0.js → diagram-IFDJBPK2-BHOQ9HH2.js} +7 -7
  61. package/webapp/dist/assets/{diagram-IFDJBPK2-y1CGHto0.js.map → diagram-IFDJBPK2-BHOQ9HH2.js.map} +1 -1
  62. package/webapp/dist/assets/{diagram-P4PSJMXO-IXiebzDc.js → diagram-P4PSJMXO-OEPgBDcD.js} +7 -7
  63. package/webapp/dist/assets/{diagram-P4PSJMXO-IXiebzDc.js.map → diagram-P4PSJMXO-OEPgBDcD.js.map} +1 -1
  64. package/webapp/dist/assets/{erDiagram-INFDFZHY-DgVQi2c7.js → erDiagram-INFDFZHY-Dcgo204J.js} +5 -5
  65. package/webapp/dist/assets/{erDiagram-INFDFZHY-DgVQi2c7.js.map → erDiagram-INFDFZHY-Dcgo204J.js.map} +1 -1
  66. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-Ccs_iaLm.js → flowDiagram-PKNHOUZH-CWLo3Lkf.js} +7 -7
  67. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-Ccs_iaLm.js.map → flowDiagram-PKNHOUZH-CWLo3Lkf.js.map} +1 -1
  68. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-BOlky6CI.js → ganttDiagram-A5KZAMGK-DWXL4ZD6.js} +3 -3
  69. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-BOlky6CI.js.map → ganttDiagram-A5KZAMGK-DWXL4ZD6.js.map} +1 -1
  70. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-loEvdSsO.js → gitGraphDiagram-K3NZZRJ6-7iLQbTrH.js} +8 -8
  71. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-loEvdSsO.js.map → gitGraphDiagram-K3NZZRJ6-7iLQbTrH.js.map} +1 -1
  72. package/webapp/dist/assets/{graph-CbpUBil5.js → graph-Bq1MLNWN.js} +3 -3
  73. package/webapp/dist/assets/{graph-CbpUBil5.js.map → graph-Bq1MLNWN.js.map} +1 -1
  74. package/webapp/dist/assets/{index-BiFvaOdQ.js → index-r4An5YoX.js} +139 -42
  75. package/webapp/dist/assets/{index-BiFvaOdQ.js.map → index-r4An5YoX.js.map} +1 -1
  76. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-hytR8L_9.js → infoDiagram-LFFYTUFH-CoF5OE3_.js} +6 -6
  77. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-hytR8L_9.js.map → infoDiagram-LFFYTUFH-CoF5OE3_.js.map} +1 -1
  78. package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-C-58-pR6.js → ishikawaDiagram-PHBUUO56-iKggfQhA.js} +2 -2
  79. package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-C-58-pR6.js.map → ishikawaDiagram-PHBUUO56-iKggfQhA.js.map} +1 -1
  80. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-DlW9wE_9.js → journeyDiagram-4ABVD52K-NYDQ7_xv.js} +5 -5
  81. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-DlW9wE_9.js.map → journeyDiagram-4ABVD52K-NYDQ7_xv.js.map} +1 -1
  82. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-DMwi6h6F.js → kanban-definition-K7BYSVSG-YWCnJwk0.js} +3 -3
  83. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-DMwi6h6F.js.map → kanban-definition-K7BYSVSG-YWCnJwk0.js.map} +1 -1
  84. package/webapp/dist/assets/{layout-m0UN-laA.js → layout-CE6gccWy.js} +5 -5
  85. package/webapp/dist/assets/{layout-m0UN-laA.js.map → layout-CE6gccWy.js.map} +1 -1
  86. package/webapp/dist/assets/{linear-Dl3WyCTF.js → linear-12arIJK-.js} +2 -2
  87. package/webapp/dist/assets/{linear-Dl3WyCTF.js.map → linear-12arIJK-.js.map} +1 -1
  88. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-CY7MDfxd.js → mindmap-definition-YRQLILUH-D_5iNhfP.js} +4 -4
  89. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-CY7MDfxd.js.map → mindmap-definition-YRQLILUH-D_5iNhfP.js.map} +1 -1
  90. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-BcpxKyhx.js → pieDiagram-SKSYHLDU-DCbLQaXM.js} +8 -8
  91. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-BcpxKyhx.js.map → pieDiagram-SKSYHLDU-DCbLQaXM.js.map} +1 -1
  92. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-BgNfCvPO.js → quadrantDiagram-337W2JSQ-CVRDOyty.js} +3 -3
  93. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-BgNfCvPO.js.map → quadrantDiagram-337W2JSQ-CVRDOyty.js.map} +1 -1
  94. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-CvBkuXMk.js → requirementDiagram-Z7DCOOCP-iBpmayOS.js} +4 -4
  95. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-CvBkuXMk.js.map → requirementDiagram-Z7DCOOCP-iBpmayOS.js.map} +1 -1
  96. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-cCG4yz8C.js → sankeyDiagram-WA2Y5GQK-DqzWCtib.js} +2 -2
  97. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-cCG4yz8C.js.map → sankeyDiagram-WA2Y5GQK-DqzWCtib.js.map} +1 -1
  98. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-DAWnxFqU.js → sequenceDiagram-2WXFIKYE-DHzt-u2j.js} +4 -4
  99. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-DAWnxFqU.js.map → sequenceDiagram-2WXFIKYE-DHzt-u2j.js.map} +1 -1
  100. package/webapp/dist/assets/{stateDiagram-RAJIS63D-rtvr6jfW.js → stateDiagram-RAJIS63D-D14FagfU.js} +9 -9
  101. package/webapp/dist/assets/{stateDiagram-RAJIS63D-rtvr6jfW.js.map → stateDiagram-RAJIS63D-D14FagfU.js.map} +1 -1
  102. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-G6IcG_Il.js → stateDiagram-v2-FVOUBMTO-CZRolF-A.js} +5 -5
  103. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-G6IcG_Il.js.map → stateDiagram-v2-FVOUBMTO-CZRolF-A.js.map} +1 -1
  104. package/webapp/dist/assets/{timeline-definition-YZTLITO2-BZ-h_t5V.js → timeline-definition-YZTLITO2-L4O4kc8p.js} +3 -3
  105. package/webapp/dist/assets/{timeline-definition-YZTLITO2-BZ-h_t5V.js.map → timeline-definition-YZTLITO2-L4O4kc8p.js.map} +1 -1
  106. package/webapp/dist/assets/{treemap-KZPCXAKY-BZyhJ20s.js → treemap-KZPCXAKY-CvHKWhtl.js} +5 -5
  107. package/webapp/dist/assets/{treemap-KZPCXAKY-BZyhJ20s.js.map → treemap-KZPCXAKY-CvHKWhtl.js.map} +1 -1
  108. package/webapp/dist/assets/{vennDiagram-LZ73GAT5-x92Elcin.js → vennDiagram-LZ73GAT5-8sPBS5jq.js} +2 -2
  109. package/webapp/dist/assets/{vennDiagram-LZ73GAT5-x92Elcin.js.map → vennDiagram-LZ73GAT5-8sPBS5jq.js.map} +1 -1
  110. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-gYBO5I1F.js → xychartDiagram-JWTSCODW-CqLmOgCw.js} +3 -3
  111. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-gYBO5I1F.js.map → xychartDiagram-JWTSCODW-CqLmOgCw.js.map} +1 -1
  112. package/webapp/dist/index.html +1 -1
@@ -302,28 +302,28 @@ function getUserOriginPromptMsgId(prompt) {
302
302
  ? prompt.msgId
303
303
  : undefined;
304
304
  }
305
- function samePendingUserInterjectionMsg(pending, msgId) {
306
- return pending.msgId === msgId;
305
+ function samePendingUserInterjectionCoordinate(left, right) {
306
+ return left.msgId === right.msgId && left.course === right.course && left.genseq === right.genseq;
307
307
  }
308
308
  async function maybeResolveAnsweredUserInterjection(args) {
309
309
  if (args.userPromptMsgId === undefined ||
310
310
  args.assistantSayingContent === null ||
311
311
  args.assistantSayingContent.trim() === '' ||
312
312
  args.assistantSayingGenseq === null) {
313
- return;
313
+ return undefined;
314
314
  }
315
315
  for (const rawGenseq of args.functionCallGenseqs) {
316
316
  if (!Number.isFinite(rawGenseq) || rawGenseq <= 0) {
317
317
  continue;
318
318
  }
319
319
  if (args.assistantSayingGenseq <= Math.floor(rawGenseq)) {
320
- return;
320
+ return undefined;
321
321
  }
322
322
  }
323
323
  const latest = await persistence_1.DialogPersistence.loadDialogLatest(args.dlg.id, args.dlg.status);
324
324
  const pending = latest?.pendingUserInterjectionReply;
325
- if (pending === undefined || !samePendingUserInterjectionMsg(pending, args.userPromptMsgId)) {
326
- return;
325
+ if (pending === undefined || pending.msgId !== args.userPromptMsgId) {
326
+ return undefined;
327
327
  }
328
328
  const course = args.dlg.activeGenCourseOrUndefined ?? args.dlg.currentCourse;
329
329
  const answerIdSource = [
@@ -369,14 +369,18 @@ async function maybeResolveAnsweredUserInterjection(args) {
369
369
  const userPromptMsgId = args.userPromptMsgId;
370
370
  if (previousPending === undefined ||
371
371
  userPromptMsgId === undefined ||
372
- !samePendingUserInterjectionMsg(previousPending, userPromptMsgId)) {
372
+ userPromptMsgId !== pending.msgId ||
373
+ !samePendingUserInterjectionCoordinate(previousPending, pending)) {
373
374
  return { kind: 'noop' };
374
375
  }
376
+ const next = { ...previous };
377
+ delete next.pendingUserInterjectionReply;
375
378
  return {
376
- kind: 'patch',
377
- patch: { pendingUserInterjectionReply: undefined },
379
+ kind: 'replace',
380
+ next,
378
381
  };
379
382
  }, args.dlg.status);
383
+ return answer;
380
384
  }
381
385
  async function persistAndEmitRuntimeGuide(dlg, content) {
382
386
  await dlg.addChatMessages({
@@ -804,10 +808,15 @@ async function renderRemindersForContext(dlg) {
804
808
  return [];
805
809
  const language = (0, work_language_1.getWorkLanguage)();
806
810
  const renderedItems = [];
811
+ const maintenanceReferenceItems = [];
807
812
  for (const reminder of reminders) {
808
813
  if (!reminder || !(0, tool_1.reminderEchoBackEnabled)(reminder)) {
809
814
  continue;
810
815
  }
816
+ maintenanceReferenceItems.push({
817
+ id: reminder.id,
818
+ meta: reminder.meta,
819
+ });
811
820
  if (reminder.owner) {
812
821
  renderedItems.push(await reminder.owner.renderReminder(dlg, reminder));
813
822
  continue;
@@ -823,12 +832,22 @@ async function renderRemindersForContext(dlg) {
823
832
  }
824
833
  if (renderedItems.length === 0)
825
834
  return [];
835
+ const maintenanceReference = (0, driver_messages_1.formatReminderMaintenanceReference)(language, maintenanceReferenceItems);
826
836
  return [
827
837
  {
828
838
  type: 'environment_msg',
829
839
  role: 'user',
830
840
  content: (0, driver_messages_1.formatReminderContextGuide)(language),
831
841
  },
842
+ ...(maintenanceReference === undefined
843
+ ? []
844
+ : [
845
+ {
846
+ type: 'transient_guide_msg',
847
+ role: 'assistant',
848
+ content: maintenanceReference,
849
+ },
850
+ ]),
832
851
  ...renderedItems,
833
852
  ];
834
853
  }
@@ -2192,6 +2211,9 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
2192
2211
  let lastFunctionCallGenseq = null;
2193
2212
  let lastAssistantReplyTarget;
2194
2213
  let lastBusinessContinuation = { kind: 'none' };
2214
+ let answeredUserInterjection;
2215
+ let currentPromptIsUserInterjection = false;
2216
+ let currentUserInterjectionReply;
2195
2217
  let fbrConclusion;
2196
2218
  let pubRemindersVer = dlg.remindersVer;
2197
2219
  let lastToolRoundStopDiagnostics;
@@ -2440,6 +2462,8 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
2440
2462
  }
2441
2463
  }
2442
2464
  lastBusinessContinuation = currentBusinessContinuation;
2465
+ currentPromptIsUserInterjection = false;
2466
+ currentUserInterjectionReply = undefined;
2443
2467
  let generationBodyError;
2444
2468
  let immediateFollowupTriggerExpectation;
2445
2469
  const q4hAnswerCallId = normalizeQ4HAnswerCallId(currentPrompt?.q4hAnswerCallId);
@@ -2461,9 +2485,10 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
2461
2485
  language: promptLanguage,
2462
2486
  });
2463
2487
  const deferredReplyReassertionDirective = replyGuidance.deferredReplyReassertionDirective;
2464
- const currentPromptIsUserInterjection = currentPrompt.origin === 'user' &&
2465
- replyGuidance.suppressInterDialogReplyGuidance &&
2466
- deferredReplyReassertionDirective !== undefined;
2488
+ currentPromptIsUserInterjection =
2489
+ currentPrompt.origin === 'user' &&
2490
+ replyGuidance.suppressInterDialogReplyGuidance &&
2491
+ deferredReplyReassertionDirective !== undefined;
2467
2492
  if (currentPromptIsUserInterjection) {
2468
2493
  // WARNING:
2469
2494
  // User interjection suppression is a reversible state transition, not a one-shot
@@ -2475,13 +2500,29 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
2475
2500
  // Legacy blocked-Continue paths may also re-enter here. A repeated interjection MUST
2476
2501
  // re-arm the deferred state and re-materialize the suppression guide, even when the
2477
2502
  // underlying reply directive itself did not change.
2503
+ const deferredDirective = deferredReplyReassertionDirective;
2504
+ if (deferredDirective === undefined) {
2505
+ throw new Error(`kernel-driver user interjection invariant violation: missing deferred reply directive for dialog=${dlg.id.valueOf()} msgId=${currentPrompt.msgId}`);
2506
+ }
2478
2507
  const existingDeferredReplyReassertion = await persistence_1.DialogPersistence.getDeferredReplyReassertion(dlg.id, dlg.status);
2508
+ currentUserInterjectionReply = {
2509
+ msgId: currentPrompt.msgId,
2510
+ course: (0, storage_1.toDialogCourseNumber)(dlg.activeGenCourseOrUndefined ?? dlg.currentCourse),
2511
+ genseq: (0, storage_1.toCallSiteGenseqNo)(dlg.activeGenSeq),
2512
+ };
2479
2513
  const nextDeferredReplyReassertion = {
2480
2514
  reason: 'user_interjection_with_parked_original_task',
2481
- directive: deferredReplyReassertionDirective,
2515
+ directive: deferredDirective,
2516
+ userInterjection: currentUserInterjectionReply,
2482
2517
  };
2483
2518
  const mustRearmDeferredReplyReassertion = existingDeferredReplyReassertion === undefined ||
2484
2519
  existingDeferredReplyReassertion.resumeGuideSurfaced === true ||
2520
+ existingDeferredReplyReassertion.userInterjection.msgId !==
2521
+ nextDeferredReplyReassertion.userInterjection.msgId ||
2522
+ existingDeferredReplyReassertion.userInterjection.course !==
2523
+ nextDeferredReplyReassertion.userInterjection.course ||
2524
+ existingDeferredReplyReassertion.userInterjection.genseq !==
2525
+ nextDeferredReplyReassertion.userInterjection.genseq ||
2485
2526
  !hasSameReplyDirective(existingDeferredReplyReassertion.directive, nextDeferredReplyReassertion.directive);
2486
2527
  if (mustRearmDeferredReplyReassertion) {
2487
2528
  await persistence_1.DialogPersistence.setDeferredReplyReassertion(dlg.id, nextDeferredReplyReassertion, dlg.status);
@@ -2513,13 +2554,15 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
2513
2554
  throw new Error(`kernel-driver reply guidance invariant violation: missing prompt content for dialog=${dlg.id.valueOf()} msgId=${currentPrompt.msgId}`);
2514
2555
  }
2515
2556
  if (currentPromptIsUserInterjection) {
2557
+ if (currentUserInterjectionReply === undefined) {
2558
+ throw new Error(`kernel-driver user interjection invariant violation: missing pending reply coordinate for dialog=${dlg.id.valueOf()} msgId=${currentPrompt.msgId}`);
2559
+ }
2560
+ const pendingUserInterjectionReply = currentUserInterjectionReply;
2516
2561
  await persistence_1.DialogPersistence.mutateDialogLatest(dlg.id, () => ({
2517
2562
  kind: 'patch',
2518
2563
  patch: {
2519
2564
  pendingUserInterjectionReply: {
2520
- msgId: currentPrompt.msgId,
2521
- course: (0, storage_1.toDialogCourseNumber)(dlg.activeGenCourseOrUndefined ?? dlg.currentCourse),
2522
- genseq: (0, storage_1.toCallSiteGenseqNo)(dlg.activeGenSeq),
2565
+ ...pendingUserInterjectionReply,
2523
2566
  },
2524
2567
  },
2525
2568
  }), dlg.status);
@@ -3202,6 +3245,31 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
3202
3245
  lastFunctionCallGenseq = callGenseq;
3203
3246
  }
3204
3247
  }
3248
+ const userInterjectionMsgIdForVisibleAnswer = currentPrompt?.origin === 'user' && !isQ4HAnswerPrompt
3249
+ ? currentPrompt.msgId
3250
+ : currentGenerationBelongsToUserToolChain
3251
+ ? currentUserPromptMsgId
3252
+ : undefined;
3253
+ if (userInterjectionMsgIdForVisibleAnswer !== undefined) {
3254
+ const streamedCurrentRoundSayingContent = batchOutputs.length === 0 &&
3255
+ lastAssistantSayingGenseq !== previousAssistantSayingGenseq
3256
+ ? lastAssistantSayingContent
3257
+ : null;
3258
+ const streamedCurrentRoundSayingGenseq = batchOutputs.length === 0 &&
3259
+ lastAssistantSayingGenseq !== previousAssistantSayingGenseq
3260
+ ? lastAssistantSayingGenseq
3261
+ : null;
3262
+ const answer = await maybeResolveAnsweredUserInterjection({
3263
+ dlg,
3264
+ userPromptMsgId: userInterjectionMsgIdForVisibleAnswer,
3265
+ assistantSayingContent: currentRoundAssistantSayingContent ?? streamedCurrentRoundSayingContent,
3266
+ assistantSayingGenseq: currentRoundAssistantSayingGenseq ?? streamedCurrentRoundSayingGenseq,
3267
+ functionCallGenseqs: currentRoundFunctionCallGenseqs,
3268
+ });
3269
+ if (answer !== undefined) {
3270
+ answeredUserInterjection = answer;
3271
+ }
3272
+ }
3205
3273
  const routed = await executeFunctionRound({
3206
3274
  dlg,
3207
3275
  agent,
@@ -3219,21 +3287,6 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
3219
3287
  newMsgs.push(...routed.pairedMessages);
3220
3288
  }
3221
3289
  await dlg.addChatMessages(...newMsgs);
3222
- const streamedCurrentRoundSayingContent = batchOutputs.length === 0 && lastAssistantSayingGenseq !== previousAssistantSayingGenseq
3223
- ? lastAssistantSayingContent
3224
- : null;
3225
- const streamedCurrentRoundSayingGenseq = batchOutputs.length === 0 && lastAssistantSayingGenseq !== previousAssistantSayingGenseq
3226
- ? lastAssistantSayingGenseq
3227
- : null;
3228
- if (currentPrompt?.origin === 'user' && !isQ4HAnswerPrompt) {
3229
- await maybeResolveAnsweredUserInterjection({
3230
- dlg,
3231
- userPromptMsgId: currentPrompt.msgId,
3232
- assistantSayingContent: currentRoundAssistantSayingContent ?? streamedCurrentRoundSayingContent,
3233
- assistantSayingGenseq: currentRoundAssistantSayingGenseq ?? streamedCurrentRoundSayingGenseq,
3234
- functionCallGenseqs: currentRoundFunctionCallGenseqs,
3235
- });
3236
- }
3237
3290
  const persistedFbrState = await loadDialogFbrState(dlg);
3238
3291
  if (persistedFbrState) {
3239
3292
  if (persistedFbrState.phase === 'finalization') {
@@ -3659,6 +3712,7 @@ async function driveDialogStreamCore(dlg, callbacks, humanPrompt, driveOptions)
3659
3712
  lastFunctionCallGenseq,
3660
3713
  lastAssistantReplyTarget,
3661
3714
  lastBusinessContinuation,
3715
+ answeredUserInterjection,
3662
3716
  fbrConclusion,
3663
3717
  };
3664
3718
  }
@@ -25,6 +25,79 @@ const idle_reminder_wake_1 = require("./idle-reminder-wake");
25
25
  const reply_guidance_1 = require("./reply-guidance");
26
26
  const sideDialog_1 = require("./sideDialog");
27
27
  const tellask_special_1 = require("./tellask-special");
28
+ async function confirmAnsweredUserInterjectionCredential(args) {
29
+ const credential = args.credential;
30
+ if (credential === undefined) {
31
+ return undefined;
32
+ }
33
+ const dialog = args.dialog;
34
+ const latest = await persistence_1.DialogPersistence.loadDialogLatest(dialog.id, dialog.status);
35
+ const answers = await persistence_1.DialogPersistence.loadAnswersToHumanState(dialog.id, dialog.status);
36
+ const persistedCredential = answers.find((answer) => answer.id === credential.id);
37
+ if (persistedCredential === undefined) {
38
+ return undefined;
39
+ }
40
+ if (persistedCredential.userInterjection.msgId !== credential.userInterjection.msgId ||
41
+ persistedCredential.userInterjection.course !== credential.userInterjection.course ||
42
+ persistedCredential.userInterjection.genseq !== credential.userInterjection.genseq ||
43
+ persistedCredential.answerRef.course !== credential.answerRef.course ||
44
+ persistedCredential.answerRef.genseq !== credential.answerRef.genseq) {
45
+ return undefined;
46
+ }
47
+ if (persistedCredential.userInterjection.msgId !== args.userInterjection.msgId ||
48
+ persistedCredential.userInterjection.course !== args.userInterjection.course ||
49
+ persistedCredential.userInterjection.genseq !== args.userInterjection.genseq) {
50
+ return undefined;
51
+ }
52
+ const pending = latest?.pendingUserInterjectionReply;
53
+ if (pending === undefined) {
54
+ return persistedCredential;
55
+ }
56
+ if (pending.msgId !== persistedCredential.userInterjection.msgId ||
57
+ pending.course !== persistedCredential.userInterjection.course ||
58
+ pending.genseq !== persistedCredential.userInterjection.genseq) {
59
+ return undefined;
60
+ }
61
+ await persistence_1.DialogPersistence.mutateDialogLatest(dialog.id, (previous) => {
62
+ const previousPending = previous.pendingUserInterjectionReply;
63
+ if (previousPending === undefined ||
64
+ previousPending.msgId !== persistedCredential.userInterjection.msgId ||
65
+ previousPending.course !== persistedCredential.userInterjection.course ||
66
+ previousPending.genseq !== persistedCredential.userInterjection.genseq) {
67
+ return { kind: 'noop' };
68
+ }
69
+ const next = { ...previous };
70
+ delete next.pendingUserInterjectionReply;
71
+ return { kind: 'replace', next };
72
+ }, dialog.status);
73
+ return persistedCredential;
74
+ }
75
+ async function resolveLatestAnsweredUserInterjectionCredential(dialog, userInterjection) {
76
+ const answers = await persistence_1.DialogPersistence.loadAnswersToHumanState(dialog.id, dialog.status);
77
+ for (let index = answers.length - 1; index >= 0; index -= 1) {
78
+ const answer = answers[index];
79
+ if (answer.userInterjection.msgId === userInterjection.msgId &&
80
+ answer.userInterjection.course === userInterjection.course &&
81
+ answer.userInterjection.genseq === userInterjection.genseq) {
82
+ return answer;
83
+ }
84
+ }
85
+ return undefined;
86
+ }
87
+ async function resolveAnsweredUserInterjectionCredentialForPrompt(args) {
88
+ const userPromptMsgId = args.userPromptMsgId;
89
+ if (userPromptMsgId === undefined) {
90
+ return undefined;
91
+ }
92
+ const answers = await persistence_1.DialogPersistence.loadAnswersToHumanState(args.dialog.id, args.dialog.status);
93
+ for (let index = answers.length - 1; index >= 0; index -= 1) {
94
+ const answer = answers[index];
95
+ if (answer.userInterjection.msgId === userPromptMsgId) {
96
+ return answer;
97
+ }
98
+ }
99
+ return undefined;
100
+ }
28
101
  function buildRuntimeReplyReminderFollowUp(args) {
29
102
  const common = {
30
103
  prompt: args.prompt,
@@ -961,6 +1034,10 @@ async function inspectSideDialogBusinessContinuationDrive(args) {
961
1034
  };
962
1035
  }
963
1036
  async function maybeResolveDeferredReplyReassertionPrompt(dialog) {
1037
+ const latest = await persistence_1.DialogPersistence.loadDialogLatest(dialog.id, dialog.status);
1038
+ if (latest?.pendingUserInterjectionReply !== undefined) {
1039
+ return undefined;
1040
+ }
964
1041
  const deferredReplyReassertion = await persistence_1.DialogPersistence.getDeferredReplyReassertion(dialog.id, dialog.status);
965
1042
  if (!deferredReplyReassertion) {
966
1043
  return undefined;
@@ -980,6 +1057,14 @@ async function maybeResolveDeferredReplyReassertionPrompt(dialog) {
980
1057
  await persistence_1.DialogPersistence.setDeferredReplyReassertion(dialog.id, undefined, dialog.status);
981
1058
  return undefined;
982
1059
  }
1060
+ const answeredUserInterjection = await confirmAnsweredUserInterjectionCredential({
1061
+ dialog,
1062
+ credential: await resolveLatestAnsweredUserInterjectionCredential(dialog, deferredReplyReassertion.userInterjection),
1063
+ userInterjection: deferredReplyReassertion.userInterjection,
1064
+ });
1065
+ if (answeredUserInterjection === undefined) {
1066
+ return undefined;
1067
+ }
983
1068
  await persistence_1.DialogPersistence.setDeferredReplyReassertion(dialog.id, undefined, dialog.status);
984
1069
  const language = (0, work_language_1.getWorkLanguage)();
985
1070
  return {
@@ -987,6 +1072,7 @@ async function maybeResolveDeferredReplyReassertionPrompt(dialog) {
987
1072
  dlg: dialog,
988
1073
  directive: deferredReplyReassertion.directive,
989
1074
  language,
1075
+ answeredUserInterjection,
990
1076
  }),
991
1077
  msgId: (0, id_1.generateShortId)(),
992
1078
  grammar: 'markdown',
@@ -1007,12 +1093,20 @@ async function maybeSurfaceDeferredReplyReassertionGuideForBlockedContinue(dialo
1007
1093
  return;
1008
1094
  }
1009
1095
  const language = (0, work_language_1.getWorkLanguage)();
1096
+ const answeredUserInterjection = await confirmAnsweredUserInterjectionCredential({
1097
+ dialog,
1098
+ credential: await resolveLatestAnsweredUserInterjectionCredential(dialog, deferredReplyReassertion.userInterjection),
1099
+ userInterjection: deferredReplyReassertion.userInterjection,
1100
+ });
1101
+ if (answeredUserInterjection === undefined) {
1102
+ return;
1103
+ }
1010
1104
  const content = await (0, reply_guidance_1.buildReplyObligationReassertionPrompt)({
1011
1105
  dlg: dialog,
1012
1106
  directive: deferredReplyReassertion.directive,
1013
1107
  language,
1108
+ answeredUserInterjection,
1014
1109
  });
1015
- const genseq = dialog.activeGenSeqOrUndefined ?? 1;
1016
1110
  // WARNING:
1017
1111
  // This helper intentionally does three things at once:
1018
1112
  // 1. append the guide into dialog.msgs so an in-memory later resume sees it naturally;
@@ -1026,6 +1120,7 @@ async function maybeSurfaceDeferredReplyReassertionGuideForBlockedContinue(dialo
1026
1120
  await persistence_1.DialogPersistence.setDeferredReplyReassertion(dialog.id, {
1027
1121
  reason: 'user_interjection_with_parked_original_task',
1028
1122
  directive: deferredReplyReassertion.directive,
1123
+ userInterjection: deferredReplyReassertion.userInterjection,
1029
1124
  resumeGuideSurfaced: true,
1030
1125
  }, dialog.status);
1031
1126
  }
@@ -1639,15 +1734,6 @@ async function executeDriveRound(args) {
1639
1734
  !replyGuidance.isQ4HAnswerPrompt &&
1640
1735
  replyGuidance.suppressInterDialogReplyGuidance &&
1641
1736
  replyGuidance.deferredReplyReassertionDirective !== undefined;
1642
- if (effectivePrompt?.origin === 'user' &&
1643
- !replyGuidance.isQ4HAnswerPrompt &&
1644
- !replyGuidance.suppressInterDialogReplyGuidance &&
1645
- replyGuidance.deferredReplyReassertionDirective !== undefined) {
1646
- await persistence_1.DialogPersistence.setDeferredReplyReassertion(dialog.id, {
1647
- reason: 'user_interjection_with_parked_original_task',
1648
- directive: replyGuidance.deferredReplyReassertionDirective,
1649
- }, dialog.status);
1650
- }
1651
1737
  activeTellaskReplyDirective =
1652
1738
  replyGuidance.activeReplyDirective ?? replyContinuationScope.directive();
1653
1739
  activePromptWasReplyToolReminder = isReplyToolReminderPrompt(effectivePrompt);
@@ -1736,6 +1822,52 @@ async function executeDriveRound(args) {
1736
1822
  }
1737
1823
  let tailError;
1738
1824
  try {
1825
+ if (shouldPauseAfterLocalUserInterjection &&
1826
+ effectivePrompt?.origin === 'user' &&
1827
+ !interruptedBySignal &&
1828
+ followUp === undefined &&
1829
+ driveResult?.lastAssistantSayingContent !== undefined &&
1830
+ driveResult.lastAssistantSayingContent !== null &&
1831
+ driveResult.lastAssistantSayingContent.trim() !== '') {
1832
+ const deferredReplyReassertion = await persistence_1.DialogPersistence.getDeferredReplyReassertion(dialog.id, dialog.status);
1833
+ if (deferredReplyReassertion !== undefined &&
1834
+ deferredReplyReassertion.reason === 'user_interjection_with_parked_original_task') {
1835
+ const answeredUserInterjection = await confirmAnsweredUserInterjectionCredential({
1836
+ dialog,
1837
+ credential: driveResult.answeredUserInterjection ??
1838
+ (await resolveAnsweredUserInterjectionCredentialForPrompt({
1839
+ dialog,
1840
+ userPromptMsgId: effectivePrompt?.msgId,
1841
+ })),
1842
+ userInterjection: deferredReplyReassertion.userInterjection,
1843
+ });
1844
+ if (answeredUserInterjection !== undefined) {
1845
+ const language = (0, work_language_1.getWorkLanguage)();
1846
+ const prompt = await (0, reply_guidance_1.buildReplyObligationReassertionPrompt)({
1847
+ dlg: dialog,
1848
+ directive: deferredReplyReassertion.directive,
1849
+ language,
1850
+ answeredUserInterjection,
1851
+ });
1852
+ followUp = {
1853
+ kind: 'runtime_reply_reminder',
1854
+ prompt,
1855
+ msgId: (0, id_1.generateShortId)(),
1856
+ grammar: 'markdown',
1857
+ origin: 'runtime',
1858
+ userLanguageCode: language,
1859
+ tellaskReplyDirective: deferredReplyReassertion.directive,
1860
+ };
1861
+ await persistence_1.DialogPersistence.setDeferredReplyReassertion(dialog.id, undefined, dialog.status);
1862
+ log_1.log.debug('kernel-driver queued automatic reply-obligation reassertion after user interjection answer', undefined, {
1863
+ dialogId: dialog.id.valueOf(),
1864
+ rootId: dialog.id.rootId,
1865
+ selfId: dialog.id.selfId,
1866
+ targetCallId: deferredReplyReassertion.directive.targetCallId,
1867
+ });
1868
+ }
1869
+ }
1870
+ }
1739
1871
  if (dialog instanceof dialog_1.SideDialog &&
1740
1872
  driveResult &&
1741
1873
  !interruptedBySignal &&
@@ -1978,36 +2110,6 @@ async function executeDriveRound(args) {
1978
2110
  }
1979
2111
  }
1980
2112
  }
1981
- if (shouldPauseAfterLocalUserInterjection &&
1982
- !interruptedBySignal &&
1983
- followUp === undefined &&
1984
- driveResult?.lastAssistantSayingContent !== null) {
1985
- const deferredReplyReassertion = await persistence_1.DialogPersistence.getDeferredReplyReassertion(dialog.id, dialog.status);
1986
- if (deferredReplyReassertion?.reason === 'user_interjection_with_parked_original_task') {
1987
- const language = (0, work_language_1.getWorkLanguage)();
1988
- const prompt = await (0, reply_guidance_1.buildReplyObligationReassertionPrompt)({
1989
- dlg: dialog,
1990
- directive: deferredReplyReassertion.directive,
1991
- language,
1992
- });
1993
- followUp = {
1994
- kind: 'runtime_reply_reminder',
1995
- prompt,
1996
- msgId: (0, id_1.generateShortId)(),
1997
- grammar: 'markdown',
1998
- origin: 'runtime',
1999
- userLanguageCode: language,
2000
- tellaskReplyDirective: deferredReplyReassertion.directive,
2001
- };
2002
- await persistence_1.DialogPersistence.setDeferredReplyReassertion(dialog.id, undefined, dialog.status);
2003
- log_1.log.debug('kernel-driver queued automatic reply-obligation reassertion after user interjection answer', undefined, {
2004
- dialogId: dialog.id.valueOf(),
2005
- rootId: dialog.id.rootId,
2006
- selfId: dialog.id.selfId,
2007
- targetCallId: deferredReplyReassertion.directive.targetCallId,
2008
- });
2009
- }
2010
- }
2011
2113
  if (followUp) {
2012
2114
  if (followUp.kind === 'runtime_reply_reminder' ||
2013
2115
  followUp.kind === 'runtime_sideDialog_reply_reminder') {
@@ -1,4 +1,4 @@
1
- import type { TellaskReplyDirective } from '@longrun-ai/kernel/types/storage';
1
+ import type { AnswerToHumanItem, TellaskReplyDirective } from '@longrun-ai/kernel/types/storage';
2
2
  import { Dialog } from '../../dialog';
3
3
  import type { KernelDriverPrompt } from './types';
4
4
  export declare function resolveReplyTargetAgentId(args: {
@@ -25,4 +25,5 @@ export declare function buildReplyObligationReassertionPrompt(args: {
25
25
  dlg: Dialog;
26
26
  directive: NonNullable<KernelDriverPrompt['tellaskReplyDirective']>;
27
27
  language: 'zh' | 'en';
28
+ answeredUserInterjection: AnswerToHumanItem;
28
29
  }): Promise<string>;
@@ -110,15 +110,20 @@ function buildCurrentSideDialogAssignmentDirective(dlg) {
110
110
  }
111
111
  }
112
112
  async function resolveFreshCurrentSideDialogAssignmentDirective(args) {
113
- if (!(args.dlg instanceof dialog_1.SideDialog) || args.prompt?.origin !== 'runtime') {
114
- return undefined;
115
- }
116
- const promptDirective = args.prompt.tellaskReplyDirective;
117
- if (!promptDirective) {
113
+ if (!(args.dlg instanceof dialog_1.SideDialog)) {
118
114
  return undefined;
119
115
  }
120
116
  const currentAssignmentDirective = buildCurrentSideDialogAssignmentDirective(args.dlg);
121
- if (!hasSameReplyDirective(promptDirective, currentAssignmentDirective)) {
117
+ if (args.prompt?.origin === 'runtime') {
118
+ const promptDirective = args.prompt.tellaskReplyDirective;
119
+ if (!promptDirective) {
120
+ return undefined;
121
+ }
122
+ if (!hasSameReplyDirective(promptDirective, currentAssignmentDirective)) {
123
+ return undefined;
124
+ }
125
+ }
126
+ else if (args.prompt?.origin !== 'user') {
122
127
  return undefined;
123
128
  }
124
129
  const latest = await persistence_1.DialogPersistence.loadDialogLatest(args.dlg.id, args.dlg.status);
@@ -1,6 +1,6 @@
1
1
  import type { DialogDisplayState, DialogInterruptionReason } from '@longrun-ai/kernel/types/display-state';
2
2
  import type { DialogDiligencePrompt, DialogPrompt, DialogRunControlSpec, DialogRuntimeGuidePrompt, DialogRuntimePrompt, DialogRuntimeReplyPrompt, DialogRuntimeSideDialogPrompt, DialogUserPrompt } from '@longrun-ai/kernel/types/drive-intent';
3
- import type { CallSiteCourseNo, CallSiteGenseqNo, DialogBusinessContinuation } from '@longrun-ai/kernel/types/storage';
3
+ import type { AnswerToHumanItem, CallSiteCourseNo, CallSiteGenseqNo, DialogBusinessContinuation } from '@longrun-ai/kernel/types/storage';
4
4
  import type { Dialog, DialogID } from '../../dialog';
5
5
  export type KernelDriverRunControl = DialogRunControlSpec;
6
6
  export type KernelDriverDriveSource = 'unspecified' | 'ws_user_message' | 'ws_user_answer' | 'ws_diligence_push' | 'ws_resume_dialog' | 'ws_resume_all' | 'kernel_driver_backend_loop' | 'kernel_driver_follow_up' | 'kernel_driver_sideDialog_init' | 'kernel_driver_sideDialog_resume' | 'kernel_driver_fbr_sideDialog_round' | 'kernel_driver_type_a_askerDialog_call' | 'kernel_driver_business_continuation' | 'kernel_driver_idle_reminder_wake';
@@ -99,6 +99,7 @@ export type KernelDriverCoreResult = {
99
99
  lastFunctionCallGenseq: number | null;
100
100
  lastAssistantReplyTarget?: KernelDriverCalleeReplyTarget;
101
101
  lastBusinessContinuation: DialogBusinessContinuation;
102
+ answeredUserInterjection?: AnswerToHumanItem;
102
103
  fbrConclusion?: {
103
104
  responseText: string;
104
105
  responseGenseq: number;
@@ -101,14 +101,12 @@ function ensureLeaseReminder(dlg, serverId) {
101
101
  ? [
102
102
  `已租用 MCP 工具集:${serverId}`,
103
103
  '',
104
- '该 MCP server 被视为非“真正无状态”。当你确认短期内不再需要它时,请释放以回收底层进程/连接:',
105
- `mcp_release({"serverId":"${serverId}"})`,
104
+ '该 MCP server 被视为非“真正无状态”;当前对话持有一个需要显式生命周期管理的底层进程/连接。',
106
105
  ].join('\n')
107
106
  : [
108
107
  `MCP toolset leased: ${serverId}`,
109
108
  '',
110
- `This MCP server is treated as non-stateless. When you are confident you won't need it again soon, release it:`,
111
- `mcp_release({"serverId":"${serverId}"})`,
109
+ `This MCP server is treated as non-stateless; the current dialog holds an underlying process/connection with explicit lifecycle management.`,
112
110
  ].join('\n');
113
111
  dlg.addReminder(content, owner, makeLeaseReminderMeta(serverId));
114
112
  }
@@ -99,8 +99,8 @@ function buildTeammateTellaskPhaseContract(language) {
99
99
  '- 队友诉请必须遵循“发起 → 等待 → 判定 → 续推”四段协议:若目标未达成,立即发出下一轮诉请推进。',
100
100
  '- 对队友诉请而言,收到回贴即表示该轮调用已结束;不存在“回贴已送达后,对方仍在后台继续执行同一诉请”的默认语义。要继续必须显式再发一轮诉请函数(通常 `tellask` 复用同一 `sessionSlug`)。',
101
101
  '- 若被诉请者在回贴送达前因 `clear_mind` 开启新一程,同一进行中诉请默认继续有效;新一程会自然承接,直到产生回贴或明确失败。不要仅因对方换程就把该轮诉请当作失效重发。',
102
- '- 只有在存在明确进行中诉请时,才可声明“等待回贴/等待结果”(通常应可在“⏳ 进行中诉请(共 N 路,自动维护;仅 0 路时可手动删除)”这类提醒项中观测到);若该提醒项不存在,或提醒项已明确“当前没有执行中的诉请”,则“等待”是错误动作,必须执行下一动作(直接诉请或本地执行)。',
103
- '- “⏳ 进行中诉请”提醒项只是系统状态窗,不是控制面:内容不可手改;当存在非 0 路进行中诉请时,不可删除,误删会被拒绝并返回引导文案。若某一路诉请需要改要求、提前收口或纠偏,只能更新那一路诉请的“任务安排”(对长线诉请通常复用同一 `sessionSlug` 再发 `tellask`),让对应主理人按最新安排自行最终回复并自然结束。',
102
+ '- 只有在存在明确进行中诉请时,才可声明“等待回贴/等待结果”(通常应可在“⏳ 进行中诉请(共 N 路,自动维护)”这类提醒项中观测到);若该提醒项不存在,或提醒项已明确“当前没有执行中的诉请”,则“等待”是错误动作,必须执行下一动作(直接诉请或本地执行)。',
103
+ '- “⏳ 进行中诉请”提醒项只是系统状态窗,不是控制面;用它判断是否确实存在仍在执行的诉请。若某一路诉请需要改要求、提前收口或纠偏,更新那一路诉请的“任务安排”(对长线诉请通常复用同一 `sessionSlug` 再发 `tellask`),让对应主理人按最新安排自行最终回复并自然结束。',
104
104
  '- 只有长线诉请(`tellask` + `sessionSlug`)能接着同一件事说、更新同一件正在做的事;一次性诉请(`tellaskSessionless`)做不到。再次发起 `tellaskSessionless` 只是另一件独立任务,不会更新、更不会要求旧任务停止;若你后来发现可能需要改要求/提前收口,一开始就不该选择 `tellaskSessionless`。',
105
105
  '- 不要把智能体队友当成真人同事:祂不会因为你又发一条诉请而被打扰。同一个队友可以同时做多件独立任务,系统会分开处理。记住这个简单规则:同一个队友 + 同一个 `sessionSlug` = 接着同一件事说,并更新那件正在做的事;`tellaskSessionless` 或不同 `sessionSlug` = 另一件独立任务。只要任务独立、目标清楚,就直接并行诉请。',
106
106
  '- 能由队友诉请完成的执行性工作,禁止转交 `askHuman` 做“转发员”;当你写“让 @X 执行 Y”时,必须在同一回复内直接发出 `tellask` 或 `tellaskSessionless`。',
@@ -112,8 +112,8 @@ function buildTeammateTellaskPhaseContract(language) {
112
112
  '- Teammate Tellasks MUST follow four phases: “initiate -> wait -> judge -> continue”. If the objective is not met, immediately send the next Tellask round.',
113
113
  '- For teammate Tellasks, a delivered response closes that call round; there is no default “still running in background after the reply is already delivered” state for the same Tellask. To continue, emit a new Tellask function call explicitly (usually `tellask` with the same `sessionSlug`).',
114
114
  '- If the tellaskee starts a new course via `clear_mind` before delivering the reply, the same in-flight Tellask stays live by default; the new course naturally continues it until a reply is delivered or an explicit failure is returned. Do not re-tellask solely because the tellaskee changed course.',
115
- '- You may claim “waiting for reply/result” only when a concrete pending Tellask exists (normally observable in a “⏳ In-flight Tellasks (N total, auto-maintained; manually deletable only at zero in-flight)” reminder). If that reminder is absent, or it explicitly states there are no in-flight Tellasks, waiting is a wrong action; execute the next action now (direct Tellask or local action).',
116
- '- The “⏳ In-flight Tellasks” reminder is only a system status window, not a control surface: its content is not hand-editable; while any Tellask is still active, it is not deletable, and mistaken deletion will be rejected with guidance. If one Tellask needs a changed scope, earlier closure, or correction, update that Tellask’s assignment instead (for a sessioned Tellask, usually send another `tellask` with the same `sessionSlug`) so the tellaskee can deliver a final reply naturally under the latest assignment.',
115
+ '- You may claim “waiting for reply/result” only when a concrete pending Tellask exists (normally observable in a “⏳ In-flight Tellasks (N total, auto-maintained)” reminder). If that reminder is absent, or it explicitly states there are no in-flight Tellasks, waiting is a wrong action; execute the next action now (direct Tellask or local action).',
116
+ '- The “⏳ In-flight Tellasks” reminder is only a system status window, not a control surface; use it to determine whether any Tellask is truly still in flight. If one Tellask needs a changed scope, earlier closure, or correction, update that Tellask’s assignment (for a sessioned Tellask, usually send another `tellask` with the same `sessionSlug`) so the tellaskee can deliver a final reply naturally under the latest assignment.',
117
117
  '- Only a sessioned Tellask (`tellask` + `sessionSlug`) can continue the same task and update that task. A one-shot Tellask (`tellaskSessionless`) cannot: another `tellaskSessionless` is a separate task and does not update, stop, or instruct the earlier task to stop. If you may need later correction or earlier wrap-up, do not choose `tellaskSessionless` in the first place.',
118
118
  '- Do not treat an agent teammate like a human coworker who can only handle one conversation at a time. The same teammate can work on several independent tasks at once, and the system keeps them separate. Simple rule: same teammate + same `sessionSlug` = continue the same task and update that task; `tellaskSessionless` or a different `sessionSlug` = another independent task. When tasks are independent and clear, tellask in parallel.',
119
119
  '- Do not use `askHuman` as a relay for executable teammate work. If you write “ask @X to do Y”, emit `tellask` or `tellaskSessionless` in the same response.',