nolo-cli 0.213.0 → 0.223.0-alpha.1

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 (262) hide show
  1. package/README.md +3 -2
  2. package/{_executeModel-CUJLCFWR.js → _executeModel-4GGQQHOB.js} +111 -82
  3. package/{accountResolver-4LKIHEKL.js → accountResolver-EK2S4PWF.js} +6 -6
  4. package/{action-DF5UYSJF.js → action-CK64LS6S.js} +12 -11
  5. package/{addContentAction-WERAONNY.js → addContentAction-GDHDOF4U.js} +18 -17
  6. package/{addDialogAgentAction-7VI7YRML.js → addDialogAgentAction-CAKRU3ZT.js} +21 -20
  7. package/{agentDeleteCommand-XJORXPGU.js → agentDeleteCommand-BPV2XZL7.js} +128 -119
  8. package/{agentEmailCommands-XTYYFR6Z.js → agentEmailCommands-EJOS75YL.js} +132 -124
  9. package/{agentFavoriteCommands-EDK743YA.js → agentFavoriteCommands-2LKGKSUD.js} +7 -8
  10. package/{agentGrantCommands-RQWK2TEV.js → agentGrantCommands-QQV4N4JW.js} +5 -5
  11. package/{agentListCommands-OBLRBLHS.js → agentListCommands-HIZODBF3.js} +155 -92
  12. package/{agentMachineCommands-5FMT3OT5.js → agentMachineCommands-ZMQ2CY7Y.js} +62 -54
  13. package/{agentProviderCommands-Q5O33MED.js → agentProviderCommands-WKJOAWBP.js} +5 -5
  14. package/{agentPullCommand-6EM3URVK.js → agentPullCommand-XN6ZPBUW.js} +7 -7
  15. package/agentRecordCommands-OMXVDLDX.js +176 -0
  16. package/agentRunCommand-CB34YWMV.js +206 -0
  17. package/{agentRunControl-TAMHJQSR.js → agentRunControl-JNONH3RP.js} +30 -15
  18. package/{agentRuntimeLocal-SOO2OPJG.js → agentRuntimeLocal-QZPFWMLG.js} +52 -45
  19. package/{agentSlice-CHR6KOZN.js → agentSlice-RD2CDU7T.js} +20 -19
  20. package/{appDeleteCommands-GUP6P5YE.js → appDeleteCommands-QCCFDIEQ.js} +61 -53
  21. package/{appDeployCommands-MH2FX4O5.js → appDeployCommands-V2T7TNMQ.js} +61 -53
  22. package/{appDeployStatusCommands-SUHN3HPJ.js → appDeployStatusCommands-6PGH7ZCG.js} +61 -53
  23. package/{appGetCommands-YWDEX6Z4.js → appGetCommands-3L7WWJA6.js} +61 -53
  24. package/{appListCommands-ZQVMLPAY.js → appListCommands-ENJCK4PO.js} +61 -53
  25. package/{authCommand-PWX2ZNUP.js → authCommand-6V47SYGK.js} +29 -28
  26. package/{authCommands-HV3EAU3V.js → authCommands-GAJ3NIXO.js} +14 -13
  27. package/{builtinSkillRegistry-2QETTQPM.js → builtinSkillRegistry-2ECA42FC.js} +11 -13
  28. package/{chromeCommands-REEAH4SX.js → chromeCommands-G5UDKVSV.js} +3 -3
  29. package/{chromeOpsCommands-DIVM2K3T.js → chromeOpsCommands-YKX2QX3A.js} +20 -10
  30. package/{chunk-CRHOO2ZR.js → chunk-27PCUMJI.js} +2 -2
  31. package/chunk-2CI3ZFWD.js +97 -0
  32. package/{chunk-NSAPDIN2.js → chunk-2GJKRKI6.js} +541 -31
  33. package/{chunk-SM3NSZJV.js → chunk-2UCBGYO4.js} +20 -1
  34. package/{chunk-PYRUW7XN.js → chunk-2VUZSVAS.js} +136 -54
  35. package/{chunk-YB3YZK56.js → chunk-2WZXXAQD.js} +1 -67
  36. package/chunk-2YGBI2XB.js +30 -0
  37. package/chunk-2ZKFCIJJ.js +13 -0
  38. package/{chunk-QG4AOSON.js → chunk-34J5K2YA.js} +13 -32
  39. package/{chunk-LOEO7LRC.js → chunk-3IK6ILVW.js} +4 -1
  40. package/{chunk-CTPXME7U.js → chunk-3LMUPOHG.js} +29 -6
  41. package/chunk-44X52WOJ.js +1621 -0
  42. package/{chunk-6VLJ6YA7.js → chunk-4DESLZTK.js} +9 -9
  43. package/{chunk-MYOH447Z.js → chunk-4JVNURX4.js} +1 -1
  44. package/chunk-5CHGAKRT.js +364 -0
  45. package/{chunk-YDH3FDFQ.js → chunk-5FUN7EG4.js} +1 -1
  46. package/{chunk-INUFILG6.js → chunk-5RKUPJYL.js} +1 -1
  47. package/{chunk-ZC3CMUKU.js → chunk-6OVNSQHN.js} +84 -2
  48. package/{chunk-MOIJOHA5.js → chunk-6WU5572L.js} +36 -25
  49. package/{chunk-IXNGOHV5.js → chunk-7EEZJ6BS.js} +11 -152
  50. package/{chunk-Y6ORVLSS.js → chunk-7ET2U67U.js} +1 -1
  51. package/{chunk-G7MLNNEX.js → chunk-7JLY4WYF.js} +5 -5
  52. package/{chunk-P5L7CXOC.js → chunk-7Z6EW7AH.js} +3 -2
  53. package/{chunk-NJLL224W.js → chunk-AD5EWDFD.js} +2 -2
  54. package/{chunk-J2NHJ7WX.js → chunk-AIHYNKGV.js} +4 -4
  55. package/{chunk-HPFCI4SK.js → chunk-AK5O76CC.js} +3 -3
  56. package/{chunk-Y63ZSOR6.js → chunk-AL3TYDIF.js} +1 -1
  57. package/{chunk-ALQ3657A.js → chunk-AMEOV5VZ.js} +32 -12
  58. package/chunk-AN74ON4G.js +675 -0
  59. package/{chunk-HRMJUN5J.js → chunk-AQZ6BMRK.js} +1 -1
  60. package/{chunk-XHQC4PXX.js → chunk-B4GOW4MT.js} +424 -194
  61. package/{chunk-4KB6WQUL.js → chunk-BGP2EDFG.js} +1 -1
  62. package/{chunk-NBTY7YJF.js → chunk-BR3GT6MR.js} +1 -0
  63. package/{chunk-7RFNTILS.js → chunk-BUDVRYES.js} +2 -2
  64. package/{chunk-SVYO6AO7.js → chunk-BV3FLP2L.js} +41 -1
  65. package/{chunk-RZOV7OMV.js → chunk-C4VAR65S.js} +83 -141
  66. package/{chunk-COFEN36Z.js → chunk-C4WTX5TU.js} +2 -2
  67. package/{chunk-ZL5RAEEB.js → chunk-CIRB724Q.js} +1 -1
  68. package/{chunk-F6UUQOG6.js → chunk-CKT6QUE2.js} +4 -4
  69. package/{chunk-X7SDOJUM.js → chunk-CMZ3Z5PT.js} +14 -14
  70. package/{secretCommands-LXDWOLZ6.js → chunk-D726I5AZ.js} +191 -16
  71. package/{chunk-TAKB25RM.js → chunk-DNKTQ3IN.js} +4 -4
  72. package/chunk-DVQH4BTR.js +1137 -0
  73. package/{chunk-WYDI6TGM.js → chunk-DWX2HEVC.js} +91 -132
  74. package/{chunk-5MQRBSMW.js → chunk-EIAI3PPH.js} +111 -113
  75. package/chunk-EUCFKKDM.js +247 -0
  76. package/chunk-EWQ3HGNZ.js +90 -0
  77. package/{chunk-RPQXPZZF.js → chunk-F3GRJO4Z.js} +908 -13
  78. package/{chunk-YTF4WH7J.js → chunk-FIYSMXHY.js} +1 -1
  79. package/{chunk-75XIDFBW.js → chunk-FJ23FZXF.js} +72 -28
  80. package/{chunk-INN4LTAJ.js → chunk-FJK526XH.js} +2 -2
  81. package/chunk-FS2XP5D7.js +142 -0
  82. package/{chunk-FUGMREBO.js → chunk-FYF2TONJ.js} +5 -5
  83. package/{chunk-PCLE46CE.js → chunk-GBWGPTA7.js} +2 -1
  84. package/{chunk-TX5EYMGT.js → chunk-GYVCJABP.js} +30 -254
  85. package/{chunk-3UKL3HPD.js → chunk-HOCHUZQ7.js} +8 -78
  86. package/{chunk-EHSZD5OI.js → chunk-HXER7YJF.js} +4 -4
  87. package/chunk-HYIETXA6.js +99 -0
  88. package/{chunk-H2TJUNCH.js → chunk-I4EADJ4P.js} +6 -6
  89. package/{chunk-TCZHTTUU.js → chunk-I7WBYGBP.js} +8 -8
  90. package/{chunk-6DWMYIUY.js → chunk-IILMY4W4.js} +14 -9
  91. package/chunk-JA3ICVJY.js +271 -0
  92. package/{chunk-ZRSNONOB.js → chunk-JWXITTQB.js} +8 -3
  93. package/{chunk-H4UOTUOX.js → chunk-KEN3N2TN.js} +148 -18
  94. package/{chunk-LEC5ALIN.js → chunk-KEPOVMF4.js} +1 -1
  95. package/{chunk-UHJGXRJ4.js → chunk-KQSYAIZR.js} +3 -3
  96. package/{chunk-4VJAC32I.js → chunk-L5I543VB.js} +3 -2
  97. package/chunk-LKA64WH4.js +227 -0
  98. package/{chunk-QHPRUL4O.js → chunk-LVL6GFCM.js} +4 -4
  99. package/{chunk-H5HF7TJA.js → chunk-MAIITKBT.js} +2 -2
  100. package/chunk-MBG66ZBH.js +226 -0
  101. package/{chunk-YUA6OAH5.js → chunk-MDLS23JK.js} +2 -2
  102. package/{chunk-VL5KOY2C.js → chunk-MK2Q7ZJD.js} +67 -5
  103. package/{chunk-MDB67IWP.js → chunk-MS4NZNKI.js} +10 -10
  104. package/{chunk-VO4WSAVP.js → chunk-MYHNBEXD.js} +3 -3
  105. package/{chunk-ZXOUUDCG.js → chunk-MZLE5HQ3.js} +3654 -231
  106. package/{chunk-AZMYUSVF.js → chunk-N5Z2V73W.js} +1 -1
  107. package/{chunk-V5Y3R6BT.js → chunk-NIZ2BXFD.js} +213 -210
  108. package/{chunk-KFLT5KAD.js → chunk-NWP2OYOX.js} +20 -20
  109. package/{chunk-G2BQWAVT.js → chunk-O6J3OTOP.js} +4 -4
  110. package/{chunk-VNYYOX3V.js → chunk-OB6DVWPF.js} +141 -48
  111. package/{chunk-YWSEPJ7C.js → chunk-OBWT45ZU.js} +3 -3
  112. package/{chunk-ZNWI6OVT.js → chunk-ODJ7BVSI.js} +80 -11
  113. package/{chunk-XJWWBO34.js → chunk-OJKUU3LP.js} +5 -7
  114. package/{chunk-HUBHAQK2.js → chunk-ON37YXGX.js} +29 -29
  115. package/{chunk-UYD5HQ6T.js → chunk-P5ZJRTCH.js} +5429 -1752
  116. package/{chunk-6XIE5ZGI.js → chunk-PDCV7P5W.js} +1 -1
  117. package/{chunk-WRYQ35LQ.js → chunk-PJCIP64Z.js} +859 -57
  118. package/{chunk-7QTZCMKL.js → chunk-PJVKMGPZ.js} +1089 -1639
  119. package/{chunk-A7TFUNZO.js → chunk-PPJYZRSQ.js} +6 -2
  120. package/chunk-QHEN7NZ7.js +46 -0
  121. package/{chunk-OQPKUBPB.js → chunk-QNWG52I4.js} +19 -7
  122. package/{chunk-YGILMZ7N.js → chunk-QVBXJNZ2.js} +1 -1
  123. package/{chunk-7BT37FK3.js → chunk-RDH5CQ4T.js} +648 -131
  124. package/{chunk-C6KNNXWU.js → chunk-RGQ4UUWZ.js} +25 -2
  125. package/{chunk-OWYYDMGJ.js → chunk-S2NTVGA2.js} +4 -2
  126. package/{chunk-KC4XDTT3.js → chunk-SOF4OWDM.js} +6 -4
  127. package/{chunk-RLBNLZVC.js → chunk-SQYIK6HO.js} +1 -1
  128. package/{chunk-YJAFKXMU.js → chunk-SVT62ULE.js} +50 -48
  129. package/{chunk-KIM6CLW5.js → chunk-SY3C4SQ7.js} +42 -15
  130. package/{chunk-JY5NGFFH.js → chunk-SYTHYBMI.js} +5 -5
  131. package/{chunk-WMTBPBMP.js → chunk-T6DXNI6Z.js} +52 -50
  132. package/chunk-TLE77UJ5.js +230 -0
  133. package/{chunk-4VNS5WPM.js → chunk-U67V476Y.js} +1 -8
  134. package/{chunk-F7CI2ZC5.js → chunk-UAIHKQIA.js} +2 -1
  135. package/{chunk-R5O4QAWG.js → chunk-UB3D4TRQ.js} +11 -77
  136. package/{chunk-WPORQFYN.js → chunk-UVLYNWIE.js} +2 -2
  137. package/{chunk-NOKUNJON.js → chunk-UYOICCYG.js} +29 -19
  138. package/{chunk-4I7ERB7F.js → chunk-VREDDN25.js} +1 -1
  139. package/{chunk-O2TZF4AI.js → chunk-WAE3GFCJ.js} +3 -3
  140. package/{chunk-H7PPIYWP.js → chunk-WI67URFP.js} +20 -20
  141. package/{chunk-7OCO4TDT.js → chunk-WJVYAO6P.js} +1 -1
  142. package/{chunk-T43B7LB2.js → chunk-WKGQSYTB.js} +1 -1
  143. package/{chunk-BBJ22CLB.js → chunk-WUUH4LWZ.js} +60 -30
  144. package/{chunk-4T2WNOY7.js → chunk-X7UF53VA.js} +33 -22
  145. package/{chunk-TY3TIUJK.js → chunk-XI2BWJM5.js} +65 -0
  146. package/{chunk-LLRPJECG.js → chunk-XWVCYUUU.js} +16 -159
  147. package/{chunk-J5JTMQIA.js → chunk-YFLVRVYK.js} +1 -1
  148. package/{chunk-EYLGAEB4.js → chunk-YGMBIXCF.js} +132 -0
  149. package/chunk-YL3EFYL3.js +199 -0
  150. package/{chunk-MMA3LZ3W.js → chunk-YNIYE47Z.js} +1 -1
  151. package/{chunk-W4S457LU.js → chunk-YU4ZPWVF.js} +41 -5
  152. package/{chunk-7Y4YTDQF.js → chunk-YWWDC3O7.js} +281 -159
  153. package/chunk-YZMNK53S.js +68 -0
  154. package/{chunk-RSHTSUEG.js → chunk-Z2PITYZN.js} +2060 -602
  155. package/{chunk-FY7F4Q6X.js → chunk-Z4PCXPUE.js} +2 -2
  156. package/{cliAgentConfigHelpers-WJBZQTLW.js → cliAgentConfigHelpers-TKYL43MT.js} +15 -16
  157. package/{cliAuthorityBrokerClient-PM3U6Q6J.js → cliAuthorityBrokerClient-XHH7MH2P.js} +1 -1
  158. package/{cliAuthorityStoreDriver-TKLXNNTG.js → cliAuthorityStoreDriver-6FE3BJNB.js} +1 -1
  159. package/{cliEnvHelpers-BVYTMUPJ.js → cliEnvHelpers-VPSJ4XWC.js} +3 -3
  160. package/{cliExecutor-BWBF2MTI.js → cliExecutor-4MAX3PZL.js} +2 -2
  161. package/cliLocalAgentRecordReader-MHHD4T7R.js +90 -0
  162. package/{commandRegistry-W63CYRZJ.js → commandRegistry-5DA5UP7S.js} +105 -97
  163. package/{contentThunks-U7PL5MQD.js → contentThunks-5GUQ7FWJ.js} +47 -43
  164. package/{cooldownCommands-TIGUHXTD.js → cooldownCommands-X7P5M2V5.js} +5 -4
  165. package/{createAgentAutomationAction-OLBQDD6R.js → createAgentAutomationAction-UCLTHQRI.js} +51 -49
  166. package/{createDialogAction-SVH6B3SB.js → createDialogAction-UPN774AF.js} +46 -48
  167. package/{createPageAction-F4DIWZ2Z.js → createPageAction-JRQ2TA4O.js} +50 -48
  168. package/{cursorProvider-YGGNMVWX.js → cursorProvider-2RACMEMF.js} +1 -1
  169. package/{db-HUCI5R4G.js → db-CS4ZJQKV.js} +1 -1
  170. package/{dbSlice-BVH2YZPQ.js → dbSlice-WNON7TOL.js} +17 -16
  171. package/{deleteFile-5YOEKV4U.js → deleteFile-Q3YDB4ML.js} +9 -9
  172. package/{desktopFolderProjects-SFY5EZS3.js → desktopFolderProjects-4POAMVJN.js} +2 -2
  173. package/{dialogCommands-KHIEPY3M.js → dialogCommands-VRI7VCXH.js} +64 -57
  174. package/dialogNotifyCommand-6TMCX4D2.js +36 -0
  175. package/{dialogSlice-ZCTDV2PZ.js → dialogSlice-LFNVUSAN.js} +42 -40
  176. package/{dialogUsageCommand-7KCPYGHG.js → dialogUsageCommand-HTVPR2CX.js} +11 -10
  177. package/{docCreateCommands-DPMZI7G5.js → docCreateCommands-AMPXMOX3.js} +61 -55
  178. package/{docDeleteCommands-IRQQLUBT.js → docDeleteCommands-I5WFAEHP.js} +63 -57
  179. package/{docReadCommands-LK37XH6L.js → docReadCommands-X53ELNIE.js} +61 -55
  180. package/{docStore-V2KECILA.js → docStore-2VAWVLWH.js} +21 -20
  181. package/{docUpdateCommands-O6T3HJHH.js → docUpdateCommands-6QPNDC7M.js} +64 -58
  182. package/{fetchMessages-NR4KNQLO.js → fetchMessages-TQEUZD7H.js} +8 -7
  183. package/{getPricing-2MNMXEVG.js → getPricing-MB2GBXOK.js} +6 -6
  184. package/{handleSendMessageAction-2PE25WM3.js → handleSendMessageAction-AAJOHXOB.js} +194 -302
  185. package/{hostCredentialCreate-S233UMAP.js → hostCredentialCreate-GLMJ22M6.js} +123 -114
  186. package/index.js +29 -29
  187. package/{keys-BEGDOTRL.js → keys-RWF7UCB4.js} +5 -4
  188. package/legacyMigration-TF4SYJCZ.js +19 -0
  189. package/{lib-5KKIBFIT.js → lib-OT5OTXRU.js} +7087 -6664
  190. package/{localDialogRead-7NNDVVF7.js → localDialogRead-SVTPA5GY.js} +3 -3
  191. package/{localFirstLog-DHNOY2NA.js → localFirstLog-OIETGK66.js} +1 -1
  192. package/localRecall-2J6QPOK2.js +15 -0
  193. package/{localRuntimeAdapter-KY6WXNBR.js → localRuntimeAdapter-BMP57P42.js} +119 -110
  194. package/{localRuntimeAuthority-OYH4AE4G.js → localRuntimeAuthority-IBJAT62G.js} +1 -1
  195. package/{localRuntimeDb-VBIMCWUC.js → localRuntimeDb-N7KHDXS2.js} +2 -2
  196. package/{machineCommands-Q6HA3IXF.js → machineCommands-3MLIAK5Q.js} +128 -119
  197. package/{machineInfo-UKPTZO5Y.js → machineInfo-LWHTEBHJ.js} +1 -1
  198. package/machineWsRunDispatch-FKIGROQF.js +191 -0
  199. package/{memberThunks-7EDJADWU.js → memberThunks-ZGLZ36PK.js} +29 -28
  200. package/{memoryCommands-ASCE5STX.js → memoryCommands-5WC3T66U.js} +4 -4
  201. package/models-ULVWLSQ6.js +9 -0
  202. package/{oauthTokenStore-OEERZFUC.js → oauthTokenStore-RUYNYALS.js} +1 -1
  203. package/{offlineMarxistsAgentCommand-2QTHJCHV.js → offlineMarxistsAgentCommand-4IC3Y4C6.js} +4 -4
  204. package/overlay-THLKYIWY.js +11 -0
  205. package/package.json +2 -2
  206. package/{pdf-U6KSUEZZ.js → pdf-KE3QI2V7.js} +1 -1
  207. package/{processSpawn-ZU5QFM43.js → processSpawn-6GEO77KV.js} +1 -1
  208. package/{profileConfig-KN3N2BLF.js → profileConfig-KOWK4HOG.js} +1 -1
  209. package/{projectArchive-DRTDIMEV.js → projectArchive-HK63GMF4.js} +52 -50
  210. package/{providerPresetApply-YXGV6NXB.js → providerPresetApply-OIFQ73LH.js} +19 -12
  211. package/{providerRegistry-S6UL6UNA.js → providerRegistry-KZ3SDZ3D.js} +10 -10
  212. package/{read-4V2RMG7N.js → read-MRQHJMJ2.js} +10 -10
  213. package/{readDocTool-BH6ATGQO.js → readDocTool-4BGTXTXA.js} +2 -2
  214. package/{readlineWorkspace-2W4WRCOU.js → readlineWorkspace-AKAHSCNY.js} +7982 -6274
  215. package/{removeDialogAgentAction-LYAZGNKW.js → removeDialogAgentAction-B6H7DXFM.js} +23 -22
  216. package/{runAgentClientLoop-J2VQBS2Z.js → runAgentClientLoop-UVAWGEON.js} +81 -79
  217. package/{runtimeDoctorCommands-QAI3MBKQ.js → runtimeDoctorCommands-FW6XKDUG.js} +12 -12
  218. package/{runtimeModeArgs-2Y7BALTO.js → runtimeModeArgs-X7DL7PUN.js} +1 -1
  219. package/secretCommands-LJXOOYA7.js +24 -0
  220. package/{setDialogExtraReferencesAction-OCRPGPYH.js → setDialogExtraReferencesAction-EVCY3TRW.js} +22 -21
  221. package/{setPrimaryDialogAgentAction-HFJDQIBU.js → setPrimaryDialogAgentAction-KPFVPHCJ.js} +23 -22
  222. package/{settingThunks-RAMHMTGM.js → settingThunks-ENOAK2WV.js} +97 -88
  223. package/{skillDiscovery-XKHROSH2.js → skillDiscovery-B5V23AXP.js} +4 -4
  224. package/{skillSummaryMarker-42HKSXYY.js → skillSummaryMarker-62UW7HI7.js} +1 -1
  225. package/{slateToRenderMarkdown-Y5IYN73U.js → slateToRenderMarkdown-R3X74MCX.js} +1 -1
  226. package/{slateUtils-NGV2NMKM.js → slateUtils-ESQAJ6RN.js} +1 -1
  227. package/{spaceCommands-KVJZVKVO.js → spaceCommands-DTTNAS2L.js} +61 -53
  228. package/store-JRVN62NM.js +46 -0
  229. package/{streamAgentChatTurn-GHBMJJ6S.js → streamAgentChatTurn-R5UY25VB.js} +875 -618
  230. package/{switchDialogAgentAction-EBRMW3RA.js → switchDialogAgentAction-SZ44XDRY.js} +21 -20
  231. package/{tableCommands-MP6VFSVT.js → tableCommands-HITDSLHS.js} +10 -10
  232. package/tombstones-FQQMEDOW.js +32 -0
  233. package/{toolApiClient-HGNO53TC.js → toolApiClient-OGQEBQVX.js} +4 -4
  234. package/{tools-EWKCPKMS.js → tools-HWFG6GMJ.js} +75 -74
  235. package/tuiSummaryLlmCaller-HQQZAMYF.js +44 -0
  236. package/{updateCommands-ZQYU6SCI.js → updateCommands-RJVCRSBP.js} +10 -8
  237. package/{updateDialogTitleAction-5GGMBTDF.js → updateDialogTitleAction-KNPOAMVS.js} +48 -46
  238. package/{usageCommand-F4IPVMIZ.js → usageCommand-FWZCB7AM.js} +11 -10
  239. package/{usageRebuildCommand-HAW2AD5N.js → usageRebuildCommand-SP2BLNJU.js} +12 -11
  240. package/userDataMerge-HT2ZVHBJ.js +13 -0
  241. package/{windowsSelfUpdate-257DV2T6.js → windowsSelfUpdate-KERHIAB4.js} +3 -3
  242. package/{workloadLifecycle-4C42SVBD.js → workloadLifecycle-DYNEYHV5.js} +6 -6
  243. package/agentRecordCommands-ZQ7SVYGG.js +0 -167
  244. package/agentRunCommand-WS7IGO2W.js +0 -196
  245. package/chunk-3CGG2PAL.js +0 -594
  246. package/chunk-5XBUWM6I.js +0 -89
  247. package/chunk-CJEIOP3E.js +0 -0
  248. package/chunk-EHGEOAHI.js +0 -636
  249. package/chunk-FW6YHHLI.js +0 -842
  250. package/chunk-GPVRUGGY.js +0 -115
  251. package/chunk-HSVBJRF4.js +0 -339
  252. package/chunk-WJZOQR2J.js +0 -151
  253. package/chunk-ZCWRMUWT.js +0 -89
  254. package/dist-M676ULYG.js +0 -7314
  255. package/machineWsRunDispatch-WWJQ6WR3.js +0 -182
  256. package/models-PJBE6JDV.js +0 -9
  257. package/tuiSummaryLlmCaller-ALQYUUWB.js +0 -189
  258. package/{chunk-WACI5I6V.js → chunk-2THCNKE4.js} +3 -3
  259. package/{chunk-2QHFH3DR.js → chunk-47ITIXO7.js} +6 -6
  260. package/{chunk-GOO6G4PY.js → chunk-CKG3PRZ7.js} +0 -0
  261. package/{chunk-OQHIVPG4.js → chunk-SNBZZPYH.js} +3 -3
  262. package/{chunk-AETZ7AD6.js → chunk-W6RFEDN4.js} +3 -3
@@ -1,10 +1,29 @@
1
- import {
2
- applyPublicAgentCatalogOverride
3
- } from "./chunk-H2TJUNCH.js";
4
1
  import {
5
2
  buildCliPrompt
6
3
  } from "./chunk-ATNTHIZI.js";
7
4
  import {
5
+ applyImageConfigRuntimeOverride,
6
+ buildDynamicContexts,
7
+ buildForegroundTurnAdmissionFetchInit,
8
+ buildStaticContexts,
9
+ compressOldToolResults,
10
+ consumeAgentRunStream,
11
+ mergeAgentToolsWithRuntime,
12
+ mergeContexts,
13
+ projectDesktopToolUiContent,
14
+ pushGate,
15
+ resolveImageGenerationStreamingState,
16
+ resolveTurnToolContext,
17
+ targetForRunKind,
18
+ validateAccessAndBalance,
19
+ withRequestContextBlocks
20
+ } from "./chunk-DWX2HEVC.js";
21
+ import {
22
+ resolveUserSkillRuntime
23
+ } from "./chunk-ODJ7BVSI.js";
24
+ import {
25
+ buildEmptyCompletionRepairBody,
26
+ buildFinalCompletionsRequestBody,
8
27
  deliverHtmlArtifactToolResult,
9
28
  filterAndCleanMessages,
10
29
  handleToolCalls,
@@ -12,12 +31,15 @@ import {
12
31
  readStreamChunk,
13
32
  sendOpenAICompletionsRequest,
14
33
  updateTotalUsage
15
- } from "./chunk-YJAFKXMU.js";
34
+ } from "./chunk-SVT62ULE.js";
16
35
  import "./chunk-JEXVIMYZ.js";
17
36
  import {
18
- prepareTools
19
- } from "./chunk-G2BQWAVT.js";
37
+ inlineImageUrlsForCustomProvider,
38
+ prepareTools,
39
+ shouldInlineImageUrlsForAgent
40
+ } from "./chunk-O6J3OTOP.js";
20
41
  import {
42
+ DirectApiKeyResolutionError,
21
43
  INVALID_TOOL_ARGS_REPLACEMENT,
22
44
  buildInvalidToolCallSelfHealResult,
23
45
  generateRequestBody,
@@ -27,259 +49,255 @@ import {
27
49
  sanitizeOutboundResponsesInput,
28
50
  selectResponsesConversationState,
29
51
  updateResponsesConversationState
30
- } from "./chunk-BBJ22CLB.js";
52
+ } from "./chunk-WUUH4LWZ.js";
31
53
  import "./chunk-HS7MLR74.js";
32
- import "./chunk-XHQC4PXX.js";
54
+ import "./chunk-B4GOW4MT.js";
33
55
  import "./chunk-KFHREHUQ.js";
34
56
  import {
35
57
  isOwnedAgentRecord,
36
58
  resolveBillingSource
37
- } from "./chunk-QG4AOSON.js";
38
- import "./chunk-PCLE46CE.js";
39
- import "./chunk-IXNGOHV5.js";
40
- import "./chunk-75XIDFBW.js";
41
- import {
42
- applyImageConfigRuntimeOverride,
43
- buildDynamicContexts,
44
- buildForegroundTurnAdmissionFetchInit,
45
- buildStaticContexts,
46
- compressOldToolResults,
47
- consumeAgentRunStream,
48
- mergeAgentToolsWithRuntime,
49
- mergeContexts,
50
- projectDesktopToolUiContent,
51
- resolveImageGenerationStreamingState,
52
- resolveTurnToolContext,
53
- trimMessagesWithSummary,
54
- validateAccessAndBalance,
55
- withRequestContextBlocks
56
- } from "./chunk-WYDI6TGM.js";
59
+ } from "./chunk-34J5K2YA.js";
57
60
  import {
58
- resolveUserSkillRuntime
59
- } from "./chunk-ZNWI6OVT.js";
60
- import {
61
- isContextOverflowText,
62
- parseApiError,
63
61
  performServerProxyFetchWithRetry
64
- } from "./chunk-TX5EYMGT.js";
62
+ } from "./chunk-GYVCJABP.js";
65
63
  import {
66
64
  createSSEParser,
67
65
  selectMaxExecutionTime,
68
66
  waitForAbortableDelay
69
- } from "./chunk-HUBHAQK2.js";
67
+ } from "./chunk-ON37YXGX.js";
70
68
  import "./chunk-NF64D32W.js";
71
69
  import "./chunk-3L2WKC3W.js";
72
- import "./chunk-R5O4QAWG.js";
73
- import "./chunk-6DWMYIUY.js";
74
- import "./chunk-MYOH447Z.js";
75
- import "./chunk-VF4K2QE6.js";
76
- import "./chunk-TAKB25RM.js";
77
- import "./chunk-RLBNLZVC.js";
70
+ import "./chunk-UB3D4TRQ.js";
71
+ import "./chunk-FJ23FZXF.js";
78
72
  import "./chunk-AGIM7IMJ.js";
79
- import "./chunk-INN4LTAJ.js";
80
- import {
81
- getPublicImageAgentDefaultProfile,
82
- getPublicImageAgentMode
83
- } from "./chunk-VIDPVFP3.js";
84
73
  import "./chunk-63W5N6P3.js";
85
- import "./chunk-LLRPJECG.js";
86
- import "./chunk-7Y4YTDQF.js";
74
+ import "./chunk-VF4K2QE6.js";
75
+ import "./chunk-IILMY4W4.js";
76
+ import "./chunk-7EEZJ6BS.js";
77
+ import "./chunk-4JVNURX4.js";
78
+ import "./chunk-DNKTQ3IN.js";
79
+ import "./chunk-SQYIK6HO.js";
80
+ import "./chunk-AK5O76CC.js";
81
+ import "./chunk-XWVCYUUU.js";
82
+ import "./chunk-YWWDC3O7.js";
87
83
  import {
88
84
  addToolMessage,
89
85
  addUserMessage,
90
- applyBuiltinAgentRuntimeOverride,
86
+ admitPendingUserMessages,
87
+ createUserBatchExecution,
91
88
  estimateMissingUsage,
92
89
  finalizeTransientMessageOnError,
93
90
  messageStreamEnd,
94
91
  messageStreaming,
95
92
  prepareAndPersistUserMessage,
96
93
  removeTransientMessage,
97
- resolveBuiltinPlatformAgentRecord,
94
+ runPendingUserBatchRequest,
95
+ selectAdmittedMessages,
98
96
  selectAllMsgs,
99
97
  selectCurrentDialogConfig,
100
98
  selectDialogConfigByKey,
99
+ snapshotUserBatchInput,
101
100
  toast,
101
+ updateDialogSummaryAction,
102
102
  updateTokens,
103
103
  updateToolMessage
104
- } from "./chunk-ZXOUUDCG.js";
104
+ } from "./chunk-MZLE5HQ3.js";
105
105
  import "./chunk-TZXPT53C.js";
106
- import "./chunk-7RFNTILS.js";
107
- import "./chunk-LEC5ALIN.js";
106
+ import "./chunk-BUDVRYES.js";
107
+ import "./chunk-KEPOVMF4.js";
108
108
  import "./chunk-523DITKR.js";
109
- import "./chunk-KFLT5KAD.js";
109
+ import "./chunk-NWP2OYOX.js";
110
110
  import {
111
111
  getCurrentSpaceId
112
- } from "./chunk-5XBUWM6I.js";
112
+ } from "./chunk-MBG66ZBH.js";
113
113
  import "./chunk-BYXBJQAS.js";
114
114
  import "./chunk-QYPE3TS3.js";
115
115
  import {
116
116
  createCliChatTurnStream,
117
117
  getCliChatSession,
118
118
  startCliChatSession
119
- } from "./chunk-NJLL224W.js";
120
- import "./chunk-4JH2UMJR.js";
121
- import "./chunk-GPVRUGGY.js";
122
- import "./chunk-UAD2WT54.js";
119
+ } from "./chunk-AD5EWDFD.js";
123
120
  import "./chunk-5RGU3J7P.js";
124
- import "./chunk-WPORQFYN.js";
125
- import "./chunk-MMA3LZ3W.js";
121
+ import "./chunk-UVLYNWIE.js";
122
+ import "./chunk-YNIYE47Z.js";
126
123
  import {
127
124
  addActiveController,
128
125
  claimDialogTurnPhase,
129
126
  clearDialogTurnPhase,
130
127
  clearPendingUserInputQueue,
131
128
  dequeueUserInput,
129
+ getDialogRuntimeState,
132
130
  removeActiveController,
133
131
  selectActiveControllers,
134
132
  selectPendingUserInputQueue,
135
133
  setDialogTurnPhase,
134
+ subscribe,
136
135
  tokenUsageLiveUpdate
137
- } from "./chunk-OWYYDMGJ.js";
138
- import "./chunk-YDH3FDFQ.js";
139
- import "./chunk-HPFCI4SK.js";
136
+ } from "./chunk-S2NTVGA2.js";
137
+ import "./chunk-5FUN7EG4.js";
140
138
  import {
141
139
  selectCurrentServer
142
- } from "./chunk-4I7ERB7F.js";
140
+ } from "./chunk-VREDDN25.js";
141
+ import "./chunk-HXER7YJF.js";
142
+ import "./chunk-JA3ICVJY.js";
143
+ import "./chunk-UAD2WT54.js";
143
144
  import {
144
145
  patch,
145
146
  read,
146
147
  selectById,
147
148
  write
148
- } from "./chunk-FW6YHHLI.js";
149
+ } from "./chunk-44X52WOJ.js";
149
150
  import "./chunk-3PVYUPXK.js";
150
- import "./chunk-COFEN36Z.js";
151
- import "./chunk-O2TZF4AI.js";
151
+ import "./chunk-C4WTX5TU.js";
152
+ import "./chunk-GBWGPTA7.js";
153
+ import "./chunk-WAE3GFCJ.js";
152
154
  import {
153
155
  selectRuntimeCurrentServer
154
- } from "./chunk-PYRUW7XN.js";
156
+ } from "./chunk-2VUZSVAS.js";
155
157
  import "./chunk-UEILX4EV.js";
156
- import "./chunk-P5L7CXOC.js";
158
+ import "./chunk-7Z6EW7AH.js";
157
159
  import {
158
160
  getIsDesktopApp
159
161
  } from "./chunk-AGP3YSEC.js";
160
162
  import "./chunk-QQ56R7KS.js";
161
- import "./chunk-OW765XBU.js";
162
163
  import {
163
164
  selectIdentityToken,
164
165
  selectIdentityUser,
165
166
  selectIdentityUserId
166
167
  } from "./chunk-PXYBUFDB.js";
167
- import "./chunk-EHSZD5OI.js";
168
- import "./chunk-SVYO6AO7.js";
169
- import "./chunk-WRYQ35LQ.js";
170
- import "./chunk-EHGEOAHI.js";
171
- import "./chunk-AETZ7AD6.js";
172
- import "./chunk-Y6ORVLSS.js";
173
- import "./chunk-KHCLMKZZ.js";
168
+ import "./chunk-BV3FLP2L.js";
169
+ import {
170
+ applyPublicAgentCatalogOverride
171
+ } from "./chunk-I4EADJ4P.js";
172
+ import {
173
+ applyBuiltinAgentRuntimeOverride,
174
+ resolveBuiltinPlatformAgentRecord
175
+ } from "./chunk-HYIETXA6.js";
174
176
  import {
175
177
  assertDesktopAgentRuntimeTurnBodyHasNoRawSecrets,
176
178
  buildDesktopAgentRuntimeAgentConfigSnapshot,
177
179
  buildDesktopAgentRuntimeDialogHistorySnapshot,
180
+ evaluateRequestBudget,
178
181
  extractImageUrlsFromMessages,
179
182
  stripImagePartsForTextOnlyAgent
180
- } from "./chunk-W4S457LU.js";
183
+ } from "./chunk-YU4ZPWVF.js";
184
+ import "./chunk-2WZXXAQD.js";
185
+ import "./chunk-OBWT45ZU.js";
181
186
  import {
182
187
  projectUserPartForModel
183
- } from "./chunk-4KB6WQUL.js";
188
+ } from "./chunk-BGP2EDFG.js";
184
189
  import "./chunk-56GBUMO5.js";
185
190
  import {
186
191
  isGptProModel,
187
192
  shouldBlockForGptPro
188
- } from "./chunk-5MQRBSMW.js";
193
+ } from "./chunk-EIAI3PPH.js";
194
+ import "./chunk-C4VAR65S.js";
195
+ import "./chunk-HOCHUZQ7.js";
196
+ import {
197
+ resolveRuntimeToolSurfaceForAgent
198
+ } from "./chunk-SOF4OWDM.js";
189
199
  import {
190
200
  extractImagePartsFromResponseOutput,
191
201
  extractTextFromResponseOutput,
192
202
  toResponsesTools
193
- } from "./chunk-H5HF7TJA.js";
203
+ } from "./chunk-MAIITKBT.js";
194
204
  import "./chunk-E2BESSAW.js";
195
- import "./chunk-RZOV7OMV.js";
196
- import "./chunk-3UKL3HPD.js";
197
205
  import {
198
- resolveRuntimeToolSurfaceForAgent
199
- } from "./chunk-KC4XDTT3.js";
200
- import "./chunk-YB3YZK56.js";
201
- import "./chunk-YWSEPJ7C.js";
202
- import "./chunk-WJZOQR2J.js";
206
+ isContextOverflowText,
207
+ parseApiError
208
+ } from "./chunk-TLE77UJ5.js";
209
+ import "./chunk-FS2XP5D7.js";
203
210
  import {
204
211
  resolveAgentCallPlan,
205
212
  resolveClientWire
206
- } from "./chunk-UHJGXRJ4.js";
213
+ } from "./chunk-KQSYAIZR.js";
207
214
  import {
208
215
  resolveAgentContextWindow
209
- } from "./chunk-V5Y3R6BT.js";
216
+ } from "./chunk-NIZ2BXFD.js";
217
+ import "./chunk-5ZUL4CUO.js";
210
218
  import {
211
219
  getModelInfo
212
- } from "./chunk-7BT37FK3.js";
220
+ } from "./chunk-RDH5CQ4T.js";
213
221
  import "./chunk-H57T64RA.js";
214
- import "./chunk-5ZUL4CUO.js";
215
222
  import {
216
223
  isOAuthApiKeyRef
217
224
  } from "./chunk-UKZX3NHN.js";
218
225
  import "./chunk-5MMAK75Q.js";
219
- import "./chunk-2QHFH3DR.js";
220
- import "./chunk-OQHIVPG4.js";
226
+ import "./chunk-47ITIXO7.js";
221
227
  import {
222
228
  asRecordOrEmpty
223
229
  } from "./chunk-KX6YBIHG.js";
230
+ import "./chunk-SNBZZPYH.js";
224
231
  import "./chunk-DWLEOOGR.js";
232
+ import "./chunk-OW765XBU.js";
225
233
  import {
226
234
  isAbortError
227
235
  } from "./chunk-7DPNBQSV.js";
228
- import "./chunk-T43B7LB2.js";
229
- import "./chunk-ZRSNONOB.js";
230
- import "./chunk-4VJAC32I.js";
231
- import "./chunk-CJEIOP3E.js";
232
- import "./chunk-ZCWRMUWT.js";
233
- import "./chunk-ZC3CMUKU.js";
236
+ import "./chunk-WKGQSYTB.js";
237
+ import {
238
+ isAntigravityOAuthAgent
239
+ } from "./chunk-SY3C4SQ7.js";
240
+ import "./chunk-PJCIP64Z.js";
241
+ import "./chunk-6OVNSQHN.js";
242
+ import "./chunk-W6RFEDN4.js";
243
+ import "./chunk-7ET2U67U.js";
234
244
  import {
235
245
  isSystemBuiltinTrustedAgentKey
236
- } from "./chunk-LOEO7LRC.js";
246
+ } from "./chunk-3IK6ILVW.js";
237
247
  import {
238
248
  extractCustomId
239
249
  } from "./chunk-M2EJHDJP.js";
250
+ import "./chunk-SYTHYBMI.js";
240
251
  import {
241
- isAntigravityOAuthAgent
242
- } from "./chunk-KIM6CLW5.js";
243
- import "./chunk-ALQ3657A.js";
252
+ createDialogMessageKeyAndId,
253
+ dialogMessageKey
254
+ } from "./chunk-OJKUU3LP.js";
255
+ import "./chunk-YZMNK53S.js";
256
+ import "./chunk-I42VC5KR.js";
257
+ import "./chunk-FJK526XH.js";
258
+ import {
259
+ getPublicImageAgentDefaultProfile,
260
+ getPublicImageAgentMode
261
+ } from "./chunk-VIDPVFP3.js";
262
+ import "./chunk-4JH2UMJR.js";
263
+ import "./chunk-JWXITTQB.js";
264
+ import "./chunk-L5I543VB.js";
265
+ import "./chunk-KHCLMKZZ.js";
266
+ import "./chunk-AMEOV5VZ.js";
267
+ import "./chunk-EWQ3HGNZ.js";
244
268
  import {
245
269
  estimateTokenCount
246
270
  } from "./chunk-PSCNXBYA.js";
247
- import "./chunk-TCZHTTUU.js";
271
+ import "./chunk-I7WBYGBP.js";
248
272
  import {
249
273
  isOpenAiResponsesModel
250
- } from "./chunk-YUA6OAH5.js";
251
- import {
252
- getApiEndpoint
253
- } from "./chunk-SM3NSZJV.js";
254
- import "./chunk-JRTNUU5Z.js";
274
+ } from "./chunk-MDLS23JK.js";
255
275
  import {
256
276
  toErrorMessage
257
277
  } from "./chunk-HNMXYYJR.js";
278
+ import {
279
+ asTrimmedString
280
+ } from "./chunk-3EUW3WEO.js";
281
+ import {
282
+ getApiEndpoint
283
+ } from "./chunk-2UCBGYO4.js";
284
+ import "./chunk-JRTNUU5Z.js";
258
285
  import {
259
286
  isRecord
260
287
  } from "./chunk-KUG52IAP.js";
261
- import "./chunk-GOO6G4PY.js";
288
+ import "./chunk-CKG3PRZ7.js";
262
289
  import "./chunk-QSJ3HFEF.js";
263
- import "./chunk-LCBAMY2M.js";
264
- import "./chunk-4SN6J65J.js";
265
- import "./chunk-CF7PE763.js";
266
- import "./chunk-G7Y4GXTY.js";
267
- import "./chunk-6UBGXX2W.js";
268
- import "./chunk-JY5NGFFH.js";
269
- import {
270
- createDialogMessageKeyAndId,
271
- dialogMessageKey
272
- } from "./chunk-XJWWBO34.js";
273
- import "./chunk-I42VC5KR.js";
274
290
  import "./chunk-U6VC4MU4.js";
275
291
  import "./chunk-WWC7I6TA.js";
276
- import {
277
- asTrimmedString
278
- } from "./chunk-3EUW3WEO.js";
292
+ import "./chunk-LCBAMY2M.js";
279
293
  import {
280
294
  asOptionalTrimmedString
281
295
  } from "./chunk-G3SUCT4W.js";
282
- import "./chunk-4VNS5WPM.js";
296
+ import "./chunk-4SN6J65J.js";
297
+ import "./chunk-CF7PE763.js";
298
+ import "./chunk-G7Y4GXTY.js";
299
+ import "./chunk-6UBGXX2W.js";
300
+ import "./chunk-U67V476Y.js";
283
301
 
284
302
  // packages/ai/agent/isVoiceModel.ts
285
303
  function isVoiceModel(model, provider) {
@@ -476,6 +494,40 @@ var hasReportedTokenOrCostUsage = (usage) => {
476
494
  var shouldSkipBillingForUserAbort = (error, usage) => {
477
495
  return isAbortError(error) && !hasReportedTokenOrCostUsage(usage);
478
496
  };
497
+ function buildResponsesRequestBodyWithTools(bodyData, agentConfig) {
498
+ const functionTools = getModelInfo(agentConfig.model)?.hasImageOutput ? [] : prepareTools(agentConfig.tools ?? [], { provider: agentConfig.provider });
499
+ const imageMode = getPublicImageAgentMode(agentConfig);
500
+ const imageProfile = imageMode === "continuous" ? getPublicImageAgentDefaultProfile("continuous") : null;
501
+ const imageGenerationModel = asOptionalTrimmedString(
502
+ agentConfig?.imageModel
503
+ );
504
+ const tools = [
505
+ ...toResponsesTools(functionTools) ?? [],
506
+ ...shouldEnableBuiltInImageGeneration(agentConfig) ? [
507
+ {
508
+ type: "image_generation",
509
+ ...imageGenerationModel ? { model: imageGenerationModel } : {}
510
+ }
511
+ ] : [],
512
+ ...imageMode === "continuous" ? [
513
+ {
514
+ type: "image_generation",
515
+ action: "auto",
516
+ ...imageGenerationModel ? { model: imageGenerationModel } : {},
517
+ quality: imageProfile?.quality,
518
+ output_format: imageProfile?.outputFormat
519
+ }
520
+ ] : []
521
+ ];
522
+ const sourceBodyData = bodyData;
523
+ const sanitizedInput = Array.isArray(sourceBodyData?.input) ? sanitizeOutboundResponsesInput(sourceBodyData.input) : sourceBodyData?.input;
524
+ const baseBodyData = sanitizedInput !== sourceBodyData?.input ? { ...sourceBodyData, input: sanitizedInput } : sourceBodyData;
525
+ return {
526
+ ...baseBodyData,
527
+ ...tools.length ? { tools, tool_choice: baseBodyData.tool_choice ?? "auto" } : {},
528
+ stream: true
529
+ };
530
+ }
479
531
  var sendOpenAIResponseRequest = async ({
480
532
  bodyData,
481
533
  agentConfig,
@@ -744,39 +796,7 @@ var sendOpenAIResponseRequest = async ({
744
796
  })
745
797
  );
746
798
  }
747
- const functionTools = getModelInfo(agentConfig.model)?.hasImageOutput ? [] : prepareTools(agentConfig.tools ?? [], { provider: agentConfig.provider });
748
- const imageMode = getPublicImageAgentMode(agentConfig);
749
- const imageProfile = imageMode === "continuous" ? getPublicImageAgentDefaultProfile("continuous") : null;
750
- const imageGenerationModel = asOptionalTrimmedString(
751
- agentConfig?.imageModel
752
- );
753
- const tools = [
754
- ...toResponsesTools(functionTools) ?? [],
755
- ...shouldEnableBuiltInImageGeneration(agentConfig) ? [
756
- {
757
- type: "image_generation",
758
- ...imageGenerationModel ? { model: imageGenerationModel } : {}
759
- }
760
- ] : [],
761
- ...imageMode === "continuous" ? [
762
- {
763
- type: "image_generation",
764
- action: "auto",
765
- ...imageGenerationModel ? { model: imageGenerationModel } : {},
766
- quality: imageProfile?.quality,
767
- output_format: imageProfile?.outputFormat
768
- }
769
- ] : []
770
- ];
771
- const buildRequestBody = (sourceBodyData) => {
772
- const sanitizedInput = Array.isArray(sourceBodyData?.input) ? sanitizeOutboundResponsesInput(sourceBodyData.input) : sourceBodyData?.input;
773
- const baseBodyData = sanitizedInput !== sourceBodyData?.input ? { ...sourceBodyData, input: sanitizedInput } : sourceBodyData;
774
- return {
775
- ...baseBodyData,
776
- ...tools.length ? { tools, tool_choice: baseBodyData.tool_choice ?? "auto" } : {},
777
- stream: true
778
- };
779
- };
799
+ const buildRequestBody = (body) => buildResponsesRequestBodyWithTools(body, agentConfig);
780
800
  let requestBody = buildRequestBody(bodyData);
781
801
  const fallbackRequestBody = fallbackBodyData ? buildRequestBody(fallbackBodyData) : null;
782
802
  const api = getApiEndpoint(agentConfig);
@@ -1146,6 +1166,81 @@ var buildAgentViewMessages = (allMessages, currentAgentKey) => {
1146
1166
  return result;
1147
1167
  };
1148
1168
 
1169
+ // packages/ai/agent/requestAdmission.ts
1170
+ function projectSummaryHistory(messages, summary, anchor) {
1171
+ if (!summary || !anchor) return messages;
1172
+ const covered = messages.findIndex((message) => message.id === anchor);
1173
+ if (covered < 0) return messages;
1174
+ let start = covered + 1;
1175
+ while (start > 0 && messages[start]?.role === "tool") start--;
1176
+ const latestUser = messages.map((message) => message.role).lastIndexOf("user");
1177
+ const suffix = messages.slice(start);
1178
+ return latestUser >= 0 && latestUser < start ? [messages[latestUser], ...suffix] : suffix;
1179
+ }
1180
+ var UNKNOWN_IMAGE_RESERVE_TOKENS = 4096;
1181
+ function projectWireImageCosts(items) {
1182
+ let imageCount = 0;
1183
+ if (!Array.isArray(items)) return { projected: items, imageCount };
1184
+ const projected = items.map((message) => {
1185
+ if (!message || !Array.isArray(message.content)) return message;
1186
+ return { ...message, content: message.content.map((part) => {
1187
+ if (part?.type === "image_url" && typeof part.image_url?.url === "string") {
1188
+ imageCount++;
1189
+ return { type: "image_url", image_url: { detail: part.image_url.detail } };
1190
+ }
1191
+ if (part?.type === "input_image" && (typeof part.image_url === "string" || typeof part.file_id === "string")) {
1192
+ imageCount++;
1193
+ return { type: "input_image", detail: part.detail };
1194
+ }
1195
+ return part;
1196
+ }) };
1197
+ });
1198
+ return { projected, imageCount };
1199
+ }
1200
+ function estimateWebRequestBudget(body, contextWindow) {
1201
+ const { messages, input, instructions, tools, ...other } = body;
1202
+ const count = (value) => value == null ? 0 : estimateTokenCount(JSON.stringify(value));
1203
+ const projectedMessages = projectWireImageCosts(messages);
1204
+ const projectedInput = projectWireImageCosts(input);
1205
+ const unknownImageCount = projectedMessages.imageCount + projectedInput.imageCount;
1206
+ const heuristicImageReserveTokens = unknownImageCount * UNKNOWN_IMAGE_RESERVE_TOKENS;
1207
+ const cap = body.max_output_tokens ?? body.max_completion_tokens ?? body.max_tokens;
1208
+ const decision = evaluateRequestBudget({
1209
+ contextWindow,
1210
+ messageTokens: count(projectedMessages.projected) + count(projectedInput.projected) + count(instructions),
1211
+ toolSchemaTokens: count(tools),
1212
+ otherInputTokens: count(other) + heuristicImageReserveTokens,
1213
+ protocolReserveTokens: 1024,
1214
+ output: { semantics: "unknown", fallbackReserveTokens: cap === void 0 ? 8192 : Number(cap) }
1215
+ });
1216
+ return { ...decision, unknownImageCount, heuristicImageReserveTokens, imageCostBasis: "unknown-provider-heuristic" };
1217
+ }
1218
+ async function admitWebRequest(options) {
1219
+ for (let attempt = 0; attempt < 2; attempt++) {
1220
+ if (options.signal.aborted) {
1221
+ const error = new Error("Request admission aborted");
1222
+ error.name = "AbortError";
1223
+ throw options.signal.reason ?? error;
1224
+ }
1225
+ const request = await options.build();
1226
+ if (options.signal.aborted) {
1227
+ const error = new Error("Request admission aborted");
1228
+ error.name = "AbortError";
1229
+ throw options.signal.reason ?? error;
1230
+ }
1231
+ const decisions = request.wireBodies.map((body) => estimateWebRequestBudget(body, options.contextWindow));
1232
+ if (decisions.length && decisions.every((decision) => decision.fitsEstimate)) return request.value;
1233
+ if (attempt) throw new Error("Context budget exceeded after budget_rescue; request not sent (heuristic estimate)");
1234
+ const allowances = request.wireBodies.map((body) => {
1235
+ const systemOnly = (items) => Array.isArray(items) ? items.filter((item) => item.role === "system" || item.role === "developer") : items;
1236
+ const external = estimateWebRequestBudget({ ...body, messages: systemOnly(body.messages), input: systemOnly(body.input) }, options.contextWindow);
1237
+ return Math.max(0, external.availableInputTokens - external.estimatedInputTokens);
1238
+ });
1239
+ await options.rescue(Math.min(...allowances));
1240
+ }
1241
+ throw new Error("Context budget admission failed");
1242
+ }
1243
+
1149
1244
  // packages/ai/agent/platformPaidCall.ts
1150
1245
  var asTrimmed = (value) => typeof value === "string" ? value.trim() : "";
1151
1246
  var hasOAuthCredentialShape = (agentConfig) => isOAuthApiKeyRef(agentConfig?.apiKeyRef) || isAntigravityOAuthAgent({
@@ -1236,13 +1331,14 @@ function buildDesktopAgentRuntimeTurnBody(args) {
1236
1331
  } else if (Array.isArray(args.dialogMessages) && continueDialogId) {
1237
1332
  dialogHistorySnapshot = buildDesktopAgentRuntimeDialogHistorySnapshot({
1238
1333
  dialogId: continueDialogId,
1239
- messages: args.dialogMessages,
1240
- currentInput: args.input
1334
+ messages: args.userMessages?.length ? args.dialogMessages.filter((message) => !args.userMessages.some((user) => user.cliMessageId === message.id)) : args.dialogMessages,
1335
+ currentInput: args.userMessages?.length ? void 0 : args.input
1241
1336
  }) ?? void 0;
1242
1337
  }
1243
1338
  const body = {
1244
1339
  agentRef: args.agentRef,
1245
1340
  input: args.input,
1341
+ ...args.userMessages?.length ? { userMessages: args.userMessages } : {},
1246
1342
  ...Array.isArray(args.contextBlocks) && args.contextBlocks.length > 0 ? { contextBlocks: args.contextBlocks } : {},
1247
1343
  ...args.runtimeContext ? { runtimeContext: args.runtimeContext } : {},
1248
1344
  ...continueDialogId ? { continueDialogId } : {},
@@ -1988,6 +2084,7 @@ var streamAgentChatTurnHandler = async (args, thunkApi) => {
1988
2084
  let loopKey = null;
1989
2085
  let runtimeDialogKey = explicitDialogKey ?? null;
1990
2086
  let turnPhaseTurnId = null;
2087
+ const batchExecution = createUserBatchExecution(loopController.signal, () => !thunkApi.signal.aborted && (!turnPhaseTurnId || !runtimeDialogKey || getDialogRuntimeState(runtimeDialogKey).turnPhaseTurnId === turnPhaseTurnId));
1991
2088
  let remoteTransientMessageId = null;
1992
2089
  let remoteTransientMessageFinalized = false;
1993
2090
  let modelRequestStarted = false;
@@ -2123,7 +2220,7 @@ var streamAgentChatTurnHandler = async (args, thunkApi) => {
2123
2220
  if (boundMachineId) {
2124
2221
  const token = selectIdentityToken(currentState);
2125
2222
  const authHeader = token ? `Bearer ${token}` : "";
2126
- const rawMessages = selectAllMsgs(currentState, dialogId2);
2223
+ const rawMessages = selectAdmittedMessages(selectAllMsgs(currentState, dialogId2));
2127
2224
  const visibleMessages = buildAgentViewMessages(
2128
2225
  rawMessages,
2129
2226
  agentConfig.dbKey
@@ -2184,15 +2281,16 @@ var streamAgentChatTurnHandler = async (args, thunkApi) => {
2184
2281
  ...Array.isArray(contextBlocks) && contextBlocks.length > 0 ? { contextBlocks } : {},
2185
2282
  messages: cleanedMessages,
2186
2283
  stream: true,
2187
- persistDialog: false,
2188
- clientDialogId: dialogId2,
2284
+ persistDialog: true,
2285
+ continueDialogId: dialogId2,
2189
2286
  ...explicitTarget ? { runtimeTarget: explicitTarget } : {},
2190
2287
  runtimeContext: {
2191
2288
  surface: "web",
2192
2289
  host: "browser",
2193
2290
  runtime: "react",
2194
2291
  entrypoint: "chat-dialog",
2195
- capabilities: ["streaming", "dialog-ui", "machine-bound-cli"]
2292
+ capabilities: ["streaming", "dialog-ui", "machine-bound-cli", "durable-user-batch", "client-user-prepersisted"],
2293
+ userMessageId: selectAdmittedMessages(selectAllMsgs(getState(), dialogId2)).filter((message) => message.role === "user").at(-1)?.id
2196
2294
  },
2197
2295
  ...dialogConfig?.spaceId ? { spaceId: dialogConfig.spaceId } : {}
2198
2296
  }),
@@ -2239,6 +2337,15 @@ var streamAgentChatTurnHandler = async (args, thunkApi) => {
2239
2337
  if (payload.type === "error") {
2240
2338
  return { reject: payload.message || "\u7535\u8111\u7AEF Agent \u6267\u884C\u5931\u8D25" };
2241
2339
  }
2340
+ if (payload.type === "action_gate" && payload.gate) {
2341
+ pushGate(
2342
+ payload.gate,
2343
+ targetForRunKind("server-run", {
2344
+ server: currentServer2,
2345
+ token
2346
+ })
2347
+ );
2348
+ }
2242
2349
  remoteToolHandlers.handleToolPayload(payload);
2243
2350
  if (payload.type === "text" && typeof payload.content === "string") {
2244
2351
  accumulated2 += payload.content;
@@ -2547,6 +2654,8 @@ var streamAgentChatTurnHandler = async (args, thunkApi) => {
2547
2654
  dialogKey,
2548
2655
  dialogId
2549
2656
  });
2657
+ turnPhaseTurnId = `turn-phase:${dialogId}:${crypto.randomUUID()}`;
2658
+ claimDialogTurnPhase({ dialogKey, turnId: turnPhaseTurnId });
2550
2659
  if (shouldUseDesktopLocalRuntime(agentConfig, explicitTarget)) {
2551
2660
  const desktopMessageMetadata = buildMessageMetadata(agentConfig);
2552
2661
  const w2 = typeof globalThis !== "undefined" && globalThis.window ? globalThis.window : null;
@@ -2554,428 +2663,489 @@ var streamAgentChatTurnHandler = async (args, thunkApi) => {
2554
2663
  dispatch(addActiveController({ messageId: loopKey, controller: loopController, dialogKey }));
2555
2664
  turnPhaseTurnId = `turn-phase:${dialogId}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2, 8)}`;
2556
2665
  claimDialogTurnPhase({ dialogKey, turnId: turnPhaseTurnId });
2557
- let currentContent = "";
2558
- const assistantSegments = [];
2559
- let assistantMessageKeys = null;
2560
- let streamResult = null;
2561
- let streamError = null;
2562
- let reasoningBuffer = "";
2563
- const activeToolMessages = /* @__PURE__ */ new Map();
2564
- let desktopToolExecutionLocation = void 0;
2565
- const ensureAssistantMessageKeys = () => {
2566
- if (!assistantMessageKeys) {
2567
- assistantMessageKeys = createDialogMessageKeyAndId(dialogId);
2568
- assistantSegments.push({
2569
- key: assistantMessageKeys.key,
2570
- messageId: assistantMessageKeys.messageId,
2571
- content: "",
2572
- finalized: false,
2573
- toolCallIds: []
2574
- });
2575
- remoteTransientMessageId = assistantMessageKeys.messageId;
2666
+ const ownsDesktopTurn = () => !loopController.signal.aborted && !thunkApi.signal.aborted && getDialogRuntimeState(dialogKey).turnPhaseTurnId === turnPhaseTurnId;
2667
+ const admitDesktopBatch = async () => {
2668
+ const admission = new AbortController();
2669
+ const checkOwner = () => {
2670
+ if (!ownsDesktopTurn()) admission.abort();
2671
+ };
2672
+ const unsubscribe = subscribe(checkOwner);
2673
+ loopController.signal.addEventListener("abort", checkOwner);
2674
+ thunkApi.signal.addEventListener("abort", checkOwner);
2675
+ checkOwner();
2676
+ try {
2677
+ return await dispatch(admitPendingUserMessages({ dialogKey, signal: admission.signal })).unwrap();
2678
+ } finally {
2679
+ unsubscribe();
2680
+ loopController.signal.removeEventListener("abort", checkOwner);
2681
+ thunkApi.signal.removeEventListener("abort", checkOwner);
2576
2682
  }
2577
- return assistantMessageKeys;
2578
- };
2579
- const streamDesktopAssistantUpsert = () => {
2580
- const { key: msgKey2, messageId: messageId2 } = ensureAssistantMessageKeys();
2581
- const segment2 = assistantSegments[assistantSegments.length - 1];
2582
- segment2.content = currentContent;
2583
- dispatch(messageStreaming({
2584
- id: messageId2,
2585
- dialogId,
2586
- dbKey: msgKey2,
2587
- content: currentContent,
2588
- role: "assistant",
2589
- isStreaming: true,
2590
- thinkContent: reasoningBuffer,
2591
- ...desktopMessageMetadata
2592
- }));
2593
- };
2594
- const streamDesktopAssistantText = (text) => {
2595
- currentContent += text;
2596
- streamDesktopAssistantUpsert();
2597
2683
  };
2598
- const finalizeCurrentAssistantSegmentForTool = () => {
2599
- const segment2 = assistantSegments[assistantSegments.length - 1];
2600
- if (segment2) {
2684
+ const sameInput = (content) => JSON.stringify(content) === JSON.stringify(userInput);
2685
+ const initialMessages = selectAllMsgs(getState(), dialogId);
2686
+ const initialUser = initialMessages.filter((message) => message.role === "user" && sameInput(message.content)).at(-1);
2687
+ const isUserTurn = !!initialUser && sameInput(initialUser.content);
2688
+ let desktopBatch = isUserTurn && initialUser.metadata?.queueState === "pending" ? await admitDesktopBatch() : isUserTurn ? [...initialMessages.filter((message) => message.role === "user" && message.id !== initialUser.id && message.metadata?.userBatchPhase === "admitted"), initialUser] : [];
2689
+ if (!ownsDesktopTurn()) return { aborted: true };
2690
+ while (ownsDesktopTurn()) {
2691
+ const desktopRequestUserInput = snapshotUserBatchInput(desktopBatch.length ? desktopBatch : selectAllMsgs(getState(), dialogId));
2692
+ const desktopInput = desktopBatch.length ? desktopBatch[desktopBatch.length - 1].content : userInput;
2693
+ let currentContent = "";
2694
+ const assistantSegments = [];
2695
+ let assistantMessageKeys = null;
2696
+ let streamResult = null;
2697
+ let streamError = null;
2698
+ let reasoningBuffer = "";
2699
+ const activeToolMessages = /* @__PURE__ */ new Map();
2700
+ let desktopToolExecutionLocation = void 0;
2701
+ const ensureAssistantMessageKeys = () => {
2702
+ if (!assistantMessageKeys) {
2703
+ assistantMessageKeys = createDialogMessageKeyAndId(dialogId);
2704
+ assistantSegments.push({
2705
+ key: assistantMessageKeys.key,
2706
+ messageId: assistantMessageKeys.messageId,
2707
+ content: "",
2708
+ finalized: false,
2709
+ toolCallIds: []
2710
+ });
2711
+ remoteTransientMessageId = assistantMessageKeys.messageId;
2712
+ }
2713
+ return assistantMessageKeys;
2714
+ };
2715
+ const streamDesktopAssistantUpsert = () => {
2716
+ const { key: msgKey2, messageId: messageId2 } = ensureAssistantMessageKeys();
2717
+ const segment2 = assistantSegments[assistantSegments.length - 1];
2601
2718
  segment2.content = currentContent;
2602
- segment2.finalized = true;
2603
- }
2604
- if (assistantMessageKeys && (currentContent.length > 0 || reasoningBuffer.length > 0)) {
2605
- dispatch(updateToolMessage({
2606
- id: assistantMessageKeys.messageId,
2719
+ dispatch(messageStreaming({
2720
+ id: messageId2,
2607
2721
  dialogId,
2608
- changes: {
2609
- content: currentContent,
2610
- thinkContent: reasoningBuffer,
2611
- isStreaming: false
2612
- }
2722
+ dbKey: msgKey2,
2723
+ content: currentContent,
2724
+ role: "assistant",
2725
+ isStreaming: true,
2726
+ thinkContent: reasoningBuffer,
2727
+ ...desktopMessageMetadata
2613
2728
  }));
2614
- }
2615
- assistantMessageKeys = null;
2616
- currentContent = "";
2617
- };
2618
- try {
2619
- const desktopAgentRef = agentConfig.dbKey || agentKey;
2620
- const eventStream = runDesktopAgentRuntimeTurnStream({
2621
- agentRef: desktopAgentRef,
2622
- input: userInput,
2623
- ...Array.isArray(contextBlocks) && contextBlocks.length > 0 ? { contextBlocks } : {},
2624
- continueDialogId: dialogId,
2625
- dialogKey,
2626
- cwd: runtimeOptions?.cwd,
2627
- restrictShellToWorkspace: runtimeOptions?.restrictShellToWorkspace === true,
2628
- workspaceToolsHint: runtimeOptions?.workspaceToolsHint === true,
2629
- agentConfigSnapshot: agentConfig,
2630
- dialogMessages: selectAllMsgs(getState(), dialogId),
2631
- signal: loopController.signal,
2632
- // SSE 传输层兜底(review 修复 4):此前本调用方从不传
2633
- // noEventWatchdogMs,watchdog 永远关闭——「已有安全网」只是
2634
- // 错觉,挂起点若在 provider.complete 之外(resolveProvider /
2635
- // adapter 内部,runtime 没有任何 deadline)就会无限静默。
2636
- // 量级必须大于 runtime 自己的 idle 窗(默认 10 分钟无新输出
2637
- // 才放弃,见 localLoop.DEFAULT_LLM_REQUEST_TIMEOUT_MS),
2638
- // 否则一个健康的慢思考轮次会被客户端提前判死,用户拿到的是
2639
- // 未分类的 "stream stalled" 而不是 runtime 的
2640
- // LLM_REQUEST_TIMEOUT 可操作文案。取 2× = 20 分钟:
2641
- // 只兜「runtime 完全没 deadline」的真悬挂。
2642
- noEventWatchdogMs: DESKTOP_SSE_NO_EVENT_WATCHDOG_MS
2643
- });
2644
- for await (const event of eventStream) {
2645
- if (loopController.signal.aborted || thunkApi.signal.aborted) {
2646
- if (w2) w2.__LOOP_STOP_REASON__ = "aborted";
2647
- break;
2729
+ };
2730
+ const streamDesktopAssistantText = (text) => {
2731
+ currentContent += text;
2732
+ streamDesktopAssistantUpsert();
2733
+ };
2734
+ const finalizeCurrentAssistantSegmentForTool = () => {
2735
+ const segment2 = assistantSegments[assistantSegments.length - 1];
2736
+ if (segment2) {
2737
+ segment2.content = currentContent;
2738
+ segment2.finalized = true;
2648
2739
  }
2649
- if (event.type === "delta") {
2650
- streamDesktopAssistantText(event.text);
2651
- } else if (event.type === "thinking") {
2652
- if (typeof event.content === "string") {
2653
- reasoningBuffer += event.content;
2654
- streamDesktopAssistantUpsert();
2740
+ if (assistantMessageKeys && (currentContent.length > 0 || reasoningBuffer.length > 0)) {
2741
+ dispatch(updateToolMessage({
2742
+ id: assistantMessageKeys.messageId,
2743
+ dialogId,
2744
+ changes: {
2745
+ content: currentContent,
2746
+ thinkContent: reasoningBuffer,
2747
+ isStreaming: false
2748
+ }
2749
+ }));
2750
+ }
2751
+ assistantMessageKeys = null;
2752
+ currentContent = "";
2753
+ };
2754
+ try {
2755
+ const desktopAgentRef = agentConfig.dbKey || agentKey;
2756
+ const eventStream = await dispatch(runPendingUserBatchRequest({
2757
+ dialogKey,
2758
+ signal: loopController.signal,
2759
+ execution: batchExecution,
2760
+ requestUserInput: desktopRequestUserInput,
2761
+ owns: ownsDesktopTurn,
2762
+ start: () => {
2763
+ const iterator = runDesktopAgentRuntimeTurnStream({
2764
+ agentRef: desktopAgentRef,
2765
+ input: desktopInput,
2766
+ ...desktopBatch.length ? {
2767
+ userMessages: desktopBatch.map((message) => ({
2768
+ role: "user",
2769
+ content: message.content,
2770
+ cliMessageId: message.id
2771
+ })),
2772
+ runtimeContext: { userMessageId: desktopBatch[desktopBatch.length - 1].id }
2773
+ } : {},
2774
+ ...Array.isArray(contextBlocks) && contextBlocks.length > 0 ? { contextBlocks } : {},
2775
+ continueDialogId: dialogId,
2776
+ dialogKey,
2777
+ cwd: runtimeOptions?.cwd,
2778
+ restrictShellToWorkspace: runtimeOptions?.restrictShellToWorkspace === true,
2779
+ workspaceToolsHint: runtimeOptions?.workspaceToolsHint === true,
2780
+ agentConfigSnapshot: agentConfig,
2781
+ dialogMessages: selectAdmittedMessages(selectAllMsgs(getState(), dialogId)),
2782
+ signal: loopController.signal,
2783
+ // SSE 传输层兜底(review 修复 4):此前本调用方从不传
2784
+ // noEventWatchdogMs,watchdog 永远关闭——「已有安全网」只是
2785
+ // 错觉,挂起点若在 provider.complete 之外(resolveProvider /
2786
+ // adapter 内部,runtime 没有任何 deadline)就会无限静默。
2787
+ // 量级必须大于 runtime 自己的 idle 窗(默认 10 分钟无新输出
2788
+ // 才放弃,见 localLoop.DEFAULT_LLM_REQUEST_TIMEOUT_MS),
2789
+ // 否则一个健康的慢思考轮次会被客户端提前判死,用户拿到的是
2790
+ // 未分类的 "stream stalled" 而不是 runtime 的
2791
+ // LLM_REQUEST_TIMEOUT 可操作文案。取 2× = 20 分钟:
2792
+ // 只兜「runtime 完全没 deadline」的真悬挂。
2793
+ noEventWatchdogMs: DESKTOP_SSE_NO_EVENT_WATCHDOG_MS
2794
+ });
2795
+ const first = iterator.next();
2796
+ return async function* () {
2797
+ const event = await first;
2798
+ if (!event.done) yield event.value;
2799
+ yield* iterator;
2800
+ }();
2655
2801
  }
2656
- } else if (event.type === "tool") {
2657
- const toolEvent = event.event;
2658
- const callId = toolEvent.toolCallId;
2659
- if (!callId) continue;
2660
- if (toolEvent.type === "tool-call") {
2661
- attachToolCallIdToSegment(assistantSegments, callId);
2662
- finalizeCurrentAssistantSegmentForTool();
2663
- const { key: dbKey, messageId: toolMsgId } = createDialogMessageKeyAndId(dialogId);
2664
- const toolMsg = {
2665
- id: toolMsgId,
2666
- dialogId,
2667
- dbKey,
2668
- role: "tool",
2669
- content: "",
2670
- isStreaming: true,
2671
- toolName: toolEvent.toolName,
2672
- toolCallId: callId,
2673
- // F2: 实际执行位置(服务端/runtime 投影)挂到 tool
2674
- // 卡片 metadata。优先事件自带 metadata(runtime
2675
- // 投影层直接注入的同名字段),兜底用 turn 级
2676
- // execution_location 帧。缺失/不合法时渲染层
2677
- // projectToolExecutionLocation 收敛为 unknown。
2678
- metadata: {
2679
- ...isRecord(toolEvent.metadata) ? toolEvent.metadata : {},
2680
- ...desktopToolExecutionLocation !== void 0 && !(isRecord(toolEvent.metadata) && toolEvent.metadata.executionLocation !== void 0) ? { executionLocation: desktopToolExecutionLocation } : {},
2681
- ...toolEvent.argumentsPreview ? { argumentsPreview: toolEvent.argumentsPreview } : {}
2682
- },
2683
- ...toolEvent.argumentsPreview ? {
2684
- toolPayload: {
2685
- input: {
2686
- command: toolEvent.argumentsPreview,
2687
- cmd: toolEvent.argumentsPreview
2802
+ })).unwrap();
2803
+ if (!eventStream || !ownsDesktopTurn()) break;
2804
+ for await (const event of eventStream) {
2805
+ if (loopController.signal.aborted || thunkApi.signal.aborted) {
2806
+ if (w2) w2.__LOOP_STOP_REASON__ = "aborted";
2807
+ break;
2808
+ }
2809
+ if (event.type === "delta") {
2810
+ streamDesktopAssistantText(event.text);
2811
+ } else if (event.type === "thinking") {
2812
+ if (typeof event.content === "string") {
2813
+ reasoningBuffer += event.content;
2814
+ streamDesktopAssistantUpsert();
2815
+ }
2816
+ } else if (event.type === "tool") {
2817
+ const toolEvent = event.event;
2818
+ const callId = toolEvent.toolCallId;
2819
+ if (!callId) continue;
2820
+ if (toolEvent.type === "tool-call") {
2821
+ attachToolCallIdToSegment(assistantSegments, callId);
2822
+ finalizeCurrentAssistantSegmentForTool();
2823
+ const { key: dbKey, messageId: toolMsgId } = createDialogMessageKeyAndId(dialogId);
2824
+ const toolMsg = {
2825
+ id: toolMsgId,
2826
+ dialogId,
2827
+ dbKey,
2828
+ role: "tool",
2829
+ content: "",
2830
+ isStreaming: true,
2831
+ toolName: toolEvent.toolName,
2832
+ toolCallId: callId,
2833
+ // F2: 实际执行位置(服务端/runtime 投影)挂到 tool
2834
+ // 卡片 metadata。优先事件自带 metadata(runtime
2835
+ // 投影层直接注入的同名字段),兜底用 turn 级
2836
+ // execution_location 帧。缺失/不合法时渲染层
2837
+ // projectToolExecutionLocation 收敛为 unknown。
2838
+ metadata: {
2839
+ ...isRecord(toolEvent.metadata) ? toolEvent.metadata : {},
2840
+ ...desktopToolExecutionLocation !== void 0 && !(isRecord(toolEvent.metadata) && toolEvent.metadata.executionLocation !== void 0) ? { executionLocation: desktopToolExecutionLocation } : {},
2841
+ ...toolEvent.argumentsPreview ? { argumentsPreview: toolEvent.argumentsPreview } : {}
2842
+ },
2843
+ ...toolEvent.argumentsPreview ? {
2844
+ toolPayload: {
2845
+ input: {
2846
+ command: toolEvent.argumentsPreview,
2847
+ cmd: toolEvent.argumentsPreview
2848
+ }
2688
2849
  }
2689
- }
2690
- } : {}
2691
- };
2692
- activeToolMessages.set(callId, toolMsg);
2693
- dispatch(messageStreaming(toolMsg));
2694
- } else if (toolEvent.type === "tool-result" || toolEvent.type === "tool-error") {
2695
- const existing = activeToolMessages.get(callId);
2696
- if (existing) {
2697
- const isError = toolEvent.type === "tool-error";
2698
- const existingMeta = asRecordOrEmpty(existing.metadata);
2699
- const existingInput = isRecord(existing.toolPayload?.input) ? existing.toolPayload.input : {};
2700
- const mergedMeta = {
2701
- ...existingMeta,
2702
- ...toolEvent.metadata,
2703
- ...isError ? { error: true, message: toolEvent.message } : {},
2704
- // 服务端/runtime 已在事件 metadata 带
2705
- // executionLocation 时尊重之;tool-call 阶段
2706
- // 已写入的值由 existingMeta 保留;仅当两边都
2707
- // 没有且 turn 级 execution_location 帧存在时
2708
- // 兜底补上,绝不覆盖已有值。
2709
- ...existingMeta.executionLocation === void 0 && (!isRecord(toolEvent.metadata) || toolEvent.metadata.executionLocation === void 0) && desktopToolExecutionLocation !== void 0 ? { executionLocation: desktopToolExecutionLocation } : {}
2710
- };
2711
- const toolResultMsg = {
2712
- ...existing,
2713
- isStreaming: false,
2714
- content: projectDesktopToolUiContent({
2715
- toolName: toolEvent.toolName || existing.toolName,
2716
- content: toolEvent.content,
2717
- summary: toolEvent.summary,
2718
- message: toolEvent.message,
2719
- metadata: mergedMeta,
2720
- argumentsPreview: asOptionalTrimmedString(mergedMeta.argumentsPreview) || asOptionalTrimmedString(existingInput.command) || asOptionalTrimmedString(existingInput.cmd) || void 0
2721
- }),
2722
- metadata: mergedMeta
2850
+ } : {}
2723
2851
  };
2724
- activeToolMessages.set(callId, toolResultMsg);
2725
- dispatch(messageStreaming(toolResultMsg));
2726
- const resultToolName = toolEvent.toolName || existing.toolName;
2727
- if (!isError) {
2728
- deliverHtmlArtifactToolResult(resultToolName, toolEvent.content, dialogKey);
2852
+ activeToolMessages.set(callId, toolMsg);
2853
+ dispatch(messageStreaming(toolMsg));
2854
+ } else if (toolEvent.type === "tool-result" || toolEvent.type === "tool-error") {
2855
+ const existing = activeToolMessages.get(callId);
2856
+ if (existing) {
2857
+ const isError = toolEvent.type === "tool-error";
2858
+ const existingMeta = asRecordOrEmpty(existing.metadata);
2859
+ const existingInput = isRecord(existing.toolPayload?.input) ? existing.toolPayload.input : {};
2860
+ const mergedMeta = {
2861
+ ...existingMeta,
2862
+ ...toolEvent.metadata,
2863
+ ...isError ? { error: true, message: toolEvent.message } : {},
2864
+ // 服务端/runtime 已在事件 metadata 带
2865
+ // executionLocation 时尊重之;tool-call 阶段
2866
+ // 已写入的值由 existingMeta 保留;仅当两边都
2867
+ // 没有且 turn 级 execution_location 帧存在时
2868
+ // 兜底补上,绝不覆盖已有值。
2869
+ ...existingMeta.executionLocation === void 0 && (!isRecord(toolEvent.metadata) || toolEvent.metadata.executionLocation === void 0) && desktopToolExecutionLocation !== void 0 ? { executionLocation: desktopToolExecutionLocation } : {}
2870
+ };
2871
+ const toolResultMsg = {
2872
+ ...existing,
2873
+ isStreaming: false,
2874
+ content: projectDesktopToolUiContent({
2875
+ toolName: toolEvent.toolName || existing.toolName,
2876
+ content: toolEvent.content,
2877
+ summary: toolEvent.summary,
2878
+ message: toolEvent.message,
2879
+ metadata: mergedMeta,
2880
+ argumentsPreview: asOptionalTrimmedString(mergedMeta.argumentsPreview) || asOptionalTrimmedString(existingInput.command) || asOptionalTrimmedString(existingInput.cmd) || void 0
2881
+ }),
2882
+ metadata: mergedMeta
2883
+ };
2884
+ activeToolMessages.set(callId, toolResultMsg);
2885
+ dispatch(messageStreaming(toolResultMsg));
2886
+ const resultToolName = toolEvent.toolName || existing.toolName;
2887
+ if (!isError) {
2888
+ deliverHtmlArtifactToolResult(resultToolName, toolEvent.content, dialogKey);
2889
+ }
2729
2890
  }
2730
2891
  }
2892
+ } else if (event.type === "status") {
2893
+ const phase = event.phase === "validating-context" ? "validating" : event.phase;
2894
+ setDialogTurnPhase({ phase, dialogKey, turnId: turnPhaseTurnId ?? void 0 });
2895
+ } else if (event.type === "execution_location") {
2896
+ desktopToolExecutionLocation = event.location;
2897
+ } else if (event.type === "action_gate") {
2898
+ pushGate(
2899
+ event.gate,
2900
+ targetForRunKind("desktop-local")
2901
+ );
2902
+ } else if (event.type === "done") {
2903
+ streamResult = event.result;
2904
+ } else if (event.type === "error") {
2905
+ streamError = event.error;
2731
2906
  }
2732
- } else if (event.type === "status") {
2733
- const phase = event.phase === "validating-context" ? "validating" : event.phase;
2734
- setDialogTurnPhase({ phase, dialogKey, turnId: turnPhaseTurnId ?? void 0 });
2735
- } else if (event.type === "execution_location") {
2736
- desktopToolExecutionLocation = event.location;
2737
- } else if (event.type === "done") {
2738
- streamResult = event.result;
2739
- } else if (event.type === "error") {
2740
- streamError = event.error;
2907
+ }
2908
+ } catch (err) {
2909
+ if (isAbortError(err) || loopController.signal.aborted || thunkApi.signal.aborted) {
2910
+ if (w2) w2.__LOOP_STOP_REASON__ = "aborted";
2911
+ } else {
2912
+ streamError = err?.message || "Local turn read stream error";
2741
2913
  }
2742
2914
  }
2743
- } catch (err) {
2744
- if (isAbortError(err) || loopController.signal.aborted || thunkApi.signal.aborted) {
2915
+ if (loopController.signal.aborted || thunkApi.signal.aborted || typeof streamError === "string" && /operation was aborted/i.test(streamError)) {
2745
2916
  if (w2) w2.__LOOP_STOP_REASON__ = "aborted";
2746
- } else {
2747
- streamError = err?.message || "Local turn read stream error";
2748
- }
2749
- }
2750
- if (loopController.signal.aborted || thunkApi.signal.aborted || typeof streamError === "string" && /operation was aborted/i.test(streamError)) {
2751
- if (w2) w2.__LOOP_STOP_REASON__ = "aborted";
2752
- const stopKeys = assistantMessageKeys;
2753
- if (stopKeys) {
2754
- const last = assistantSegments[assistantSegments.length - 1];
2755
- if (last && last.messageId === stopKeys.messageId) {
2756
- last.content = currentContent;
2917
+ const stopKeys = assistantMessageKeys;
2918
+ if (stopKeys) {
2919
+ const last = assistantSegments[assistantSegments.length - 1];
2920
+ if (last && last.messageId === stopKeys.messageId) {
2921
+ last.content = currentContent;
2922
+ }
2757
2923
  }
2758
- }
2759
- const stopToolNameById = /* @__PURE__ */ new Map();
2760
- for (const [callId, toolMsg] of activeToolMessages) {
2761
- if (!toolMessageWillPersist(toolMsg)) continue;
2762
- const toolName = toolMsg?.toolName;
2763
- stopToolNameById.set(
2764
- callId,
2765
- typeof toolName === "string" && toolName ? toolName : "tool"
2766
- );
2767
- }
2768
- for (const segment2 of assistantSegments) {
2769
- const hasContent = segment2.content.trim().length > 0;
2770
- const hasToolCalls = segment2.toolCallIds && segment2.toolCallIds.length > 0;
2771
- if (hasContent || hasToolCalls) {
2772
- const stopToolCalls = buildMinimalToolCallsFromIds(
2773
- segment2.toolCallIds,
2774
- stopToolNameById
2924
+ const stopToolNameById = /* @__PURE__ */ new Map();
2925
+ for (const [callId, toolMsg] of activeToolMessages) {
2926
+ if (!toolMessageWillPersist(toolMsg)) continue;
2927
+ const toolName = toolMsg?.toolName;
2928
+ stopToolNameById.set(
2929
+ callId,
2930
+ typeof toolName === "string" && toolName ? toolName : "tool"
2775
2931
  );
2776
- await persistMessageWithFixedId(dispatch, {
2777
- dialogId,
2778
- id: segment2.messageId,
2779
- dbKey: segment2.key,
2780
- role: "assistant",
2781
- content: segment2.content,
2782
- ...stopToolCalls.length > 0 ? { tool_calls: stopToolCalls } : {},
2783
- ...desktopMessageMetadata,
2784
- userId: selectIdentityUserId(getState())
2785
- });
2786
- } else {
2787
- dispatch(removeTransientMessage(segment2.messageId));
2788
2932
  }
2789
- }
2790
- const durableTools = [];
2791
- for (const toolMsg of activeToolMessages.values()) {
2792
- const content = toolMsg?.content;
2793
- const hasContent = typeof content === "string" ? content.trim().length > 0 : Array.isArray(content) && content.length > 0;
2794
- if (!hasContent) {
2795
- dispatch(removeTransientMessage(toolMsg.id));
2796
- continue;
2933
+ for (const segment2 of assistantSegments) {
2934
+ const hasContent = segment2.content.trim().length > 0;
2935
+ const hasToolCalls = segment2.toolCallIds && segment2.toolCallIds.length > 0;
2936
+ if (hasContent || hasToolCalls) {
2937
+ const stopToolCalls = buildMinimalToolCallsFromIds(
2938
+ segment2.toolCallIds,
2939
+ stopToolNameById
2940
+ );
2941
+ await persistMessageWithFixedId(dispatch, {
2942
+ dialogId,
2943
+ id: segment2.messageId,
2944
+ dbKey: segment2.key,
2945
+ role: "assistant",
2946
+ content: segment2.content,
2947
+ ...stopToolCalls.length > 0 ? { tool_calls: stopToolCalls } : {},
2948
+ ...desktopMessageMetadata,
2949
+ userId: selectIdentityUserId(getState())
2950
+ });
2951
+ } else {
2952
+ dispatch(removeTransientMessage(segment2.messageId));
2953
+ }
2797
2954
  }
2798
- const stopped = { ...toolMsg, isStreaming: false };
2799
- dispatch(messageStreaming(stopped));
2800
- durableTools.push(stopped);
2801
- }
2802
- await persistToolMessages(dispatch, durableTools, {
2803
- isStreaming: false,
2804
- soft: true
2805
- });
2806
- remoteTransientMessageFinalized = true;
2807
- return { aborted: true };
2808
- }
2809
- const finalizeDesktopTurnOnError = async (errorText) => {
2810
- const errorToolNameById = /* @__PURE__ */ new Map();
2811
- for (const [callId, toolMsg] of activeToolMessages) {
2812
- if (!toolMessageWillPersist(toolMsg)) continue;
2813
- const toolName = toolMsg?.toolName;
2814
- errorToolNameById.set(
2815
- callId,
2816
- typeof toolName === "string" && toolName ? toolName : "tool"
2817
- );
2955
+ const durableTools = [];
2956
+ for (const toolMsg of activeToolMessages.values()) {
2957
+ const content = toolMsg?.content;
2958
+ const hasContent = typeof content === "string" ? content.trim().length > 0 : Array.isArray(content) && content.length > 0;
2959
+ if (!hasContent) {
2960
+ dispatch(removeTransientMessage(toolMsg.id));
2961
+ continue;
2962
+ }
2963
+ const stopped = { ...toolMsg, isStreaming: false };
2964
+ dispatch(messageStreaming(stopped));
2965
+ durableTools.push(stopped);
2966
+ }
2967
+ await persistToolMessages(dispatch, durableTools, {
2968
+ isStreaming: false,
2969
+ soft: true
2970
+ });
2971
+ remoteTransientMessageFinalized = true;
2972
+ return { aborted: true };
2818
2973
  }
2819
- for (const segment2 of assistantSegments) {
2820
- const hasContent = segment2.content.trim().length > 0;
2821
- const hasToolCalls = segment2.toolCallIds && segment2.toolCallIds.length > 0;
2822
- if (hasContent || hasToolCalls) {
2823
- const errorToolCalls = buildMinimalToolCallsFromIds(
2824
- segment2.toolCallIds,
2825
- errorToolNameById
2974
+ const finalizeDesktopTurnOnError = async (errorText) => {
2975
+ const errorToolNameById = /* @__PURE__ */ new Map();
2976
+ for (const [callId, toolMsg] of activeToolMessages) {
2977
+ if (!toolMessageWillPersist(toolMsg)) continue;
2978
+ const toolName = toolMsg?.toolName;
2979
+ errorToolNameById.set(
2980
+ callId,
2981
+ typeof toolName === "string" && toolName ? toolName : "tool"
2826
2982
  );
2827
- await persistMessageWithFixedId(dispatch, {
2828
- dialogId,
2829
- id: segment2.messageId,
2830
- dbKey: segment2.key,
2831
- role: "assistant",
2832
- content: segment2.content,
2833
- ...errorToolCalls.length > 0 ? { tool_calls: errorToolCalls } : {},
2834
- ...desktopMessageMetadata,
2835
- userId: selectIdentityUserId(getState())
2836
- });
2837
- if (hasContent) {
2983
+ }
2984
+ for (const segment2 of assistantSegments) {
2985
+ const hasContent = segment2.content.trim().length > 0;
2986
+ const hasToolCalls = segment2.toolCallIds && segment2.toolCallIds.length > 0;
2987
+ if (hasContent || hasToolCalls) {
2988
+ const errorToolCalls = buildMinimalToolCallsFromIds(
2989
+ segment2.toolCallIds,
2990
+ errorToolNameById
2991
+ );
2992
+ await persistMessageWithFixedId(dispatch, {
2993
+ dialogId,
2994
+ id: segment2.messageId,
2995
+ dbKey: segment2.key,
2996
+ role: "assistant",
2997
+ content: segment2.content,
2998
+ ...errorToolCalls.length > 0 ? { tool_calls: errorToolCalls } : {},
2999
+ ...desktopMessageMetadata,
3000
+ userId: selectIdentityUserId(getState())
3001
+ });
3002
+ if (hasContent) {
3003
+ dispatch(finalizeTransientMessageOnError({
3004
+ id: segment2.messageId,
3005
+ error: errorText
3006
+ }));
3007
+ }
3008
+ } else {
2838
3009
  dispatch(finalizeTransientMessageOnError({
2839
3010
  id: segment2.messageId,
2840
3011
  error: errorText
2841
3012
  }));
2842
3013
  }
2843
- } else {
2844
- dispatch(finalizeTransientMessageOnError({
2845
- id: segment2.messageId,
2846
- error: errorText
2847
- }));
2848
3014
  }
2849
- }
2850
- const durableTools = [];
2851
- for (const toolMsg of activeToolMessages.values()) {
2852
- const content = toolMsg?.content;
2853
- const hasContent = typeof content === "string" ? content.trim().length > 0 : Array.isArray(content) && content.length > 0;
2854
- if (!hasContent) {
2855
- dispatch(removeTransientMessage(toolMsg.id));
2856
- continue;
3015
+ const durableTools = [];
3016
+ for (const toolMsg of activeToolMessages.values()) {
3017
+ const content = toolMsg?.content;
3018
+ const hasContent = typeof content === "string" ? content.trim().length > 0 : Array.isArray(content) && content.length > 0;
3019
+ if (!hasContent) {
3020
+ dispatch(removeTransientMessage(toolMsg.id));
3021
+ continue;
3022
+ }
3023
+ const stopped = { ...toolMsg, isStreaming: false };
3024
+ dispatch(messageStreaming(stopped));
3025
+ durableTools.push(stopped);
2857
3026
  }
2858
- const stopped = { ...toolMsg, isStreaming: false };
2859
- dispatch(messageStreaming(stopped));
2860
- durableTools.push(stopped);
2861
- }
2862
- await persistToolMessages(dispatch, durableTools, {
2863
- isStreaming: false,
2864
- soft: true
2865
- });
2866
- remoteTransientMessageFinalized = true;
2867
- setLoopStopReason("error");
2868
- };
2869
- if (streamError) {
2870
- const info = classifyLocalTurnStreamError(streamError);
2871
- const finalError = info.actionHint ? `${streamError}
3027
+ await persistToolMessages(dispatch, durableTools, {
3028
+ isStreaming: false,
3029
+ soft: true
3030
+ });
3031
+ remoteTransientMessageFinalized = true;
3032
+ setLoopStopReason("error");
3033
+ };
3034
+ if (streamError) {
3035
+ const info = classifyLocalTurnStreamError(streamError);
3036
+ const finalError = info.actionHint ? `${streamError}
2872
3037
 
2873
3038
  ${info.actionHint}` : streamError;
2874
- await finalizeDesktopTurnOnError(finalError);
2875
- return rejectWithValue(finalError);
2876
- }
2877
- if (!streamResult) {
2878
- const message = "Local turn stream closed unexpectedly without result";
2879
- await finalizeDesktopTurnOnError(message);
2880
- return rejectWithValue(message);
2881
- }
2882
- const desktopTurnMessages = streamResult.turnMessages || [];
2883
- const hasSegmentWithCallIds = assistantSegments.some(
2884
- (s) => s.toolCallIds.length > 0
2885
- );
2886
- if (!hasSegmentWithCallIds) {
2887
- const doneOnlyAssistantCalls = desktopTurnMessages.filter(
2888
- (m) => m?.role === "assistant" && Array.isArray(m.tool_calls) && m.tool_calls.length > 0
2889
- ).flatMap((m) => m.tool_calls.map((tc) => tc?.id)).filter((id) => typeof id === "string");
2890
- if (doneOnlyAssistantCalls.length > 0) {
2891
- ensureAssistantMessageKeys();
2892
- for (const callId of doneOnlyAssistantCalls) {
2893
- attachToolCallIdToSegment(assistantSegments, callId);
3039
+ await finalizeDesktopTurnOnError(finalError);
3040
+ return rejectWithValue(finalError);
3041
+ }
3042
+ if (!streamResult) {
3043
+ const message = "Local turn stream closed unexpectedly without result";
3044
+ await finalizeDesktopTurnOnError(message);
3045
+ return rejectWithValue(message);
3046
+ }
3047
+ const desktopTurnMessages = streamResult.turnMessages || [];
3048
+ const hasSegmentWithCallIds = assistantSegments.some(
3049
+ (s) => s.toolCallIds.length > 0
3050
+ );
3051
+ if (!hasSegmentWithCallIds) {
3052
+ const doneOnlyAssistantCalls = desktopTurnMessages.filter(
3053
+ (m) => m?.role === "assistant" && Array.isArray(m.tool_calls) && m.tool_calls.length > 0
3054
+ ).flatMap((m) => m.tool_calls.map((tc) => tc?.id)).filter((id) => typeof id === "string");
3055
+ if (doneOnlyAssistantCalls.length > 0) {
3056
+ ensureAssistantMessageKeys();
3057
+ for (const callId of doneOnlyAssistantCalls) {
3058
+ attachToolCallIdToSegment(assistantSegments, callId);
3059
+ }
3060
+ if (currentContent.length === 0) {
3061
+ finalizeCurrentAssistantSegmentForTool();
3062
+ }
2894
3063
  }
2895
- if (currentContent.length === 0) {
2896
- finalizeCurrentAssistantSegmentForTool();
3064
+ }
3065
+ if (activeToolMessages.size === 0) {
3066
+ for (const toolMessage of buildDesktopRuntimeToolMessagesForUi({
3067
+ dialogId,
3068
+ turnMessages: desktopTurnMessages
3069
+ })) {
3070
+ dispatch(messageStreaming(toolMessage));
3071
+ activeToolMessages.set(
3072
+ asTrimmedString(toolMessage.toolCallId) || toolMessage.id,
3073
+ toolMessage
3074
+ );
2897
3075
  }
2898
3076
  }
2899
- }
2900
- if (activeToolMessages.size === 0) {
2901
- for (const toolMessage of buildDesktopRuntimeToolMessagesForUi({
2902
- dialogId,
2903
- turnMessages: desktopTurnMessages
2904
- })) {
2905
- dispatch(messageStreaming(toolMessage));
2906
- activeToolMessages.set(
2907
- asTrimmedString(toolMessage.toolCallId) || toolMessage.id,
2908
- toolMessage
3077
+ await persistToolMessages(
3078
+ dispatch,
3079
+ activeToolMessages.values(),
3080
+ { isStreaming: false, soft: true }
3081
+ );
3082
+ const earlierFinalizedSegments = selectPersistableFinalizedSegments(assistantSegments);
3083
+ for (const segment2 of earlierFinalizedSegments) {
3084
+ const segmentToolCalls = resolveSegmentToolCalls(
3085
+ segment2.toolCallIds,
3086
+ desktopTurnMessages
2909
3087
  );
3088
+ dispatch(write({
3089
+ data: {
3090
+ id: segment2.messageId,
3091
+ dbKey: segment2.key,
3092
+ dialogId,
3093
+ content: segment2.content,
3094
+ role: "assistant",
3095
+ isStreaming: false,
3096
+ type: "msg" /* MSG */,
3097
+ ...segmentToolCalls.length > 0 ? { tool_calls: segmentToolCalls } : {},
3098
+ ...desktopMessageMetadata
3099
+ },
3100
+ customKey: segment2.key
3101
+ }));
2910
3102
  }
2911
- }
2912
- await persistToolMessages(
2913
- dispatch,
2914
- activeToolMessages.values(),
2915
- { isStreaming: false, soft: true }
2916
- );
2917
- const earlierFinalizedSegments = selectPersistableFinalizedSegments(assistantSegments);
2918
- for (const segment2 of earlierFinalizedSegments) {
2919
- const segmentToolCalls = resolveSegmentToolCalls(
2920
- segment2.toolCallIds,
2921
- desktopTurnMessages
2922
- );
2923
- dispatch(write({
2924
- data: {
2925
- id: segment2.messageId,
2926
- dbKey: segment2.key,
2927
- dialogId,
2928
- content: segment2.content,
2929
- role: "assistant",
2930
- isStreaming: false,
2931
- type: "msg" /* MSG */,
2932
- ...segmentToolCalls.length > 0 ? { tool_calls: segmentToolCalls } : {},
2933
- ...desktopMessageMetadata
2934
- },
2935
- customKey: segment2.key
3103
+ const { key: msgKey, messageId } = ensureAssistantMessageKeys();
3104
+ const lastSegmentContent = hasInlineExecutedToolCalls(streamResult) ? currentContent || "" : streamResult.content || currentContent || "";
3105
+ const segment = assistantSegments[assistantSegments.length - 1];
3106
+ segment.content = lastSegmentContent;
3107
+ dispatch(messageStreaming({
3108
+ id: messageId,
3109
+ dialogId,
3110
+ dbKey: msgKey,
3111
+ content: lastSegmentContent,
3112
+ role: "assistant",
3113
+ isStreaming: false,
3114
+ ...desktopMessageMetadata
2936
3115
  }));
3116
+ const lastSegmentToolCalls = segment ? resolveSegmentToolCalls(segment.toolCallIds, desktopTurnMessages) : [];
3117
+ await dispatch(messageStreamEnd({
3118
+ finalContentBuffer: [
3119
+ {
3120
+ type: "text",
3121
+ text: lastSegmentContent
3122
+ }
3123
+ ],
3124
+ totalUsage: streamResult.usage ?? void 0,
3125
+ billingUsageRecords: streamResult.usageRecords,
3126
+ messageId,
3127
+ msgKey,
3128
+ agentConfig,
3129
+ dialogId,
3130
+ dialogKey,
3131
+ // 优先用本 turn 累计的 thinking SSE;为空时兜底 streamResult.reasoning_content
3132
+ // (provider 在 SSE 流内累计返回的 reasoning_content)。
3133
+ reasoningBuffer: reasoningBuffer || (typeof streamResult?.reasoning_content === "string" ? streamResult.reasoning_content : ""),
3134
+ toolCalls: lastSegmentToolCalls,
3135
+ // 把 provider 报告的 finish_reason 透传给 messageStreamEnd,
3136
+ // 由 assembleFinalAssistantMessage 决定是否写进最终 Message。
3137
+ finishReason: streamResult.finish_reason ?? void 0,
3138
+ messageMetadata: desktopMessageMetadata
3139
+ })).unwrap();
3140
+ remoteTransientMessageFinalized = true;
3141
+ if (!isUserTurn || !ownsDesktopTurn() || streamResult.finish_reason !== "stop" || streamResult.stopReason && streamResult.stopReason !== "done" || streamResult.pendingInteraction || streamResult.hasPendingInteraction || streamResult.error || streamResult.emptyAssistantFallbackReason) {
3142
+ return { usage: streamResult.usage ?? void 0 };
3143
+ }
3144
+ desktopBatch = await admitDesktopBatch();
3145
+ if (!ownsDesktopTurn()) return { aborted: true };
3146
+ if (!desktopBatch.length) return { usage: streamResult.usage ?? void 0 };
2937
3147
  }
2938
- const { key: msgKey, messageId } = ensureAssistantMessageKeys();
2939
- const lastSegmentContent = hasInlineExecutedToolCalls(streamResult) ? currentContent || "" : streamResult.content || currentContent || "";
2940
- const segment = assistantSegments[assistantSegments.length - 1];
2941
- segment.content = lastSegmentContent;
2942
- dispatch(messageStreaming({
2943
- id: messageId,
2944
- dialogId,
2945
- dbKey: msgKey,
2946
- content: lastSegmentContent,
2947
- role: "assistant",
2948
- isStreaming: false,
2949
- ...desktopMessageMetadata
2950
- }));
2951
- const lastSegmentToolCalls = segment ? resolveSegmentToolCalls(segment.toolCallIds, desktopTurnMessages) : [];
2952
- await dispatch(messageStreamEnd({
2953
- finalContentBuffer: [
2954
- {
2955
- type: "text",
2956
- text: lastSegmentContent
2957
- }
2958
- ],
2959
- totalUsage: streamResult.usage ?? void 0,
2960
- billingUsageRecords: streamResult.usageRecords,
2961
- messageId,
2962
- msgKey,
2963
- agentConfig,
2964
- dialogId,
2965
- dialogKey,
2966
- // 优先用本 turn 累计的 thinking SSE;为空时兜底 streamResult.reasoning_content
2967
- // (provider 在 SSE 流内累计返回的 reasoning_content)。
2968
- reasoningBuffer: reasoningBuffer || (typeof streamResult?.reasoning_content === "string" ? streamResult.reasoning_content : ""),
2969
- toolCalls: lastSegmentToolCalls,
2970
- // 把 provider 报告的 finish_reason 透传给 messageStreamEnd,
2971
- // 由 assembleFinalAssistantMessage 决定是否写进最终 Message。
2972
- finishReason: streamResult.finish_reason ?? void 0,
2973
- messageMetadata: desktopMessageMetadata
2974
- })).unwrap();
2975
- remoteTransientMessageFinalized = true;
2976
- return {
2977
- usage: streamResult.usage ?? void 0
2978
- };
3148
+ return { aborted: true };
2979
3149
  }
2980
3150
  const userInputText = extractAgentRunUserText(userInput);
2981
3151
  const explicitServerBase = asOptionalTrimmedString(args.serverBase) ?? null;
@@ -2990,7 +3160,7 @@ ${info.actionHint}` : streamError;
2990
3160
  } else {
2991
3161
  const token = selectIdentityToken(state);
2992
3162
  const authHeader = token ? `Bearer ${token}` : "";
2993
- const rawMessages = selectAllMsgs(state, dialogId);
3163
+ const rawMessages = selectAdmittedMessages(selectAllMsgs(state, dialogId));
2994
3164
  const visibleMessages = buildAgentViewMessages(
2995
3165
  rawMessages,
2996
3166
  agentConfig.dbKey
@@ -3124,6 +3294,15 @@ ${info.actionHint}` : streamError;
3124
3294
  if (payload.type === "error") {
3125
3295
  return { reject: payload.message || "\u8FDC\u7AEF Agent \u6267\u884C\u5931\u8D25" };
3126
3296
  }
3297
+ if (payload.type === "action_gate" && payload.gate) {
3298
+ pushGate(
3299
+ payload.gate,
3300
+ targetForRunKind("server-run", {
3301
+ server: explicitServerBase,
3302
+ token
3303
+ })
3304
+ );
3305
+ }
3127
3306
  if (payload.type === "agent_handoff") {
3128
3307
  await patchDialogThreadMetadata(
3129
3308
  dispatch,
@@ -3229,7 +3408,7 @@ ${info.actionHint}` : streamError;
3229
3408
  recommendedSkillHints: turnToolContext.recommendedSkillHints,
3230
3409
  skillPromptPatches: turnToolContext.skillPromptPatches
3231
3410
  };
3232
- const initialRawMsgs = selectAllMsgs(state, dialogId);
3411
+ const initialRawMsgs = selectAdmittedMessages(selectAllMsgs(state, dialogId));
3233
3412
  const initialHistoryIds = new Set(initialRawMsgs.map((m) => m.id));
3234
3413
  const accountSkillRuntime = agentConfigWithReferences.runtimePromptAlreadyInMessages ? null : await resolveUserSkillRuntime(agentConfigWithReferences, state.settings);
3235
3414
  const agentConfigWithTools = resolveWebAgentRuntimeToolSurface(
@@ -3391,7 +3570,7 @@ ${info.actionHint}` : streamError;
3391
3570
  mergeContexts(staticContexts2, dynamicContexts),
3392
3571
  contextBlocks
3393
3572
  );
3394
- const rawMessages = selectAllMsgs(loopState, dialogId);
3573
+ const rawMessages = selectAdmittedMessages(selectAllMsgs(loopState, dialogId));
3395
3574
  let visibleMessages = buildAgentViewMessages(
3396
3575
  rawMessages,
3397
3576
  agentConfigForCall.dbKey
@@ -3419,9 +3598,9 @@ ${info.actionHint}` : streamError;
3419
3598
  }
3420
3599
  }
3421
3600
  }
3601
+ const requestUserInput = snapshotUserBatchInput(selectAllMsgs(loopState, dialogId));
3422
3602
  const cleanedMessages = filterAndCleanMessages(visibleMessages);
3423
3603
  const ctxWindow = resolveAgentContextWindow(agentConfigForCall);
3424
- const summaryTokenCount = contexts.dialogSummary ? estimateTokenCount(contexts.dialogSummary) : 0;
3425
3604
  const messagesBeforeStrip = compressOldToolResults(cleanedMessages);
3426
3605
  const preprocessedResult = await stripImagePartsForTextOnlyAgent(
3427
3606
  messagesBeforeStrip,
@@ -3432,49 +3611,69 @@ ${info.actionHint}` : streamError;
3432
3611
  messagesBeforeStrip,
3433
3612
  targetUserMessageId: activeTurnUserMessageId2
3434
3613
  });
3435
- let processedMessages = trimMessagesWithSummary(
3436
- preprocessedResult.messages,
3437
- ctxWindow,
3438
- summaryTokenCount
3439
- );
3440
- let firstDynamicIdx = processedMessages.findIndex(
3441
- (m) => m.id && !initialHistoryIds.has(m.id)
3442
- );
3443
- if (firstDynamicIdx === -1) firstDynamicIdx = processedMessages.length;
3444
- let stableMessages = processedMessages.slice(0, firstDynamicIdx);
3445
- let dynamicMessages = processedMessages.slice(firstDynamicIdx);
3446
- const bodyData = generateRequestBody({
3447
- agentConfig: effectiveAgentConfig,
3448
- messages: dynamicMessages,
3449
- stableMessages,
3450
- userInput: userInputText,
3451
- contexts,
3452
- responsesState
3614
+ const { bodyData, fallbackBodyData, dynamicMessages, stableMessages } = await admitWebRequest({
3615
+ contextWindow: ctxWindow,
3616
+ signal: loopController.signal,
3617
+ rescue: (availableHistoryTokens) => updateDialogSummaryAction({
3618
+ dialogKey,
3619
+ force: true,
3620
+ reason: "budget_rescue",
3621
+ availableHistoryTokens,
3622
+ contextWindow: ctxWindow,
3623
+ preserveLatestUserByProjection: true
3624
+ }, { ...thunkApi, signal: loopController.signal }),
3625
+ build: async () => {
3626
+ const summaryConfig = selectById(getState(), dialogKey);
3627
+ const refreshedContexts = { ...contexts, dialogSummary: summaryConfig?.summary || null };
3628
+ const processedMessages = projectSummaryHistory(preprocessedResult.messages, summaryConfig?.summary, summaryConfig?.summarizedBeforeId);
3629
+ let firstDynamicIdx = processedMessages.findIndex(
3630
+ (m) => m.id && !initialHistoryIds.has(m.id)
3631
+ );
3632
+ if (firstDynamicIdx === -1) firstDynamicIdx = processedMessages.length;
3633
+ let stableMessages2 = processedMessages.slice(0, firstDynamicIdx);
3634
+ let dynamicMessages2 = processedMessages.slice(firstDynamicIdx);
3635
+ const bodyData2 = generateRequestBody({
3636
+ agentConfig: effectiveAgentConfig,
3637
+ messages: dynamicMessages2,
3638
+ stableMessages: stableMessages2,
3639
+ userInput: userInputText,
3640
+ contexts: refreshedContexts,
3641
+ responsesState
3642
+ });
3643
+ const fallbackBodyData2 = responsesState ? generateRequestBody({
3644
+ agentConfig: effectiveAgentConfig,
3645
+ messages: dynamicMessages2,
3646
+ stableMessages: stableMessages2,
3647
+ userInput: userInputText,
3648
+ contexts: refreshedContexts,
3649
+ responsesState: null
3650
+ }) : void 0;
3651
+ return { value: { bodyData: bodyData2, fallbackBodyData: fallbackBodyData2, dynamicMessages: dynamicMessages2, stableMessages: stableMessages2 }, wireBodies: [buildResponsesRequestBodyWithTools(bodyData2, agentConfigForCall), ...fallbackBodyData2 ? [buildResponsesRequestBodyWithTools(fallbackBodyData2, agentConfigForCall)] : []] };
3652
+ }
3453
3653
  });
3454
- const fallbackBodyData = responsesState ? generateRequestBody({
3455
- agentConfig: effectiveAgentConfig,
3456
- messages: dynamicMessages,
3457
- stableMessages,
3458
- userInput: userInputText,
3459
- contexts,
3460
- responsesState: null
3461
- }) : void 0;
3462
3654
  logQuickChatPerfStage2(quickChatPerfStartedAt, "stream-agent-model-request-starting", {
3463
3655
  responseApi: true,
3464
3656
  dynamicMessageCount: dynamicMessages.length,
3465
3657
  stableMessageCount: stableMessages.length
3466
3658
  });
3467
3659
  modelRequestStarted = true;
3468
- const meta = await sendOpenAIResponseRequest({
3469
- bodyData,
3470
- agentConfig: agentConfigForCall,
3471
- thunkApi,
3660
+ const meta = await dispatch(runPendingUserBatchRequest({
3472
3661
  dialogKey,
3473
- parentMessageId: currentParentMessageId2,
3474
- messageMetadata: streamingMessageMetadata,
3475
- quickChatPerfStartedAt,
3476
- fallbackBodyData
3477
- });
3662
+ signal: loopController.signal,
3663
+ execution: batchExecution,
3664
+ requestUserInput,
3665
+ start: () => sendOpenAIResponseRequest({
3666
+ bodyData,
3667
+ agentConfig: agentConfigForCall,
3668
+ thunkApi,
3669
+ dialogKey,
3670
+ parentMessageId: currentParentMessageId2,
3671
+ messageMetadata: streamingMessageMetadata,
3672
+ quickChatPerfStartedAt,
3673
+ fallbackBodyData
3674
+ })
3675
+ })).unwrap();
3676
+ if (!meta || loopController.signal.aborted || thunkApi.signal.aborted) break;
3478
3677
  logQuickChatPerfStage2(quickChatPerfStartedAt, "stream-agent-model-request-finished", {
3479
3678
  responseApi: true,
3480
3679
  hasToolCalls: meta.hasToolCalls,
@@ -3524,6 +3723,17 @@ ${info.actionHint}` : streamError;
3524
3723
  if (w2) w2.__LOOP_STOP_REASON__ = "pending";
3525
3724
  break;
3526
3725
  }
3726
+ if (!loopController.signal.aborted && !thunkApi.signal.aborted) {
3727
+ const admitted = await dispatch(admitPendingUserMessages({
3728
+ dialogKey,
3729
+ signal: loopController.signal
3730
+ })).unwrap();
3731
+ if (loopController.signal.aborted || thunkApi.signal.aborted) break;
3732
+ if (admitted.length) {
3733
+ activeTurnUserMessageId2 = admitted[admitted.length - 1].id;
3734
+ continue;
3735
+ }
3736
+ }
3527
3737
  const afterTurnState = getState();
3528
3738
  const queuedMessages = selectPendingUserInputQueue(afterTurnState, dialogKey);
3529
3739
  if (queuedMessages.length > 0) {
@@ -3673,7 +3883,7 @@ ${info.actionHint}` : streamError;
3673
3883
  mergeContexts(staticContexts, dynamicContexts),
3674
3884
  contextBlocks
3675
3885
  );
3676
- const rawMessages = selectAllMsgs(loopState, dialogId);
3886
+ const rawMessages = selectAdmittedMessages(selectAllMsgs(loopState, dialogId));
3677
3887
  let visibleMessages = buildAgentViewMessages(
3678
3888
  rawMessages,
3679
3889
  agentConfigForCall.dbKey
@@ -3701,9 +3911,9 @@ ${info.actionHint}` : streamError;
3701
3911
  }
3702
3912
  }
3703
3913
  }
3914
+ const requestUserInput = snapshotUserBatchInput(selectAllMsgs(loopState, dialogId));
3704
3915
  const cleanedMessages = filterAndCleanMessages(visibleMessages);
3705
3916
  const ctxWindow = resolveAgentContextWindow(agentConfigForCall);
3706
- const summaryTokenCount = contexts.dialogSummary ? estimateTokenCount(contexts.dialogSummary) : 0;
3707
3917
  const messagesBeforeStrip = compressOldToolResults(cleanedMessages);
3708
3918
  const preprocessedResult = await stripImagePartsForTextOnlyAgent(
3709
3919
  messagesBeforeStrip,
@@ -3714,23 +3924,44 @@ ${info.actionHint}` : streamError;
3714
3924
  messagesBeforeStrip,
3715
3925
  targetUserMessageId: activeTurnUserMessageId
3716
3926
  });
3717
- let processedMessages = trimMessagesWithSummary(
3718
- preprocessedResult.messages,
3719
- ctxWindow,
3720
- summaryTokenCount
3721
- );
3722
- let firstDynamicIdx = processedMessages.findIndex(
3723
- (m) => m.id && !initialHistoryIds.has(m.id)
3724
- );
3725
- if (firstDynamicIdx === -1) firstDynamicIdx = processedMessages.length;
3726
- let stableMessages = processedMessages.slice(0, firstDynamicIdx);
3727
- let dynamicMessages = processedMessages.slice(firstDynamicIdx);
3728
- const bodyData = generateRequestBody({
3729
- agentConfig: effectiveAgentConfig,
3730
- messages: dynamicMessages,
3731
- stableMessages,
3732
- userInput: userInputText,
3733
- contexts
3927
+ const { bodyData, dynamicMessages, stableMessages } = await admitWebRequest({
3928
+ contextWindow: ctxWindow,
3929
+ signal: loopController.signal,
3930
+ rescue: (availableHistoryTokens) => updateDialogSummaryAction({
3931
+ dialogKey,
3932
+ force: true,
3933
+ reason: "budget_rescue",
3934
+ availableHistoryTokens,
3935
+ contextWindow: ctxWindow,
3936
+ preserveLatestUserByProjection: true
3937
+ }, { ...thunkApi, signal: loopController.signal }),
3938
+ build: async () => {
3939
+ const summaryConfig = selectById(getState(), dialogKey);
3940
+ const refreshedContexts = { ...contexts, dialogSummary: summaryConfig?.summary || null };
3941
+ const processedMessages = projectSummaryHistory(preprocessedResult.messages, summaryConfig?.summary, summaryConfig?.summarizedBeforeId);
3942
+ let firstDynamicIdx = processedMessages.findIndex(
3943
+ (m) => m.id && !initialHistoryIds.has(m.id)
3944
+ );
3945
+ if (firstDynamicIdx === -1) firstDynamicIdx = processedMessages.length;
3946
+ let stableMessages2 = processedMessages.slice(0, firstDynamicIdx);
3947
+ let dynamicMessages2 = processedMessages.slice(firstDynamicIdx);
3948
+ const bodyData2 = generateRequestBody({
3949
+ agentConfig: effectiveAgentConfig,
3950
+ messages: dynamicMessages2,
3951
+ stableMessages: stableMessages2,
3952
+ userInput: userInputText,
3953
+ contexts: refreshedContexts
3954
+ });
3955
+ const finalBody = await inlineImageUrlsForCustomProvider(
3956
+ buildFinalCompletionsRequestBody(
3957
+ bodyData2,
3958
+ agentConfigForCall,
3959
+ shouldDisableQuickChatToolsForDirectAnswer(quickChatPerfStartedAt, userInput, runtimeOptions, currentDialog)
3960
+ ),
3961
+ { shouldInline: shouldInlineImageUrlsForAgent(agentConfigForCall), signal: loopController.signal }
3962
+ );
3963
+ return { value: { bodyData: finalBody, dynamicMessages: dynamicMessages2, stableMessages: stableMessages2 }, wireBodies: [buildEmptyCompletionRepairBody(finalBody)] };
3964
+ }
3734
3965
  });
3735
3966
  logQuickChatPerfStage2(quickChatPerfStartedAt, "stream-agent-model-request-starting", {
3736
3967
  responseApi: false,
@@ -3754,16 +3985,23 @@ ${info.actionHint}` : streamError;
3754
3985
  }
3755
3986
  );
3756
3987
  }
3757
- const meta = await sendOpenAICompletionsRequest({
3758
- bodyData,
3759
- agentConfig: agentConfigForCall,
3760
- thunkApi,
3988
+ const meta = await dispatch(runPendingUserBatchRequest({
3761
3989
  dialogKey,
3762
- parentMessageId: currentParentMessageId,
3763
- messageMetadata: streamingMessageMetadata,
3764
- disableToolsForThisRequest,
3765
- quickChatPerfStartedAt
3766
- });
3990
+ signal: loopController.signal,
3991
+ execution: batchExecution,
3992
+ requestUserInput,
3993
+ start: () => sendOpenAICompletionsRequest({
3994
+ bodyData,
3995
+ agentConfig: agentConfigForCall,
3996
+ thunkApi,
3997
+ dialogKey,
3998
+ parentMessageId: currentParentMessageId,
3999
+ messageMetadata: streamingMessageMetadata,
4000
+ disableToolsForThisRequest,
4001
+ quickChatPerfStartedAt
4002
+ })
4003
+ })).unwrap();
4004
+ if (!meta || loopController.signal.aborted || thunkApi.signal.aborted) break;
3767
4005
  logQuickChatPerfStage2(quickChatPerfStartedAt, "stream-agent-model-request-finished", {
3768
4006
  responseApi: false,
3769
4007
  hasToolCalls: meta.hasToolCalls,
@@ -3784,6 +4022,17 @@ ${info.actionHint}` : streamError;
3784
4022
  if (w) w.__LOOP_STOP_REASON__ = "pending";
3785
4023
  break;
3786
4024
  }
4025
+ if (!loopController.signal.aborted && !thunkApi.signal.aborted) {
4026
+ const admitted = await dispatch(admitPendingUserMessages({
4027
+ dialogKey,
4028
+ signal: loopController.signal
4029
+ })).unwrap();
4030
+ if (loopController.signal.aborted || thunkApi.signal.aborted) break;
4031
+ if (admitted.length) {
4032
+ activeTurnUserMessageId = admitted[admitted.length - 1].id;
4033
+ continue;
4034
+ }
4035
+ }
3787
4036
  const afterTurnState = getState();
3788
4037
  const queuedMessages = selectPendingUserInputQueue(afterTurnState, dialogKey);
3789
4038
  if (queuedMessages.length > 0) {
@@ -3844,10 +4093,18 @@ ${info.actionHint}` : streamError;
3844
4093
  } else if (!isTurnAborted(error)) {
3845
4094
  setLoopStopReason("error");
3846
4095
  }
4096
+ if (error instanceof DirectApiKeyResolutionError || error?.kind === "credential_missing") {
4097
+ return rejectWithValue({
4098
+ kind: "credential_missing",
4099
+ credentialRef: error.credentialRef,
4100
+ message: error.message
4101
+ });
4102
+ }
3847
4103
  return rejectWithValue(
3848
4104
  error?.message || "An unexpected error occurred in streamAgentChatTurn."
3849
4105
  );
3850
4106
  } finally {
4107
+ batchExecution.dispose();
3851
4108
  clearDialogTurnPhase({ dialogKey: runtimeDialogKey ?? void 0, turnId: turnPhaseTurnId ?? void 0 });
3852
4109
  if (loopKey && runtimeDialogKey) {
3853
4110
  dispatch(removeActiveController({ messageId: loopKey, dialogKey: runtimeDialogKey }));