dominds 1.12.2 → 1.13.2

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 (174) hide show
  1. package/dist/llm/client.d.ts +1 -0
  2. package/dist/llm/defaults.yaml +1 -0
  3. package/dist/llm/gen/anthropic.d.ts +2 -1
  4. package/dist/llm/gen/anthropic.js +4 -0
  5. package/dist/llm/gen/codex.d.ts +2 -1
  6. package/dist/llm/gen/codex.js +4 -0
  7. package/dist/llm/gen/failure-classifier.d.ts +3 -0
  8. package/dist/llm/gen/failure-classifier.js +156 -0
  9. package/dist/llm/gen/openai-compatible.d.ts +2 -1
  10. package/dist/llm/gen/openai-compatible.js +4 -0
  11. package/dist/llm/gen/openai.d.ts +2 -1
  12. package/dist/llm/gen/openai.js +4 -0
  13. package/dist/llm/gen.d.ts +10 -0
  14. package/dist/llm/kernel-driver/drive.js +22 -6
  15. package/dist/llm/kernel-driver/flow.js +15 -20
  16. package/dist/llm/kernel-driver/reply-guidance.d.ts +7 -1
  17. package/dist/llm/kernel-driver/reply-guidance.js +30 -4
  18. package/dist/llm/kernel-driver/runtime.d.ts +3 -0
  19. package/dist/llm/kernel-driver/runtime.js +103 -30
  20. package/dist/persistence.js +31 -6
  21. package/dist/runtime/inter-dialog-format.js +46 -16
  22. package/dist/runtime/reply-prompt-copy.d.ts +12 -2
  23. package/dist/runtime/reply-prompt-copy.js +74 -16
  24. package/dist/runtime/tellask-labels.d.ts +8 -0
  25. package/dist/runtime/tellask-labels.js +47 -0
  26. package/dist/shared/utils/fbr.js +8 -12
  27. package/dist/shared/utils/inter-dialog-format.js +4 -6
  28. package/dist/tools/pending-tellask-reminder.js +3 -19
  29. package/package.json +3 -3
  30. package/webapp/dist/assets/{_basePickBy-B1lGEusm.js → _basePickBy-CBOtd63g.js} +3 -3
  31. package/webapp/dist/assets/_basePickBy-CBOtd63g.js.map +1 -0
  32. package/webapp/dist/assets/{_baseUniq-SGAsMSaE.js → _baseUniq-mfoKz4Wm.js} +2 -2
  33. package/webapp/dist/assets/_baseUniq-mfoKz4Wm.js.map +1 -0
  34. package/webapp/dist/assets/{arc-B2joU0eL.js → arc-Dq0WZLyu.js} +2 -2
  35. package/webapp/dist/assets/arc-Dq0WZLyu.js.map +1 -0
  36. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-CsuG-Xa3.js → architectureDiagram-VXUJARFQ-CNmygmp3.js} +8 -26
  37. package/webapp/dist/assets/architectureDiagram-VXUJARFQ-CNmygmp3.js.map +1 -0
  38. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-D8_SVEGn.js → blockDiagram-VD42YOAC-DvE0lybt.js} +170 -187
  39. package/webapp/dist/assets/blockDiagram-VD42YOAC-DvE0lybt.js.map +1 -0
  40. package/webapp/dist/assets/{c4Diagram-IC4MRINW-D_lhLw36.js → c4Diagram-YG6GDRKO-CR7zJ2_u.js} +4 -4
  41. package/webapp/dist/assets/c4Diagram-YG6GDRKO-CR7zJ2_u.js.map +1 -0
  42. package/webapp/dist/assets/{channel-BI76pqQS.js → channel-DrTrnYx4.js} +2 -2
  43. package/webapp/dist/assets/channel-DrTrnYx4.js.map +1 -0
  44. package/webapp/dist/assets/{chunk-4BX2VUAB-BVI27QNV.js → chunk-4BX2VUAB-CVuJEIeN.js} +2 -2
  45. package/webapp/dist/assets/chunk-4BX2VUAB-CVuJEIeN.js.map +1 -0
  46. package/webapp/dist/assets/{chunk-55IACEB6-D2ECkhpq.js → chunk-55IACEB6-BxUoXApB.js} +2 -2
  47. package/webapp/dist/assets/chunk-55IACEB6-BxUoXApB.js.map +1 -0
  48. package/webapp/dist/assets/{chunk-WL4C6EOR-Cd-rWL8V.js → chunk-B4BG7PRW-DpMa3-9L.js} +121 -171
  49. package/webapp/dist/assets/chunk-B4BG7PRW-DpMa3-9L.js.map +1 -0
  50. package/webapp/dist/assets/{chunk-NQ4KR5QH-CZmmNdX5.js → chunk-DI55MBZ5-SAhxUTqQ.js} +7 -9
  51. package/webapp/dist/assets/chunk-DI55MBZ5-SAhxUTqQ.js.map +1 -0
  52. package/webapp/dist/assets/{chunk-FMBD7UC4-BAtzNqV5.js → chunk-FMBD7UC4-TX-LVAaV.js} +2 -2
  53. package/webapp/dist/assets/chunk-FMBD7UC4-TX-LVAaV.js.map +1 -0
  54. package/webapp/dist/assets/{chunk-KX2RTZJC-Dt3XFfSl.js → chunk-QN33PNHL-D1uiKlOO.js} +2 -2
  55. package/webapp/dist/assets/chunk-QN33PNHL-D1uiKlOO.js.map +1 -0
  56. package/webapp/dist/assets/{chunk-QZHKN3VN-BI_lqvsU.js → chunk-QZHKN3VN-BxuV0Oba.js} +2 -2
  57. package/webapp/dist/assets/chunk-QZHKN3VN-BxuV0Oba.js.map +1 -0
  58. package/webapp/dist/assets/{chunk-JSJVCQXG-BYyIDBzB.js → chunk-TZMSLE5B-Cw689yRl.js} +6 -14
  59. package/webapp/dist/assets/chunk-TZMSLE5B-Cw689yRl.js.map +1 -0
  60. package/webapp/dist/assets/{classDiagram-VBA2DB6C-CGVpNFjf.js → classDiagram-2ON5EDUG-BTTGianr.js} +6 -7
  61. package/webapp/dist/assets/classDiagram-2ON5EDUG-BTTGianr.js.map +1 -0
  62. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-CGVpNFjf.js → classDiagram-v2-WZHVMYZB-BTTGianr.js} +6 -7
  63. package/webapp/dist/assets/classDiagram-v2-WZHVMYZB-BTTGianr.js.map +1 -0
  64. package/webapp/dist/assets/{clone-BcAwA2lT.js → clone-Dk8cAI3I.js} +2 -2
  65. package/webapp/dist/assets/clone-Dk8cAI3I.js.map +1 -0
  66. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-CfkPOIie.js → cose-bilkent-S5V4N54A-BjJnzB2N.js} +2 -2
  67. package/webapp/dist/assets/cose-bilkent-S5V4N54A-BjJnzB2N.js.map +1 -0
  68. package/webapp/dist/assets/cytoscape.esm-Bm8DJGmZ.js.map +1 -1
  69. package/webapp/dist/assets/{dagre-KLK3FWXG-ETpwT3pg.js → dagre-6UL2VRFP-VF-xGhAf.js} +7 -7
  70. package/webapp/dist/assets/dagre-6UL2VRFP-VF-xGhAf.js.map +1 -0
  71. package/webapp/dist/assets/defaultLocale-B2RvLBDe.js.map +1 -1
  72. package/webapp/dist/assets/{diagram-E7M64L7V-CAkt3_Wu.js → diagram-PSM6KHXK-Ba5U0oRY.js} +10 -10
  73. package/webapp/dist/assets/diagram-PSM6KHXK-Ba5U0oRY.js.map +1 -0
  74. package/webapp/dist/assets/{diagram-IFDJBPK2-BUoOrHGY.js → diagram-QEK2KX5R-DoYCnEw_.js} +8 -9
  75. package/webapp/dist/assets/diagram-QEK2KX5R-DoYCnEw_.js.map +1 -0
  76. package/webapp/dist/assets/{diagram-P4PSJMXO-CITRT5KI.js → diagram-S2PKOQOG-CkK4SRyE.js} +8 -8
  77. package/webapp/dist/assets/diagram-S2PKOQOG-CkK4SRyE.js.map +1 -0
  78. package/webapp/dist/assets/{erDiagram-INFDFZHY-Cjpy0ose.js → erDiagram-Q2GNP2WA-DkI5eYww.js} +75 -96
  79. package/webapp/dist/assets/erDiagram-Q2GNP2WA-DkI5eYww.js.map +1 -0
  80. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-CBmrK8ST.js → flowDiagram-NV44I4VS-wOdPUQ7Y.js} +81 -98
  81. package/webapp/dist/assets/flowDiagram-NV44I4VS-wOdPUQ7Y.js.map +1 -0
  82. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-CLoJRKb7.js → ganttDiagram-JELNMOA3-BtRWgkUH.js} +3 -28
  83. package/webapp/dist/assets/ganttDiagram-JELNMOA3-BtRWgkUH.js.map +1 -0
  84. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-DcAa_Q3i.js → gitGraphDiagram-V2S2FVAM-Bsz7u1vi.js} +46 -38
  85. package/webapp/dist/assets/gitGraphDiagram-V2S2FVAM-Bsz7u1vi.js.map +1 -0
  86. package/webapp/dist/assets/graph-DAMkuTbn.js +425 -0
  87. package/webapp/dist/assets/graph-DAMkuTbn.js.map +1 -0
  88. package/webapp/dist/assets/{index-B219Q97D.js → index-rYmIohM_.js} +1072 -1025
  89. package/webapp/dist/assets/{index-B219Q97D.js.map → index-rYmIohM_.js.map} +1 -1
  90. package/webapp/dist/assets/{index-YaxF76or.css → index-xvYYeHuy.css} +1 -1
  91. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-CXY1BDG-.js → infoDiagram-HS3SLOUP-BMaxCvH5.js} +7 -7
  92. package/webapp/dist/assets/infoDiagram-HS3SLOUP-BMaxCvH5.js.map +1 -0
  93. package/webapp/dist/assets/init-ZxktEp_H.js.map +1 -1
  94. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-jFEOb3_9.js → journeyDiagram-XKPGCS4Q-ejyerzmG.js} +5 -5
  95. package/webapp/dist/assets/journeyDiagram-XKPGCS4Q-ejyerzmG.js.map +1 -0
  96. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-g9DIRWk3.js → kanban-definition-3W4ZIXB7-CYj35TEs.js} +3 -5
  97. package/webapp/dist/assets/kanban-definition-3W4ZIXB7-CYj35TEs.js.map +1 -0
  98. package/webapp/dist/assets/{layout-BvoIJLam.js → layout-7Ql4zmuL.js} +5 -5
  99. package/webapp/dist/assets/layout-7Ql4zmuL.js.map +1 -0
  100. package/webapp/dist/assets/{linear-WhxKIgP6.js → linear-CVmgVPuZ.js} +2 -2
  101. package/webapp/dist/assets/linear-CVmgVPuZ.js.map +1 -0
  102. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-BXxTVKab.js → mindmap-definition-VGOIOE7T-DOpxjGVo.js} +5 -7
  103. package/webapp/dist/assets/mindmap-definition-VGOIOE7T-DOpxjGVo.js.map +1 -0
  104. package/webapp/dist/assets/ordinal-CxptdPJm.js.map +1 -1
  105. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-BVfKuFkc.js → pieDiagram-ADFJNKIX-CLQjpmAG.js} +8 -8
  106. package/webapp/dist/assets/pieDiagram-ADFJNKIX-CLQjpmAG.js.map +1 -0
  107. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-DjOan1Ul.js → quadrantDiagram-AYHSOK5B-ClD_bz7z.js} +3 -3
  108. package/webapp/dist/assets/quadrantDiagram-AYHSOK5B-ClD_bz7z.js.map +1 -0
  109. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-CdkkhNJu.js → requirementDiagram-UZGBJVZJ-DOpb-TWH.js} +6 -16
  110. package/webapp/dist/assets/requirementDiagram-UZGBJVZJ-DOpb-TWH.js.map +1 -0
  111. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-Cc7UCE1M.js → sankeyDiagram-TZEHDZUN-D8Hsj3yx.js} +2 -2
  112. package/webapp/dist/assets/sankeyDiagram-TZEHDZUN-D8Hsj3yx.js.map +1 -0
  113. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-CAf-TzzV.js → sequenceDiagram-WL72ISMW-CFMNjBER.js} +201 -601
  114. package/webapp/dist/assets/sequenceDiagram-WL72ISMW-CFMNjBER.js.map +1 -0
  115. package/webapp/dist/assets/{stateDiagram-RAJIS63D-CjQh2yGU.js → stateDiagram-FKZM4ZOC-BQeDlw0P.js} +9 -9
  116. package/webapp/dist/assets/stateDiagram-FKZM4ZOC-BQeDlw0P.js.map +1 -0
  117. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-BINESHF-.js → stateDiagram-v2-4FDKWEC3-DscX61Rs.js} +5 -5
  118. package/webapp/dist/assets/stateDiagram-v2-4FDKWEC3-DscX61Rs.js.map +1 -0
  119. package/webapp/dist/assets/{timeline-definition-YZTLITO2-FCh1aV2p.js → timeline-definition-IT6M3QCI-BcXPSTiw.js} +3 -3
  120. package/webapp/dist/assets/timeline-definition-IT6M3QCI-BcXPSTiw.js.map +1 -0
  121. package/webapp/dist/assets/{treemap-KZPCXAKY-J-UTxKUf.js → treemap-GDKQZRPO-BBr4UV0Z.js} +24 -37
  122. package/webapp/dist/assets/treemap-GDKQZRPO-BBr4UV0Z.js.map +1 -0
  123. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-KYLvRsLH.js → xychartDiagram-PRI3JC2R-CS5RAtQE.js} +4 -4
  124. package/webapp/dist/assets/xychartDiagram-PRI3JC2R-CS5RAtQE.js.map +1 -0
  125. package/webapp/dist/index.html +2 -2
  126. package/webapp/dist/assets/_basePickBy-B1lGEusm.js.map +0 -1
  127. package/webapp/dist/assets/_baseUniq-SGAsMSaE.js.map +0 -1
  128. package/webapp/dist/assets/arc-B2joU0eL.js.map +0 -1
  129. package/webapp/dist/assets/architectureDiagram-2XIMDMQ5-CsuG-Xa3.js.map +0 -1
  130. package/webapp/dist/assets/blockDiagram-WCTKOSBZ-D8_SVEGn.js.map +0 -1
  131. package/webapp/dist/assets/c4Diagram-IC4MRINW-D_lhLw36.js.map +0 -1
  132. package/webapp/dist/assets/channel-BI76pqQS.js.map +0 -1
  133. package/webapp/dist/assets/chunk-4BX2VUAB-BVI27QNV.js.map +0 -1
  134. package/webapp/dist/assets/chunk-55IACEB6-D2ECkhpq.js.map +0 -1
  135. package/webapp/dist/assets/chunk-FMBD7UC4-BAtzNqV5.js.map +0 -1
  136. package/webapp/dist/assets/chunk-JSJVCQXG-BYyIDBzB.js.map +0 -1
  137. package/webapp/dist/assets/chunk-KX2RTZJC-Dt3XFfSl.js.map +0 -1
  138. package/webapp/dist/assets/chunk-NQ4KR5QH-CZmmNdX5.js.map +0 -1
  139. package/webapp/dist/assets/chunk-QZHKN3VN-BI_lqvsU.js.map +0 -1
  140. package/webapp/dist/assets/chunk-WL4C6EOR-Cd-rWL8V.js.map +0 -1
  141. package/webapp/dist/assets/classDiagram-VBA2DB6C-CGVpNFjf.js.map +0 -1
  142. package/webapp/dist/assets/classDiagram-v2-RAHNMMFH-CGVpNFjf.js.map +0 -1
  143. package/webapp/dist/assets/clone-BcAwA2lT.js.map +0 -1
  144. package/webapp/dist/assets/cose-bilkent-S5V4N54A-CfkPOIie.js.map +0 -1
  145. package/webapp/dist/assets/dagre-KLK3FWXG-ETpwT3pg.js.map +0 -1
  146. package/webapp/dist/assets/diagram-E7M64L7V-CAkt3_Wu.js.map +0 -1
  147. package/webapp/dist/assets/diagram-IFDJBPK2-BUoOrHGY.js.map +0 -1
  148. package/webapp/dist/assets/diagram-P4PSJMXO-CITRT5KI.js.map +0 -1
  149. package/webapp/dist/assets/erDiagram-INFDFZHY-Cjpy0ose.js.map +0 -1
  150. package/webapp/dist/assets/flowDiagram-PKNHOUZH-CBmrK8ST.js.map +0 -1
  151. package/webapp/dist/assets/ganttDiagram-A5KZAMGK-CLoJRKb7.js.map +0 -1
  152. package/webapp/dist/assets/gitGraphDiagram-K3NZZRJ6-DcAa_Q3i.js.map +0 -1
  153. package/webapp/dist/assets/graph-CyYArI_M.js +0 -782
  154. package/webapp/dist/assets/graph-CyYArI_M.js.map +0 -1
  155. package/webapp/dist/assets/infoDiagram-LFFYTUFH-CXY1BDG-.js.map +0 -1
  156. package/webapp/dist/assets/ishikawaDiagram-PHBUUO56-CCgHez0F.js +0 -966
  157. package/webapp/dist/assets/ishikawaDiagram-PHBUUO56-CCgHez0F.js.map +0 -1
  158. package/webapp/dist/assets/journeyDiagram-4ABVD52K-jFEOb3_9.js.map +0 -1
  159. package/webapp/dist/assets/kanban-definition-K7BYSVSG-g9DIRWk3.js.map +0 -1
  160. package/webapp/dist/assets/layout-BvoIJLam.js.map +0 -1
  161. package/webapp/dist/assets/linear-WhxKIgP6.js.map +0 -1
  162. package/webapp/dist/assets/mindmap-definition-YRQLILUH-BXxTVKab.js.map +0 -1
  163. package/webapp/dist/assets/pieDiagram-SKSYHLDU-BVfKuFkc.js.map +0 -1
  164. package/webapp/dist/assets/quadrantDiagram-337W2JSQ-DjOan1Ul.js.map +0 -1
  165. package/webapp/dist/assets/requirementDiagram-Z7DCOOCP-CdkkhNJu.js.map +0 -1
  166. package/webapp/dist/assets/sankeyDiagram-WA2Y5GQK-Cc7UCE1M.js.map +0 -1
  167. package/webapp/dist/assets/sequenceDiagram-2WXFIKYE-CAf-TzzV.js.map +0 -1
  168. package/webapp/dist/assets/stateDiagram-RAJIS63D-CjQh2yGU.js.map +0 -1
  169. package/webapp/dist/assets/stateDiagram-v2-FVOUBMTO-BINESHF-.js.map +0 -1
  170. package/webapp/dist/assets/timeline-definition-YZTLITO2-FCh1aV2p.js.map +0 -1
  171. package/webapp/dist/assets/treemap-KZPCXAKY-J-UTxKUf.js.map +0 -1
  172. package/webapp/dist/assets/vennDiagram-LZ73GAT5-T1yQlS2L.js +0 -2487
  173. package/webapp/dist/assets/vennDiagram-LZ73GAT5-T1yQlS2L.js.map +0 -1
  174. package/webapp/dist/assets/xychartDiagram-JWTSCODW-KYLvRsLH.js.map +0 -1
@@ -265,16 +265,6 @@ function isRetriableLlmErrorCode(code) {
265
265
  return false;
266
266
  return RETRIABLE_LLM_ERROR_CODES.has(code);
267
267
  }
268
- function isOpenAiRetriableProcessingFailureMessage(lowerMessage) {
269
- if (!lowerMessage.includes('processing your request')) {
270
- return false;
271
- }
272
- if (lowerMessage.includes('you can retry your request') ||
273
- lowerMessage.includes('please retry your request')) {
274
- return true;
275
- }
276
- return lowerMessage.includes('help.openai.com') && lowerMessage.includes('request id');
277
- }
278
268
  function isRetriableLlmMessage(message) {
279
269
  const lower = message.toLowerCase();
280
270
  if (lower.includes('fetch failed') || lower.includes('socket hang up')) {
@@ -286,12 +276,25 @@ function isRetriableLlmMessage(message) {
286
276
  if (lower.includes('timeout') || lower.includes('timed out') || lower.includes('rate limit')) {
287
277
  return true;
288
278
  }
289
- if (isOpenAiRetriableProcessingFailureMessage(lower)) {
290
- return true;
291
- }
292
279
  return false;
293
280
  }
294
- function classifyLlmFailure(err) {
281
+ function normalizeFailureDisposition(err, disposition) {
282
+ const fallbackMessage = err instanceof Error
283
+ ? err.message || err.name
284
+ : typeof err === 'string'
285
+ ? err
286
+ : JSON.stringify(err);
287
+ const errCode = readErrorCode(err);
288
+ const causeCode = readErrorCode(readErrorCause(err));
289
+ return {
290
+ kind: disposition.kind,
291
+ message: disposition.message.trim().length > 0 ? disposition.message : fallbackMessage,
292
+ status: disposition.status,
293
+ code: disposition.code ?? errCode ?? causeCode,
294
+ retryStrategy: disposition.retryStrategy,
295
+ };
296
+ }
297
+ function classifyGenericLlmFailure(err) {
295
298
  const fallbackMessage = err instanceof Error
296
299
  ? err.message || err.name
297
300
  : typeof err === 'string'
@@ -304,10 +307,20 @@ function classifyLlmFailure(err) {
304
307
  return { kind: 'fatal', message: 'Aborted.' };
305
308
  }
306
309
  if (isRetriableLlmErrorCode(errCode)) {
307
- return { kind: 'retriable', code: errCode, message: fallbackMessage };
310
+ return {
311
+ kind: 'retriable',
312
+ code: errCode,
313
+ message: fallbackMessage,
314
+ retryStrategy: 'aggressive',
315
+ };
308
316
  }
309
317
  if (isRetriableLlmErrorCode(causeCode)) {
310
- return { kind: 'retriable', code: causeCode, message: fallbackMessage };
318
+ return {
319
+ kind: 'retriable',
320
+ code: causeCode,
321
+ message: fallbackMessage,
322
+ retryStrategy: 'aggressive',
323
+ };
311
324
  }
312
325
  {
313
326
  const msg = err instanceof Error
@@ -319,7 +332,12 @@ function classifyLlmFailure(err) {
319
332
  : undefined;
320
333
  if (typeof msg === 'string' && msg.length > 0) {
321
334
  if (isRetriableLlmMessage(msg)) {
322
- return { kind: 'retriable', code: errCode ?? causeCode, message: msg };
335
+ return {
336
+ kind: 'retriable',
337
+ code: errCode ?? causeCode,
338
+ message: msg,
339
+ retryStrategy: 'aggressive',
340
+ };
323
341
  }
324
342
  }
325
343
  }
@@ -335,21 +353,38 @@ function classifyLlmFailure(err) {
335
353
  : fallbackMessage;
336
354
  if (typeof status === 'number') {
337
355
  if (status === 408 || status === 429 || status >= 500) {
338
- return { kind: 'retriable', status, message: msg };
356
+ return {
357
+ kind: 'retriable',
358
+ status,
359
+ message: msg,
360
+ retryStrategy: status === 503 || status === 529 ? 'conservative' : 'aggressive',
361
+ };
339
362
  }
340
363
  if (status >= 400 && status < 500) {
341
364
  return { kind: 'rejected', status, message: msg };
342
365
  }
343
366
  }
344
367
  if (isRetriableLlmErrorCode(code)) {
345
- return { kind: 'retriable', code, message: msg };
368
+ return { kind: 'retriable', code, message: msg, retryStrategy: 'aggressive' };
346
369
  }
347
370
  if (isRetriableLlmMessage(msg)) {
348
- return { kind: 'retriable', code: code ?? causeCode, message: msg };
371
+ return {
372
+ kind: 'retriable',
373
+ code: code ?? causeCode,
374
+ message: msg,
375
+ retryStrategy: 'aggressive',
376
+ };
349
377
  }
350
378
  }
351
379
  return { kind: 'fatal', message: fallbackMessage };
352
380
  }
381
+ function classifyLlmFailure(err, classifyFailure) {
382
+ const providerDisposition = classifyFailure?.(err);
383
+ if (providerDisposition) {
384
+ return normalizeFailureDisposition(err, providerDisposition);
385
+ }
386
+ return classifyGenericLlmFailure(err);
387
+ }
353
388
  async function sleepWithAbort(ms, abortSignal) {
354
389
  if (abortSignal?.aborted) {
355
390
  throw new Error('AbortError');
@@ -373,6 +408,14 @@ function normalizeRetryInitialDelayMs(value) {
373
408
  const normalized = Math.floor(value);
374
409
  return normalized >= 0 ? normalized : 1000;
375
410
  }
411
+ function normalizeRetryConservativeDelayMs(value, fallbackMin) {
412
+ if (!Number.isFinite(value))
413
+ return Math.max(30000, fallbackMin);
414
+ const normalized = Math.floor(value);
415
+ if (normalized < 0)
416
+ return Math.max(30000, fallbackMin);
417
+ return Math.max(fallbackMin, normalized);
418
+ }
376
419
  function normalizeRetryBackoffMultiplier(value) {
377
420
  if (!Number.isFinite(value))
378
421
  return 2;
@@ -399,6 +442,8 @@ function emitLlmRetryEventBestEffort(args) {
399
442
  genseq: Math.floor(rawGenseq),
400
443
  phase: args.phase,
401
444
  provider: args.provider,
445
+ retryStrategy: args.retryStrategy,
446
+ retryForever: args.retryForever,
402
447
  attempt: args.attempt,
403
448
  totalAttempts: args.totalAttempts,
404
449
  maxRetries: args.maxRetries,
@@ -413,23 +458,28 @@ function emitLlmRetryEventBestEffort(args) {
413
458
  }
414
459
  async function runLlmRequestWithRetry(params) {
415
460
  const providerProblemId = `llm/provider_rejected/${params.dlg.id.valueOf()}`;
416
- const totalAttempts = params.maxRetries + 1;
461
+ const aggressiveTotalAttempts = params.maxRetries + 1;
417
462
  const retryInitialDelayMs = normalizeRetryInitialDelayMs(params.retryInitialDelayMs);
463
+ const retryConservativeDelayMs = normalizeRetryConservativeDelayMs(params.retryConservativeDelayMs, retryInitialDelayMs);
418
464
  const retryBackoffMultiplier = normalizeRetryBackoffMultiplier(params.retryBackoffMultiplier);
419
- const retryMaxDelayMs = normalizeRetryMaxDelayMs(params.retryMaxDelayMs, retryInitialDelayMs);
465
+ const retryMaxDelayMs = normalizeRetryMaxDelayMs(params.retryMaxDelayMs, Math.max(retryInitialDelayMs, retryConservativeDelayMs));
420
466
  const retryFlowStartedAtMs = Date.now();
421
467
  let activeRetryContext;
422
- for (let attempt = 0; attempt <= params.maxRetries; attempt++) {
468
+ for (let attempt = 0;; attempt++) {
423
469
  try {
424
470
  if (attempt > 0 && activeRetryContext) {
471
+ const retryStrategy = activeRetryContext.failure.retryStrategy ?? 'aggressive';
472
+ const retryForever = retryStrategy === 'conservative';
425
473
  emitLlmRetryEventBestEffort({
426
474
  dlg: params.dlg,
427
475
  phase: 'running',
428
476
  provider: params.provider,
477
+ retryStrategy,
478
+ retryForever,
429
479
  attempt: attempt + 1,
430
- totalAttempts,
480
+ totalAttempts: retryForever ? 0 : aggressiveTotalAttempts,
431
481
  maxRetries: params.maxRetries,
432
- retriesRemaining: Math.max(0, params.maxRetries - attempt),
482
+ retriesRemaining: retryForever ? undefined : Math.max(0, params.maxRetries - attempt),
433
483
  failure: activeRetryContext.failure,
434
484
  errorText: activeRetryContext.errorText,
435
485
  });
@@ -442,19 +492,24 @@ async function runLlmRequestWithRetry(params) {
442
492
  if (params.abortSignal?.aborted) {
443
493
  throw err;
444
494
  }
445
- const failure = classifyLlmFailure(err);
495
+ const failure = classifyLlmFailure(err, params.classifyFailure);
446
496
  const detail = (0, log_1.extractErrorDetails)(err).message;
447
497
  const errorCode = readErrorCode(err);
448
498
  const cause = readErrorCause(err);
449
499
  const causeCode = readErrorCode(cause);
450
500
  const causeMessage = cause === undefined || cause === null ? undefined : (0, log_1.extractErrorDetails)(cause).message;
451
501
  const attemptNo = attempt + 1;
452
- const retriesRemaining = Math.max(0, params.maxRetries - attempt);
502
+ const retryStrategy = failure.retryStrategy ?? 'aggressive';
503
+ const retryForever = retryStrategy === 'conservative';
504
+ const retriesRemaining = retryForever ? undefined : Math.max(0, params.maxRetries - attempt);
505
+ const totalAttempts = retryForever ? 0 : aggressiveTotalAttempts;
453
506
  log_1.log.warn('LLM request attempt failed', err, {
454
507
  provider: params.provider,
455
508
  dialogId: params.dlg.id.valueOf(),
456
509
  rootId: params.dlg.id.rootId,
457
510
  selfId: params.dlg.id.selfId,
511
+ retryStrategy,
512
+ retryForever,
458
513
  attempt: attemptNo,
459
514
  totalAttempts,
460
515
  retriesRemaining,
@@ -489,17 +544,19 @@ async function runLlmRequestWithRetry(params) {
489
544
  throw new Error(`Provider '${params.provider}' rejected the request: ${failure.message}`);
490
545
  }
491
546
  const canRetry = failure.kind === 'retriable' && params.canRetry();
492
- const isLastAttempt = attempt >= params.maxRetries;
547
+ const isLastAttempt = retryForever ? false : attempt >= params.maxRetries;
493
548
  if (!canRetry || isLastAttempt) {
494
549
  if (params.onGiveUp) {
495
550
  await params.onGiveUp();
496
551
  }
497
552
  if (failure.kind === 'retriable') {
498
- const suggestion = `Consider increasing providers.${params.provider}.llm_retry_max_retries / llm_retry_initial_delay_ms / llm_retry_backoff_multiplier / llm_retry_max_delay_ms in .minds/llm.yaml, and verify provider/network stability.`;
553
+ const suggestion = `Consider adjusting providers.${params.provider}.llm_retry_max_retries / llm_retry_initial_delay_ms / llm_retry_conservative_delay_ms / llm_retry_backoff_multiplier / llm_retry_max_delay_ms in .minds/llm.yaml, and verify provider/network stability.`;
499
554
  emitLlmRetryEventBestEffort({
500
555
  dlg: params.dlg,
501
556
  phase: 'exhausted',
502
557
  provider: params.provider,
558
+ retryStrategy,
559
+ retryForever,
503
560
  attempt: attemptNo,
504
561
  totalAttempts,
505
562
  maxRetries: params.maxRetries,
@@ -513,10 +570,13 @@ async function runLlmRequestWithRetry(params) {
513
570
  dialogId: params.dlg.id.valueOf(),
514
571
  rootId: params.dlg.id.rootId,
515
572
  selfId: params.dlg.id.selfId,
573
+ retryStrategy,
574
+ retryForever,
516
575
  attempt: attemptNo,
517
576
  totalAttempts,
518
577
  maxRetries: params.maxRetries,
519
578
  retryInitialDelayMs,
579
+ retryConservativeDelayMs,
520
580
  retryBackoffMultiplier,
521
581
  retryMaxDelayMs,
522
582
  errorText: detail,
@@ -537,6 +597,7 @@ async function runLlmRequestWithRetry(params) {
537
597
  maxRetries: params.maxRetries,
538
598
  elapsedMs: Date.now() - retryFlowStartedAtMs,
539
599
  retryInitialDelayMs,
600
+ retryConservativeDelayMs,
540
601
  retryBackoffMultiplier,
541
602
  retryMaxDelayMs,
542
603
  errorText: detail,
@@ -545,11 +606,16 @@ async function runLlmRequestWithRetry(params) {
545
606
  }
546
607
  throw new Error(`LLM failed: ${failure.message}`);
547
608
  }
548
- const backoffMs = Math.min(retryMaxDelayMs, Math.max(0, Math.floor(retryInitialDelayMs * retryBackoffMultiplier ** attempt)));
609
+ const conservativeRampAttempt = Math.max(0, Math.floor(attempt / 10));
610
+ const backoffMs = retryStrategy === 'conservative'
611
+ ? Math.min(retryMaxDelayMs, Math.max(0, Math.floor(retryConservativeDelayMs * retryBackoffMultiplier ** conservativeRampAttempt)))
612
+ : Math.min(retryMaxDelayMs, Math.max(0, Math.floor(retryInitialDelayMs * retryBackoffMultiplier ** attempt)));
549
613
  emitLlmRetryEventBestEffort({
550
614
  dlg: params.dlg,
551
615
  phase: 'waiting',
552
616
  provider: params.provider,
617
+ retryStrategy,
618
+ retryForever,
553
619
  attempt: attemptNo,
554
620
  totalAttempts,
555
621
  maxRetries: params.maxRetries,
@@ -564,9 +630,12 @@ async function runLlmRequestWithRetry(params) {
564
630
  };
565
631
  log_1.log.warn(`Retrying LLM request after retriable error`, undefined, {
566
632
  provider: params.provider,
633
+ retryStrategy,
634
+ retryForever,
567
635
  attempt: attemptNo,
568
636
  backoffMs,
569
637
  retryInitialDelayMs,
638
+ retryConservativeDelayMs,
570
639
  retryBackoffMultiplier,
571
640
  retryMaxDelayMs,
572
641
  failure,
@@ -607,11 +676,13 @@ function formatLlmRetryExhaustedInterruptionDetail(args) {
607
676
  `(初始请求 1 次 + 重试 ${args.maxRetries} 次),总耗时 ${durationText}。` +
608
677
  `当前重试配置:llm_retry_max_retries=${args.maxRetries},` +
609
678
  `llm_retry_initial_delay_ms=${args.retryInitialDelayMs},` +
679
+ `llm_retry_conservative_delay_ms=${args.retryConservativeDelayMs},` +
610
680
  `llm_retry_backoff_multiplier=${args.retryBackoffMultiplier},` +
611
681
  `llm_retry_max_delay_ms=${args.retryMaxDelayMs}。` +
612
682
  `若想增加重试次数或拉长重试间隔,请编辑 \`.minds/llm.yaml\` 中的 ` +
613
683
  `\`${providerPath}.llm_retry_max_retries\`、` +
614
684
  `\`${providerPath}.llm_retry_initial_delay_ms\`、` +
685
+ `\`${providerPath}.llm_retry_conservative_delay_ms\`、` +
615
686
  `\`${providerPath}.llm_retry_backoff_multiplier\`、` +
616
687
  `\`${providerPath}.llm_retry_max_delay_ms\`,并检查 provider / network 稳定性。` +
617
688
  `最后错误:${trimmedError}`);
@@ -620,11 +691,13 @@ function formatLlmRetryExhaustedInterruptionDetail(args) {
620
691
  `(1 initial request + ${args.maxRetries} retries), elapsed ${durationText}. ` +
621
692
  `Current retry config: llm_retry_max_retries=${args.maxRetries}, ` +
622
693
  `llm_retry_initial_delay_ms=${args.retryInitialDelayMs}, ` +
694
+ `llm_retry_conservative_delay_ms=${args.retryConservativeDelayMs}, ` +
623
695
  `llm_retry_backoff_multiplier=${args.retryBackoffMultiplier}, ` +
624
696
  `llm_retry_max_delay_ms=${args.retryMaxDelayMs}. ` +
625
697
  `If you want more retries or longer retry intervals, edit ` +
626
698
  `\`.minds/llm.yaml\`: \`${providerPath}.llm_retry_max_retries\`, ` +
627
699
  `\`${providerPath}.llm_retry_initial_delay_ms\`, ` +
700
+ `\`${providerPath}.llm_retry_conservative_delay_ms\`, ` +
628
701
  `\`${providerPath}.llm_retry_backoff_multiplier\`, ` +
629
702
  `\`${providerPath}.llm_retry_max_delay_ms\`, and verify provider/network stability. ` +
630
703
  `Last error: ${trimmedError}`);
@@ -2792,23 +2792,48 @@ exports.DiskFileDialogStore = DiskFileDialogStore;
2792
2792
  */
2793
2793
  class DialogPersistence {
2794
2794
  static async repairInterruptedFunctionCallsOnRestore(args) {
2795
- if (args.status !== 'running') {
2796
- return args.events;
2797
- }
2795
+ const repaired = [];
2798
2796
  const unresolvedById = new Map();
2799
2797
  for (const event of args.events) {
2800
2798
  if (event.type === 'func_call_record') {
2801
2799
  unresolvedById.set(event.id, event);
2800
+ repaired.push(event);
2802
2801
  continue;
2803
2802
  }
2804
2803
  if (event.type === 'func_result_record') {
2805
- unresolvedById.delete(event.id);
2804
+ if (!unresolvedById.has(event.id)) {
2805
+ const repairCall = {
2806
+ ts: event.ts,
2807
+ type: 'func_call_record',
2808
+ genseq: event.genseq,
2809
+ id: event.id,
2810
+ name: event.name,
2811
+ arguments: {},
2812
+ };
2813
+ log_1.log.error('Recovered orphaned persisted func_result_record by synthesizing missing func_call_record during dialog restore', new Error('dialog_restore_recovered_orphaned_func_result'), {
2814
+ rootId: args.dialogId.rootId,
2815
+ selfId: args.dialogId.selfId,
2816
+ course: args.course,
2817
+ genseq: event.genseq,
2818
+ callId: event.id,
2819
+ toolName: event.name,
2820
+ });
2821
+ repaired.push(repairCall);
2822
+ }
2823
+ else {
2824
+ unresolvedById.delete(event.id);
2825
+ }
2826
+ repaired.push(event);
2827
+ continue;
2806
2828
  }
2829
+ repaired.push(event);
2830
+ }
2831
+ if (args.status !== 'running') {
2832
+ return repaired;
2807
2833
  }
2808
2834
  if (unresolvedById.size === 0) {
2809
- return args.events;
2835
+ return repaired;
2810
2836
  }
2811
- const repaired = [...args.events];
2812
2837
  for (const call of unresolvedById.values()) {
2813
2838
  const repairRecord = {
2814
2839
  ts: (0, time_1.formatUnifiedTimestamp)(new Date()),
@@ -24,17 +24,18 @@ exports.formatTellaskCarryoverResultContent = formatTellaskCarryoverResultConten
24
24
  const driver_messages_1 = require("./driver-messages");
25
25
  const markdown_format_1 = require("./markdown-format");
26
26
  const reply_prompt_copy_1 = require("./reply-prompt-copy");
27
+ const tellask_labels_1 = require("./tellask-labels");
27
28
  function getRuntimeTransferMarkers(language) {
28
29
  if (language === 'zh') {
29
30
  return {
30
- tellaskBack: '【回问诉请】',
31
+ tellaskBack: (0, tellask_labels_1.getTellaskKindLabel)({ language, name: 'tellaskBack', bracketed: true }),
31
32
  finalCompleted: '【最终完成】',
32
33
  fbrDirectReply: '【FBR-直接回复】',
33
34
  fbrReasoningOnly: '【FBR-仅推理】',
34
35
  };
35
36
  }
36
37
  return {
37
- tellaskBack: '【TellaskBack】',
38
+ tellaskBack: (0, tellask_labels_1.getTellaskKindLabel)({ language, name: 'tellaskBack', bracketed: true }),
38
39
  finalCompleted: '【Completed】',
39
40
  fbrDirectReply: '【FBR-Direct Reply】',
40
41
  fbrReasoningOnly: '【FBR-Reasoning Only】',
@@ -103,6 +104,14 @@ function stripMentionPrefix(value) {
103
104
  return '';
104
105
  return trimmed.startsWith('@') ? trimmed.slice(1).trim() : trimmed;
105
106
  }
107
+ function formatQuotedRequestBlock(args) {
108
+ const lines = [args.title, ''];
109
+ if (args.mentionLine && args.mentionLine.trim() !== '') {
110
+ lines.push((0, markdown_format_1.markdownQuote)(args.mentionLine));
111
+ }
112
+ lines.push((0, markdown_format_1.markdownQuote)(requireNonEmpty(args.body, 'body')));
113
+ return lines.join('\n');
114
+ }
106
115
  function formatAssignmentFromSupdialog(input) {
107
116
  const language = input.language ?? 'en';
108
117
  const runtimeMarkers = getRuntimeTransferMarkers(language);
@@ -159,12 +168,16 @@ function formatAssignmentFromSupdialog(input) {
159
168
  const sessionSlug = input.sessionSlug?.trim() ?? '';
160
169
  const greeting = language === 'zh'
161
170
  ? sessionSlug === ''
162
- ? '现在:'
163
- : `现在(${sessionSlug}):`
171
+ ? '诉请内容:'
172
+ : `诉请内容(${sessionSlug}):`
164
173
  : sessionSlug === ''
165
- ? 'Now:'
166
- : `Now (${sessionSlug}):`;
167
- return `${roleHeader}\n\n${markerProtocolNote}\n\n${greeting}\n\n${(0, markdown_format_1.markdownQuote)(mentionLine)}\n${(0, markdown_format_1.markdownQuote)(tellaskContent)}\n`;
174
+ ? 'Request:'
175
+ : `Request (${sessionSlug}):`;
176
+ return `${roleHeader}\n\n${markerProtocolNote}\n\n${formatQuotedRequestBlock({
177
+ title: greeting,
178
+ mentionLine,
179
+ body: tellaskContent,
180
+ })}\n`;
168
181
  }
169
182
  function formatUpdatedAssignmentFromSupdialog(input) {
170
183
  const language = input.language ?? 'en';
@@ -182,24 +195,41 @@ function formatSupdialogCallPrompt(input) {
182
195
  const supMention = (() => {
183
196
  if (input.supdialogAssignment.callName === 'tellask' ||
184
197
  input.supdialogAssignment.callName === 'tellaskSessionless') {
185
- return (0, markdown_format_1.markdownQuote)(requireMentionLine(input.supdialogAssignment.mentionList ?? []));
198
+ return requireMentionLine(input.supdialogAssignment.mentionList ?? []);
186
199
  }
187
200
  return '';
188
201
  })();
189
- const hello = language === 'zh'
190
- ? `你好 @${requireNonEmpty(input.toAgentId, 'toAgentId')},在处理 ${supMention} 以下任务期间(如下引文):`
191
- : `Hi @${requireNonEmpty(input.toAgentId, 'toAgentId')}, while working on the following original task of ${supMention} (quoted following):`;
192
- const asking = language === 'zh'
193
- ? `\`@${requireNonEmpty(input.fromAgentId, 'fromAgentId')}\` 回问:`
194
- : `\`@${requireNonEmpty(input.fromAgentId, 'fromAgentId')}\` TellaskBack:`;
202
+ const fromAgentId = requireNonEmpty(input.fromAgentId, 'fromAgentId');
203
+ const toAgentId = requireNonEmpty(input.toAgentId, 'toAgentId');
204
+ const askBackLabel = (0, tellask_labels_1.getTellaskKindLabel)({ language, name: 'tellaskBack', bracketed: true });
195
205
  const subMention = (() => {
196
206
  if (input.subdialogRequest.callName === 'tellask' ||
197
207
  input.subdialogRequest.callName === 'tellaskSessionless') {
198
- return (0, markdown_format_1.markdownQuote)(requireMentionLine(input.subdialogRequest.mentionList ?? []));
208
+ return requireMentionLine(input.subdialogRequest.mentionList ?? []);
199
209
  }
200
210
  return '';
201
211
  })();
202
- return `${hello}\n\n${(0, markdown_format_1.markdownQuote)(requireNonEmpty(input.supdialogAssignment.tellaskContent, 'assignmentTellaskContent'))}\n\n${asking}\n\n${subMention ? `${subMention}\n` : ''}${(0, markdown_format_1.markdownQuote)(requireNonEmpty(input.subdialogRequest.tellaskContent, 'requestTellaskContent'))}\n`;
212
+ const intro = language === 'zh'
213
+ ? `@${fromAgentId} 发来一条 ${askBackLabel} 给 @${toAgentId}。`
214
+ : `@${fromAgentId} sent a ${askBackLabel} to @${toAgentId}.`;
215
+ const originalTitle = language === 'zh' ? '原诉请:' : 'Original request:';
216
+ const askBackTitle = language === 'zh' ? '回问内容:' : 'Ask-back content:';
217
+ return [
218
+ intro,
219
+ '',
220
+ formatQuotedRequestBlock({
221
+ title: originalTitle,
222
+ mentionLine: supMention,
223
+ body: requireNonEmpty(input.supdialogAssignment.tellaskContent, 'assignmentTellaskContent'),
224
+ }),
225
+ '',
226
+ formatQuotedRequestBlock({
227
+ title: askBackTitle,
228
+ mentionLine: subMention,
229
+ body: requireNonEmpty(input.subdialogRequest.tellaskContent, 'requestTellaskContent'),
230
+ }),
231
+ '',
232
+ ].join('\n');
203
233
  }
204
234
  function formatTellaskResponseContent(input) {
205
235
  const language = input.language ?? 'en';
@@ -1,10 +1,16 @@
1
1
  import type { LanguageCode } from '@longrun-ai/kernel/types/language';
2
+ import type { TellaskReplyDirective } from '@longrun-ai/kernel/types/storage';
2
3
  export declare const ACTIVE_REPLY_TOOL_PREFIX_EN = "[Dominds active reply tool]";
3
4
  export declare const ACTIVE_REPLY_TOOL_PREFIX_ZH = "[Dominds \u5F53\u524D\u56DE\u590D\u5DE5\u5177]";
4
5
  export declare const REPLY_REASSERTION_PREFIX_EN = "[Dominds long-line reminder]";
5
6
  export declare const REPLY_REASSERTION_PREFIX_ZH = "[Dominds \u957F\u7EBF\u63D0\u9192]";
6
7
  export declare const REPLY_SUPPRESSION_PREFIX_EN = "[Dominds handle this interjection first]";
7
8
  export declare const REPLY_SUPPRESSION_PREFIX_ZH = "[Dominds \u5148\u63A5\u4F4F\u8FD9\u8F6E]";
9
+ type ReplyObligationCopyArgs = {
10
+ language: LanguageCode;
11
+ directive: TellaskReplyDirective;
12
+ replyTargetAgentId?: string;
13
+ };
8
14
  export declare function buildActiveReplyToolNote(args: {
9
15
  language: LanguageCode;
10
16
  toolName: 'replyTellask' | 'replyTellaskSessionless' | 'replyTellaskBack';
@@ -16,8 +22,12 @@ export declare function buildSubdialogRoleHeaderCopy(args: {
16
22
  expectedReplyTool?: 'replyTellask' | 'replyTellaskSessionless' | 'replyTellaskBack' | undefined;
17
23
  }): string;
18
24
  export declare function buildReplyObligationSuppressionGuideText(language: LanguageCode): string;
19
- export declare function buildReplyObligationReassertionText(args: {
25
+ export declare function buildReplyObligationReassertionText(args: ReplyObligationCopyArgs): string;
26
+ export declare function buildReplyToolReminderText(args: {
20
27
  language: LanguageCode;
21
- toolName: 'replyTellask' | 'replyTellaskSessionless' | 'replyTellaskBack';
28
+ directive: TellaskReplyDirective;
29
+ prefix: string;
30
+ replyTargetAgentId?: string;
22
31
  }): string;
23
32
  export declare function isStandaloneRuntimeGuidePromptContent(content: string): boolean;
33
+ export {};
@@ -6,13 +6,45 @@ exports.buildSidelineCompletionRule = buildSidelineCompletionRule;
6
6
  exports.buildSubdialogRoleHeaderCopy = buildSubdialogRoleHeaderCopy;
7
7
  exports.buildReplyObligationSuppressionGuideText = buildReplyObligationSuppressionGuideText;
8
8
  exports.buildReplyObligationReassertionText = buildReplyObligationReassertionText;
9
+ exports.buildReplyToolReminderText = buildReplyToolReminderText;
9
10
  exports.isStandaloneRuntimeGuidePromptContent = isStandaloneRuntimeGuidePromptContent;
11
+ const tellask_labels_1 = require("./tellask-labels");
10
12
  exports.ACTIVE_REPLY_TOOL_PREFIX_EN = '[Dominds active reply tool]';
11
13
  exports.ACTIVE_REPLY_TOOL_PREFIX_ZH = '[Dominds 当前回复工具]';
12
14
  exports.REPLY_REASSERTION_PREFIX_EN = '[Dominds long-line reminder]';
13
15
  exports.REPLY_REASSERTION_PREFIX_ZH = '[Dominds 长线提醒]';
14
16
  exports.REPLY_SUPPRESSION_PREFIX_EN = '[Dominds handle this interjection first]';
15
17
  exports.REPLY_SUPPRESSION_PREFIX_ZH = '[Dominds 先接住这轮]';
18
+ function formatReplyTargetAgentId(agentId, language) {
19
+ if (agentId && agentId.trim() !== '') {
20
+ return `@${agentId}`;
21
+ }
22
+ return language === 'zh' ? '对方' : 'the other dialog';
23
+ }
24
+ function buildReplyObligationReassertionLine(args) {
25
+ const toolName = args.directive.expectedReplyCallName;
26
+ const replyTarget = formatReplyTargetAgentId(args.replyTargetAgentId, args.language);
27
+ const kindLabel = (0, tellask_labels_1.getTellaskKindLabel)({
28
+ language: args.language,
29
+ name: args.directive.expectedReplyCallName,
30
+ bracketed: true,
31
+ });
32
+ return args.language === 'zh'
33
+ ? `${replyTarget} 的${kindLabel}还在等你的回复。等你准备好回复内容后,调用 \`${toolName}\` 完成回复。这里不是催你立刻回复。`
34
+ : `${replyTarget}'s ${kindLabel} is still waiting for your reply. Once your reply content is ready, call \`${toolName}\` to deliver it. This is not asking you to reply immediately.`;
35
+ }
36
+ function buildReplyToolReminderLine(args) {
37
+ const toolName = args.directive.expectedReplyCallName;
38
+ const replyTarget = formatReplyTargetAgentId(args.replyTargetAgentId, args.language);
39
+ const kindLabel = (0, tellask_labels_1.getTellaskKindLabel)({
40
+ language: args.language,
41
+ name: args.directive.expectedReplyCallName,
42
+ bracketed: true,
43
+ });
44
+ return args.language === 'zh'
45
+ ? `${replyTarget} 的${kindLabel}还在等你的回复。请现在调用 \`${toolName}({ replyContent })\` 完成回复。`
46
+ : `${replyTarget}'s ${kindLabel} is still waiting for your reply. Call \`${toolName}({ replyContent })\` now to deliver it.`;
47
+ }
16
48
  function buildActiveReplyToolNote(args) {
17
49
  if (args.language === 'zh') {
18
50
  return [
@@ -33,14 +65,20 @@ function buildSidelineCompletionRule(language) {
33
65
  : 'If the current sideline is complete and can deliver the final result: stay focused on finishing the actual task first; if runtime names an exact reply function, call that function only at final upstream delivery, do not switch among `reply*` variants, and do not use `tellaskBack` for final delivery.';
34
66
  }
35
67
  function buildSubdialogRoleHeaderCopy(args) {
68
+ const requester = `@${args.requesterId}`;
36
69
  if (args.expectedReplyTool === undefined) {
37
70
  return args.language === 'zh'
38
- ? `你是当前被诉请者对话(tellaskee dialog)的主理人;诉请者对话(tellasker dialog)为 @${args.requesterId}(当前发起本次诉请)。只有在需要回问上游时才调用 \`tellaskBack\`。`
39
- : `You are the responder (tellaskee dialog) for this dialog; the tellasker dialog is @${args.requesterId} (the current caller). Call \`tellaskBack\` only when you need to ask back upstream.`;
71
+ ? `${requester} 的诉请已交给你处理。只有需要回问时,才调用 \`tellaskBack\`。`
72
+ : `You are handling ${requester}'s request. Call \`tellaskBack\` only when you truly need to ask back.`;
40
73
  }
74
+ const kindLabel = (0, tellask_labels_1.getTellaskKindLabel)({
75
+ language: args.language,
76
+ name: args.expectedReplyTool,
77
+ bracketed: true,
78
+ });
41
79
  return args.language === 'zh'
42
- ? `你是当前被诉请者对话(tellaskee dialog)的主理人;诉请者对话(tellasker dialog)为 @${args.requesterId}(当前发起本次诉请)。先把当前任务做对;若本轮最终需要对上游完成交付,必须精确调用 \`${args.expectedReplyTool}\` 收口,不要改选其他 \`reply*\`。只有在需要回问上游时才调用 \`tellaskBack\`。`
43
- : `You are the responder (tellaskee dialog) for this dialog; the tellasker dialog is @${args.requesterId} (the current caller). First, do the current task correctly; if this round ultimately needs final delivery back upstream, you must close with \`${args.expectedReplyTool}\` exactly and must not switch to another \`reply*\` variant. Call \`tellaskBack\` only when you need to ask back upstream.`;
80
+ ? `${requester} 的${kindLabel}已交给你处理。等你准备好回复内容后,调用 \`${args.expectedReplyTool}\` 完成回复。只有需要回问时,才调用 \`tellaskBack\`。`
81
+ : `${requester}'s ${kindLabel} is now assigned to you. Once your reply content is ready, call \`${args.expectedReplyTool}\` to deliver it. Call \`tellaskBack\` only when you truly need to ask back.`;
44
82
  }
45
83
  function buildReplyObligationSuppressionGuideText(language) {
46
84
  if (language === 'zh') {
@@ -59,20 +97,40 @@ function buildReplyObligationSuppressionGuideText(language) {
59
97
  ].join('\n');
60
98
  }
61
99
  function buildReplyObligationReassertionText(args) {
62
- if (args.language === 'zh') {
63
- return [
100
+ return args.language === 'zh'
101
+ ? [
64
102
  exports.REPLY_REASSERTION_PREFIX_ZH,
65
- '刚才那轮用户插话已经先接住了,现在继续原来那条长线任务本身。',
66
- '继续做该做的事,别只盯着 `reply*` 工具名。',
67
- `真走到需要对上游完成交付的时候,再精确调用 \`${args.toolName}\`;这条提醒不是在催你立刻收口。`,
103
+ '',
104
+ '刚才那轮插话已经处理完了,现在继续原来的长线任务。',
105
+ '',
106
+ buildReplyObligationReassertionLine(args),
107
+ ].join('\n')
108
+ : [
109
+ exports.REPLY_REASSERTION_PREFIX_EN,
110
+ '',
111
+ 'The interjection has been handled. Now continue the original longer-running task.',
112
+ '',
113
+ buildReplyObligationReassertionLine(args),
114
+ ].join('\n');
115
+ }
116
+ function buildReplyToolReminderText(args) {
117
+ return args.language === 'zh'
118
+ ? [
119
+ args.prefix,
120
+ '',
121
+ `你刚才已经写了正文,但还没调用 \`${args.directive.expectedReplyCallName}\`。`,
122
+ '',
123
+ buildReplyToolReminderLine(args),
124
+ '如果你再次直接输出最终消息而仍不调用该工具,运行时当前会暂按 direct-reply fallback 投递,并在 UI/传递正文中明确标注。',
125
+ ].join('\n')
126
+ : [
127
+ args.prefix,
128
+ '',
129
+ `You already wrote the reply body, but you still have not called \`${args.directive.expectedReplyCallName}\`.`,
130
+ '',
131
+ buildReplyToolReminderLine(args),
132
+ 'If you still emit a plain final message without the tool, runtime will currently deliver it via direct-reply fallback and label that path explicitly in UI and transfer text.',
68
133
  ].join('\n');
69
- }
70
- return [
71
- exports.REPLY_REASSERTION_PREFIX_EN,
72
- 'The user interjection has already been handled first; now continue the original longer-running task itself.',
73
- 'Keep doing the actual work instead of fixating on the `reply*` tool name.',
74
- `Only when that work truly reaches final delivery upstream should you call \`${args.toolName}\`; this reminder is not asking you to close immediately.`,
75
- ].join('\n');
76
134
  }
77
135
  function isStandaloneRuntimeGuidePromptContent(content) {
78
136
  return (content.startsWith(exports.REPLY_REASSERTION_PREFIX_ZH) ||
@@ -0,0 +1,8 @@
1
+ import type { LanguageCode } from '@longrun-ai/kernel/types/language';
2
+ type TellaskKindName = 'tellaskBack' | 'tellask' | 'tellaskSessionless' | 'freshBootsReasoning' | 'replyTellaskBack' | 'replyTellask' | 'replyTellaskSessionless';
3
+ export declare function getTellaskKindLabel(args: {
4
+ language: LanguageCode;
5
+ name: TellaskKindName;
6
+ bracketed?: boolean;
7
+ }): string;
8
+ export {};