dominds 1.16.1 → 1.16.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 (175) hide show
  1. package/dist/dialog-display-state.d.ts +4 -0
  2. package/dist/dialog-display-state.js +138 -19
  3. package/dist/dialog-fork.js +13 -5
  4. package/dist/dialog-interruption.d.ts +18 -0
  5. package/dist/dialog-interruption.js +34 -0
  6. package/dist/docs/dominds-agent-collaboration.zh.md +401 -0
  7. package/dist/llm/api-quirks.d.ts +11 -0
  8. package/dist/llm/api-quirks.js +322 -24
  9. package/dist/llm/defaults.yaml +2 -1
  10. package/dist/llm/gen/mock.d.ts +1 -1
  11. package/dist/llm/gen/mock.js +12 -0
  12. package/dist/llm/gen/openai-compatible.d.ts +1 -1
  13. package/dist/llm/gen/openai-compatible.js +9 -1
  14. package/dist/llm/gen/openai.d.ts +1 -1
  15. package/dist/llm/gen/openai.js +16 -2
  16. package/dist/llm/gen.d.ts +10 -0
  17. package/dist/llm/gen.js +10 -0
  18. package/dist/llm/kernel-driver/drive.js +994 -866
  19. package/dist/llm/kernel-driver/runtime.d.ts +16 -2
  20. package/dist/llm/kernel-driver/runtime.js +75 -10
  21. package/dist/llm/stop-reason-i18n.d.ts +9 -0
  22. package/dist/llm/stop-reason-i18n.js +114 -0
  23. package/dist/persistence-errors.d.ts +26 -0
  24. package/dist/persistence-errors.js +68 -0
  25. package/dist/persistence.d.ts +119 -82
  26. package/dist/persistence.js +1055 -426
  27. package/dist/server/api-routes.js +174 -58
  28. package/dist/server/websocket-handler.js +125 -21
  29. package/dist/tools/team_mgmt.js +2 -2
  30. package/package.json +3 -3
  31. package/webapp/dist/assets/{_basePickBy-C0MXVhMo.js → _basePickBy-BJWCmtUm.js} +3 -3
  32. package/webapp/dist/assets/_basePickBy-BJWCmtUm.js.map +1 -0
  33. package/webapp/dist/assets/{_baseUniq-CRygl41M.js → _baseUniq-D6k_lGfs.js} +2 -2
  34. package/webapp/dist/assets/_baseUniq-D6k_lGfs.js.map +1 -0
  35. package/webapp/dist/assets/{arc-BeHJtnt2.js → arc-DYDaESgj.js} +2 -2
  36. package/webapp/dist/assets/arc-DYDaESgj.js.map +1 -0
  37. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-CGdo5TVi.js → architectureDiagram-VXUJARFQ-DZMT7dqc.js} +8 -26
  38. package/webapp/dist/assets/architectureDiagram-VXUJARFQ-DZMT7dqc.js.map +1 -0
  39. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-C59VaSGw.js → blockDiagram-VD42YOAC-CABpgVAa.js} +170 -187
  40. package/webapp/dist/assets/blockDiagram-VD42YOAC-CABpgVAa.js.map +1 -0
  41. package/webapp/dist/assets/{c4Diagram-IC4MRINW-B3YCBmTx.js → c4Diagram-YG6GDRKO-COLZS8Ul.js} +4 -4
  42. package/webapp/dist/assets/c4Diagram-YG6GDRKO-COLZS8Ul.js.map +1 -0
  43. package/webapp/dist/assets/{channel-Dn4i8EAY.js → channel-CYFm9Cri.js} +2 -2
  44. package/webapp/dist/assets/channel-CYFm9Cri.js.map +1 -0
  45. package/webapp/dist/assets/{chunk-4BX2VUAB-CQbB3HlW.js → chunk-4BX2VUAB-CX_-XbaN.js} +2 -2
  46. package/webapp/dist/assets/chunk-4BX2VUAB-CX_-XbaN.js.map +1 -0
  47. package/webapp/dist/assets/{chunk-55IACEB6-CkQR_Qu9.js → chunk-55IACEB6-ByD-NdBC.js} +2 -2
  48. package/webapp/dist/assets/chunk-55IACEB6-ByD-NdBC.js.map +1 -0
  49. package/webapp/dist/assets/{chunk-WL4C6EOR-Bjl-j3bf.js → chunk-B4BG7PRW-BANemsDD.js} +121 -171
  50. package/webapp/dist/assets/chunk-B4BG7PRW-BANemsDD.js.map +1 -0
  51. package/webapp/dist/assets/{chunk-NQ4KR5QH-DBxY8LL2.js → chunk-DI55MBZ5-DV7sdJmQ.js} +7 -9
  52. package/webapp/dist/assets/chunk-DI55MBZ5-DV7sdJmQ.js.map +1 -0
  53. package/webapp/dist/assets/{chunk-FMBD7UC4-YSIOuaST.js → chunk-FMBD7UC4-DYGviJnf.js} +2 -2
  54. package/webapp/dist/assets/chunk-FMBD7UC4-DYGviJnf.js.map +1 -0
  55. package/webapp/dist/assets/{chunk-KX2RTZJC-DFiwgnFf.js → chunk-QN33PNHL-B8DWRL9f.js} +2 -2
  56. package/webapp/dist/assets/chunk-QN33PNHL-B8DWRL9f.js.map +1 -0
  57. package/webapp/dist/assets/{chunk-QZHKN3VN-BAdR6lLc.js → chunk-QZHKN3VN-B1aYIzMR.js} +2 -2
  58. package/webapp/dist/assets/chunk-QZHKN3VN-B1aYIzMR.js.map +1 -0
  59. package/webapp/dist/assets/{chunk-JSJVCQXG-CWDLRawz.js → chunk-TZMSLE5B-_HISzxl3.js} +6 -14
  60. package/webapp/dist/assets/chunk-TZMSLE5B-_HISzxl3.js.map +1 -0
  61. package/webapp/dist/assets/{classDiagram-VBA2DB6C-KBeS6WXD.js → classDiagram-2ON5EDUG-CpyYj1Rc.js} +6 -7
  62. package/webapp/dist/assets/classDiagram-2ON5EDUG-CpyYj1Rc.js.map +1 -0
  63. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-KBeS6WXD.js → classDiagram-v2-WZHVMYZB-CpyYj1Rc.js} +6 -7
  64. package/webapp/dist/assets/classDiagram-v2-WZHVMYZB-CpyYj1Rc.js.map +1 -0
  65. package/webapp/dist/assets/{clone-C7-aS2vm.js → clone-B_9AxWIU.js} +2 -2
  66. package/webapp/dist/assets/clone-B_9AxWIU.js.map +1 -0
  67. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-Bo5IsL-5.js → cose-bilkent-S5V4N54A-17ECLfPR.js} +2 -2
  68. package/webapp/dist/assets/cose-bilkent-S5V4N54A-17ECLfPR.js.map +1 -0
  69. package/webapp/dist/assets/cytoscape.esm-Bm8DJGmZ.js.map +1 -1
  70. package/webapp/dist/assets/{dagre-KLK3FWXG-C3FeHj7D.js → dagre-6UL2VRFP-DhRqcF1o.js} +7 -7
  71. package/webapp/dist/assets/dagre-6UL2VRFP-DhRqcF1o.js.map +1 -0
  72. package/webapp/dist/assets/defaultLocale-B2RvLBDe.js.map +1 -1
  73. package/webapp/dist/assets/{diagram-E7M64L7V-0HfiRW0u.js → diagram-PSM6KHXK-lpDT6Wwb.js} +10 -10
  74. package/webapp/dist/assets/diagram-PSM6KHXK-lpDT6Wwb.js.map +1 -0
  75. package/webapp/dist/assets/{diagram-IFDJBPK2-DJwh7SMO.js → diagram-QEK2KX5R-ohxbPpDH.js} +8 -9
  76. package/webapp/dist/assets/diagram-QEK2KX5R-ohxbPpDH.js.map +1 -0
  77. package/webapp/dist/assets/{diagram-P4PSJMXO-Y0RbvUZX.js → diagram-S2PKOQOG-DAFFGfch.js} +8 -8
  78. package/webapp/dist/assets/diagram-S2PKOQOG-DAFFGfch.js.map +1 -0
  79. package/webapp/dist/assets/{erDiagram-INFDFZHY-B183xyLa.js → erDiagram-Q2GNP2WA-BH-7rI43.js} +75 -96
  80. package/webapp/dist/assets/erDiagram-Q2GNP2WA-BH-7rI43.js.map +1 -0
  81. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-C_BR3Y3J.js → flowDiagram-NV44I4VS-CdEjFbz4.js} +81 -98
  82. package/webapp/dist/assets/flowDiagram-NV44I4VS-CdEjFbz4.js.map +1 -0
  83. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-CHLgkuJT.js → ganttDiagram-JELNMOA3-Cju2t-lK.js} +3 -28
  84. package/webapp/dist/assets/ganttDiagram-JELNMOA3-Cju2t-lK.js.map +1 -0
  85. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-D6C_HU1q.js → gitGraphDiagram-V2S2FVAM-CUJ5oxCg.js} +46 -38
  86. package/webapp/dist/assets/gitGraphDiagram-V2S2FVAM-CUJ5oxCg.js.map +1 -0
  87. package/webapp/dist/assets/graph-mhcc7ldf.js +425 -0
  88. package/webapp/dist/assets/graph-mhcc7ldf.js.map +1 -0
  89. package/webapp/dist/assets/{index-CLoNHmSQ.js → index-BLnM-uON.js} +2098 -1841
  90. package/webapp/dist/assets/{index-CLoNHmSQ.js.map → index-BLnM-uON.js.map} +1 -1
  91. package/webapp/dist/assets/{index-YaxF76or.css → index-xvYYeHuy.css} +1 -1
  92. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-mnMS61NO.js → infoDiagram-HS3SLOUP-Df8p0okQ.js} +7 -7
  93. package/webapp/dist/assets/infoDiagram-HS3SLOUP-Df8p0okQ.js.map +1 -0
  94. package/webapp/dist/assets/init-ZxktEp_H.js.map +1 -1
  95. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-BdeERn0r.js → journeyDiagram-XKPGCS4Q-BXMl8H-d.js} +5 -5
  96. package/webapp/dist/assets/journeyDiagram-XKPGCS4Q-BXMl8H-d.js.map +1 -0
  97. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-MLeCGcYg.js → kanban-definition-3W4ZIXB7-Cc5RwCEh.js} +3 -5
  98. package/webapp/dist/assets/kanban-definition-3W4ZIXB7-Cc5RwCEh.js.map +1 -0
  99. package/webapp/dist/assets/{layout-DY9VEQ9M.js → layout-BB2SvQcE.js} +5 -5
  100. package/webapp/dist/assets/layout-BB2SvQcE.js.map +1 -0
  101. package/webapp/dist/assets/{linear-D-T1xRsr.js → linear-Cj50lA0a.js} +2 -2
  102. package/webapp/dist/assets/linear-Cj50lA0a.js.map +1 -0
  103. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-CrVm8vj2.js → mindmap-definition-VGOIOE7T-BLBklJVX.js} +5 -7
  104. package/webapp/dist/assets/mindmap-definition-VGOIOE7T-BLBklJVX.js.map +1 -0
  105. package/webapp/dist/assets/ordinal-CxptdPJm.js.map +1 -1
  106. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-GtLLV0r1.js → pieDiagram-ADFJNKIX-BQrOgSc-.js} +8 -8
  107. package/webapp/dist/assets/pieDiagram-ADFJNKIX-BQrOgSc-.js.map +1 -0
  108. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-BCgk_2LP.js → quadrantDiagram-AYHSOK5B-C62TxtsO.js} +3 -3
  109. package/webapp/dist/assets/quadrantDiagram-AYHSOK5B-C62TxtsO.js.map +1 -0
  110. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-DYUKHWKR.js → requirementDiagram-UZGBJVZJ-Is6Q3osM.js} +6 -16
  111. package/webapp/dist/assets/requirementDiagram-UZGBJVZJ-Is6Q3osM.js.map +1 -0
  112. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-CFAH8OaY.js → sankeyDiagram-TZEHDZUN-CCAW8Dr2.js} +2 -2
  113. package/webapp/dist/assets/sankeyDiagram-TZEHDZUN-CCAW8Dr2.js.map +1 -0
  114. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-BTnhbv6w.js → sequenceDiagram-WL72ISMW-DpODpbl6.js} +201 -601
  115. package/webapp/dist/assets/sequenceDiagram-WL72ISMW-DpODpbl6.js.map +1 -0
  116. package/webapp/dist/assets/{stateDiagram-RAJIS63D-DWUnJTwO.js → stateDiagram-FKZM4ZOC-B8LHaf5T.js} +9 -9
  117. package/webapp/dist/assets/stateDiagram-FKZM4ZOC-B8LHaf5T.js.map +1 -0
  118. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-B-fc52bp.js → stateDiagram-v2-4FDKWEC3-4FzTkpgz.js} +5 -5
  119. package/webapp/dist/assets/stateDiagram-v2-4FDKWEC3-4FzTkpgz.js.map +1 -0
  120. package/webapp/dist/assets/{timeline-definition-YZTLITO2-BMZ52QaG.js → timeline-definition-IT6M3QCI-Ckxc4qZe.js} +3 -3
  121. package/webapp/dist/assets/timeline-definition-IT6M3QCI-Ckxc4qZe.js.map +1 -0
  122. package/webapp/dist/assets/{treemap-KZPCXAKY-fgSrze0S.js → treemap-GDKQZRPO-QQa4vKMv.js} +24 -37
  123. package/webapp/dist/assets/treemap-GDKQZRPO-QQa4vKMv.js.map +1 -0
  124. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-D6aviLtC.js → xychartDiagram-PRI3JC2R-Ba2uJcs6.js} +4 -4
  125. package/webapp/dist/assets/xychartDiagram-PRI3JC2R-Ba2uJcs6.js.map +1 -0
  126. package/webapp/dist/index.html +2 -2
  127. package/webapp/dist/assets/_basePickBy-C0MXVhMo.js.map +0 -1
  128. package/webapp/dist/assets/_baseUniq-CRygl41M.js.map +0 -1
  129. package/webapp/dist/assets/arc-BeHJtnt2.js.map +0 -1
  130. package/webapp/dist/assets/architectureDiagram-2XIMDMQ5-CGdo5TVi.js.map +0 -1
  131. package/webapp/dist/assets/blockDiagram-WCTKOSBZ-C59VaSGw.js.map +0 -1
  132. package/webapp/dist/assets/c4Diagram-IC4MRINW-B3YCBmTx.js.map +0 -1
  133. package/webapp/dist/assets/channel-Dn4i8EAY.js.map +0 -1
  134. package/webapp/dist/assets/chunk-4BX2VUAB-CQbB3HlW.js.map +0 -1
  135. package/webapp/dist/assets/chunk-55IACEB6-CkQR_Qu9.js.map +0 -1
  136. package/webapp/dist/assets/chunk-FMBD7UC4-YSIOuaST.js.map +0 -1
  137. package/webapp/dist/assets/chunk-JSJVCQXG-CWDLRawz.js.map +0 -1
  138. package/webapp/dist/assets/chunk-KX2RTZJC-DFiwgnFf.js.map +0 -1
  139. package/webapp/dist/assets/chunk-NQ4KR5QH-DBxY8LL2.js.map +0 -1
  140. package/webapp/dist/assets/chunk-QZHKN3VN-BAdR6lLc.js.map +0 -1
  141. package/webapp/dist/assets/chunk-WL4C6EOR-Bjl-j3bf.js.map +0 -1
  142. package/webapp/dist/assets/classDiagram-VBA2DB6C-KBeS6WXD.js.map +0 -1
  143. package/webapp/dist/assets/classDiagram-v2-RAHNMMFH-KBeS6WXD.js.map +0 -1
  144. package/webapp/dist/assets/clone-C7-aS2vm.js.map +0 -1
  145. package/webapp/dist/assets/cose-bilkent-S5V4N54A-Bo5IsL-5.js.map +0 -1
  146. package/webapp/dist/assets/dagre-KLK3FWXG-C3FeHj7D.js.map +0 -1
  147. package/webapp/dist/assets/diagram-E7M64L7V-0HfiRW0u.js.map +0 -1
  148. package/webapp/dist/assets/diagram-IFDJBPK2-DJwh7SMO.js.map +0 -1
  149. package/webapp/dist/assets/diagram-P4PSJMXO-Y0RbvUZX.js.map +0 -1
  150. package/webapp/dist/assets/erDiagram-INFDFZHY-B183xyLa.js.map +0 -1
  151. package/webapp/dist/assets/flowDiagram-PKNHOUZH-C_BR3Y3J.js.map +0 -1
  152. package/webapp/dist/assets/ganttDiagram-A5KZAMGK-CHLgkuJT.js.map +0 -1
  153. package/webapp/dist/assets/gitGraphDiagram-K3NZZRJ6-D6C_HU1q.js.map +0 -1
  154. package/webapp/dist/assets/graph-D0hgB-X8.js +0 -782
  155. package/webapp/dist/assets/graph-D0hgB-X8.js.map +0 -1
  156. package/webapp/dist/assets/infoDiagram-LFFYTUFH-mnMS61NO.js.map +0 -1
  157. package/webapp/dist/assets/ishikawaDiagram-PHBUUO56-XFIJsnJj.js +0 -966
  158. package/webapp/dist/assets/ishikawaDiagram-PHBUUO56-XFIJsnJj.js.map +0 -1
  159. package/webapp/dist/assets/journeyDiagram-4ABVD52K-BdeERn0r.js.map +0 -1
  160. package/webapp/dist/assets/kanban-definition-K7BYSVSG-MLeCGcYg.js.map +0 -1
  161. package/webapp/dist/assets/layout-DY9VEQ9M.js.map +0 -1
  162. package/webapp/dist/assets/linear-D-T1xRsr.js.map +0 -1
  163. package/webapp/dist/assets/mindmap-definition-YRQLILUH-CrVm8vj2.js.map +0 -1
  164. package/webapp/dist/assets/pieDiagram-SKSYHLDU-GtLLV0r1.js.map +0 -1
  165. package/webapp/dist/assets/quadrantDiagram-337W2JSQ-BCgk_2LP.js.map +0 -1
  166. package/webapp/dist/assets/requirementDiagram-Z7DCOOCP-DYUKHWKR.js.map +0 -1
  167. package/webapp/dist/assets/sankeyDiagram-WA2Y5GQK-CFAH8OaY.js.map +0 -1
  168. package/webapp/dist/assets/sequenceDiagram-2WXFIKYE-BTnhbv6w.js.map +0 -1
  169. package/webapp/dist/assets/stateDiagram-RAJIS63D-DWUnJTwO.js.map +0 -1
  170. package/webapp/dist/assets/stateDiagram-v2-FVOUBMTO-B-fc52bp.js.map +0 -1
  171. package/webapp/dist/assets/timeline-definition-YZTLITO2-BMZ52QaG.js.map +0 -1
  172. package/webapp/dist/assets/treemap-KZPCXAKY-fgSrze0S.js.map +0 -1
  173. package/webapp/dist/assets/vennDiagram-LZ73GAT5-D5DmDY9l.js +0 -2487
  174. package/webapp/dist/assets/vennDiagram-LZ73GAT5-D5DmDY9l.js.map +0 -1
  175. package/webapp/dist/assets/xychartDiagram-JWTSCODW-D6aviLtC.js.map +0 -1
@@ -2,40 +2,321 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.normalizeProviderApiQuirks = normalizeProviderApiQuirks;
4
4
  exports.createLlmFailureQuirkHandlerSession = createLlmFailureQuirkHandlerSession;
5
+ const persistence_errors_1 = require("../persistence-errors");
5
6
  const DOMINDS_LLM_EMPTY_RESPONSE_ERROR_CODE = 'DOMINDS_LLM_EMPTY_RESPONSE';
6
7
  const XCODE_BEST_EMPTY_RESPONSE_SINGLE_RETRY_DELAY_MS = 3000;
7
8
  const XCODE_BEST_EMPTY_RESPONSE_GIVE_UP_THRESHOLD = 5;
9
+ const XCODE_BEST_GATEWAY_HTML_502_RETRY_MESSAGE = 'xcode.best gateway returned an HTML 502 Bad Gateway page; retrying conservatively.';
10
+ const XCODE_BEST_UNEXPECTED_EOF_RETRY_MESSAGE = 'xcode.best upstream stream ended unexpectedly (unexpected EOF); retrying conservatively.';
11
+ const LOCAL_FILE_IO_ERROR_CODES = new Set(['ENOENT', 'ENOTDIR', 'EISDIR', 'EACCES', 'EPERM']);
12
+ const LOCAL_FILE_IO_SYSCALLS = new Set([
13
+ 'open',
14
+ 'read',
15
+ 'write',
16
+ 'close',
17
+ 'stat',
18
+ 'lstat',
19
+ 'fstat',
20
+ 'rename',
21
+ 'truncate',
22
+ 'mkdir',
23
+ 'readdir',
24
+ ]);
25
+ function isXcodeBestGatewayHtml502Failure(failure, error) {
26
+ const status = failure.status ?? readErrorStatus(error);
27
+ if (status !== 502) {
28
+ return false;
29
+ }
30
+ const message = readErrorMessage(error) ?? failure.message;
31
+ const lowerMessage = message.toLowerCase();
32
+ if (!lowerMessage.includes('bad gateway')) {
33
+ return false;
34
+ }
35
+ if (lowerMessage.includes('<!doctype html')) {
36
+ return true;
37
+ }
38
+ return lowerMessage.includes('<html') || lowerMessage.includes('cloudflare');
39
+ }
40
+ function isXcodeBestUnexpectedEofFailure(failure, error) {
41
+ return ((errorChainIncludesMessageFragment(error, 'unexpected eof') ||
42
+ failure.message.toLowerCase().includes('unexpected eof')) &&
43
+ !hasLikelyLocalFileErrorContext(error));
44
+ }
45
+ function getErrorChain(error) {
46
+ const queue = [error];
47
+ const visited = new Set();
48
+ const chain = [];
49
+ while (queue.length > 0) {
50
+ const current = queue.shift();
51
+ if (current === undefined) {
52
+ continue;
53
+ }
54
+ if (typeof current === 'object' && current !== null) {
55
+ if (visited.has(current)) {
56
+ continue;
57
+ }
58
+ visited.add(current);
59
+ }
60
+ chain.push(current);
61
+ const nestedError = readNestedError(current);
62
+ if (nestedError !== undefined) {
63
+ queue.push(nestedError);
64
+ }
65
+ const cause = readErrorCause(current);
66
+ if (cause !== undefined) {
67
+ queue.push(cause);
68
+ }
69
+ }
70
+ return chain;
71
+ }
72
+ function readErrorStatus(error) {
73
+ for (const current of getErrorChain(error)) {
74
+ if (isRecord(current)) {
75
+ if ('status' in current && typeof current.status === 'number') {
76
+ return current.status;
77
+ }
78
+ if ('statusCode' in current && typeof current.statusCode === 'number') {
79
+ return current.statusCode;
80
+ }
81
+ }
82
+ }
83
+ return undefined;
84
+ }
85
+ function readErrorCause(error) {
86
+ if (error instanceof Error) {
87
+ const withCause = error;
88
+ return withCause.cause;
89
+ }
90
+ if (isRecord(error) && 'cause' in error) {
91
+ return error.cause;
92
+ }
93
+ return undefined;
94
+ }
95
+ function readNestedError(error) {
96
+ if (isRecord(error) && 'error' in error && isRecord(error.error)) {
97
+ return error.error;
98
+ }
99
+ return undefined;
100
+ }
101
+ function readErrorPath(error) {
102
+ for (const current of getErrorChain(error)) {
103
+ if (current instanceof Error) {
104
+ const withPath = current;
105
+ if (typeof withPath.path === 'string' && withPath.path.trim() !== '') {
106
+ return withPath.path;
107
+ }
108
+ }
109
+ if (isRecord(current)) {
110
+ if ('path' in current && typeof current.path === 'string' && current.path.trim() !== '') {
111
+ return current.path;
112
+ }
113
+ }
114
+ }
115
+ return undefined;
116
+ }
117
+ function readErrorSyscall(error) {
118
+ for (const current of getErrorChain(error)) {
119
+ if (current instanceof Error) {
120
+ const withSyscall = current;
121
+ if (typeof withSyscall.syscall === 'string' && withSyscall.syscall.trim() !== '') {
122
+ return withSyscall.syscall;
123
+ }
124
+ }
125
+ if (isRecord(current)) {
126
+ if ('syscall' in current &&
127
+ typeof current.syscall === 'string' &&
128
+ current.syscall.trim() !== '') {
129
+ return current.syscall;
130
+ }
131
+ }
132
+ }
133
+ return undefined;
134
+ }
135
+ function readErrorMessage(error) {
136
+ for (const current of getErrorChain(error)) {
137
+ if (current instanceof Error) {
138
+ const trimmed = current.message.trim();
139
+ if (trimmed.length > 0) {
140
+ return trimmed;
141
+ }
142
+ if (current.name.trim().length > 0) {
143
+ return current.name;
144
+ }
145
+ }
146
+ if (typeof current === 'string') {
147
+ const trimmed = current.trim();
148
+ if (trimmed.length > 0) {
149
+ return trimmed;
150
+ }
151
+ }
152
+ if (isRecord(current)) {
153
+ if ('message' in current && typeof current.message === 'string') {
154
+ const trimmed = current.message.trim();
155
+ if (trimmed.length > 0) {
156
+ return trimmed;
157
+ }
158
+ }
159
+ }
160
+ }
161
+ return undefined;
162
+ }
163
+ function errorChainIncludesMessageFragment(error, fragment) {
164
+ const lowerFragment = fragment.toLowerCase();
165
+ for (const current of getErrorChain(error)) {
166
+ if (current instanceof Error) {
167
+ if (current.message.toLowerCase().includes(lowerFragment)) {
168
+ return true;
169
+ }
170
+ continue;
171
+ }
172
+ if (typeof current === 'string') {
173
+ if (current.toLowerCase().includes(lowerFragment)) {
174
+ return true;
175
+ }
176
+ continue;
177
+ }
178
+ if (isRecord(current) && 'message' in current && typeof current.message === 'string') {
179
+ if (current.message.toLowerCase().includes(lowerFragment)) {
180
+ return true;
181
+ }
182
+ }
183
+ }
184
+ return false;
185
+ }
186
+ function isRecord(value) {
187
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
188
+ }
189
+ function hasLikelyLocalFileErrorContext(error) {
190
+ const persistenceFileError = (0, persistence_errors_1.findDomindsPersistenceFileError)(error);
191
+ if (persistenceFileError) {
192
+ return true;
193
+ }
194
+ const pathValue = readErrorPath(error);
195
+ const syscall = readErrorSyscall(error);
196
+ if (typeof syscall === 'string' && LOCAL_FILE_IO_SYSCALLS.has(syscall)) {
197
+ return true;
198
+ }
199
+ const code = readErrorCode(error);
200
+ if (typeof code === 'string' &&
201
+ LOCAL_FILE_IO_ERROR_CODES.has(code) &&
202
+ isLikelyDomindsFilePath(pathValue)) {
203
+ return true;
204
+ }
205
+ if (isLikelyDomindsFilePath(pathValue)) {
206
+ return true;
207
+ }
208
+ return false;
209
+ }
210
+ function isLikelyDomindsFilePath(filePath) {
211
+ if (typeof filePath !== 'string') {
212
+ return false;
213
+ }
214
+ const normalized = filePath.split('\\').join('/').trim().toLowerCase();
215
+ if (normalized === '') {
216
+ return false;
217
+ }
218
+ return (normalized.includes('/.dialogs/') ||
219
+ normalized.includes('/.minds/') ||
220
+ normalized.endsWith('/latest.yaml') ||
221
+ normalized.endsWith('/dialog.yaml') ||
222
+ normalized.endsWith('/q4h.yaml') ||
223
+ normalized.endsWith('.jsonl'));
224
+ }
225
+ function readErrorCode(error) {
226
+ for (const current of getErrorChain(error)) {
227
+ if (current instanceof Error) {
228
+ const withCode = current;
229
+ if (typeof withCode.code === 'string' && withCode.code.trim() !== '') {
230
+ return withCode.code;
231
+ }
232
+ if (typeof withCode.errno === 'string' && withCode.errno.trim() !== '') {
233
+ return withCode.errno;
234
+ }
235
+ }
236
+ if (isRecord(current)) {
237
+ if ('code' in current && typeof current.code === 'string' && current.code.trim() !== '') {
238
+ return current.code;
239
+ }
240
+ if ('errno' in current && typeof current.errno === 'string' && current.errno.trim() !== '') {
241
+ return current.errno;
242
+ }
243
+ }
244
+ }
245
+ return undefined;
246
+ }
247
+ function buildXcodeBestEmptyResponseGiveUpText(providerConfig, provider) {
248
+ const providerName = providerConfig.name.trim().length > 0 ? providerConfig.name : provider;
249
+ const summaryTextI18n = {
250
+ zh: `${providerName} 在同一对话上下文中连续返回 empty response。` +
251
+ `Dominds 已在 ${String(XCODE_BEST_EMPTY_RESPONSE_GIVE_UP_THRESHOLD)} 次 empty response 后停止继续重试,因为这通常表示 provider 侧该对话上下文已经卡住;` +
252
+ '如果直接点继续,大概率仍然无真实进展;更建议结合真实情况灵活尝试多种新的指令,例如改写问题、补充上下文、换一个切入方式。',
253
+ en: `${providerName} returned empty responses repeatedly for the same dialog context. ` +
254
+ `Dominds stopped retrying after ${String(XCODE_BEST_EMPTY_RESPONSE_GIVE_UP_THRESHOLD)} empty responses because this usually means the provider-side conversation ` +
255
+ 'context is stuck; simply pressing Continue is still unlikely to make real progress, ' +
256
+ 'so it is better to try different fresh instructions based on the real situation, such as reframing the ask, adding context, or changing the angle.',
257
+ };
258
+ return {
259
+ providerName,
260
+ summaryTextI18n,
261
+ recoveryAction: { kind: 'diligence_push_once' },
262
+ };
263
+ }
8
264
  function createXcodeBestFailureQuirkHandlerSession(providerConfig) {
9
265
  let consecutiveEmptyResponseCount = 0;
266
+ let consumedDiligencePushRecoverySinceLastSuccess = false;
10
267
  return {
268
+ quirkName: 'xcode.best',
11
269
  onFailure(args) {
12
- if (args.failure.code !== DOMINDS_LLM_EMPTY_RESPONSE_ERROR_CODE) {
13
- consecutiveEmptyResponseCount = 0;
14
- return { kind: 'default' };
270
+ const { providerName, summaryTextI18n, recoveryAction } = buildXcodeBestEmptyResponseGiveUpText(providerConfig, args.provider);
271
+ if (args.failure.code === DOMINDS_LLM_EMPTY_RESPONSE_ERROR_CODE) {
272
+ consecutiveEmptyResponseCount += 1;
273
+ if (consecutiveEmptyResponseCount < XCODE_BEST_EMPTY_RESPONSE_GIVE_UP_THRESHOLD) {
274
+ return {
275
+ kind: 'single_retry',
276
+ delayMs: XCODE_BEST_EMPTY_RESPONSE_SINGLE_RETRY_DELAY_MS,
277
+ };
278
+ }
279
+ return {
280
+ kind: 'give_up',
281
+ message: `${providerName} returned empty responses repeatedly for the same dialog context; ` +
282
+ 'automatic retries were stopped; simply continuing is still unlikely to make real progress, so it is better to flexibly try different fresh instructions based on the real situation.',
283
+ summaryTextI18n,
284
+ recoveryAction: consumedDiligencePushRecoverySinceLastSuccess
285
+ ? { kind: 'none' }
286
+ : recoveryAction,
287
+ };
15
288
  }
16
- consecutiveEmptyResponseCount += 1;
17
- if (consecutiveEmptyResponseCount < XCODE_BEST_EMPTY_RESPONSE_GIVE_UP_THRESHOLD) {
289
+ consecutiveEmptyResponseCount = 0;
290
+ if (isXcodeBestUnexpectedEofFailure(args.failure, args.error)) {
18
291
  return {
19
- kind: 'single_retry',
20
- delayMs: XCODE_BEST_EMPTY_RESPONSE_SINGLE_RETRY_DELAY_MS,
292
+ kind: 'retry_strategy',
293
+ retryStrategy: 'conservative',
294
+ message: XCODE_BEST_UNEXPECTED_EOF_RETRY_MESSAGE,
21
295
  };
22
296
  }
23
- const providerName = providerConfig.name.trim().length > 0 ? providerConfig.name : args.provider;
24
- const summaryTextI18n = {
25
- zh: `${providerName} 在同一对话上下文中连续返回 empty response。` +
26
- `Dominds 已在 ${String(XCODE_BEST_EMPTY_RESPONSE_GIVE_UP_THRESHOLD)} 次 empty response 后停止继续重试,因为这通常表示 provider 侧该对话上下文已经卡住;` +
27
- '继续调整常规重试策略也无助于恢复。请新开对话继续。',
28
- en: `${providerName} returned empty responses repeatedly for the same dialog context. ` +
29
- `Dominds stopped retrying after ${String(XCODE_BEST_EMPTY_RESPONSE_GIVE_UP_THRESHOLD)} empty responses because this usually means the provider-side conversation ` +
30
- 'context is stuck; adjusting the normal retry policies will not recover it. ' +
31
- 'Start a new dialog to continue.',
32
- };
33
- return {
34
- kind: 'give_up',
35
- message: `${providerName} returned empty responses repeatedly for the same dialog context; ` +
36
- 'automatic retries will not help until a new dialog is started.',
37
- summaryTextI18n,
38
- };
297
+ if (isXcodeBestGatewayHtml502Failure(args.failure, args.error)) {
298
+ return {
299
+ kind: 'retry_strategy',
300
+ retryStrategy: 'conservative',
301
+ message: XCODE_BEST_GATEWAY_HTML_502_RETRY_MESSAGE,
302
+ };
303
+ }
304
+ return { kind: 'default' };
305
+ },
306
+ onRequestSucceeded() {
307
+ consecutiveEmptyResponseCount = 0;
308
+ consumedDiligencePushRecoverySinceLastSuccess = false;
309
+ },
310
+ onRecoveryActionUsed(usage) {
311
+ if (usage.action.kind !== 'diligence_push_once') {
312
+ return;
313
+ }
314
+ // This state intentionally spans multiple request invocations in the same driver run, even if
315
+ // the dialog opens a new course in between; provider/API retry heuristics are treated as
316
+ // independent from course boundaries. Once the driver accepts and reserves this automatic
317
+ // recovery path for the current stop decision, consider it consumed immediately.
318
+ consecutiveEmptyResponseCount = 0;
319
+ consumedDiligencePushRecoverySinceLastSuccess = true;
39
320
  },
40
321
  };
41
322
  }
@@ -69,14 +350,31 @@ function createLlmFailureQuirkHandlerSession(providerConfig) {
69
350
  return undefined;
70
351
  }
71
352
  return {
353
+ quirkName: 'aggregate',
72
354
  onFailure(args) {
73
355
  for (const session of sessions) {
74
356
  const handling = session.onFailure(args);
75
357
  if (handling.kind !== 'default') {
76
- return handling;
358
+ return {
359
+ ...handling,
360
+ sourceQuirk: handling.sourceQuirk ?? session.quirkName,
361
+ };
77
362
  }
78
363
  }
79
364
  return { kind: 'default' };
80
365
  },
366
+ onRequestSucceeded() {
367
+ for (const session of sessions) {
368
+ session.onRequestSucceeded?.();
369
+ }
370
+ },
371
+ onRecoveryActionUsed(usage) {
372
+ for (const session of sessions) {
373
+ if (usage.sourceQuirk !== undefined && usage.sourceQuirk !== session.quirkName) {
374
+ continue;
375
+ }
376
+ session.onRecoveryActionUsed?.(usage);
377
+ }
378
+ },
81
379
  };
82
380
  }
@@ -7,7 +7,8 @@
7
7
  # - apiQuirks: optional provider/gateway quirk profile(s) for non-standard transport behavior
8
8
  # and provider-specific failure handling that can override the driver's default retry disposition.
9
9
  # Example: `apiQuirks: xcode.best` currently covers both keepalive/heartbeat stream quirks and
10
- # repeated empty-response handling for the same dialog context.
10
+ # repeated empty-response handling for the same dialog context, plus conservative retry
11
+ # classification for gateway-returned HTML 502 Bad Gateway pages.
11
12
  # - tool_result_max_chars: optional transport-level cap for a single tool-result text payload
12
13
  # before Dominds projects it into the provider request. Use this when a provider/gateway enforces
13
14
  # a stricter per-item string limit than Dominds' built-in defaults.
@@ -56,7 +56,7 @@
56
56
  import type { Team } from '../../team';
57
57
  import type { FuncTool } from '../../tool';
58
58
  import type { ChatMessage, ProviderConfig } from '../client';
59
- import type { LlmBatchResult, LlmGenerator, LlmRequestContext, LlmStreamReceiver, LlmStreamResult } from '../gen';
59
+ import { type LlmBatchResult, type LlmGenerator, type LlmRequestContext, type LlmStreamReceiver, type LlmStreamResult } from '../gen';
60
60
  export declare class MockGen implements LlmGenerator {
61
61
  get apiType(): string;
62
62
  private databaseCache;
@@ -64,6 +64,8 @@ const path_1 = __importDefault(require("path"));
64
64
  const yaml_1 = __importDefault(require("yaml"));
65
65
  const log_1 = require("../../log");
66
66
  const reply_prompt_copy_1 = require("../../runtime/reply-prompt-copy");
67
+ const gen_1 = require("../gen");
68
+ const stop_reason_i18n_1 = require("../stop-reason-i18n");
67
69
  const REPLY_TOOL_REMINDER_PREFIXES = [
68
70
  '[Dominds replyTellask required]',
69
71
  '[Dominds 必须调用回复工具]',
@@ -376,6 +378,16 @@ responses:
376
378
  await receiver.thinkingChunk(content.substring(0, 50) || '(empty)');
377
379
  await receiver.thinkingFinish();
378
380
  if (matched?.streamError) {
381
+ if (matched.emitStreamErrorBeforeThrow && receiver.streamError) {
382
+ await receiver.streamError(matched.streamError);
383
+ throw new gen_1.LlmStreamErrorEmittedError({
384
+ detail: matched.streamError,
385
+ i18nStopReason: (0, stop_reason_i18n_1.buildHumanSystemStopReasonTextI18n)({
386
+ detail: matched.streamError,
387
+ fallbackKind: 'request_failed',
388
+ }),
389
+ });
390
+ }
379
391
  throw new Error(matched.streamError);
380
392
  }
381
393
  const responseText = matched?.response ?? this.makeFallbackResponse(dbPath, content, role, modelName);
@@ -14,7 +14,7 @@ import type { ChatCompletionMessageParam } from 'openai/resources/chat/completio
14
14
  import type { Team } from '../../team';
15
15
  import type { FuncTool } from '../../tool';
16
16
  import type { ChatMessage, ProviderConfig } from '../client';
17
- import type { LlmBatchResult, LlmFailureDisposition, LlmGenerator, LlmRequestContext, LlmStreamReceiver, LlmStreamResult } from '../gen';
17
+ import { type LlmBatchResult, type LlmFailureDisposition, type LlmGenerator, type LlmRequestContext, type LlmStreamReceiver, type LlmStreamResult } from '../gen';
18
18
  export declare function buildOpenAiCompatibleRequestMessagesWrapper(systemPrompt: string, context: ChatMessage[], options?: {
19
19
  reasoningContentMode?: boolean;
20
20
  providerConfig?: ProviderConfig;
@@ -21,6 +21,8 @@ const openai_1 = __importDefault(require("openai"));
21
21
  const log_1 = require("../../log");
22
22
  const i18n_text_1 = require("../../runtime/i18n-text");
23
23
  const work_language_1 = require("../../runtime/work-language");
24
+ const gen_1 = require("../gen");
25
+ const stop_reason_i18n_1 = require("../stop-reason-i18n");
24
26
  const artifacts_1 = require("./artifacts");
25
27
  const failure_classifier_1 = require("./failure-classifier");
26
28
  const tool_call_context_1 = require("./tool-call-context");
@@ -624,7 +626,13 @@ class OpenAiCompatibleGen {
624
626
  if (receiver.streamError) {
625
627
  await receiver.streamError(detail);
626
628
  }
627
- throw new Error(detail);
629
+ throw new gen_1.LlmStreamErrorEmittedError({
630
+ detail,
631
+ i18nStopReason: (0, stop_reason_i18n_1.buildHumanSystemStopReasonTextI18n)({
632
+ detail,
633
+ kind: 'invalid_tool_call',
634
+ }),
635
+ });
628
636
  }
629
637
  const index = rawIndex;
630
638
  const existing = activeCallsByIndex.get(index);
@@ -9,7 +9,7 @@ import type { ResponseInputItem } from 'openai/resources/responses/responses';
9
9
  import type { Team } from '../../team';
10
10
  import type { FuncTool } from '../../tool';
11
11
  import type { ChatMessage, ProviderConfig } from '../client';
12
- import type { LlmBatchResult, LlmFailureDisposition, LlmGenerator, LlmRequestContext, LlmStreamReceiver, LlmStreamResult } from '../gen';
12
+ import { type LlmBatchResult, type LlmFailureDisposition, type LlmGenerator, type LlmRequestContext, type LlmStreamReceiver, type LlmStreamResult } from '../gen';
13
13
  export declare function buildOpenAiRequestInputWrapper(context: ChatMessage[], providerConfig?: ProviderConfig): Promise<ResponseInputItem[]>;
14
14
  export declare class OpenAiGen implements LlmGenerator {
15
15
  get apiType(): string;
@@ -17,6 +17,8 @@ const log_1 = require("../../log");
17
17
  const i18n_text_1 = require("../../runtime/i18n-text");
18
18
  const work_language_1 = require("../../runtime/work-language");
19
19
  const api_quirks_1 = require("../api-quirks");
20
+ const gen_1 = require("../gen");
21
+ const stop_reason_i18n_1 = require("../stop-reason-i18n");
20
22
  const artifacts_1 = require("./artifacts");
21
23
  const failure_classifier_1 = require("./failure-classifier");
22
24
  const tool_call_context_1 = require("./tool-call-context");
@@ -502,7 +504,13 @@ async function throwOpenAiMalformedStreamEvent(receiver, eventType, detail) {
502
504
  if (receiver.streamError) {
503
505
  await receiver.streamError(message);
504
506
  }
505
- throw new Error(message);
507
+ throw new gen_1.LlmStreamErrorEmittedError({
508
+ detail: message,
509
+ i18nStopReason: (0, stop_reason_i18n_1.buildHumanSystemStopReasonTextI18n)({
510
+ detail: message,
511
+ kind: 'malformed_stream',
512
+ }),
513
+ });
506
514
  }
507
515
  function buildOpenAiNativeToolCallFromState(state, phase) {
508
516
  if (state.itemType === 'custom_tool_call') {
@@ -1701,7 +1709,13 @@ class OpenAiGen {
1701
1709
  if (receiver.streamError) {
1702
1710
  await receiver.streamError(detail);
1703
1711
  }
1704
- throw new Error(detail);
1712
+ throw new gen_1.LlmStreamErrorEmittedError({
1713
+ detail,
1714
+ i18nStopReason: (0, stop_reason_i18n_1.buildHumanSystemStopReasonTextI18n)({
1715
+ detail,
1716
+ kind: 'incomplete_tool_call_stream',
1717
+ }),
1718
+ });
1705
1719
  }
1706
1720
  }
1707
1721
  catch (error) {
package/dist/llm/gen.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { LlmUsageStats } from '@longrun-ai/kernel/types/context-health';
2
+ import type { DialogDisplayTextI18n } from '@longrun-ai/kernel/types/display-state';
2
3
  import type { ReasoningPayload } from '@longrun-ai/kernel/types/storage';
3
4
  import { Team } from '../team';
4
5
  import { FuncTool } from '../tool';
@@ -7,6 +8,15 @@ export interface LlmStreamResult {
7
8
  usage: LlmUsageStats;
8
9
  llmGenModel?: string;
9
10
  }
11
+ export declare class LlmStreamErrorEmittedError extends Error {
12
+ readonly detail: string;
13
+ readonly i18nStopReason: DialogDisplayTextI18n;
14
+ constructor(args: {
15
+ detail: string;
16
+ message?: string;
17
+ i18nStopReason: DialogDisplayTextI18n;
18
+ });
19
+ }
10
20
  export type LlmBatchOutput = {
11
21
  kind: 'message';
12
22
  message: ChatMessage;
package/dist/llm/gen.js CHANGED
@@ -1,2 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LlmStreamErrorEmittedError = void 0;
4
+ class LlmStreamErrorEmittedError extends Error {
5
+ constructor(args) {
6
+ super(args.message ?? args.detail);
7
+ this.name = 'LlmStreamErrorEmittedError';
8
+ this.detail = args.detail;
9
+ this.i18nStopReason = args.i18nStopReason;
10
+ }
11
+ }
12
+ exports.LlmStreamErrorEmittedError = LlmStreamErrorEmittedError;