dominds 1.17.4 → 1.17.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. package/dist/apps/runtime.d.ts +24 -0
  2. package/dist/apps/runtime.js +50 -8
  3. package/dist/dialog.d.ts +7 -2
  4. package/dist/dialog.js +32 -10
  5. package/dist/docs/app-constitution.md +18 -1
  6. package/dist/docs/app-constitution.zh.md +9 -1
  7. package/dist/docs/dialog-system.md +6 -5
  8. package/dist/docs/dialog-system.zh.md +2 -1
  9. package/dist/docs/diligence-push.md +20 -9
  10. package/dist/docs/diligence-push.zh.md +14 -6
  11. package/dist/docs/fbr.md +1 -1
  12. package/dist/docs/fbr.zh.md +1 -1
  13. package/dist/docs/mcp-support.md +10 -6
  14. package/dist/docs/mcp-support.zh.md +10 -6
  15. package/dist/docs/tellask-collab.md +6 -6
  16. package/dist/docs/tellask-collab.zh.md +2 -2
  17. package/dist/docs/tool-availability-protocol.md +255 -0
  18. package/dist/llm/kernel-driver/drive.js +17 -16
  19. package/dist/llm/kernel-driver/subdialog.js +14 -2
  20. package/dist/llm/kernel-driver/tellask-special.js +84 -22
  21. package/dist/mcp/supervisor.d.ts +4 -0
  22. package/dist/mcp/supervisor.js +38 -0
  23. package/dist/minds/system-prompt.js +6 -6
  24. package/dist/persistence.js +266 -49
  25. package/dist/priming.js +7 -4
  26. package/dist/server/api-routes.js +122 -73
  27. package/dist/server/static-server.js +2 -2
  28. package/dist/server/websocket-handler.js +4 -0
  29. package/dist/team-config-updates.js +3 -0
  30. package/dist/tool-availability-updates.d.ts +9 -0
  31. package/dist/tool-availability-updates.js +62 -0
  32. package/dist/tool-availability.d.ts +8 -0
  33. package/dist/tool-availability.js +276 -0
  34. package/dist/tool.js +2 -11
  35. package/dist/tools/mcp.js +12 -10
  36. package/dist/tools/prompts/mcp_admin/en/principles.md +4 -4
  37. package/dist/tools/prompts/mcp_admin/en/tools.md +1 -1
  38. package/dist/tools/prompts/mcp_admin/zh/principles.md +4 -4
  39. package/dist/tools/prompts/mcp_admin/zh/tools.md +1 -1
  40. package/dist/tools/team_mgmt-manual.js +2 -2
  41. package/dist/tools/team_mgmt-mcp-manual.js +2 -2
  42. package/package.json +3 -3
  43. package/webapp/dist/assets/{_basePickBy-CgM-M_q8.js → _basePickBy-CdAKD4rj.js} +3 -3
  44. package/webapp/dist/assets/_basePickBy-CdAKD4rj.js.map +1 -0
  45. package/webapp/dist/assets/{_baseUniq-B06twih4.js → _baseUniq-_dXSeigA.js} +2 -2
  46. package/webapp/dist/assets/_baseUniq-_dXSeigA.js.map +1 -0
  47. package/webapp/dist/assets/{arc-CoXJvjeB.js → arc-DNnfKGXe.js} +2 -2
  48. package/webapp/dist/assets/arc-DNnfKGXe.js.map +1 -0
  49. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-BLFRWTKn.js → architectureDiagram-VXUJARFQ-400MthuC.js} +8 -26
  50. package/webapp/dist/assets/architectureDiagram-VXUJARFQ-400MthuC.js.map +1 -0
  51. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-CYRE6deu.js → blockDiagram-VD42YOAC-UjvoDLu0.js} +170 -187
  52. package/webapp/dist/assets/blockDiagram-VD42YOAC-UjvoDLu0.js.map +1 -0
  53. package/webapp/dist/assets/{c4Diagram-IC4MRINW-B26QTIJt.js → c4Diagram-YG6GDRKO-BUPEBKuT.js} +4 -4
  54. package/webapp/dist/assets/c4Diagram-YG6GDRKO-BUPEBKuT.js.map +1 -0
  55. package/webapp/dist/assets/{channel-C5U2W0P9.js → channel-Bc-dSNjB.js} +2 -2
  56. package/webapp/dist/assets/channel-Bc-dSNjB.js.map +1 -0
  57. package/webapp/dist/assets/{chunk-4BX2VUAB-7z2PgnSv.js → chunk-4BX2VUAB-D0CwOvuG.js} +2 -2
  58. package/webapp/dist/assets/chunk-4BX2VUAB-D0CwOvuG.js.map +1 -0
  59. package/webapp/dist/assets/{chunk-55IACEB6-6sRVmXqs.js → chunk-55IACEB6-_z-JPBKr.js} +2 -2
  60. package/webapp/dist/assets/chunk-55IACEB6-_z-JPBKr.js.map +1 -0
  61. package/webapp/dist/assets/{chunk-WL4C6EOR-DkpfoQzK.js → chunk-B4BG7PRW-D4q30SD5.js} +121 -171
  62. package/webapp/dist/assets/chunk-B4BG7PRW-D4q30SD5.js.map +1 -0
  63. package/webapp/dist/assets/{chunk-NQ4KR5QH-3cQSOzCt.js → chunk-DI55MBZ5-c4c0VIRJ.js} +7 -9
  64. package/webapp/dist/assets/chunk-DI55MBZ5-c4c0VIRJ.js.map +1 -0
  65. package/webapp/dist/assets/{chunk-FMBD7UC4-BwYp8OtY.js → chunk-FMBD7UC4-BZJ6MV7q.js} +2 -2
  66. package/webapp/dist/assets/chunk-FMBD7UC4-BZJ6MV7q.js.map +1 -0
  67. package/webapp/dist/assets/{chunk-KX2RTZJC-CzFE355P.js → chunk-QN33PNHL-Dt5_zoWx.js} +2 -2
  68. package/webapp/dist/assets/chunk-QN33PNHL-Dt5_zoWx.js.map +1 -0
  69. package/webapp/dist/assets/{chunk-QZHKN3VN-DWkpxb-w.js → chunk-QZHKN3VN-C233UTgJ.js} +2 -2
  70. package/webapp/dist/assets/chunk-QZHKN3VN-C233UTgJ.js.map +1 -0
  71. package/webapp/dist/assets/{chunk-JSJVCQXG-CRq8LK53.js → chunk-TZMSLE5B-CYz6GjE2.js} +6 -14
  72. package/webapp/dist/assets/chunk-TZMSLE5B-CYz6GjE2.js.map +1 -0
  73. package/webapp/dist/assets/{classDiagram-VBA2DB6C-mVfJeuZL.js → classDiagram-2ON5EDUG-Bh9Mw-kt.js} +6 -7
  74. package/webapp/dist/assets/classDiagram-2ON5EDUG-Bh9Mw-kt.js.map +1 -0
  75. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-mVfJeuZL.js → classDiagram-v2-WZHVMYZB-Bh9Mw-kt.js} +6 -7
  76. package/webapp/dist/assets/classDiagram-v2-WZHVMYZB-Bh9Mw-kt.js.map +1 -0
  77. package/webapp/dist/assets/{clone-5uLJc7AC.js → clone-2lFjyI7N.js} +2 -2
  78. package/webapp/dist/assets/clone-2lFjyI7N.js.map +1 -0
  79. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-CoiJzdQi.js → cose-bilkent-S5V4N54A-3DOT2IPV.js} +2 -2
  80. package/webapp/dist/assets/cose-bilkent-S5V4N54A-3DOT2IPV.js.map +1 -0
  81. package/webapp/dist/assets/cytoscape.esm-Bm8DJGmZ.js.map +1 -1
  82. package/webapp/dist/assets/{dagre-KLK3FWXG-DU_3BSOq.js → dagre-6UL2VRFP-ClogWVOL.js} +7 -7
  83. package/webapp/dist/assets/dagre-6UL2VRFP-ClogWVOL.js.map +1 -0
  84. package/webapp/dist/assets/defaultLocale-B2RvLBDe.js.map +1 -1
  85. package/webapp/dist/assets/{diagram-E7M64L7V-DgqOvF1U.js → diagram-PSM6KHXK-C7W5uMOI.js} +10 -10
  86. package/webapp/dist/assets/diagram-PSM6KHXK-C7W5uMOI.js.map +1 -0
  87. package/webapp/dist/assets/{diagram-IFDJBPK2-CFWMc1oD.js → diagram-QEK2KX5R-2hcqk2fE.js} +8 -9
  88. package/webapp/dist/assets/diagram-QEK2KX5R-2hcqk2fE.js.map +1 -0
  89. package/webapp/dist/assets/{diagram-P4PSJMXO-lrqvXDXp.js → diagram-S2PKOQOG-DSTjb4Ot.js} +8 -8
  90. package/webapp/dist/assets/diagram-S2PKOQOG-DSTjb4Ot.js.map +1 -0
  91. package/webapp/dist/assets/{erDiagram-INFDFZHY-C28KjRkA.js → erDiagram-Q2GNP2WA-Cyzo2gRU.js} +75 -96
  92. package/webapp/dist/assets/erDiagram-Q2GNP2WA-Cyzo2gRU.js.map +1 -0
  93. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-DkxGh-JF.js → flowDiagram-NV44I4VS-vwGV7In0.js} +81 -98
  94. package/webapp/dist/assets/flowDiagram-NV44I4VS-vwGV7In0.js.map +1 -0
  95. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-BmZnHD96.js → ganttDiagram-JELNMOA3-BwnKcFdH.js} +3 -28
  96. package/webapp/dist/assets/ganttDiagram-JELNMOA3-BwnKcFdH.js.map +1 -0
  97. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-xiHqomZC.js → gitGraphDiagram-V2S2FVAM-AHZBVTYC.js} +46 -38
  98. package/webapp/dist/assets/gitGraphDiagram-V2S2FVAM-AHZBVTYC.js.map +1 -0
  99. package/webapp/dist/assets/graph-8UtNyWA6.js +425 -0
  100. package/webapp/dist/assets/graph-8UtNyWA6.js.map +1 -0
  101. package/webapp/dist/assets/{index-Cyx7eev_.js → index-BxP2ljx_.js} +1369 -1105
  102. package/webapp/dist/assets/{index-Cyx7eev_.js.map → index-BxP2ljx_.js.map} +1 -1
  103. package/webapp/dist/assets/{index-YaxF76or.css → index-xvYYeHuy.css} +1 -1
  104. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-fLl_TA1F.js → infoDiagram-HS3SLOUP-BjVLGKXo.js} +7 -7
  105. package/webapp/dist/assets/infoDiagram-HS3SLOUP-BjVLGKXo.js.map +1 -0
  106. package/webapp/dist/assets/init-ZxktEp_H.js.map +1 -1
  107. package/webapp/dist/assets/{journeyDiagram-4ABVD52K--aRyymZs.js → journeyDiagram-XKPGCS4Q-CR4SmnDB.js} +5 -5
  108. package/webapp/dist/assets/journeyDiagram-XKPGCS4Q-CR4SmnDB.js.map +1 -0
  109. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-BO_QdW_O.js → kanban-definition-3W4ZIXB7-BRwp6TGw.js} +3 -5
  110. package/webapp/dist/assets/kanban-definition-3W4ZIXB7-BRwp6TGw.js.map +1 -0
  111. package/webapp/dist/assets/{layout-Bu3Xw0z2.js → layout-CGl07Gcr.js} +5 -5
  112. package/webapp/dist/assets/layout-CGl07Gcr.js.map +1 -0
  113. package/webapp/dist/assets/{linear-Bq77itJm.js → linear-BZLEuG3I.js} +2 -2
  114. package/webapp/dist/assets/linear-BZLEuG3I.js.map +1 -0
  115. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-CHB8qv8L.js → mindmap-definition-VGOIOE7T-CSKILdE-.js} +5 -7
  116. package/webapp/dist/assets/mindmap-definition-VGOIOE7T-CSKILdE-.js.map +1 -0
  117. package/webapp/dist/assets/ordinal-CxptdPJm.js.map +1 -1
  118. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-Cxg_wh4K.js → pieDiagram-ADFJNKIX-B_V3b26u.js} +8 -8
  119. package/webapp/dist/assets/pieDiagram-ADFJNKIX-B_V3b26u.js.map +1 -0
  120. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-DFguuaS9.js → quadrantDiagram-AYHSOK5B-CUtWvL54.js} +3 -3
  121. package/webapp/dist/assets/quadrantDiagram-AYHSOK5B-CUtWvL54.js.map +1 -0
  122. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP--tJ_dfsT.js → requirementDiagram-UZGBJVZJ-i2tJjoPk.js} +6 -16
  123. package/webapp/dist/assets/requirementDiagram-UZGBJVZJ-i2tJjoPk.js.map +1 -0
  124. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-f0zWimMc.js → sankeyDiagram-TZEHDZUN-nPQL9_d2.js} +2 -2
  125. package/webapp/dist/assets/sankeyDiagram-TZEHDZUN-nPQL9_d2.js.map +1 -0
  126. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-dwXRRnyq.js → sequenceDiagram-WL72ISMW-C2hX7rec.js} +201 -601
  127. package/webapp/dist/assets/sequenceDiagram-WL72ISMW-C2hX7rec.js.map +1 -0
  128. package/webapp/dist/assets/{stateDiagram-RAJIS63D-DToxcEC2.js → stateDiagram-FKZM4ZOC-C94MSmDQ.js} +9 -9
  129. package/webapp/dist/assets/stateDiagram-FKZM4ZOC-C94MSmDQ.js.map +1 -0
  130. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-BY5hDUqz.js → stateDiagram-v2-4FDKWEC3-C3pjtK0h.js} +5 -5
  131. package/webapp/dist/assets/stateDiagram-v2-4FDKWEC3-C3pjtK0h.js.map +1 -0
  132. package/webapp/dist/assets/{timeline-definition-YZTLITO2-CT3WRcFt.js → timeline-definition-IT6M3QCI-c087-Lzc.js} +3 -3
  133. package/webapp/dist/assets/timeline-definition-IT6M3QCI-c087-Lzc.js.map +1 -0
  134. package/webapp/dist/assets/{treemap-KZPCXAKY-Lnkh2bpd.js → treemap-GDKQZRPO-PkjxSOwj.js} +24 -37
  135. package/webapp/dist/assets/treemap-GDKQZRPO-PkjxSOwj.js.map +1 -0
  136. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-DgvaqrGO.js → xychartDiagram-PRI3JC2R-DtMWPXHa.js} +4 -4
  137. package/webapp/dist/assets/xychartDiagram-PRI3JC2R-DtMWPXHa.js.map +1 -0
  138. package/webapp/dist/index.html +2 -2
  139. package/dist/tools/registry-snapshot.d.ts +0 -4
  140. package/dist/tools/registry-snapshot.js +0 -35
  141. package/webapp/dist/assets/_basePickBy-CgM-M_q8.js.map +0 -1
  142. package/webapp/dist/assets/_baseUniq-B06twih4.js.map +0 -1
  143. package/webapp/dist/assets/arc-CoXJvjeB.js.map +0 -1
  144. package/webapp/dist/assets/architectureDiagram-2XIMDMQ5-BLFRWTKn.js.map +0 -1
  145. package/webapp/dist/assets/blockDiagram-WCTKOSBZ-CYRE6deu.js.map +0 -1
  146. package/webapp/dist/assets/c4Diagram-IC4MRINW-B26QTIJt.js.map +0 -1
  147. package/webapp/dist/assets/channel-C5U2W0P9.js.map +0 -1
  148. package/webapp/dist/assets/chunk-4BX2VUAB-7z2PgnSv.js.map +0 -1
  149. package/webapp/dist/assets/chunk-55IACEB6-6sRVmXqs.js.map +0 -1
  150. package/webapp/dist/assets/chunk-FMBD7UC4-BwYp8OtY.js.map +0 -1
  151. package/webapp/dist/assets/chunk-JSJVCQXG-CRq8LK53.js.map +0 -1
  152. package/webapp/dist/assets/chunk-KX2RTZJC-CzFE355P.js.map +0 -1
  153. package/webapp/dist/assets/chunk-NQ4KR5QH-3cQSOzCt.js.map +0 -1
  154. package/webapp/dist/assets/chunk-QZHKN3VN-DWkpxb-w.js.map +0 -1
  155. package/webapp/dist/assets/chunk-WL4C6EOR-DkpfoQzK.js.map +0 -1
  156. package/webapp/dist/assets/classDiagram-VBA2DB6C-mVfJeuZL.js.map +0 -1
  157. package/webapp/dist/assets/classDiagram-v2-RAHNMMFH-mVfJeuZL.js.map +0 -1
  158. package/webapp/dist/assets/clone-5uLJc7AC.js.map +0 -1
  159. package/webapp/dist/assets/cose-bilkent-S5V4N54A-CoiJzdQi.js.map +0 -1
  160. package/webapp/dist/assets/dagre-KLK3FWXG-DU_3BSOq.js.map +0 -1
  161. package/webapp/dist/assets/diagram-E7M64L7V-DgqOvF1U.js.map +0 -1
  162. package/webapp/dist/assets/diagram-IFDJBPK2-CFWMc1oD.js.map +0 -1
  163. package/webapp/dist/assets/diagram-P4PSJMXO-lrqvXDXp.js.map +0 -1
  164. package/webapp/dist/assets/erDiagram-INFDFZHY-C28KjRkA.js.map +0 -1
  165. package/webapp/dist/assets/flowDiagram-PKNHOUZH-DkxGh-JF.js.map +0 -1
  166. package/webapp/dist/assets/ganttDiagram-A5KZAMGK-BmZnHD96.js.map +0 -1
  167. package/webapp/dist/assets/gitGraphDiagram-K3NZZRJ6-xiHqomZC.js.map +0 -1
  168. package/webapp/dist/assets/graph-ozb0amP0.js +0 -782
  169. package/webapp/dist/assets/graph-ozb0amP0.js.map +0 -1
  170. package/webapp/dist/assets/infoDiagram-LFFYTUFH-fLl_TA1F.js.map +0 -1
  171. package/webapp/dist/assets/ishikawaDiagram-PHBUUO56-ZL9tBKUr.js +0 -966
  172. package/webapp/dist/assets/ishikawaDiagram-PHBUUO56-ZL9tBKUr.js.map +0 -1
  173. package/webapp/dist/assets/journeyDiagram-4ABVD52K--aRyymZs.js.map +0 -1
  174. package/webapp/dist/assets/kanban-definition-K7BYSVSG-BO_QdW_O.js.map +0 -1
  175. package/webapp/dist/assets/layout-Bu3Xw0z2.js.map +0 -1
  176. package/webapp/dist/assets/linear-Bq77itJm.js.map +0 -1
  177. package/webapp/dist/assets/mindmap-definition-YRQLILUH-CHB8qv8L.js.map +0 -1
  178. package/webapp/dist/assets/pieDiagram-SKSYHLDU-Cxg_wh4K.js.map +0 -1
  179. package/webapp/dist/assets/quadrantDiagram-337W2JSQ-DFguuaS9.js.map +0 -1
  180. package/webapp/dist/assets/requirementDiagram-Z7DCOOCP--tJ_dfsT.js.map +0 -1
  181. package/webapp/dist/assets/sankeyDiagram-WA2Y5GQK-f0zWimMc.js.map +0 -1
  182. package/webapp/dist/assets/sequenceDiagram-2WXFIKYE-dwXRRnyq.js.map +0 -1
  183. package/webapp/dist/assets/stateDiagram-RAJIS63D-DToxcEC2.js.map +0 -1
  184. package/webapp/dist/assets/stateDiagram-v2-FVOUBMTO-BY5hDUqz.js.map +0 -1
  185. package/webapp/dist/assets/timeline-definition-YZTLITO2-CT3WRcFt.js.map +0 -1
  186. package/webapp/dist/assets/treemap-KZPCXAKY-Lnkh2bpd.js.map +0 -1
  187. package/webapp/dist/assets/vennDiagram-LZ73GAT5-CYSLSh1w.js +0 -2487
  188. package/webapp/dist/assets/vennDiagram-LZ73GAT5-CYSLSh1w.js.map +0 -1
  189. package/webapp/dist/assets/xychartDiagram-JWTSCODW-DgvaqrGO.js.map +0 -1
@@ -1,4 +1,15 @@
1
1
  import { type AppsHostClient } from '../apps-host/client';
2
+ export type DynamicAppToolAvailabilityResult = Readonly<{
3
+ status: 'ready';
4
+ toolsetIds: ReadonlyArray<string>;
5
+ } | {
6
+ status: 'error';
7
+ toolsetIds: ReadonlyArray<string>;
8
+ errorText: string;
9
+ } | {
10
+ status: 'not_applicable';
11
+ toolsetIds: ReadonlyArray<string>;
12
+ }>;
2
13
  export declare function getAppsHostClient(): AppsHostClient;
3
14
  export declare function waitForAppsHostClient(): Promise<AppsHostClient>;
4
15
  export declare function shutdownAppsRuntime(): Promise<void>;
@@ -9,7 +20,20 @@ export declare function listDynamicAppToolsetsForMember(_params: {
9
20
  rtwsRootAbs: string;
10
21
  taskDocPath: string;
11
22
  memberId: string;
23
+ dialogId?: string;
24
+ rootDialogId?: string;
25
+ agentId?: string;
26
+ sessionSlug?: string;
12
27
  }): Promise<readonly string[]>;
28
+ export declare function resolveDynamicAppToolAvailabilityForMember(_params: {
29
+ rtwsRootAbs: string;
30
+ taskDocPath: string;
31
+ memberId: string;
32
+ dialogId?: string;
33
+ rootDialogId?: string;
34
+ agentId?: string;
35
+ sessionSlug?: string;
36
+ }): Promise<DynamicAppToolAvailabilityResult>;
13
37
  export declare function initAppsRuntime(params: {
14
38
  rtwsRootAbs: string;
15
39
  kernel: Readonly<{
@@ -8,6 +8,7 @@ exports.waitForAppsHostClient = waitForAppsHostClient;
8
8
  exports.shutdownAppsRuntime = shutdownAppsRuntime;
9
9
  exports.registerEnabledAppsToolProxies = registerEnabledAppsToolProxies;
10
10
  exports.listDynamicAppToolsetsForMember = listDynamicAppToolsetsForMember;
11
+ exports.resolveDynamicAppToolAvailabilityForMember = resolveDynamicAppToolAvailabilityForMember;
11
12
  exports.initAppsRuntime = initAppsRuntime;
12
13
  const crypto_1 = require("crypto");
13
14
  const promises_1 = __importDefault(require("fs/promises"));
@@ -16,6 +17,7 @@ const dialog_1 = require("../dialog");
16
17
  const dialog_global_registry_1 = require("../dialog-global-registry");
17
18
  const dialog_instance_registry_1 = require("../dialog-instance-registry");
18
19
  const log_1 = require("../log");
20
+ const tool_availability_updates_1 = require("../tool-availability-updates");
19
21
  const app_reminders_1 = require("../tools/app-reminders");
20
22
  const registry_1 = require("../tools/registry");
21
23
  const client_1 = require("../apps-host/client");
@@ -352,10 +354,12 @@ function registerAppArtifacts(app) {
352
354
  });
353
355
  }
354
356
  function syncRegisteredAppArtifacts(params) {
357
+ let changed = false;
355
358
  const nextAppIds = new Set(params.enabledApps.map((app) => app.appId));
356
359
  for (const appId of registeredAppArtifactsById.keys()) {
357
360
  if (!nextAppIds.has(appId)) {
358
361
  unregisterRegisteredAppArtifacts(appId);
362
+ changed = true;
359
363
  }
360
364
  }
361
365
  for (const app of params.enabledApps) {
@@ -368,7 +372,9 @@ function syncRegisteredAppArtifacts(params) {
368
372
  unregisterRegisteredAppArtifacts(app.appId);
369
373
  }
370
374
  registerAppArtifacts(app);
375
+ changed = true;
371
376
  }
377
+ return changed;
372
378
  }
373
379
  async function syncAppsHostToEnabledApps(params) {
374
380
  const config = appsRuntimeConfig;
@@ -417,7 +423,13 @@ async function refreshEnabledAppsRuntimeNow(params) {
417
423
  installJson: app.installJson,
418
424
  }),
419
425
  })));
420
- syncRegisteredAppArtifacts({ enabledApps });
426
+ const appArtifactsChanged = syncRegisteredAppArtifacts({ enabledApps });
427
+ if (appArtifactsChanged) {
428
+ (0, tool_availability_updates_1.notifyToolAvailabilityRegistryMaybeChanged)({
429
+ reason: 'registry_changed',
430
+ trigger: 'apps-runtime:tool-proxies-refreshed',
431
+ });
432
+ }
421
433
  if (params.ensureHost) {
422
434
  await syncAppsHostToEnabledApps({ enabledApps });
423
435
  }
@@ -431,29 +443,59 @@ async function registerEnabledAppsToolProxies(params) {
431
443
  await run;
432
444
  }
433
445
  async function listDynamicAppToolsetsForMember(_params) {
446
+ const result = await resolveDynamicAppToolAvailabilityForMember(_params);
447
+ return result.status === 'ready' ? result.toolsetIds : [];
448
+ }
449
+ async function resolveDynamicAppToolAvailabilityForMember(_params) {
450
+ if (_params.taskDocPath.trim() === '') {
451
+ return { status: 'not_applicable', toolsetIds: [] };
452
+ }
434
453
  try {
435
454
  await registerEnabledAppsToolProxies({ rtwsRootAbs: _params.rtwsRootAbs });
436
455
  }
437
456
  catch (error) {
438
- log.warn(`Failed to refresh enabled app tool proxies while resolving dynamic toolsets for member '${_params.memberId}'; continuing without dynamic app toolsets.`, asError(error));
439
- return [];
457
+ const err = asError(error);
458
+ log.warn(`Failed to refresh enabled app tool proxies while resolving dynamic toolsets for member '${_params.memberId}'.`, err);
459
+ return {
460
+ status: 'error',
461
+ toolsetIds: [],
462
+ errorText: err.message,
463
+ };
440
464
  }
441
465
  if (!appsRuntimeConfig && !appsHostClient && !appsHostTransition) {
442
- return [];
466
+ return { status: 'not_applicable', toolsetIds: [] };
443
467
  }
444
468
  if (!appsHostClient && !appsHostTransition) {
445
- return [];
469
+ return { status: 'not_applicable', toolsetIds: [] };
446
470
  }
447
471
  try {
448
472
  const host = await ensureAppsHostReadyForToolCalls();
449
- return await host.listDynamicToolsets({
473
+ const toolsetIds = await host.listDynamicToolsets({
450
474
  memberId: _params.memberId,
451
475
  taskDocPath: _params.taskDocPath,
476
+ ...(typeof _params.dialogId === 'string' && _params.dialogId.trim() !== ''
477
+ ? { dialogId: _params.dialogId.trim() }
478
+ : {}),
479
+ ...(typeof _params.rootDialogId === 'string' && _params.rootDialogId.trim() !== ''
480
+ ? { rootDialogId: _params.rootDialogId.trim() }
481
+ : {}),
482
+ ...(typeof _params.agentId === 'string' && _params.agentId.trim() !== ''
483
+ ? { agentId: _params.agentId.trim() }
484
+ : {}),
485
+ ...(typeof _params.sessionSlug === 'string' && _params.sessionSlug.trim() !== ''
486
+ ? { sessionSlug: _params.sessionSlug.trim() }
487
+ : {}),
452
488
  });
489
+ return { status: 'ready', toolsetIds };
453
490
  }
454
491
  catch (error) {
455
- log.warn(`Failed to load dynamic app toolsets for member '${_params.memberId}'; continuing without dynamic app toolsets.`, asError(error));
456
- return [];
492
+ const err = asError(error);
493
+ log.warn(`Failed to load dynamic app toolsets for member '${_params.memberId}'.`, err);
494
+ return {
495
+ status: 'error',
496
+ toolsetIds: [],
497
+ errorText: err.message,
498
+ };
457
499
  }
458
500
  }
459
501
  async function initAppsRuntime(params) {
package/dist/dialog.d.ts CHANGED
@@ -16,7 +16,7 @@ import type { ContextHealthSnapshot } from '@longrun-ai/kernel/types/context-hea
16
16
  import type { DialogEvent, NativeToolCallPayload, ReminderContent, WebSearchCallAction, WebSearchCallSource } from '@longrun-ai/kernel/types/dialog';
17
17
  import type { DialogPrompt, DialogRunControlSpec, DialogSubdialogReplyTarget, DriveIntent } from '@longrun-ai/kernel/types/drive-intent';
18
18
  import type { LanguageCode } from '@longrun-ai/kernel/types/language';
19
- import type { CalleeCourseNumber, CalleeGenerationSeqNumber, CallingCourseNumber, DialogMetadataFile, HumanQuestion, ProviderData, ReasoningPayload, TellaskCallRecordName, TellaskReplyDirective } from '@longrun-ai/kernel/types/storage';
19
+ import type { CalleeCourseNumber, CalleeGenerationSeqNumber, CallingCourseNumber, CallingGenerationSeqNumber, DialogMetadataFile, HumanQuestion, ProviderData, ReasoningPayload, TellaskCallRecordName, TellaskReplyDirective } from '@longrun-ai/kernel/types/storage';
20
20
  import { ChatMessage, FuncResultMsg, TellaskCarryoverMsg, TellaskResultMsg } from './llm/client';
21
21
  import type { ToolResultImageIngest } from './llm/gen';
22
22
  import type { JsonValue } from './tool';
@@ -294,6 +294,7 @@ export declare abstract class Dialog {
294
294
  get activeGenSeq(): number;
295
295
  get activeGenSeqOrUndefined(): number | undefined;
296
296
  get activeGenCourseOrUndefined(): number | undefined;
297
+ get hasActiveGeneration(): boolean;
297
298
  /**
298
299
  * Check if generation has started for the current course.
299
300
  * Used to ensure subdialog_final_response_evt arrives after parent events.
@@ -375,13 +376,17 @@ export declare abstract class Dialog {
375
376
  receiveFuncResult(result: FuncResultMsg): Promise<void>;
376
377
  receiveTellaskResult(result: TellaskResultMsg): Promise<void>;
377
378
  receiveTellaskCarryover(result: TellaskCarryoverMsg): Promise<void>;
378
- receiveTellaskCallResult(responderId: string, callName: 'tellaskBack' | 'tellask' | 'tellaskSessionless' | 'askHuman' | 'freshBootsReasoning', mentionList: string[] | undefined, tellaskContent: string, result: string, status: 'completed' | 'failed', callId: string): Promise<void>;
379
+ receiveTellaskCallResult(responderId: string, callName: 'tellaskBack' | 'tellask' | 'tellaskSessionless' | 'askHuman' | 'freshBootsReasoning', mentionList: string[] | undefined, tellaskContent: string, result: string, status: 'completed' | 'failed', callId: string, options?: {
380
+ originCourse?: CallingCourseNumber;
381
+ calling_genseq?: CallingGenerationSeqNumber;
382
+ }): Promise<void>;
379
383
  receiveTellaskResponse(responderId: string, callName: 'tellaskBack' | 'tellask' | 'tellaskSessionless' | 'askHuman' | 'freshBootsReasoning', mentionList: string[] | undefined, tellaskContent: string, status: 'completed' | 'failed', subdialogId: DialogID | undefined, options: {
380
384
  response: string;
381
385
  agentId: string;
382
386
  callId: string;
383
387
  originMemberId: string;
384
388
  originCourse?: CallingCourseNumber;
389
+ calling_genseq?: CallingGenerationSeqNumber;
385
390
  carryoverContent?: string;
386
391
  sessionSlug?: string;
387
392
  calleeCourse?: CalleeCourseNumber;
package/dist/dialog.js CHANGED
@@ -586,6 +586,9 @@ class Dialog {
586
586
  get activeGenCourseOrUndefined() {
587
587
  return this._activeGenCourse;
588
588
  }
589
+ get hasActiveGeneration() {
590
+ return this._activeGenCourse !== undefined;
591
+ }
589
592
  /**
590
593
  * Check if generation has started for the current course.
591
594
  * Used to ensure subdialog_final_response_evt arrives after parent events.
@@ -933,16 +936,19 @@ class Dialog {
933
936
  async receiveTellaskCarryover(result) {
934
937
  return await this.dlgStore.receiveTellaskCarryover(this, result);
935
938
  }
936
- async receiveTellaskCallResult(responderId, callName, mentionList, tellaskContent, result, status, callId) {
939
+ async receiveTellaskCallResult(responderId, callName, mentionList, tellaskContent, result, status, callId, options) {
937
940
  const tellaskResult = callName === 'tellask'
938
941
  ? {
939
942
  type: 'tellask_result_msg',
940
943
  role: 'tool',
941
- genseq: this.activeGenSeqOrUndefined ?? 1,
942
944
  callId,
943
945
  callName,
944
946
  status,
945
947
  content: result,
948
+ ...(options?.originCourse !== undefined ? { originCourse: options.originCourse } : {}),
949
+ ...(options?.calling_genseq !== undefined
950
+ ? { calling_genseq: options.calling_genseq }
951
+ : {}),
946
952
  call: {
947
953
  tellaskContent,
948
954
  mentionList: mentionList ?? [],
@@ -955,11 +961,16 @@ class Dialog {
955
961
  ? {
956
962
  type: 'tellask_result_msg',
957
963
  role: 'tool',
958
- genseq: this.activeGenSeqOrUndefined ?? 1,
959
964
  callId,
960
965
  callName,
961
966
  status,
962
967
  content: result,
968
+ ...(options?.originCourse !== undefined
969
+ ? { originCourse: options.originCourse }
970
+ : {}),
971
+ ...(options?.calling_genseq !== undefined
972
+ ? { calling_genseq: options.calling_genseq }
973
+ : {}),
963
974
  call: {
964
975
  tellaskContent,
965
976
  mentionList: mentionList ?? [],
@@ -971,11 +982,16 @@ class Dialog {
971
982
  : {
972
983
  type: 'tellask_result_msg',
973
984
  role: 'tool',
974
- genseq: this.activeGenSeqOrUndefined ?? 1,
975
985
  callId,
976
986
  callName,
977
987
  status,
978
988
  content: result,
989
+ ...(options?.originCourse !== undefined
990
+ ? { originCourse: options.originCourse }
991
+ : {}),
992
+ ...(options?.calling_genseq !== undefined
993
+ ? { calling_genseq: options.calling_genseq }
994
+ : {}),
979
995
  call: {
980
996
  tellaskContent,
981
997
  },
@@ -1047,11 +1063,14 @@ class Dialog {
1047
1063
  ? {
1048
1064
  type: 'tellask_result_msg',
1049
1065
  role: 'tool',
1050
- genseq: this.activeGenSeqOrUndefined ?? 1,
1051
1066
  callId: options.callId,
1052
1067
  callName,
1053
1068
  status,
1054
1069
  content: options.response,
1070
+ ...(options.originCourse !== undefined ? { originCourse: options.originCourse } : {}),
1071
+ ...(options.calling_genseq !== undefined
1072
+ ? { calling_genseq: options.calling_genseq }
1073
+ : {}),
1055
1074
  call: {
1056
1075
  tellaskContent,
1057
1076
  mentionList: mentionList ?? [],
@@ -1068,11 +1087,14 @@ class Dialog {
1068
1087
  ? {
1069
1088
  type: 'tellask_result_msg',
1070
1089
  role: 'tool',
1071
- genseq: this.activeGenSeqOrUndefined ?? 1,
1072
1090
  callId: options.callId,
1073
1091
  callName,
1074
1092
  status,
1075
1093
  content: options.response,
1094
+ ...(options.originCourse !== undefined ? { originCourse: options.originCourse } : {}),
1095
+ ...(options.calling_genseq !== undefined
1096
+ ? { calling_genseq: options.calling_genseq }
1097
+ : {}),
1076
1098
  call: {
1077
1099
  tellaskContent,
1078
1100
  mentionList: mentionList ?? [],
@@ -1087,11 +1109,14 @@ class Dialog {
1087
1109
  : {
1088
1110
  type: 'tellask_result_msg',
1089
1111
  role: 'tool',
1090
- genseq: this.activeGenSeqOrUndefined ?? 1,
1091
1112
  callId: options.callId,
1092
1113
  callName,
1093
1114
  status,
1094
1115
  content: options.response,
1116
+ ...(options.originCourse !== undefined ? { originCourse: options.originCourse } : {}),
1117
+ ...(options.calling_genseq !== undefined
1118
+ ? { calling_genseq: options.calling_genseq }
1119
+ : {}),
1095
1120
  call: {
1096
1121
  tellaskContent,
1097
1122
  },
@@ -1309,7 +1334,6 @@ class Dialog {
1309
1334
  status: 'completed',
1310
1335
  course: this.currentCourse,
1311
1336
  callId,
1312
- genseq: this.activeGenSeqOrUndefined ?? 1,
1313
1337
  content: rawResponse,
1314
1338
  responder: {
1315
1339
  responderId,
@@ -1331,7 +1355,6 @@ class Dialog {
1331
1355
  status: 'completed',
1332
1356
  course: this.currentCourse,
1333
1357
  callId,
1334
- genseq: this.activeGenSeqOrUndefined ?? 1,
1335
1358
  content: rawResponse,
1336
1359
  responder: {
1337
1360
  responderId,
@@ -1352,7 +1375,6 @@ class Dialog {
1352
1375
  status: 'completed',
1353
1376
  course: this.currentCourse,
1354
1377
  callId,
1355
- genseq: this.activeGenSeqOrUndefined ?? 1,
1356
1378
  content: rawResponse,
1357
1379
  responder: {
1358
1380
  responderId,
@@ -129,6 +129,17 @@ rtws is the runtime workspace root (`process.cwd()`). The kernel reads/writes:
129
129
  - App context: the app-local team (app `.minds/team.yaml` plus its dependency/override composition).
130
130
 
131
131
  > Target direction: decouple “team visibility” from “tool availability”, but keep both encapsulated and overridable at app boundaries.
132
+ >
133
+ > Design principle: the app mechanism customizes Dominds by registering callbacks at explicit
134
+ > kernel control points. Tool availability is one such control point; it should not be modeled as a
135
+ > hidden side effect of lease/registry/cache behavior.
136
+ >
137
+ > Evolution policy: keep control points explicit and concrete first. Do not rush into a generalized
138
+ > app callback framework before several control points have independently matured.
139
+ >
140
+ > Current-stage note: app-side protocol details are still relatively sparse. This is expected at the
141
+ > current phase and should be read as “direction fixed, surface area still growing”, not as a sign
142
+ > that the app model is undefined.
132
143
 
133
144
  ## App packages and manifests
134
145
 
@@ -485,7 +496,13 @@ Current prototype note (`dominds-apps/@longrun-ai/web-dev`, as of March 8, 2026)
485
496
  - `kind: "web"` sessions now create a real Playwright-backed browser/context/page runtime and report live page surfaces via session status/reminders.
486
497
  - `kind: "electron"` is **not** at the same completion level yet: it still falls back to the older prototype runtime path and should be treated as unfinished.
487
498
  - Reminder UX contract: tool output may summarize reminder-sync actions, but the reminder panel is the authoritative surface for attachment state.
488
- - Runtime refresh contract: after enabling the app, a full Dominds instance restart should not be required just to discover the toolset; the next minds reload / tools-registry fetch should refresh enabled app tool proxies. This does **not** mean in-flight prompts are rewritten retroactively.
499
+ - Runtime refresh contract: after enabling the app, a full Dominds instance restart should not be required just to discover the toolset; the next minds reload / tool-availability fetch should refresh enabled app tool proxies. This does **not** mean in-flight prompts are rewritten retroactively.
500
+ - Dynamic tool availability protocol note: app-controlled dynamic availability is a protocol layer of
501
+ its own and must remain semantically orthogonal to MCP registry/lease and member binding. See
502
+ [tool-availability-protocol.md](./tool-availability-protocol.md).
503
+ - App mechanism note: this dynamic availability is expressed through an app callback registered at a
504
+ kernel control point, not through an app-owned registry or an implicit coupling to MCP/runtime
505
+ cache behavior.
489
506
  - Remaining gap list for the browser capability layer: screenshot / console / network evidence are not yet exposed as first-class tool outputs, and there is not yet a production-grade browser lifecycle manager.
490
507
  - Restart boundary: if the kernel/apps-host process restarts, persisted session records remain but the in-memory browser runtime degrades and must be recreated.
491
508
 
@@ -128,6 +128,12 @@ rtws 是一次运行的工作区根目录(`process.cwd()`)。Kernel 在其
128
128
  - App 上下文:该 app 的本地团队(app 的 `.minds/team.yaml`,以及其依赖/覆盖组合之后的结果)。
129
129
 
130
130
  > 目标:把“团队视野(能看见谁)”从“工具可用性(能调用什么)”中解耦,但都需要以 app 为单位封装与可覆写。
131
+ >
132
+ > 设计原则:app 机制的核心是“在 kernel 的显式 control points 注册 callback 来定制系统行为”。工具可用性只是其中一个 control point,不能被建模成 lease/registry/cache 的隐式副作用。
133
+ >
134
+ > 演进策略:先坚持“显式、具名、具体”的 control points,不要在多个 control point 都还未独立成熟之前,过早抽象成通用 app callback framework。
135
+ >
136
+ > 阶段说明:目前 app 侧协议细节仍然偏少,这是预期中的现状。它表达的是“方向先树稳、表面积后生长”,而不是 app 模型尚未定型。
131
137
 
132
138
  ## App 包与清单
133
139
 
@@ -484,7 +490,9 @@ members:
484
490
  - `kind: "web"` 会话现在会创建真实的 Playwright browser/context/page 运行时,并通过 status/reminder 报告实时页面状态。
485
491
  - `kind: "electron"` 还没有达到同等完成度:当前仍回落到旧的原型运行时路径,应视为未完成能力。
486
492
  - 提醒体验契约:tool 输出可以摘要提示提醒同步动作,但附着状态的权威可见面仍是 reminder 面板本身。
487
- - 运行时刷新契约:app 启用后,不应再要求为了“看见工具集”而整实例重启;下一次 minds 重新加载 / tools-registry 拉取应刷新已启用 app 的工具代理。但这 **不表示** 已经发出的进行中 prompt 会被追写更新。
493
+ - 运行时刷新契约:app 启用后,不应再要求为了“看见工具集”而整实例重启;下一次 minds 重新加载 / tool-availability 拉取应刷新已启用 app 的工具代理。但这 **不表示** 已经发出的进行中 prompt 会被追写更新。
494
+ - 动态工具可用性协议说明:app 控制的 dynamic availability 是独立协议层,语义上必须与 MCP registry/lease 和成员工具绑定正交;见 [tool-availability-protocol.md](./tool-availability-protocol.md)。
495
+ - app 机制说明:这里的 dynamic availability 应通过注册到 kernel control point 的 app callback 表达,而不是引入 app 自己的 registry,或与 MCP/runtime cache 隐式耦合。
488
496
  - 浏览器能力层的剩余缺口:截图 / console / network 证据尚未作为一等 tool output 暴露,也还没有生产级浏览器生命周期管理器。
489
497
  - 重启边界:若 kernel/apps-host 进程重启,已持久化的 session record 仍在,但内存态浏览器运行时会退化,需要后续 tool call 重新建立。
490
498
 
@@ -246,9 +246,9 @@ flowchart TD
246
246
  **Sideline delivery rule (normative)**:
247
247
 
248
248
  - If a sideline dialog has completed all assigned goals and can deliver the final result, it MUST reply directly with the response body; do not use `tellaskBack` to send final delivery.
249
- - Runtime treats that direct reply as the completion delivery to the tellasker dialog and injects the work-language marker automatically (`【Completed】` in English work language, and the localized Chinese completion marker in Chinese work language).
249
+ - Runtime treats that direct reply as the completion delivery to the tellasker dialog and injects the work-language marker automatically (`【Completed】` in English work language, `【最终完成】` in Chinese work language).
250
250
  - If any goal is incomplete, the dialog is blocked, or critical context is missing, it MUST issue `tellaskBack({ tellaskContent: "..." })` to request clarification or next-step confirmation before proceeding.
251
- - **FBR exception**: FBR sideline dialogs are tellask-free (no `tellaskBack`); they must list missing context and return.
251
+ - **FBR exception**: FBR sideline dialogs forbid all tellask calls (including `tellaskBack` / `tellask` / `tellaskSessionless` / `askHuman`); they must list missing context and return.
252
252
 
253
253
  **Inter-dialog transfer and markers (normative)**:
254
254
 
@@ -259,9 +259,10 @@ flowchart TD
259
259
  - Regular completed sideline reply: `【Completed】`
260
260
  - FBR sideline reply: `【FBR-Direct Reply】` or `【FBR-Reasoning Only】`
261
261
  - Chinese work language:
262
- - Ask-back reply: `【TellaskBack】`
263
- - Regular completed sideline reply: `【Completed】`
264
- - FBR sideline reply: `【FBR-Direct Reply】` or `【FBR-Reasoning Only】`
262
+ - Ask-back reply: `【回问诉请】`
263
+ - Regular completed sideline reply: `【最终完成】`
264
+ - FBR sideline reply: `【FBR-直接回复】` or `【FBR-仅推理】`
265
+ - If the requester defines a “reply/delivery format” inside the tellask body, keep it to the business delivery structure; do not require responder-side hand-written markers, because runtime injects those markers automatically.
265
266
  - Source-dialog model raw is naturally preserved in source-dialog persistence; inter-dialog transfer must not rewrite or overwrite that source raw.
266
267
  - Template-wrapped transfer is allowed: a model output from one dialog may be embedded into a runtime template and sent as the body to another dialog.
267
268
 
@@ -242,7 +242,7 @@ flowchart TD
242
242
 
243
243
  - 只有当所有目标完成时,支线对话才可直接正常回复诉请者对话。
244
244
  - 若任何目标未完成或关键信息缺失,必须先用 `tellaskBack({ tellaskContent: "..." })` 回问诉请者对话再继续。
245
- - **FBR 例外**:FBR 支线对话禁止任何诉请(包括 `tellaskBack`),只能列出缺口与阻塞原因并直接回复。
245
+ - **FBR 例外**:FBR 支线对话禁止一切 tellask(包括 `tellaskBack` / `tellask` / `tellaskSessionless` / `askHuman`),只能列出缺口与阻塞原因并直接回复。
246
246
 
247
247
  **跨对话传递与标记(强制)**:
248
248
 
@@ -256,6 +256,7 @@ flowchart TD
256
256
  - 回问诉请回贴:`【TellaskBack】`
257
257
  - 常规支线完成回贴:`【Completed】`
258
258
  - FBR 回贴:`【FBR-Direct Reply】` 或 `【FBR-Reasoning Only】`
259
+ - 若诉请方在正文中定义“回贴格式/交付格式”,只写业务交付结构即可;不得要求被诉请者手写任何标记,因为这些标记由运行时自动注入。
259
260
  - 源对话的模型原始输出(raw)天然保留在源对话持久记录中;跨对话传递不得改写或覆盖该源 raw。
260
261
  - 允许将“某对话的模型原文”拼接进运行时模板后,作为传递到另一对话的正文(即模板化传递是规范路径)。
261
262
 
@@ -55,6 +55,14 @@ This is the "controlled convergence" path. The diligence-push mechanism should *
55
55
  - no pending subdialogs (waiting for backfill).
56
56
  - The driver would otherwise stop the generation loop (i.e., no tool/function outputs require another iteration).
57
57
 
58
+ ### Exception: provider deadlock recovery
59
+
60
+ Some provider/API quirk handlers may request a one-time Diligence Push recovery after Dominds stops
61
+ same-context retries for a known deadlock pattern. This is not the ordinary "dialog is about to go
62
+ idle" path. In that recovery-only case, pending subdialogs do not veto the single Diligence Push
63
+ injection, because the deadlock may happen in a function-result-driven generation round right after
64
+ the root dialog has already registered an in-flight tellask/subdialog. Q4H remains a hard blocker.
65
+
58
66
  ### Action
59
67
 
60
68
  The runtime auto-sends a diligence prompt (rendered as a normal user bubble) and runs another
@@ -63,8 +71,8 @@ generation iteration.
63
71
  ### Boundedness
64
72
 
65
73
  To avoid infinite loops, diligence-push has a per-dialog budget (per-member `diligence-push-max`) that controls
66
- how many auto-continued diligence prompts can be injected for a given dialog before the runtime forces a
67
- Q4H suspension.
74
+ how many auto-continued diligence prompts can be injected for a given dialog before the runtime stops
75
+ issuing further automatic Diligence Pushes for that budget.
68
76
 
69
77
  - Default: **3**
70
78
  - If `< 1`, diligence-push is effectively disabled for that member
@@ -76,11 +84,10 @@ When a dialog becomes suspended due to a pending Q4H (Questions for Human), the
76
84
  counter is reset. This ensures that after the human answers the Q4H and the dialog is resumed, the
77
85
  dialog gets a fresh diligence-push budget again.
78
86
 
79
- ### Budget exhausted → force Q4H
87
+ ### Budget exhausted → stop auto-pushing for that budget
80
88
 
81
- When the diligence-push budget is exhausted, the runtime creates a Q4H entry that asks the human whether
82
- to continue or stop. This converts "boundedness" into a legitimate suspension point and avoids
83
- infinite auto-continue loops.
89
+ When the diligence-push budget is exhausted, the runtime emits an informational UI notice and stops
90
+ issuing further automatic Diligence Pushes for that budget. It does not create a Q4H by itself.
84
91
 
85
92
  ### Disable switch
86
93
 
@@ -135,13 +142,17 @@ Rules:
135
142
 
136
143
  ### Where
137
144
 
138
- Implemented in the LLM driver loop (`dominds/main/llm/driver.ts`) as a small post-iteration check:
145
+ Implemented in the kernel driver loop (`dominds/main/llm/kernel-driver/drive.ts`) as a small
146
+ post-iteration check:
139
147
 
140
- 1. If `suspendForHuman` is true, stop (Q4H / subdialog pending).
148
+ 1. If the dialog is suspended, stop (Q4H / subdialog pending), except for the deadlock-recovery
149
+ special case described above where one recovery-only Diligence Push may ignore pending
150
+ subdialogs.
141
151
  2. If there is any tool feedback, continue normally.
142
152
  3. Otherwise (root only), attempt diligence-push auto-continue:
143
153
  - If disabled → stop normally.
144
- - If budget exhausted → create Q4H and stop.
154
+ - If budget exhausted → emit an informational UI notice and stop further automatic Diligence
155
+ Pushes for the current budget.
145
156
  - Else → auto-send diligence prompt and continue.
146
157
 
147
158
  ### Message type
@@ -51,13 +51,20 @@ Dominds 根对话旨在长期运行。根对话"停止"(变为空闲)通常
51
51
  - 没有待处理的子对话(等待回填)。
52
52
  - 驱动程序即将停止生成循环(即没有工具/函数输出需要另一次迭代)。
53
53
 
54
+ ### 例外:provider deadlock recovery
55
+
56
+ 某些 provider/API quirk 在识别到已知的 same-context deadlock,并停止沿用同一上下文自动重试后,
57
+ 会请求一次性的鞭策恢复。这不是普通的“对话即将空转停止”路径。在这个仅用于恢复的特例里,
58
+ 即使根对话已经登记了在途诉请/支线对话,pending subdialog 也不应否决这一次鞭策注入;因为卡死
59
+ 可能正发生在函数结果驱动的生成轮次里。Q4H 仍然是硬阻塞条件。
60
+
54
61
  ### 操作
55
62
 
56
63
  运行时自动发送一个鞭策语(渲染为正常的用户气泡)并运行另一次生成迭代。
57
64
 
58
65
  ### 有界性
59
66
 
60
- 为避免无限循环,diligence-push 有一个按对话的预算(每个成员的 `diligence-push-max`),控制对于给定对话在运行时强制 Q4H 暂停之前可以注入多少个自动继续的鞭策语。
67
+ 为避免无限循环,diligence-push 有一个按对话的预算(每个成员的 `diligence-push-max`),控制对于给定对话在当前预算内还能注入多少个自动继续的鞭策语;预算耗尽后,运行时会停止继续自动鞭策。
61
68
 
62
69
  - 默认值:**3**
63
70
  - 如果 `< 1`,则该成员的 diligence-push 有效禁用
@@ -67,9 +74,9 @@ Dominds 根对话旨在长期运行。根对话"停止"(变为空闲)通常
67
74
 
68
75
  当对话因待处理的 Q4H(Questions for Human)而暂停时,diligence-push 注入计数器会被重置。这确保在人类回答 Q4H 并恢复对话后,对话会获得新的 diligence-push 预算。
69
76
 
70
- ### 预算耗尽 → 强制 Q4H
77
+ ### 预算耗尽 → 停止继续自动鞭策当前预算
71
78
 
72
- 当 diligence-push 预算耗尽时,运行时会创建一个 Q4H 条目,询问人类是否继续或停止。这将"有界性"转换为合法的暂停点,并避免无限自动继续循环。
79
+ 当 diligence-push 预算耗尽时,运行时会发出一条仅用于提示的 UI 信息,并停止继续自动鞭策当前预算。它不会仅因预算耗尽而自动创建 Q4H
73
80
 
74
81
  ### 禁用开关
75
82
 
@@ -121,13 +128,14 @@ members:
121
128
 
122
129
  ### 位置
123
130
 
124
- LLM 驱动程序循环中实现(`dominds/main/llm/driver.ts`),作为迭代后的小检查:
131
+ kernel driver 循环中实现(`dominds/main/llm/kernel-driver/drive.ts`),作为迭代后的小检查:
125
132
 
126
- 1. 如果 `suspendForHuman` true,则停止(Q4H / 子对话待处理)。
133
+ 1. 如果对话处于暂停状态,则停止(Q4H / 子对话待处理);但上文所述 deadlock-recovery 特例除外,
134
+ 即那一次恢复专用的鞭策可忽略 pending subdialog。
127
135
  2. 如果有任何工具反馈,则正常继续。
128
136
  3. 否则(仅限根),尝试 diligence-push 自动继续:
129
137
  - 如果禁用 → 正常停止。
130
- - 如果预算耗尽 → 创建 Q4H 并停止。
138
+ - 如果预算耗尽 → 发出一条仅用于提示的 UI 信息,并停止继续自动鞭策当前预算。
131
139
  - 否则 → 自动发送鞭策语并继续。
132
140
 
133
141
  ### 消息类型
package/dist/docs/fbr.md CHANGED
@@ -126,7 +126,7 @@ If the model attempts any other tool/function call, runtime MUST hard-reject it
126
126
 
127
127
  ### 4.3 Tellask restriction: none allowed
128
128
 
129
- FBR sideline dialogs MUST NOT issue any teammate Tellasks (including `tellaskBack({ tellaskContent: "..." })` or `askHuman({ tellaskContent: "..." })`).
129
+ FBR sideline dialogs MUST NOT issue any tellask call (including `tellaskBack({ tellaskContent: "..." })`, `tellask({ ... })`, `tellaskSessionless({ ... })`, or `askHuman({ tellaskContent: "..." })`).
130
130
  If critical context is missing, the FBR sideline should **list the missing items** and why they block reasoning, then return.
131
131
 
132
132
  ### 4.4 Output contract (easy to distill)
@@ -122,7 +122,7 @@ FBR 支线对话的 system prompt 必须明确包含(措辞可不同,但语
122
122
 
123
123
  ### 4.3 诉请限制:一律禁止
124
124
 
125
- FBR 支线对话不得发起任何队友诉请(包括 `tellaskBack({ tellaskContent: "..." })` 或 `askHuman({ tellaskContent: "..." })`)。
125
+ FBR 支线对话不得发起任何 tellask 调用(包括 `tellaskBack({ tellaskContent: "..." })`、`tellask({ ... })`、`tellaskSessionless({ ... })` 或 `askHuman({ tellaskContent: "..." })`)。
126
126
  若关键上下文缺失,应**列出缺口与阻塞原因**,然后直接回复。
127
127
 
128
128
  ### 4.4 输出契约(在 FBR 内部完成去噪)
@@ -67,6 +67,10 @@ or have global process-scoped caches.
67
67
 
68
68
  Dominds therefore treats MCP client connections/processes as **leased resources** by default.
69
69
 
70
+ Lease semantics are intentionally **orthogonal** to tool visibility. A lease decides runtime
71
+ instance/process ownership only; it does not define the global MCP tool catalog or the final
72
+ member-visible tool set. See [tool-availability-protocol.md](./tool-availability-protocol.md).
73
+
70
74
  ### Server config: `truely-stateless` (default: `false`)
71
75
 
72
76
  Each MCP server supports an explicit boolean flag:
@@ -81,23 +85,23 @@ implemented config surface.
81
85
  ### Default behavior (`truely-stateless: false`)
82
86
 
83
87
  - The first time any MCP tool from that server’s toolset is used in a given dialog, Dominds creates
84
- a **dedicated MCP client instance** (and thus a dedicated MCP server process/connection for that
88
+ a **dedicated MCP runtime instance** (and thus a dedicated MCP server process/connection for that
85
89
  dialog).
86
- - That client instance remains **leased to that dialog** for future function tool calls from the same
90
+ - That runtime instance remains **leased to that dialog** for future function tool calls from the same
87
91
  toolset.
88
- - If another dialog uses the same MCP toolset concurrently, Dominds creates **another** MCP client
92
+ - If another dialog uses the same MCP toolset concurrently, Dominds creates **another** MCP runtime
89
93
  instance for that requesting dialog (no cross-dialog sharing).
90
94
  - On first lease, Dominds adds a **sticky owned reminder** to the dialog instructing the agent to
91
- release the lease when it is confident the toolset won’t be needed again soon.
95
+ release the lease when it is confident the runtime instance won’t be needed again soon.
92
96
 
93
97
  Releasing:
94
98
 
95
99
  - Agents should call `mcp_release({"serverId":"<serverId>"})` (from `mcp_admin`) to release the
96
- leased client instance for the current dialog.
100
+ leased runtime instance for the current dialog.
97
101
 
98
102
  ### Shared behavior (`truely-stateless: true`)
99
103
 
100
- - Dominds may share a single MCP client instance across dialogs for that server/toolset.
104
+ - Dominds may share a single MCP runtime instance across dialogs for that server/toolset.
101
105
  - No per-dialog lease reminder is required.
102
106
 
103
107
  ## Goals