@namzu/cli 37.0.0 → 37.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/bin.js +1 -1
  3. package/dist/chunks/{acp-NJUDAWEV.js → acp-Y2WQVKWL.js} +57 -44
  4. package/dist/chunks/acp-Y2WQVKWL.js.map +6 -0
  5. package/dist/chunks/{activity-command-YUENOVUC.js → activity-command-UMTER4IK.js} +10 -10
  6. package/dist/chunks/{add-3F3PRHZ5.js → add-AIDLR6U4.js} +15 -15
  7. package/dist/chunks/{agent-KYILQUOP.js → agent-C7TDIJ67.js} +24 -24
  8. package/dist/chunks/agent-session-D4Z3TOX3.js +49 -0
  9. package/dist/chunks/{archive-VXAYIALI.js → archive-FKUQ77FG.js} +8 -8
  10. package/dist/chunks/{bin-main-7CCZXZ53.js → bin-main-EIWOQZCZ.js} +3 -3
  11. package/dist/chunks/{browser-LAZRYCOJ.js → browser-7P2TABJG.js} +6 -6
  12. package/dist/chunks/{chat-RI2TEONK.js → chat-YN6WWBI6.js} +13 -13
  13. package/dist/chunks/{chunk-SJW2UYTK.js → chunk-23SR4YFL.js} +2 -2
  14. package/dist/chunks/{chunk-QXSIBEFU.js → chunk-2EDGH6Y3.js} +3 -3
  15. package/dist/chunks/{chunk-MK4U26GZ.js → chunk-2YPMHUI4.js} +2 -2
  16. package/dist/chunks/{chunk-3M5GHYIX.js → chunk-37A6M7P4.js} +4 -4
  17. package/dist/chunks/{chunk-4JQ2VCTQ.js → chunk-3NCL3Y53.js} +4 -4
  18. package/dist/chunks/{chunk-T5D5HHTY.js → chunk-3SGEHTJ4.js} +6 -6
  19. package/dist/chunks/{chunk-DEYX6OXI.js → chunk-45MA2WMX.js} +3 -3
  20. package/dist/chunks/{chunk-PGPL6KIS.js → chunk-4GDOFBZF.js} +3 -3
  21. package/dist/chunks/{chunk-VNGFBD26.js → chunk-5GOYK3IN.js} +2 -2
  22. package/dist/chunks/{chunk-W5PML5BG.js → chunk-5WDPVM7Q.js} +2 -2
  23. package/dist/chunks/{chunk-YJVLERBF.js → chunk-6CQJH56B.js} +2 -2
  24. package/dist/chunks/{chunk-BXJ7G5XN.js → chunk-6HDBRUB7.js} +84 -28
  25. package/dist/chunks/chunk-6HDBRUB7.js.map +6 -0
  26. package/dist/chunks/{chunk-34CCZWJM.js → chunk-74WE6T6M.js} +6 -6
  27. package/dist/chunks/{chunk-K7ADP5FF.js → chunk-BUQ7VMBS.js} +3 -3
  28. package/dist/chunks/{chunk-2KSXZBZK.js → chunk-BV2SDA2D.js} +12 -6
  29. package/dist/chunks/chunk-BV2SDA2D.js.map +6 -0
  30. package/dist/chunks/{chunk-6V3D6JMG.js → chunk-D7FPVZDC.js} +2 -2
  31. package/dist/chunks/{chunk-EIMWVYBK.js → chunk-DBBWIOQS.js} +3 -3
  32. package/dist/chunks/{chunk-UMVFXQYE.js → chunk-DFU5KG3V.js} +4 -4
  33. package/dist/chunks/{chunk-5RTONMXP.js → chunk-EBFWNPMU.js} +9 -9
  34. package/dist/chunks/{chunk-MR34S4AM.js → chunk-F2JKDYHA.js} +4 -4
  35. package/dist/chunks/{chunk-BPGADECQ.js → chunk-FKLDO6SF.js} +3 -3
  36. package/dist/chunks/{chunk-5J3T7DNL.js → chunk-FLUVTAXY.js} +1677 -618
  37. package/dist/chunks/{chunk-5J3T7DNL.js.map → chunk-FLUVTAXY.js.map} +3 -3
  38. package/dist/chunks/{chunk-TCXO5WZX.js → chunk-GR452YOE.js} +2 -2
  39. package/dist/chunks/{chunk-5GUMVF2I.js → chunk-HHKKHUJK.js} +2 -2
  40. package/dist/chunks/{chunk-IOGROWMG.js → chunk-HV4SSQ2Y.js} +3 -3
  41. package/dist/chunks/{chunk-4DDYSIB2.js → chunk-HXFPEA6Z.js} +5 -2
  42. package/dist/chunks/{chunk-4DDYSIB2.js.map → chunk-HXFPEA6Z.js.map} +1 -1
  43. package/dist/chunks/{chunk-PSZ6GS75.js → chunk-I3Q53U6H.js} +2 -2
  44. package/dist/chunks/{chunk-LSMOWOWC.js → chunk-I6XWCKKW.js} +4 -4
  45. package/dist/chunks/{chunk-2K4A2MVQ.js → chunk-JH2O55TT.js} +4 -4
  46. package/dist/chunks/{chunk-EV57ARS2.js → chunk-KQM2NQ2W.js} +12 -11
  47. package/dist/chunks/chunk-KQM2NQ2W.js.map +6 -0
  48. package/dist/chunks/{chunk-DFLYRMHP.js → chunk-KSFS3BI7.js} +2 -2
  49. package/dist/chunks/{chunk-AHKD4XSH.js → chunk-L7Q7QNNE.js} +3 -3
  50. package/dist/chunks/{chunk-OEI64DLJ.js → chunk-MVGNG67O.js} +2 -2
  51. package/dist/chunks/{chunk-SDHJ2YUN.js → chunk-MYRLRBZG.js} +15 -3
  52. package/dist/chunks/chunk-MYRLRBZG.js.map +6 -0
  53. package/dist/chunks/{chunk-UY74BJBW.js → chunk-NKERGDBZ.js} +2 -2
  54. package/dist/chunks/{chunk-7BXRAEQU.js → chunk-OKB66ICJ.js} +10 -10
  55. package/dist/chunks/{chunk-VA63RY7U.js → chunk-OVVIFOAR.js} +4 -4
  56. package/dist/chunks/{chunk-NQGVXNXO.js → chunk-QCJU5KFR.js} +6 -6
  57. package/dist/chunks/{chunk-XAFTUVN7.js → chunk-QU3LGVTZ.js} +5 -5
  58. package/dist/chunks/{chunk-JAPAPPNH.js → chunk-QVMTUMTW.js} +3 -3
  59. package/dist/chunks/{chunk-KF7KR67Z.js → chunk-R23DP7S7.js} +7 -7
  60. package/dist/chunks/{chunk-PXLJT6YH.js → chunk-SEKX6IR5.js} +13 -13
  61. package/dist/chunks/{chunk-2IWFTP44.js → chunk-UFZGVNFQ.js} +2 -2
  62. package/dist/chunks/{chunk-KXRBZ2IT.js → chunk-VZ4KVZWO.js} +28 -28
  63. package/dist/chunks/{chunk-VHEMDWNA.js → chunk-WMOYTZXD.js} +12 -12
  64. package/dist/chunks/{chunk-5Y2HRYPF.js → chunk-WWE4W2R6.js} +2 -2
  65. package/dist/chunks/{chunk-I7GFMQGF.js → chunk-X3ZBCYV6.js} +2 -2
  66. package/dist/chunks/{chunk-STHNLNY5.js → chunk-XDAMUTVR.js} +4 -4
  67. package/dist/chunks/{chunk-O3XQA4ZZ.js → chunk-XYXPAVPG.js} +4 -4
  68. package/dist/chunks/{chunk-EHEEEVWJ.js → chunk-Y3UE64PV.js} +3 -3
  69. package/dist/chunks/{chunk-NADDUQSP.js → chunk-YCVR5E2Z.js} +4 -4
  70. package/dist/chunks/{chunk-YQHHGBOR.js → chunk-ZKI3Z4VR.js} +2 -2
  71. package/dist/chunks/{chunk-3RGJ3AC7.js → chunk-ZRAALEF2.js} +2 -2
  72. package/dist/chunks/{chunk-QEWQONLW.js → chunk-ZRJYG2F2.js} +2 -2
  73. package/dist/chunks/{cli-runtime-KH73NP4C.js → cli-runtime-74KKQHC7.js} +7 -7
  74. package/dist/chunks/{commands-IMV24FMR.js → commands-2Q7KPVLW.js} +5 -5
  75. package/dist/chunks/{crash-report-VQBUHKGL.js → crash-report-KDVWQ2RR.js} +6 -6
  76. package/dist/chunks/{dist-CQLUZMPF.js → dist-25C2CYHP.js} +2 -2
  77. package/dist/chunks/{dist-LNY6YOW7.js → dist-4TGHKBRS.js} +2 -2
  78. package/dist/chunks/{dist-7Y7RRIE5.js → dist-674RS73L.js} +2 -2
  79. package/dist/chunks/{dist-E6HO2DY4.js → dist-OMRUSJ5R.js} +12 -2
  80. package/dist/chunks/{dist-E6HO2DY4.js.map → dist-OMRUSJ5R.js.map} +1 -1
  81. package/dist/chunks/{dist-WAEUJUZL.js → dist-Q523V5L2.js} +2 -2
  82. package/dist/chunks/{dist-EZYJPZFW.js → dist-UYD7IXG3.js} +2 -2
  83. package/dist/chunks/{dist-ZNBV3COW.js → dist-ZDSPMZ5S.js} +2 -2
  84. package/dist/chunks/{doctor-DEG3FKDC.js → doctor-TFION64N.js} +6 -6
  85. package/dist/chunks/{drain-NPWQOBUJ.js → drain-3W3A4KPX.js} +10 -10
  86. package/dist/chunks/{eval-GI6JQAOX.js → eval-TCUVH3S3.js} +2 -2
  87. package/dist/chunks/{exec-RP67LSL5.js → exec-EIELDRPM.js} +23 -23
  88. package/dist/chunks/{home-7EKRNFWG.js → home-FYDAEWNW.js} +3 -3
  89. package/dist/chunks/{host-queries-YN42AIUD.js → host-queries-WFWM672O.js} +13 -13
  90. package/dist/chunks/{lifecycle-T7GDJRCI.js → lifecycle-ALDBR656.js} +22 -22
  91. package/dist/chunks/{list-FQZJ3GDF.js → list-Z4XOJJ7V.js} +11 -11
  92. package/dist/chunks/{login-NO23T6HC.js → login-UZONOHHT.js} +8 -8
  93. package/dist/chunks/{logs-LJVTOGXE.js → logs-O3NGOQFC.js} +4 -4
  94. package/dist/chunks/{mcp-NBWL73J5.js → mcp-YI6PL4TH.js} +16 -16
  95. package/dist/chunks/{message-command-YIURBF2Q.js → message-command-QEQJ25KR.js} +30 -30
  96. package/dist/chunks/{operator-tools-MQXMUQLG.js → operator-tools-GKYGHHPM.js} +11 -11
  97. package/dist/chunks/{output-schema-2BCRDYWG.js → output-schema-KXKCYDI4.js} +3 -3
  98. package/dist/chunks/{pal-PTOFIOCI.js → pal-2EYYHPXC.js} +11 -11
  99. package/dist/chunks/{providers-YRNXCZW5.js → providers-JF5SWSTH.js} +6 -6
  100. package/dist/chunks/{resident-QI33LA6J.js → resident-WHH7YQGZ.js} +19 -19
  101. package/dist/chunks/{resume-3R5VLEIS.js → resume-WR4KOI7Q.js} +9 -9
  102. package/dist/chunks/{resume-command-7SGSPKXV.js → resume-command-A3HKQSRH.js} +4 -4
  103. package/dist/chunks/{schedule-YOMKA5IF.js → schedule-QIJCYWIQ.js} +8 -8
  104. package/dist/chunks/{service-A4YKUMRI.js → service-IXPGBY3F.js} +21 -21
  105. package/dist/chunks/session-step-ZZBENVGS.js +26 -0
  106. package/dist/chunks/{skills-BARULYB3.js → skills-AGU7FTRG.js} +8 -8
  107. package/dist/chunks/{state-ZD6WF2PZ.js → state-MTHK7DUX.js} +2 -2
  108. package/dist/chunks/{store-RD7EX5RD.js → store-EWEKEKSG.js} +8 -8
  109. package/dist/chunks/{store-HEOMPNER.js → store-LPOET7IK.js} +4 -4
  110. package/dist/chunks/{store-YWZ6SY2M.js → store-XPSGZANO.js} +6 -6
  111. package/dist/chunks/{tui-JLOFXK7O.js → tui-YMBQLMGW.js} +43 -43
  112. package/dist/chunks/{upgrade-FLMI5ZYW.js → upgrade-3YOFSMAQ.js} +2 -2
  113. package/dist/chunks/{worktree-GUWRR5KY.js → worktree-VPD2N53Y.js} +10 -10
  114. package/dist/commands/acp.d.ts.map +1 -1
  115. package/dist/commands/desktop-host.d.ts.map +1 -1
  116. package/dist/index.js +10 -10
  117. package/dist/integrations/providers/image-input.d.ts +22 -0
  118. package/dist/integrations/providers/image-input.d.ts.map +1 -0
  119. package/dist/integrations/resident/runner-worker.js +16 -16
  120. package/dist/pals/agent-session.d.ts.map +1 -1
  121. package/dist/terminal/pty.d.ts +8 -0
  122. package/dist/terminal/pty.d.ts.map +1 -1
  123. package/dist/tui/agent.d.ts.map +1 -1
  124. package/dist/tui/capability-notice.d.ts +1 -1
  125. package/dist/tui/capability-notice.d.ts.map +1 -1
  126. package/dist/tui/plain-interruption.d.ts.map +1 -1
  127. package/dist/tui/turn-interruption.d.ts.map +1 -1
  128. package/package.json +4 -4
  129. package/dist/chunks/acp-NJUDAWEV.js.map +0 -6
  130. package/dist/chunks/agent-session-2YMHOAKF.js +0 -49
  131. package/dist/chunks/chunk-2KSXZBZK.js.map +0 -6
  132. package/dist/chunks/chunk-BXJ7G5XN.js.map +0 -6
  133. package/dist/chunks/chunk-EV57ARS2.js.map +0 -6
  134. package/dist/chunks/chunk-SDHJ2YUN.js.map +0 -6
  135. package/dist/chunks/session-step-N5EWWZ4K.js +0 -26
  136. /package/dist/chunks/{activity-command-YUENOVUC.js.map → activity-command-UMTER4IK.js.map} +0 -0
  137. /package/dist/chunks/{add-3F3PRHZ5.js.map → add-AIDLR6U4.js.map} +0 -0
  138. /package/dist/chunks/{agent-KYILQUOP.js.map → agent-C7TDIJ67.js.map} +0 -0
  139. /package/dist/chunks/{agent-session-2YMHOAKF.js.map → agent-session-D4Z3TOX3.js.map} +0 -0
  140. /package/dist/chunks/{archive-VXAYIALI.js.map → archive-FKUQ77FG.js.map} +0 -0
  141. /package/dist/chunks/{bin-main-7CCZXZ53.js.map → bin-main-EIWOQZCZ.js.map} +0 -0
  142. /package/dist/chunks/{browser-LAZRYCOJ.js.map → browser-7P2TABJG.js.map} +0 -0
  143. /package/dist/chunks/{chat-RI2TEONK.js.map → chat-YN6WWBI6.js.map} +0 -0
  144. /package/dist/chunks/{chunk-SJW2UYTK.js.map → chunk-23SR4YFL.js.map} +0 -0
  145. /package/dist/chunks/{chunk-QXSIBEFU.js.map → chunk-2EDGH6Y3.js.map} +0 -0
  146. /package/dist/chunks/{chunk-MK4U26GZ.js.map → chunk-2YPMHUI4.js.map} +0 -0
  147. /package/dist/chunks/{chunk-3M5GHYIX.js.map → chunk-37A6M7P4.js.map} +0 -0
  148. /package/dist/chunks/{chunk-4JQ2VCTQ.js.map → chunk-3NCL3Y53.js.map} +0 -0
  149. /package/dist/chunks/{chunk-T5D5HHTY.js.map → chunk-3SGEHTJ4.js.map} +0 -0
  150. /package/dist/chunks/{chunk-DEYX6OXI.js.map → chunk-45MA2WMX.js.map} +0 -0
  151. /package/dist/chunks/{chunk-PGPL6KIS.js.map → chunk-4GDOFBZF.js.map} +0 -0
  152. /package/dist/chunks/{chunk-VNGFBD26.js.map → chunk-5GOYK3IN.js.map} +0 -0
  153. /package/dist/chunks/{chunk-W5PML5BG.js.map → chunk-5WDPVM7Q.js.map} +0 -0
  154. /package/dist/chunks/{chunk-YJVLERBF.js.map → chunk-6CQJH56B.js.map} +0 -0
  155. /package/dist/chunks/{chunk-34CCZWJM.js.map → chunk-74WE6T6M.js.map} +0 -0
  156. /package/dist/chunks/{chunk-K7ADP5FF.js.map → chunk-BUQ7VMBS.js.map} +0 -0
  157. /package/dist/chunks/{chunk-6V3D6JMG.js.map → chunk-D7FPVZDC.js.map} +0 -0
  158. /package/dist/chunks/{chunk-EIMWVYBK.js.map → chunk-DBBWIOQS.js.map} +0 -0
  159. /package/dist/chunks/{chunk-UMVFXQYE.js.map → chunk-DFU5KG3V.js.map} +0 -0
  160. /package/dist/chunks/{chunk-5RTONMXP.js.map → chunk-EBFWNPMU.js.map} +0 -0
  161. /package/dist/chunks/{chunk-MR34S4AM.js.map → chunk-F2JKDYHA.js.map} +0 -0
  162. /package/dist/chunks/{chunk-BPGADECQ.js.map → chunk-FKLDO6SF.js.map} +0 -0
  163. /package/dist/chunks/{chunk-TCXO5WZX.js.map → chunk-GR452YOE.js.map} +0 -0
  164. /package/dist/chunks/{chunk-5GUMVF2I.js.map → chunk-HHKKHUJK.js.map} +0 -0
  165. /package/dist/chunks/{chunk-IOGROWMG.js.map → chunk-HV4SSQ2Y.js.map} +0 -0
  166. /package/dist/chunks/{chunk-PSZ6GS75.js.map → chunk-I3Q53U6H.js.map} +0 -0
  167. /package/dist/chunks/{chunk-LSMOWOWC.js.map → chunk-I6XWCKKW.js.map} +0 -0
  168. /package/dist/chunks/{chunk-2K4A2MVQ.js.map → chunk-JH2O55TT.js.map} +0 -0
  169. /package/dist/chunks/{chunk-DFLYRMHP.js.map → chunk-KSFS3BI7.js.map} +0 -0
  170. /package/dist/chunks/{chunk-AHKD4XSH.js.map → chunk-L7Q7QNNE.js.map} +0 -0
  171. /package/dist/chunks/{chunk-OEI64DLJ.js.map → chunk-MVGNG67O.js.map} +0 -0
  172. /package/dist/chunks/{chunk-UY74BJBW.js.map → chunk-NKERGDBZ.js.map} +0 -0
  173. /package/dist/chunks/{chunk-7BXRAEQU.js.map → chunk-OKB66ICJ.js.map} +0 -0
  174. /package/dist/chunks/{chunk-VA63RY7U.js.map → chunk-OVVIFOAR.js.map} +0 -0
  175. /package/dist/chunks/{chunk-NQGVXNXO.js.map → chunk-QCJU5KFR.js.map} +0 -0
  176. /package/dist/chunks/{chunk-XAFTUVN7.js.map → chunk-QU3LGVTZ.js.map} +0 -0
  177. /package/dist/chunks/{chunk-JAPAPPNH.js.map → chunk-QVMTUMTW.js.map} +0 -0
  178. /package/dist/chunks/{chunk-KF7KR67Z.js.map → chunk-R23DP7S7.js.map} +0 -0
  179. /package/dist/chunks/{chunk-PXLJT6YH.js.map → chunk-SEKX6IR5.js.map} +0 -0
  180. /package/dist/chunks/{chunk-2IWFTP44.js.map → chunk-UFZGVNFQ.js.map} +0 -0
  181. /package/dist/chunks/{chunk-KXRBZ2IT.js.map → chunk-VZ4KVZWO.js.map} +0 -0
  182. /package/dist/chunks/{chunk-VHEMDWNA.js.map → chunk-WMOYTZXD.js.map} +0 -0
  183. /package/dist/chunks/{chunk-5Y2HRYPF.js.map → chunk-WWE4W2R6.js.map} +0 -0
  184. /package/dist/chunks/{chunk-I7GFMQGF.js.map → chunk-X3ZBCYV6.js.map} +0 -0
  185. /package/dist/chunks/{chunk-STHNLNY5.js.map → chunk-XDAMUTVR.js.map} +0 -0
  186. /package/dist/chunks/{chunk-O3XQA4ZZ.js.map → chunk-XYXPAVPG.js.map} +0 -0
  187. /package/dist/chunks/{chunk-EHEEEVWJ.js.map → chunk-Y3UE64PV.js.map} +0 -0
  188. /package/dist/chunks/{chunk-NADDUQSP.js.map → chunk-YCVR5E2Z.js.map} +0 -0
  189. /package/dist/chunks/{chunk-YQHHGBOR.js.map → chunk-ZKI3Z4VR.js.map} +0 -0
  190. /package/dist/chunks/{chunk-3RGJ3AC7.js.map → chunk-ZRAALEF2.js.map} +0 -0
  191. /package/dist/chunks/{chunk-QEWQONLW.js.map → chunk-ZRJYG2F2.js.map} +0 -0
  192. /package/dist/chunks/{cli-runtime-KH73NP4C.js.map → cli-runtime-74KKQHC7.js.map} +0 -0
  193. /package/dist/chunks/{commands-IMV24FMR.js.map → commands-2Q7KPVLW.js.map} +0 -0
  194. /package/dist/chunks/{crash-report-VQBUHKGL.js.map → crash-report-KDVWQ2RR.js.map} +0 -0
  195. /package/dist/chunks/{dist-CQLUZMPF.js.map → dist-25C2CYHP.js.map} +0 -0
  196. /package/dist/chunks/{dist-LNY6YOW7.js.map → dist-4TGHKBRS.js.map} +0 -0
  197. /package/dist/chunks/{dist-7Y7RRIE5.js.map → dist-674RS73L.js.map} +0 -0
  198. /package/dist/chunks/{dist-WAEUJUZL.js.map → dist-Q523V5L2.js.map} +0 -0
  199. /package/dist/chunks/{dist-EZYJPZFW.js.map → dist-UYD7IXG3.js.map} +0 -0
  200. /package/dist/chunks/{dist-ZNBV3COW.js.map → dist-ZDSPMZ5S.js.map} +0 -0
  201. /package/dist/chunks/{doctor-DEG3FKDC.js.map → doctor-TFION64N.js.map} +0 -0
  202. /package/dist/chunks/{drain-NPWQOBUJ.js.map → drain-3W3A4KPX.js.map} +0 -0
  203. /package/dist/chunks/{eval-GI6JQAOX.js.map → eval-TCUVH3S3.js.map} +0 -0
  204. /package/dist/chunks/{exec-RP67LSL5.js.map → exec-EIELDRPM.js.map} +0 -0
  205. /package/dist/chunks/{home-7EKRNFWG.js.map → home-FYDAEWNW.js.map} +0 -0
  206. /package/dist/chunks/{host-queries-YN42AIUD.js.map → host-queries-WFWM672O.js.map} +0 -0
  207. /package/dist/chunks/{lifecycle-T7GDJRCI.js.map → lifecycle-ALDBR656.js.map} +0 -0
  208. /package/dist/chunks/{list-FQZJ3GDF.js.map → list-Z4XOJJ7V.js.map} +0 -0
  209. /package/dist/chunks/{login-NO23T6HC.js.map → login-UZONOHHT.js.map} +0 -0
  210. /package/dist/chunks/{logs-LJVTOGXE.js.map → logs-O3NGOQFC.js.map} +0 -0
  211. /package/dist/chunks/{mcp-NBWL73J5.js.map → mcp-YI6PL4TH.js.map} +0 -0
  212. /package/dist/chunks/{message-command-YIURBF2Q.js.map → message-command-QEQJ25KR.js.map} +0 -0
  213. /package/dist/chunks/{operator-tools-MQXMUQLG.js.map → operator-tools-GKYGHHPM.js.map} +0 -0
  214. /package/dist/chunks/{output-schema-2BCRDYWG.js.map → output-schema-KXKCYDI4.js.map} +0 -0
  215. /package/dist/chunks/{pal-PTOFIOCI.js.map → pal-2EYYHPXC.js.map} +0 -0
  216. /package/dist/chunks/{providers-YRNXCZW5.js.map → providers-JF5SWSTH.js.map} +0 -0
  217. /package/dist/chunks/{resident-QI33LA6J.js.map → resident-WHH7YQGZ.js.map} +0 -0
  218. /package/dist/chunks/{resume-3R5VLEIS.js.map → resume-WR4KOI7Q.js.map} +0 -0
  219. /package/dist/chunks/{resume-command-7SGSPKXV.js.map → resume-command-A3HKQSRH.js.map} +0 -0
  220. /package/dist/chunks/{schedule-YOMKA5IF.js.map → schedule-QIJCYWIQ.js.map} +0 -0
  221. /package/dist/chunks/{service-A4YKUMRI.js.map → service-IXPGBY3F.js.map} +0 -0
  222. /package/dist/chunks/{session-step-N5EWWZ4K.js.map → session-step-ZZBENVGS.js.map} +0 -0
  223. /package/dist/chunks/{skills-BARULYB3.js.map → skills-AGU7FTRG.js.map} +0 -0
  224. /package/dist/chunks/{state-ZD6WF2PZ.js.map → state-MTHK7DUX.js.map} +0 -0
  225. /package/dist/chunks/{store-HEOMPNER.js.map → store-EWEKEKSG.js.map} +0 -0
  226. /package/dist/chunks/{store-RD7EX5RD.js.map → store-LPOET7IK.js.map} +0 -0
  227. /package/dist/chunks/{store-YWZ6SY2M.js.map → store-XPSGZANO.js.map} +0 -0
  228. /package/dist/chunks/{tui-JLOFXK7O.js.map → tui-YMBQLMGW.js.map} +0 -0
  229. /package/dist/chunks/{upgrade-FLMI5ZYW.js.map → upgrade-3YOFSMAQ.js.map} +0 -0
  230. /package/dist/chunks/{worktree-GUWRR5KY.js.map → worktree-VPD2N53Y.js.map} +0 -0
@@ -3655,6 +3655,14 @@ function readOutputOverflow(err) {
3655
3655
  return void 0;
3656
3656
  }
3657
3657
  __name(readOutputOverflow, "readOutputOverflow");
3658
+ function isUndiciTermination(err) {
3659
+ for (const link6 of causeChain(err)) {
3660
+ if (link6 instanceof TypeError && link6.message === "terminated")
3661
+ return true;
3662
+ }
3663
+ return false;
3664
+ }
3665
+ __name(isUndiciTermination, "isUndiciTermination");
3658
3666
  var NETWORK_ERRNOS = /* @__PURE__ */ new Set([
3659
3667
  "ECONNRESET",
3660
3668
  "ECONNREFUSED",
@@ -3693,13 +3701,23 @@ function codeFromStatus(status) {
3693
3701
  return "unknown";
3694
3702
  }
3695
3703
  __name(codeFromStatus, "codeFromStatus");
3696
- function codeFromMessage(message) {
3704
+ function overflowWordingAllowed(status) {
3705
+ return status === void 0 || status === 400 || status === 413;
3706
+ }
3707
+ __name(overflowWordingAllowed, "overflowWordingAllowed");
3708
+ var CONTEXT_WINDOW_OVERFLOW = /(?:exceed\w*|too (?:long|large|big)|larger than|longer than|over the|beyond|maximum|overflow\w*)\b[^.]{0,60}context window|context window[^.]{0,60}\b(?:exceed\w*|too (?:long|large|big)|larger than|longer than|over the|beyond|maximum|overflow\w*)/i;
3709
+ function codeFromMessage(message, status) {
3697
3710
  const m = message.toLowerCase();
3698
3711
  if (m.includes("context length") || m.includes("context_length") || m.includes("maximum context") || m.includes("too many tokens") || m.includes("prompt is too long") || // Real wordings that missed every phrase above and so classified as
3699
3712
  // a plain invalid request — which is not retryable, and which the
3700
3713
  // overflow rescue tests for by exact equality. The turn died holding
3701
3714
  // the remedy.
3702
- m.includes("too long for") || m.includes("maximum length") || m.includes("exceeds the maximum") || m.includes("input is too large") || m.includes("too large for")) {
3715
+ m.includes("too long for") || // The reference terminal's own wordings (its `context window` and
3716
+ // `input length and max_tokens exceed context limit` matchers).
3717
+ // Only where the status cannot say otherwise: a 429, 5xx or 401 that
3718
+ // mentions the window is still a rate limit, a server fault or an auth
3719
+ // failure, and must keep its retry and fallback behaviour.
3720
+ overflowWordingAllowed(status) && (CONTEXT_WINDOW_OVERFLOW.test(message) || m.includes("exceed context limit")) || m.includes("maximum length") || m.includes("exceeds the maximum") || m.includes("input is too large") || m.includes("too large for")) {
3703
3721
  return "context_length_exceeded";
3704
3722
  }
3705
3723
  if (m.includes("rate limit") || m.includes("rate_limit") || m.includes("too many requests")) {
@@ -3788,7 +3806,7 @@ function classifyProviderError(err, providerId, now = Date.now()) {
3788
3806
  const errno = readErrnoCode(err);
3789
3807
  const retryAfterMs = readRetryAfterMs(err, now);
3790
3808
  const messages = chainMessages(err);
3791
- const fromMessage = messages.map(codeFromMessage).find((code) => code !== void 0);
3809
+ const fromMessage = messages.map((m) => codeFromMessage(m, status)).find((code) => code !== void 0);
3792
3810
  const declared = declaredRetryable(err);
3793
3811
  const structural = codeFromStructure(err);
3794
3812
  if (structural !== void 0) {
@@ -3802,7 +3820,7 @@ function classifyProviderError(err, providerId, now = Date.now()) {
3802
3820
  cause: err
3803
3821
  });
3804
3822
  }
3805
- if (messages.some((m) => codeFromMessage(m) === "context_length_exceeded")) {
3823
+ if (messages.some((m) => codeFromMessage(m, status) === "context_length_exceeded")) {
3806
3824
  return new ProviderError({
3807
3825
  code: "context_length_exceeded",
3808
3826
  message,
@@ -3843,7 +3861,7 @@ function classifyProviderError(err, providerId, now = Date.now()) {
3843
3861
  });
3844
3862
  }
3845
3863
  }
3846
- if (err instanceof TypeError && /fetch|network/i.test(message)) {
3864
+ if (err instanceof TypeError && /fetch|network/i.test(message) || isUndiciTermination(err)) {
3847
3865
  return new ProviderError({
3848
3866
  code: "network",
3849
3867
  message,
@@ -14209,6 +14227,483 @@ var PromptContributionRegistry = class {
14209
14227
  };
14210
14228
  var SKILLS_CONTRIBUTION_ID = "namzu.skills";
14211
14229
 
14230
+ // ../sdk/dist/provider/errors.js
14231
+ var PROVIDER_ERROR_KINDS = [
14232
+ "throttle",
14233
+ "network",
14234
+ "auth",
14235
+ "context_overflow",
14236
+ "bad_request",
14237
+ "server"
14238
+ ];
14239
+ var ProviderRequestError = class extends Error {
14240
+ static {
14241
+ __name(this, "ProviderRequestError");
14242
+ }
14243
+ kind;
14244
+ providerId;
14245
+ providerCode;
14246
+ status;
14247
+ retryAfterMs;
14248
+ /**
14249
+ * What the provider said was wrong, truncated and redacted.
14250
+ *
14251
+ * `ProviderRequestErrorInit` has declared this field all along and the
14252
+ * constructor never read it, so every caller that set it was writing to
14253
+ * nothing. That is not a cosmetic gap: a provider rejecting a request
14254
+ * usually names the exact offending field, and losing that sentence turns
14255
+ * a one-line diagnosis into hypothesis elimination against a live API. It
14256
+ * did — a tool schema in the wrong JSON Schema dialect cost a day of
14257
+ * production downtime while the wire had been saying
14258
+ * `tools.0.custom.input_schema: … must match JSON Schema draft 2020-12`
14259
+ * the whole time.
14260
+ *
14261
+ * See {@link vendorDetail} for what is kept and what is scrubbed.
14262
+ */
14263
+ detail;
14264
+ /** The provider's `x-should-retry` verdict, when it sent one; see {@link ProviderRequestErrorInit.shouldRetry}. */
14265
+ shouldRetry;
14266
+ constructor(init) {
14267
+ super(buildProviderErrorMessage(init));
14268
+ this.name = "ProviderRequestError";
14269
+ this.kind = init.kind;
14270
+ this.providerId = init.providerId;
14271
+ const exactProviderCode = safeProviderCode(init.providerCode);
14272
+ if (exactProviderCode !== void 0)
14273
+ this.providerCode = exactProviderCode;
14274
+ if (init.status !== void 0)
14275
+ this.status = init.status;
14276
+ if (init.retryAfterMs !== void 0)
14277
+ this.retryAfterMs = init.retryAfterMs;
14278
+ if (init.detail !== void 0)
14279
+ this.detail = init.detail;
14280
+ if (init.shouldRetry !== void 0)
14281
+ this.shouldRetry = init.shouldRetry;
14282
+ }
14283
+ };
14284
+ var DETAIL_MAX = 400;
14285
+ var PROVIDER_CODE = /^[A-Za-z][A-Za-z0-9._-]{0,79}$/;
14286
+ function safeProviderCode(value) {
14287
+ if (typeof value !== "string" || !PROVIDER_CODE.test(value))
14288
+ return void 0;
14289
+ return redactSecrets(value) === value ? value : void 0;
14290
+ }
14291
+ __name(safeProviderCode, "safeProviderCode");
14292
+ function providerCode(value) {
14293
+ let decoded = value;
14294
+ if (typeof decoded === "string") {
14295
+ try {
14296
+ decoded = JSON.parse(decoded);
14297
+ } catch {
14298
+ return void 0;
14299
+ }
14300
+ }
14301
+ if (typeof decoded !== "object" || decoded === null)
14302
+ return void 0;
14303
+ const record3 = decoded;
14304
+ const nested = typeof record3.error === "object" && record3.error !== null ? record3.error.code : void 0;
14305
+ return safeProviderCode(record3.code ?? nested);
14306
+ }
14307
+ __name(providerCode, "providerCode");
14308
+ function vendorDetail(body) {
14309
+ if (body === void 0 || body === null)
14310
+ return void 0;
14311
+ let text9;
14312
+ if (typeof body === "string") {
14313
+ try {
14314
+ text9 = pickMessage(JSON.parse(body)) ?? body;
14315
+ } catch {
14316
+ text9 = body;
14317
+ }
14318
+ } else {
14319
+ text9 = pickMessage(body) ?? "";
14320
+ }
14321
+ const cleaned = redactSecrets(text9.trim());
14322
+ if (cleaned.length === 0)
14323
+ return void 0;
14324
+ return cleaned.length > DETAIL_MAX ? `${cleaned.slice(0, DETAIL_MAX)}\u2026` : cleaned;
14325
+ }
14326
+ __name(vendorDetail, "vendorDetail");
14327
+ function redactSecrets(text9) {
14328
+ let out = text9;
14329
+ for (const [label5, pattern] of LOG_SECRET_PATTERNS) {
14330
+ out = out.replace(pattern, `[REDACTED:${label5}]`);
14331
+ }
14332
+ return out;
14333
+ }
14334
+ __name(redactSecrets, "redactSecrets");
14335
+ function pickMessage(value) {
14336
+ if (typeof value === "string")
14337
+ return value;
14338
+ if (typeof value !== "object" || value === null)
14339
+ return void 0;
14340
+ const node = value;
14341
+ const nested = node.error;
14342
+ if (typeof nested === "string")
14343
+ return nested;
14344
+ if (typeof nested === "object" && nested !== null) {
14345
+ const message = nested.message;
14346
+ if (typeof message === "string")
14347
+ return message;
14348
+ }
14349
+ if (typeof node.message === "string")
14350
+ return node.message;
14351
+ return void 0;
14352
+ }
14353
+ __name(pickMessage, "pickMessage");
14354
+ function isProviderRequestError(err) {
14355
+ const exactProviderCode = err?.providerCode;
14356
+ return err instanceof Error && err.name === "ProviderRequestError" && typeof err.providerId === "string" && PROVIDER_ERROR_KINDS.includes(err.kind) && (exactProviderCode === void 0 || safeProviderCode(exactProviderCode) === exactProviderCode);
14357
+ }
14358
+ __name(isProviderRequestError, "isProviderRequestError");
14359
+ function isCallerAbortError(error, signal) {
14360
+ if (!signal?.aborted)
14361
+ return false;
14362
+ if (error === signal.reason)
14363
+ return true;
14364
+ if (!(error instanceof Error))
14365
+ return false;
14366
+ return error.name === "AbortError" || error.name === "APIUserAbortError";
14367
+ }
14368
+ __name(isCallerAbortError, "isCallerAbortError");
14369
+ var KIND_SENTENCE = {
14370
+ throttle: "rate limited by the provider",
14371
+ network: "could not reach the provider",
14372
+ auth: "the provider rejected the request credentials",
14373
+ context_overflow: "the request exceeded the model context window",
14374
+ bad_request: "the provider rejected the request as invalid",
14375
+ server: "the provider failed to complete the request"
14376
+ };
14377
+ function buildProviderErrorMessage(init) {
14378
+ const status = init.status !== void 0 ? ` (HTTP ${init.status})` : "";
14379
+ const detail = init.detail ? `: ${init.detail}` : "";
14380
+ return `${init.providerId}${status} \u2014 ${KIND_SENTENCE[init.kind]}${detail}`;
14381
+ }
14382
+ __name(buildProviderErrorMessage, "buildProviderErrorMessage");
14383
+ var OVERFLOW_BODY_PATTERNS = [
14384
+ /prompt is too long/i,
14385
+ /context[_ ]length[_ ]exceeded/i,
14386
+ /maximum context length/i,
14387
+ /too long for requested model/i,
14388
+ /input is too long/i,
14389
+ /(?:input|prompt|context).{0,80}exceeds the maximum/i,
14390
+ /reduce the (?:input|prompt|context) length/i,
14391
+ // Ollama phrases it the other way round — "input length exceeds context
14392
+ // length" — so a pattern anchored on "exceeded" misses it entirely.
14393
+ /exceeds?\s+(?:the\s+)?(?:model'?s?\s+)?context\s+(?:length|window|size)/i,
14394
+ /context\s+(?:length|window|size)\s+exceed/i,
14395
+ // The reference terminal's own list matches the bare phrase "context
14396
+ // window". Here it must sit next to a verb that says the request did not
14397
+ // fit ("larger than the model context window of N tokens"), so a 400 that
14398
+ // only names the window ("does not support this parameter with the 1M
14399
+ // context window beta") stays an invalid request. The same pattern lives in
14400
+ // `types/provider/errors.ts` (`codeFromMessage`), which also gates it on the
14401
+ // status; keep them equal.
14402
+ /(?:exceed\w*|too (?:long|large|big)|larger than|longer than|over the|beyond|maximum|overflow\w*)\b[^.]{0,60}context window|context window[^.]{0,60}\b(?:exceed\w*|too (?:long|large|big)|larger than|longer than|over the|beyond|maximum|overflow\w*)/i,
14403
+ // "input length and `max_tokens` exceed context limit: A + B > C". The
14404
+ // prompt may fit and only the requested output not; the loop tries a smaller
14405
+ // `max_tokens` first (readOutputOverflow) and falls back to shedding history
14406
+ // when there is no room for a useful reply, which needs this to classify.
14407
+ /input length and `?max_tokens`? exceed context limit/i
14408
+ ];
14409
+ function bodySaysContextOverflow(body) {
14410
+ if (!body)
14411
+ return false;
14412
+ return OVERFLOW_BODY_PATTERNS.some((re2) => re2.test(body));
14413
+ }
14414
+ __name(bodySaysContextOverflow, "bodySaysContextOverflow");
14415
+ function parseShouldRetry(value) {
14416
+ return value?.trim().toLowerCase() === "false" ? false : void 0;
14417
+ }
14418
+ __name(parseShouldRetry, "parseShouldRetry");
14419
+ function parseRetryAfterMs(headerValue2, now = Date.now()) {
14420
+ if (!headerValue2)
14421
+ return void 0;
14422
+ const trimmed = headerValue2.trim();
14423
+ if (trimmed === "")
14424
+ return void 0;
14425
+ if (/^\d+(\.\d+)?$/.test(trimmed)) {
14426
+ const seconds = Number(trimmed);
14427
+ if (!Number.isFinite(seconds) || seconds < 0)
14428
+ return void 0;
14429
+ return Math.round(seconds * 1e3);
14430
+ }
14431
+ const at = Date.parse(trimmed);
14432
+ if (Number.isNaN(at))
14433
+ return void 0;
14434
+ const delta = at - now;
14435
+ return delta > 0 ? delta : void 0;
14436
+ }
14437
+ __name(parseRetryAfterMs, "parseRetryAfterMs");
14438
+ function classifyProviderHttpStatus(status, body) {
14439
+ if (status === 401 || status === 403)
14440
+ return "auth";
14441
+ if (status === 429)
14442
+ return "throttle";
14443
+ if (status === 408 || status === 425)
14444
+ return "network";
14445
+ if (status >= 500)
14446
+ return "server";
14447
+ if (status === 413) {
14448
+ return bodySaysContextOverflow(body) ? "context_overflow" : "bad_request";
14449
+ }
14450
+ if (status >= 400) {
14451
+ return bodySaysContextOverflow(body) ? "context_overflow" : "bad_request";
14452
+ }
14453
+ return "server";
14454
+ }
14455
+ __name(classifyProviderHttpStatus, "classifyProviderHttpStatus");
14456
+ var VENDOR_TYPE_KINDS = [
14457
+ [/overloaded_error|api_error|service_unavailable/i, "server"],
14458
+ [/rate_limit_error|rate_limit_exceeded/i, "throttle"],
14459
+ [/authentication_error|permission_error|invalid_api_key|unauthorized/i, "auth"],
14460
+ [/timeout_error|connection_error/i, "network"]
14461
+ ];
14462
+ function vendorTypeKind(message) {
14463
+ for (const [re2, kind] of VENDOR_TYPE_KINDS) {
14464
+ if (re2.test(message))
14465
+ return kind;
14466
+ }
14467
+ return void 0;
14468
+ }
14469
+ __name(vendorTypeKind, "vendorTypeKind");
14470
+ function vendorErrorStatus(err) {
14471
+ if (typeof err !== "object" || err === null)
14472
+ return void 0;
14473
+ const e = err;
14474
+ for (const candidate of [e.status, e.statusCode, e.status_code, e.$metadata?.httpStatusCode]) {
14475
+ if (typeof candidate === "number" && Number.isFinite(candidate))
14476
+ return candidate;
14477
+ }
14478
+ return void 0;
14479
+ }
14480
+ __name(vendorErrorStatus, "vendorErrorStatus");
14481
+ function vendorRetryAfter(err) {
14482
+ if (typeof err !== "object" || err === null)
14483
+ return void 0;
14484
+ const headers = err.headers ?? err.$response?.headers;
14485
+ if (!headers)
14486
+ return void 0;
14487
+ if (typeof headers.get === "function") {
14488
+ return headers.get("retry-after") ?? void 0;
14489
+ }
14490
+ const record3 = headers;
14491
+ for (const key5 of ["retry-after", "Retry-After", "retryAfter"]) {
14492
+ const value = record3[key5];
14493
+ if (typeof value === "string")
14494
+ return value;
14495
+ }
14496
+ return void 0;
14497
+ }
14498
+ __name(vendorRetryAfter, "vendorRetryAfter");
14499
+ var REQUEST_ID_HEADERS = ["x-request-id", "request-id", "x-goog-request-id"];
14500
+ function vendorHeader(err, names) {
14501
+ if (typeof err !== "object" || err === null)
14502
+ return void 0;
14503
+ const headers = err.headers ?? err.$response?.headers;
14504
+ if (!headers)
14505
+ return void 0;
14506
+ for (const name2 of names) {
14507
+ if (typeof headers.get === "function") {
14508
+ const value2 = headers.get(name2);
14509
+ if (value2)
14510
+ return value2;
14511
+ continue;
14512
+ }
14513
+ const value = headers[name2];
14514
+ if (typeof value === "string" && value)
14515
+ return value;
14516
+ }
14517
+ return void 0;
14518
+ }
14519
+ __name(vendorHeader, "vendorHeader");
14520
+ var FIELD_VALUE = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$/;
14521
+ function fieldValue(value) {
14522
+ return typeof value === "string" && FIELD_VALUE.test(value) && redactSecrets(value) === value ? value : void 0;
14523
+ }
14524
+ __name(fieldValue, "fieldValue");
14525
+ function structuredVendorDetail(input) {
14526
+ const message = vendorDetail(input.message?.replace(/^\d{3}\s+/, ""));
14527
+ const type = fieldValue(input.type);
14528
+ const code = fieldValue(input.code);
14529
+ const param = fieldValue(input.param);
14530
+ const requestId = fieldValue(input.requestId);
14531
+ if (!type && !code && !param && !requestId)
14532
+ return message;
14533
+ if (!message)
14534
+ return void 0;
14535
+ return JSON.stringify({
14536
+ error: {
14537
+ message,
14538
+ ...type ? { type } : {},
14539
+ ...code ? { code } : {},
14540
+ ...param ? { param } : {}
14541
+ },
14542
+ ...requestId ? { request_id: requestId } : {}
14543
+ });
14544
+ }
14545
+ __name(structuredVendorDetail, "structuredVendorDetail");
14546
+ function providerVendorError(input) {
14547
+ const { error } = input;
14548
+ const status = vendorErrorStatus(error);
14549
+ const exactProviderCode = providerCode(error);
14550
+ const name2 = error instanceof Error ? error.name : "";
14551
+ const message = error instanceof Error ? error.message : "";
14552
+ let kind;
14553
+ if (/ThrottlingException|TooManyRequests|ServiceQuotaExceeded/i.test(name2)) {
14554
+ kind = "throttle";
14555
+ } else if (/AccessDenied|Unauthorized|Forbidden|Authentication/i.test(name2)) {
14556
+ kind = "auth";
14557
+ } else if (/ValidationException/i.test(name2)) {
14558
+ kind = bodySaysContextOverflow(message) ? "context_overflow" : "bad_request";
14559
+ } else if (/ServiceUnavailable|InternalServer|ModelTimeout|ModelStreamError|ModelError|ModelNotReady/i.test(name2)) {
14560
+ kind = "server";
14561
+ } else if (status !== void 0) {
14562
+ kind = classifyProviderHttpStatus(status, message);
14563
+ } else if (exactProviderCode === "invalid_image") {
14564
+ kind = "bad_request";
14565
+ } else if (bodySaysContextOverflow(message)) {
14566
+ kind = "context_overflow";
14567
+ } else {
14568
+ kind = vendorTypeKind(message) ?? "network";
14569
+ }
14570
+ const retryAfterMs = parseRetryAfterMs(input.retryAfter ?? vendorRetryAfter(error), input.now ?? Date.now());
14571
+ const shouldRetry = parseShouldRetry(vendorHeader(error, ["x-should-retry"]));
14572
+ const fields2 = error;
14573
+ const detail = carriesBody(message) ? vendorDetail(message) : structuredVendorDetail({
14574
+ message,
14575
+ type: fields2?.type,
14576
+ code: exactProviderCode,
14577
+ param: fields2?.param,
14578
+ requestId: fields2?.requestID ?? vendorHeader(error, REQUEST_ID_HEADERS)
14579
+ });
14580
+ return new ProviderRequestError({
14581
+ kind,
14582
+ providerId: input.providerId,
14583
+ ...exactProviderCode !== void 0 ? { providerCode: exactProviderCode } : {},
14584
+ ...status !== void 0 ? { status } : {},
14585
+ ...retryAfterMs !== void 0 ? { retryAfterMs } : {},
14586
+ ...detail !== void 0 ? { detail } : {},
14587
+ ...shouldRetry !== void 0 ? { shouldRetry } : {}
14588
+ });
14589
+ }
14590
+ __name(providerVendorError, "providerVendorError");
14591
+ function carriesBody(message) {
14592
+ const rest = message.replace(/^\d{3}\s+/, "").trim();
14593
+ if (!rest.startsWith("{"))
14594
+ return false;
14595
+ try {
14596
+ const parsed = JSON.parse(rest);
14597
+ return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed);
14598
+ } catch {
14599
+ return false;
14600
+ }
14601
+ }
14602
+ __name(carriesBody, "carriesBody");
14603
+ function parsedBody(body) {
14604
+ let decoded = body;
14605
+ if (typeof decoded === "string") {
14606
+ try {
14607
+ decoded = JSON.parse(decoded);
14608
+ } catch {
14609
+ return void 0;
14610
+ }
14611
+ }
14612
+ return typeof decoded === "object" && decoded !== null && !Array.isArray(decoded) ? decoded : void 0;
14613
+ }
14614
+ __name(parsedBody, "parsedBody");
14615
+ function bodyErrorFields(body) {
14616
+ const inner = body && typeof body.error === "object" && body.error !== null ? body.error : void 0;
14617
+ if (!inner)
14618
+ return {};
14619
+ return {
14620
+ type: inner.type ?? (typeof inner.status === "string" ? inner.status : void 0),
14621
+ code: typeof inner.code === "string" ? inner.code : void 0,
14622
+ param: inner.param
14623
+ };
14624
+ }
14625
+ __name(bodyErrorFields, "bodyErrorFields");
14626
+ function providerHttpError(input) {
14627
+ const kind = classifyProviderHttpStatus(input.status, input.body);
14628
+ const retryAfterMs = parseRetryAfterMs(input.retryAfter, input.now ?? Date.now());
14629
+ const body = parsedBody(input.body);
14630
+ const bodyError = bodyErrorFields(body);
14631
+ const detail = body ? structuredVendorDetail({
14632
+ message: vendorDetail(input.body),
14633
+ type: bodyError.type,
14634
+ code: bodyError.code,
14635
+ param: bodyError.param,
14636
+ requestId: input.requestId
14637
+ }) : vendorDetail(input.body);
14638
+ const exactProviderCode = providerCode(input.body);
14639
+ const shouldRetry = parseShouldRetry(input.shouldRetry);
14640
+ return new ProviderRequestError({
14641
+ kind,
14642
+ providerId: input.providerId,
14643
+ ...exactProviderCode !== void 0 ? { providerCode: exactProviderCode } : {},
14644
+ status: input.status,
14645
+ ...retryAfterMs !== void 0 ? { retryAfterMs } : {},
14646
+ ...detail !== void 0 ? { detail } : {},
14647
+ ...shouldRetry !== void 0 ? { shouldRetry } : {}
14648
+ });
14649
+ }
14650
+ __name(providerHttpError, "providerHttpError");
14651
+
14652
+ // ../sdk/dist/provider/capabilities.js
14653
+ var PERMISSIVE_PROVIDER_CAPABILITIES = {
14654
+ supportsTools: true,
14655
+ supportsStreaming: true,
14656
+ supportsFunctionCalling: true,
14657
+ supportsVision: true,
14658
+ supportsDocuments: true,
14659
+ supportsToolResultImages: true,
14660
+ supportsToolResultDocuments: true
14661
+ };
14662
+ function resolveProviderCapabilities(provider) {
14663
+ const declared = provider.capabilities;
14664
+ return {
14665
+ supportsTools: declared?.supportsTools ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsTools,
14666
+ supportsStreaming: declared?.supportsStreaming ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsStreaming,
14667
+ supportsFunctionCalling: declared?.supportsFunctionCalling ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsFunctionCalling,
14668
+ supportsVision: declared?.supportsVision ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsVision,
14669
+ supportsDocuments: declared?.supportsDocuments ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsDocuments,
14670
+ supportsToolResultImages: declared?.supportsToolResultImages ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsToolResultImages,
14671
+ supportsToolResultDocuments: declared?.supportsToolResultDocuments ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsToolResultDocuments,
14672
+ maxOutputTokens: declared?.maxOutputTokens
14673
+ };
14674
+ }
14675
+ __name(resolveProviderCapabilities, "resolveProviderCapabilities");
14676
+ function modelReadsImages(provider, model) {
14677
+ if (provider.capabilities?.supportsVision === false)
14678
+ return false;
14679
+ if (model === void 0 || model === "")
14680
+ return true;
14681
+ return provider.supportsImageInputFor?.(model) ?? true;
14682
+ }
14683
+ __name(modelReadsImages, "modelReadsImages");
14684
+ function assertNativeStructuredOutputSupported(provider, params) {
14685
+ if (params.responseFormat?.type === "json_schema" && provider.capabilities?.supportsNativeStructuredOutput !== true) {
14686
+ throw new ProviderRequestError({
14687
+ kind: "bad_request",
14688
+ providerId: provider.id,
14689
+ providerCode: "native_structured_output_unsupported",
14690
+ detail: "Native JSON Schema output requires a provider that declares supportsNativeStructuredOutput: true."
14691
+ });
14692
+ }
14693
+ }
14694
+ __name(assertNativeStructuredOutputSupported, "assertNativeStructuredOutputSupported");
14695
+ function assertHostedWebSearchSupported(provider, params) {
14696
+ if (params.webSearch && (provider.capabilities?.supportsHostedWebSearch !== true || provider.supportsHostedWebSearchFor && !provider.supportsHostedWebSearchFor(params.model ?? "", params.webSearch.mode))) {
14697
+ throw new ProviderRequestError({
14698
+ kind: "bad_request",
14699
+ providerId: provider.id,
14700
+ providerCode: "hosted_web_search_unsupported",
14701
+ detail: "This provider does not support hosted web search. Disable web.search or select a supported provider."
14702
+ });
14703
+ }
14704
+ }
14705
+ __name(assertHostedWebSearchSupported, "assertHostedWebSearchSupported");
14706
+
14212
14707
  // ../sdk/dist/registry/tool/execute.js
14213
14708
  var TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]{1,64}$/;
14214
14709
  function assertToolName(name2) {
@@ -26311,462 +26806,6 @@ async function readEverRecordedMessages(log) {
26311
26806
  }
26312
26807
  __name(readEverRecordedMessages, "readEverRecordedMessages");
26313
26808
 
26314
- // ../sdk/dist/provider/errors.js
26315
- var PROVIDER_ERROR_KINDS = [
26316
- "throttle",
26317
- "network",
26318
- "auth",
26319
- "context_overflow",
26320
- "bad_request",
26321
- "server"
26322
- ];
26323
- var ProviderRequestError = class extends Error {
26324
- static {
26325
- __name(this, "ProviderRequestError");
26326
- }
26327
- kind;
26328
- providerId;
26329
- providerCode;
26330
- status;
26331
- retryAfterMs;
26332
- /**
26333
- * What the provider said was wrong, truncated and redacted.
26334
- *
26335
- * `ProviderRequestErrorInit` has declared this field all along and the
26336
- * constructor never read it, so every caller that set it was writing to
26337
- * nothing. That is not a cosmetic gap: a provider rejecting a request
26338
- * usually names the exact offending field, and losing that sentence turns
26339
- * a one-line diagnosis into hypothesis elimination against a live API. It
26340
- * did — a tool schema in the wrong JSON Schema dialect cost a day of
26341
- * production downtime while the wire had been saying
26342
- * `tools.0.custom.input_schema: … must match JSON Schema draft 2020-12`
26343
- * the whole time.
26344
- *
26345
- * See {@link vendorDetail} for what is kept and what is scrubbed.
26346
- */
26347
- detail;
26348
- /** The provider's `x-should-retry` verdict, when it sent one; see {@link ProviderRequestErrorInit.shouldRetry}. */
26349
- shouldRetry;
26350
- constructor(init) {
26351
- super(buildProviderErrorMessage(init));
26352
- this.name = "ProviderRequestError";
26353
- this.kind = init.kind;
26354
- this.providerId = init.providerId;
26355
- const exactProviderCode = safeProviderCode(init.providerCode);
26356
- if (exactProviderCode !== void 0)
26357
- this.providerCode = exactProviderCode;
26358
- if (init.status !== void 0)
26359
- this.status = init.status;
26360
- if (init.retryAfterMs !== void 0)
26361
- this.retryAfterMs = init.retryAfterMs;
26362
- if (init.detail !== void 0)
26363
- this.detail = init.detail;
26364
- if (init.shouldRetry !== void 0)
26365
- this.shouldRetry = init.shouldRetry;
26366
- }
26367
- };
26368
- var DETAIL_MAX = 400;
26369
- var PROVIDER_CODE = /^[A-Za-z][A-Za-z0-9._-]{0,79}$/;
26370
- function safeProviderCode(value) {
26371
- if (typeof value !== "string" || !PROVIDER_CODE.test(value))
26372
- return void 0;
26373
- return redactSecrets(value) === value ? value : void 0;
26374
- }
26375
- __name(safeProviderCode, "safeProviderCode");
26376
- function providerCode(value) {
26377
- let decoded = value;
26378
- if (typeof decoded === "string") {
26379
- try {
26380
- decoded = JSON.parse(decoded);
26381
- } catch {
26382
- return void 0;
26383
- }
26384
- }
26385
- if (typeof decoded !== "object" || decoded === null)
26386
- return void 0;
26387
- const record3 = decoded;
26388
- const nested = typeof record3.error === "object" && record3.error !== null ? record3.error.code : void 0;
26389
- return safeProviderCode(record3.code ?? nested);
26390
- }
26391
- __name(providerCode, "providerCode");
26392
- function vendorDetail(body) {
26393
- if (body === void 0 || body === null)
26394
- return void 0;
26395
- let text9;
26396
- if (typeof body === "string") {
26397
- try {
26398
- text9 = pickMessage(JSON.parse(body)) ?? body;
26399
- } catch {
26400
- text9 = body;
26401
- }
26402
- } else {
26403
- text9 = pickMessage(body) ?? "";
26404
- }
26405
- const cleaned = redactSecrets(text9.trim());
26406
- if (cleaned.length === 0)
26407
- return void 0;
26408
- return cleaned.length > DETAIL_MAX ? `${cleaned.slice(0, DETAIL_MAX)}\u2026` : cleaned;
26409
- }
26410
- __name(vendorDetail, "vendorDetail");
26411
- function redactSecrets(text9) {
26412
- let out = text9;
26413
- for (const [label5, pattern] of LOG_SECRET_PATTERNS) {
26414
- out = out.replace(pattern, `[REDACTED:${label5}]`);
26415
- }
26416
- return out;
26417
- }
26418
- __name(redactSecrets, "redactSecrets");
26419
- function pickMessage(value) {
26420
- if (typeof value === "string")
26421
- return value;
26422
- if (typeof value !== "object" || value === null)
26423
- return void 0;
26424
- const node = value;
26425
- const nested = node.error;
26426
- if (typeof nested === "string")
26427
- return nested;
26428
- if (typeof nested === "object" && nested !== null) {
26429
- const message = nested.message;
26430
- if (typeof message === "string")
26431
- return message;
26432
- }
26433
- if (typeof node.message === "string")
26434
- return node.message;
26435
- return void 0;
26436
- }
26437
- __name(pickMessage, "pickMessage");
26438
- function isProviderRequestError(err) {
26439
- const exactProviderCode = err?.providerCode;
26440
- return err instanceof Error && err.name === "ProviderRequestError" && typeof err.providerId === "string" && PROVIDER_ERROR_KINDS.includes(err.kind) && (exactProviderCode === void 0 || safeProviderCode(exactProviderCode) === exactProviderCode);
26441
- }
26442
- __name(isProviderRequestError, "isProviderRequestError");
26443
- function isCallerAbortError(error, signal) {
26444
- if (!signal?.aborted)
26445
- return false;
26446
- if (error === signal.reason)
26447
- return true;
26448
- if (!(error instanceof Error))
26449
- return false;
26450
- return error.name === "AbortError" || error.name === "APIUserAbortError";
26451
- }
26452
- __name(isCallerAbortError, "isCallerAbortError");
26453
- var KIND_SENTENCE = {
26454
- throttle: "rate limited by the provider",
26455
- network: "could not reach the provider",
26456
- auth: "the provider rejected the request credentials",
26457
- context_overflow: "the request exceeded the model context window",
26458
- bad_request: "the provider rejected the request as invalid",
26459
- server: "the provider failed to complete the request"
26460
- };
26461
- function buildProviderErrorMessage(init) {
26462
- const status = init.status !== void 0 ? ` (HTTP ${init.status})` : "";
26463
- const detail = init.detail ? `: ${init.detail}` : "";
26464
- return `${init.providerId}${status} \u2014 ${KIND_SENTENCE[init.kind]}${detail}`;
26465
- }
26466
- __name(buildProviderErrorMessage, "buildProviderErrorMessage");
26467
- var OVERFLOW_BODY_PATTERNS = [
26468
- /prompt is too long/i,
26469
- /context[_ ]length[_ ]exceeded/i,
26470
- /maximum context length/i,
26471
- /too long for requested model/i,
26472
- /input is too long/i,
26473
- /(?:input|prompt|context).{0,80}exceeds the maximum/i,
26474
- /reduce the (?:input|prompt|context) length/i,
26475
- // Ollama phrases it the other way round — "input length exceeds context
26476
- // length" — so a pattern anchored on "exceeded" misses it entirely.
26477
- /exceeds?\s+(?:the\s+)?(?:model'?s?\s+)?context\s+(?:length|window|size)/i,
26478
- /context\s+(?:length|window|size)\s+exceed/i
26479
- ];
26480
- function bodySaysContextOverflow(body) {
26481
- if (!body)
26482
- return false;
26483
- return OVERFLOW_BODY_PATTERNS.some((re2) => re2.test(body));
26484
- }
26485
- __name(bodySaysContextOverflow, "bodySaysContextOverflow");
26486
- function parseShouldRetry(value) {
26487
- return value?.trim().toLowerCase() === "false" ? false : void 0;
26488
- }
26489
- __name(parseShouldRetry, "parseShouldRetry");
26490
- function parseRetryAfterMs(headerValue2, now = Date.now()) {
26491
- if (!headerValue2)
26492
- return void 0;
26493
- const trimmed = headerValue2.trim();
26494
- if (trimmed === "")
26495
- return void 0;
26496
- if (/^\d+(\.\d+)?$/.test(trimmed)) {
26497
- const seconds = Number(trimmed);
26498
- if (!Number.isFinite(seconds) || seconds < 0)
26499
- return void 0;
26500
- return Math.round(seconds * 1e3);
26501
- }
26502
- const at = Date.parse(trimmed);
26503
- if (Number.isNaN(at))
26504
- return void 0;
26505
- const delta = at - now;
26506
- return delta > 0 ? delta : void 0;
26507
- }
26508
- __name(parseRetryAfterMs, "parseRetryAfterMs");
26509
- function classifyProviderHttpStatus(status, body) {
26510
- if (status === 401 || status === 403)
26511
- return "auth";
26512
- if (status === 429)
26513
- return "throttle";
26514
- if (status === 408 || status === 425)
26515
- return "network";
26516
- if (status >= 500)
26517
- return "server";
26518
- if (status === 413) {
26519
- return bodySaysContextOverflow(body) ? "context_overflow" : "bad_request";
26520
- }
26521
- if (status >= 400) {
26522
- return bodySaysContextOverflow(body) ? "context_overflow" : "bad_request";
26523
- }
26524
- return "server";
26525
- }
26526
- __name(classifyProviderHttpStatus, "classifyProviderHttpStatus");
26527
- var VENDOR_TYPE_KINDS = [
26528
- [/overloaded_error|api_error|service_unavailable/i, "server"],
26529
- [/rate_limit_error|rate_limit_exceeded/i, "throttle"],
26530
- [/authentication_error|permission_error|invalid_api_key|unauthorized/i, "auth"],
26531
- [/timeout_error|connection_error/i, "network"]
26532
- ];
26533
- function vendorTypeKind(message) {
26534
- for (const [re2, kind] of VENDOR_TYPE_KINDS) {
26535
- if (re2.test(message))
26536
- return kind;
26537
- }
26538
- return void 0;
26539
- }
26540
- __name(vendorTypeKind, "vendorTypeKind");
26541
- function vendorErrorStatus(err) {
26542
- if (typeof err !== "object" || err === null)
26543
- return void 0;
26544
- const e = err;
26545
- for (const candidate of [e.status, e.statusCode, e.status_code, e.$metadata?.httpStatusCode]) {
26546
- if (typeof candidate === "number" && Number.isFinite(candidate))
26547
- return candidate;
26548
- }
26549
- return void 0;
26550
- }
26551
- __name(vendorErrorStatus, "vendorErrorStatus");
26552
- function vendorRetryAfter(err) {
26553
- if (typeof err !== "object" || err === null)
26554
- return void 0;
26555
- const headers = err.headers ?? err.$response?.headers;
26556
- if (!headers)
26557
- return void 0;
26558
- if (typeof headers.get === "function") {
26559
- return headers.get("retry-after") ?? void 0;
26560
- }
26561
- const record3 = headers;
26562
- for (const key5 of ["retry-after", "Retry-After", "retryAfter"]) {
26563
- const value = record3[key5];
26564
- if (typeof value === "string")
26565
- return value;
26566
- }
26567
- return void 0;
26568
- }
26569
- __name(vendorRetryAfter, "vendorRetryAfter");
26570
- var REQUEST_ID_HEADERS = ["x-request-id", "request-id", "x-goog-request-id"];
26571
- function vendorHeader(err, names) {
26572
- if (typeof err !== "object" || err === null)
26573
- return void 0;
26574
- const headers = err.headers ?? err.$response?.headers;
26575
- if (!headers)
26576
- return void 0;
26577
- for (const name2 of names) {
26578
- if (typeof headers.get === "function") {
26579
- const value2 = headers.get(name2);
26580
- if (value2)
26581
- return value2;
26582
- continue;
26583
- }
26584
- const value = headers[name2];
26585
- if (typeof value === "string" && value)
26586
- return value;
26587
- }
26588
- return void 0;
26589
- }
26590
- __name(vendorHeader, "vendorHeader");
26591
- var FIELD_VALUE = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$/;
26592
- function fieldValue(value) {
26593
- return typeof value === "string" && FIELD_VALUE.test(value) && redactSecrets(value) === value ? value : void 0;
26594
- }
26595
- __name(fieldValue, "fieldValue");
26596
- function structuredVendorDetail(input) {
26597
- const message = vendorDetail(input.message?.replace(/^\d{3}\s+/, ""));
26598
- const type = fieldValue(input.type);
26599
- const code = fieldValue(input.code);
26600
- const param = fieldValue(input.param);
26601
- const requestId = fieldValue(input.requestId);
26602
- if (!type && !code && !param && !requestId)
26603
- return message;
26604
- if (!message)
26605
- return void 0;
26606
- return JSON.stringify({
26607
- error: {
26608
- message,
26609
- ...type ? { type } : {},
26610
- ...code ? { code } : {},
26611
- ...param ? { param } : {}
26612
- },
26613
- ...requestId ? { request_id: requestId } : {}
26614
- });
26615
- }
26616
- __name(structuredVendorDetail, "structuredVendorDetail");
26617
- function providerVendorError(input) {
26618
- const { error } = input;
26619
- const status = vendorErrorStatus(error);
26620
- const exactProviderCode = providerCode(error);
26621
- const name2 = error instanceof Error ? error.name : "";
26622
- const message = error instanceof Error ? error.message : "";
26623
- let kind;
26624
- if (/ThrottlingException|TooManyRequests|ServiceQuotaExceeded/i.test(name2)) {
26625
- kind = "throttle";
26626
- } else if (/AccessDenied|Unauthorized|Forbidden|Authentication/i.test(name2)) {
26627
- kind = "auth";
26628
- } else if (/ValidationException/i.test(name2)) {
26629
- kind = bodySaysContextOverflow(message) ? "context_overflow" : "bad_request";
26630
- } else if (/ServiceUnavailable|InternalServer|ModelTimeout|ModelStreamError|ModelError|ModelNotReady/i.test(name2)) {
26631
- kind = "server";
26632
- } else if (status !== void 0) {
26633
- kind = classifyProviderHttpStatus(status, message);
26634
- } else if (exactProviderCode === "invalid_image") {
26635
- kind = "bad_request";
26636
- } else if (bodySaysContextOverflow(message)) {
26637
- kind = "context_overflow";
26638
- } else {
26639
- kind = vendorTypeKind(message) ?? "network";
26640
- }
26641
- const retryAfterMs = parseRetryAfterMs(input.retryAfter ?? vendorRetryAfter(error), input.now ?? Date.now());
26642
- const shouldRetry = parseShouldRetry(vendorHeader(error, ["x-should-retry"]));
26643
- const fields2 = error;
26644
- const detail = carriesBody(message) ? vendorDetail(message) : structuredVendorDetail({
26645
- message,
26646
- type: fields2?.type,
26647
- code: exactProviderCode,
26648
- param: fields2?.param,
26649
- requestId: fields2?.requestID ?? vendorHeader(error, REQUEST_ID_HEADERS)
26650
- });
26651
- return new ProviderRequestError({
26652
- kind,
26653
- providerId: input.providerId,
26654
- ...exactProviderCode !== void 0 ? { providerCode: exactProviderCode } : {},
26655
- ...status !== void 0 ? { status } : {},
26656
- ...retryAfterMs !== void 0 ? { retryAfterMs } : {},
26657
- ...detail !== void 0 ? { detail } : {},
26658
- ...shouldRetry !== void 0 ? { shouldRetry } : {}
26659
- });
26660
- }
26661
- __name(providerVendorError, "providerVendorError");
26662
- function carriesBody(message) {
26663
- const rest = message.replace(/^\d{3}\s+/, "").trim();
26664
- if (!rest.startsWith("{"))
26665
- return false;
26666
- try {
26667
- const parsed = JSON.parse(rest);
26668
- return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed);
26669
- } catch {
26670
- return false;
26671
- }
26672
- }
26673
- __name(carriesBody, "carriesBody");
26674
- function parsedBody(body) {
26675
- let decoded = body;
26676
- if (typeof decoded === "string") {
26677
- try {
26678
- decoded = JSON.parse(decoded);
26679
- } catch {
26680
- return void 0;
26681
- }
26682
- }
26683
- return typeof decoded === "object" && decoded !== null && !Array.isArray(decoded) ? decoded : void 0;
26684
- }
26685
- __name(parsedBody, "parsedBody");
26686
- function bodyErrorFields(body) {
26687
- const inner = body && typeof body.error === "object" && body.error !== null ? body.error : void 0;
26688
- if (!inner)
26689
- return {};
26690
- return {
26691
- type: inner.type ?? (typeof inner.status === "string" ? inner.status : void 0),
26692
- code: typeof inner.code === "string" ? inner.code : void 0,
26693
- param: inner.param
26694
- };
26695
- }
26696
- __name(bodyErrorFields, "bodyErrorFields");
26697
- function providerHttpError(input) {
26698
- const kind = classifyProviderHttpStatus(input.status, input.body);
26699
- const retryAfterMs = parseRetryAfterMs(input.retryAfter, input.now ?? Date.now());
26700
- const body = parsedBody(input.body);
26701
- const bodyError = bodyErrorFields(body);
26702
- const detail = body ? structuredVendorDetail({
26703
- message: vendorDetail(input.body),
26704
- type: bodyError.type,
26705
- code: bodyError.code,
26706
- param: bodyError.param,
26707
- requestId: input.requestId
26708
- }) : vendorDetail(input.body);
26709
- const exactProviderCode = providerCode(input.body);
26710
- const shouldRetry = parseShouldRetry(input.shouldRetry);
26711
- return new ProviderRequestError({
26712
- kind,
26713
- providerId: input.providerId,
26714
- ...exactProviderCode !== void 0 ? { providerCode: exactProviderCode } : {},
26715
- status: input.status,
26716
- ...retryAfterMs !== void 0 ? { retryAfterMs } : {},
26717
- ...detail !== void 0 ? { detail } : {},
26718
- ...shouldRetry !== void 0 ? { shouldRetry } : {}
26719
- });
26720
- }
26721
- __name(providerHttpError, "providerHttpError");
26722
-
26723
- // ../sdk/dist/provider/capabilities.js
26724
- var PERMISSIVE_PROVIDER_CAPABILITIES = {
26725
- supportsTools: true,
26726
- supportsStreaming: true,
26727
- supportsFunctionCalling: true,
26728
- supportsVision: true,
26729
- supportsDocuments: true,
26730
- supportsToolResultImages: true,
26731
- supportsToolResultDocuments: true
26732
- };
26733
- function resolveProviderCapabilities(provider) {
26734
- const declared = provider.capabilities;
26735
- return {
26736
- supportsTools: declared?.supportsTools ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsTools,
26737
- supportsStreaming: declared?.supportsStreaming ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsStreaming,
26738
- supportsFunctionCalling: declared?.supportsFunctionCalling ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsFunctionCalling,
26739
- supportsVision: declared?.supportsVision ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsVision,
26740
- supportsDocuments: declared?.supportsDocuments ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsDocuments,
26741
- supportsToolResultImages: declared?.supportsToolResultImages ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsToolResultImages,
26742
- supportsToolResultDocuments: declared?.supportsToolResultDocuments ?? PERMISSIVE_PROVIDER_CAPABILITIES.supportsToolResultDocuments,
26743
- maxOutputTokens: declared?.maxOutputTokens
26744
- };
26745
- }
26746
- __name(resolveProviderCapabilities, "resolveProviderCapabilities");
26747
- function assertNativeStructuredOutputSupported(provider, params) {
26748
- if (params.responseFormat?.type === "json_schema" && provider.capabilities?.supportsNativeStructuredOutput !== true) {
26749
- throw new ProviderRequestError({
26750
- kind: "bad_request",
26751
- providerId: provider.id,
26752
- providerCode: "native_structured_output_unsupported",
26753
- detail: "Native JSON Schema output requires a provider that declares supportsNativeStructuredOutput: true."
26754
- });
26755
- }
26756
- }
26757
- __name(assertNativeStructuredOutputSupported, "assertNativeStructuredOutputSupported");
26758
- function assertHostedWebSearchSupported(provider, params) {
26759
- if (params.webSearch && (provider.capabilities?.supportsHostedWebSearch !== true || provider.supportsHostedWebSearchFor && !provider.supportsHostedWebSearchFor(params.model ?? "", params.webSearch.mode))) {
26760
- throw new ProviderRequestError({
26761
- kind: "bad_request",
26762
- providerId: provider.id,
26763
- providerCode: "hosted_web_search_unsupported",
26764
- detail: "This provider does not support hosted web search. Disable web.search or select a supported provider."
26765
- });
26766
- }
26767
- }
26768
- __name(assertHostedWebSearchSupported, "assertHostedWebSearchSupported");
26769
-
26770
26809
  // ../sdk/dist/provider/idle-timeout.js
26771
26810
  var DEFAULT_STREAM_IDLE_TIMEOUT_MS = 5 * 6e4;
26772
26811
  var MAX_TIMER_DELAY_MS = 2147483647;
@@ -26874,6 +26913,9 @@ function withStreamIdleTimeout(provider, options) {
26874
26913
  ...provider.supportsHostedWebSearchFor ? {
26875
26914
  supportsHostedWebSearchFor: /* @__PURE__ */ __name((model, mode) => provider.supportsHostedWebSearchFor?.(model, mode) ?? false, "supportsHostedWebSearchFor")
26876
26915
  } : {},
26916
+ ...provider.supportsImageInputFor ? {
26917
+ supportsImageInputFor: /* @__PURE__ */ __name((model) => provider.supportsImageInputFor?.(model) ?? true, "supportsImageInputFor")
26918
+ } : {},
26877
26919
  ...provider.reasoningEffortLevelsFor ? {
26878
26920
  reasoningEffortLevelsFor: /* @__PURE__ */ __name((model, thinking) => provider.reasoningEffortLevelsFor?.(model, thinking), "reasoningEffortLevelsFor")
26879
26921
  } : {},
@@ -28450,6 +28492,69 @@ function withDefined(key5, value) {
28450
28492
  }
28451
28493
  __name(withDefined, "withDefined");
28452
28494
 
28495
+ // ../sdk/dist/runtime/query/deferred-sandbox.js
28496
+ var SandboxAcquisitionStopped = class extends Error {
28497
+ static {
28498
+ __name(this, "SandboxAcquisitionStopped");
28499
+ }
28500
+ acquisition;
28501
+ constructor(acquisition) {
28502
+ super(acquisition.kind === "timed_out" ? acquisition.error.message : "Sandbox acquisition was cancelled before it finished");
28503
+ this.name = "SandboxAcquisitionStopped";
28504
+ this.acquisition = acquisition;
28505
+ }
28506
+ };
28507
+ function createDeferredSandbox(options) {
28508
+ const controller = new AbortController();
28509
+ const relay = /* @__PURE__ */ __name(() => controller.abort(options.turnSignal.reason), "relay");
28510
+ if (options.turnSignal.aborted)
28511
+ relay();
28512
+ else
28513
+ options.turnSignal.addEventListener("abort", relay, { once: true });
28514
+ let outcome;
28515
+ const start = /* @__PURE__ */ __name(() => {
28516
+ outcome ??= (async () => {
28517
+ try {
28518
+ const acquired = await options.acquire(controller.signal);
28519
+ if (acquired.kind === "created")
28520
+ await options.publish(acquired.sandbox);
28521
+ return acquired;
28522
+ } catch (error) {
28523
+ return { kind: "failed", error };
28524
+ }
28525
+ })();
28526
+ return outcome;
28527
+ }, "start");
28528
+ const rethrow = /* @__PURE__ */ __name((settled) => {
28529
+ if (settled.kind === "created")
28530
+ return;
28531
+ if (settled.kind === "failed")
28532
+ throw settled.error;
28533
+ throw new SandboxAcquisitionStopped(settled);
28534
+ }, "rethrow");
28535
+ return {
28536
+ start: /* @__PURE__ */ __name(() => {
28537
+ void start();
28538
+ }, "start"),
28539
+ ensure: /* @__PURE__ */ __name(async () => rethrow(await start()), "ensure"),
28540
+ settle: /* @__PURE__ */ __name(async () => {
28541
+ if (outcome === void 0)
28542
+ return;
28543
+ const settled = await outcome;
28544
+ if (options.turnSignal.aborted)
28545
+ return;
28546
+ rethrow(settled);
28547
+ }, "settle"),
28548
+ cancel: /* @__PURE__ */ __name(async () => {
28549
+ options.turnSignal.removeEventListener("abort", relay);
28550
+ controller.abort();
28551
+ if (outcome !== void 0)
28552
+ await outcome;
28553
+ }, "cancel")
28554
+ };
28555
+ }
28556
+ __name(createDeferredSandbox, "createDeferredSandbox");
28557
+
28453
28558
  // ../sdk/dist/store/memory/digest.js
28454
28559
  import { createHash as createHash9 } from "node:crypto";
28455
28560
  var KNOWLEDGE_TAG_PREFIX = "knowledge:";
@@ -29722,13 +29827,23 @@ var rejectedUserImageMarker = /* @__PURE__ */ __name(() => "[image omitted from
29722
29827
  var rejectedToolImageMarker = /* @__PURE__ */ __name(() => `[image omitted from this model request because the provider rejected this image. ${toolRecovery} Correct the image source before presenting it again.]`, "rejectedToolImageMarker");
29723
29828
  var invalidUserImageMarker = /* @__PURE__ */ __name(() => "[image omitted from this model request because its encoded bytes are not a complete supported raster matching the declared media type; attach a corrected image in a new message if it is still needed.]", "invalidUserImageMarker");
29724
29829
  var invalidToolImageMarker = /* @__PURE__ */ __name(() => `[image omitted from this model request because the producing tool returned encoded bytes that are not a complete supported raster matching the declared media type. ${toolRecovery} Correct the image source before presenting it again.]`, "invalidToolImageMarker");
29830
+ function describeEncodedSize(base64Length) {
29831
+ const bytes = Math.floor(base64Length * 3 / 4);
29832
+ if (bytes < 1024)
29833
+ return `${bytes} B`;
29834
+ if (bytes < 1024 * 1024)
29835
+ return `${Math.round(bytes / 1024)} KB`;
29836
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
29837
+ }
29838
+ __name(describeEncodedSize, "describeEncodedSize");
29839
+ var textOnlyImageMarker = /* @__PURE__ */ __name((mediaType, base64Length) => `[image omitted: the current model cannot read images${mediaType ? ` (${mediaType}, ${describeEncodedSize(base64Length)})` : ""}]`, "textOnlyImageMarker");
29725
29840
  function assertInlineAttachment(attachment) {
29726
29841
  if (attachment.type === "stored") {
29727
29842
  throw new TypeError("Cannot budget an unresolved stored attachment; resolve attachment bytes before building a model request");
29728
29843
  }
29729
29844
  }
29730
29845
  __name(assertInlineAttachment, "assertInlineAttachment");
29731
- function collectRichOccurrences(messages) {
29846
+ function collectRichOccurrences(messages, imagesReadable) {
29732
29847
  const occurrences = [];
29733
29848
  for (const [messageIndex, message] of messages.entries()) {
29734
29849
  if (message.role === "user") {
@@ -29740,7 +29855,8 @@ function collectRichOccurrences(messages) {
29740
29855
  source: "user",
29741
29856
  kind: attachment.type === "document" ? "document" : "image",
29742
29857
  bytes: attachment.data.length,
29743
- reason: attachment.type !== "document" && attachment.modelOmission?.reason === "invalid-image" ? "invalid-image" : attachment.type !== "document" && attachment.modelOmission?.reason === "provider-rejected" ? "provider-rejected" : "budget"
29858
+ mediaType: attachment.mediaType,
29859
+ reason: attachment.type !== "document" && !imagesReadable ? "model-text-only" : attachment.type !== "document" && attachment.modelOmission?.reason === "invalid-image" ? "invalid-image" : attachment.type !== "document" && attachment.modelOmission?.reason === "provider-rejected" ? "provider-rejected" : "budget"
29744
29860
  });
29745
29861
  }
29746
29862
  continue;
@@ -29756,7 +29872,8 @@ function collectRichOccurrences(messages) {
29756
29872
  source: "tool",
29757
29873
  kind: block.type,
29758
29874
  bytes: block.data.length,
29759
- reason: block.type === "image" && block.modelOmission?.reason === "invalid-image" ? "invalid-image" : block.type === "image" && block.modelOmission?.reason === "provider-rejected" ? "provider-rejected" : "budget"
29875
+ mediaType: block.mediaType,
29876
+ reason: block.type === "image" && !imagesReadable ? "model-text-only" : block.type === "image" && block.modelOmission?.reason === "invalid-image" ? "invalid-image" : block.type === "image" && block.modelOmission?.reason === "provider-rejected" ? "provider-rejected" : "budget"
29760
29877
  });
29761
29878
  }
29762
29879
  }
@@ -29773,12 +29890,12 @@ ${joined3}` : joined3;
29773
29890
  }
29774
29891
  __name(appendTextMarkers, "appendTextMarkers");
29775
29892
  function appendMarkers(content, occurrences) {
29776
- const markers = occurrences.map((occurrence) => occurrence.reason === "provider-rejected" ? rejectedUserImageMarker() : occurrence.reason === "invalid-image" ? invalidUserImageMarker() : userMarker(occurrence.kind));
29893
+ const markers = occurrences.map((occurrence) => occurrence.reason === "model-text-only" ? textOnlyImageMarker(occurrence.mediaType, occurrence.bytes) : occurrence.reason === "provider-rejected" ? rejectedUserImageMarker() : occurrence.reason === "invalid-image" ? invalidUserImageMarker() : userMarker(occurrence.kind));
29777
29894
  return appendTextMarkers(content, markers);
29778
29895
  }
29779
29896
  __name(appendMarkers, "appendMarkers");
29780
- function projectRequestRichContent(messages, maxBytes) {
29781
- const occurrences = collectRichOccurrences(messages);
29897
+ function projectRequestRichContent(messages, maxBytes, options = {}) {
29898
+ const occurrences = collectRichOccurrences(messages, options.imagesReadable ?? true);
29782
29899
  if (occurrences.length === 0)
29783
29900
  return messages;
29784
29901
  const omitted = /* @__PURE__ */ new Map();
@@ -29791,9 +29908,8 @@ function projectRequestRichContent(messages, maxBytes) {
29791
29908
  byItem.set(occurrence.itemIndex, occurrence);
29792
29909
  }, "omit");
29793
29910
  for (const occurrence of occurrences) {
29794
- if (occurrence.reason === "provider-rejected" || occurrence.reason === "invalid-image") {
29911
+ if (occurrence.reason !== "budget")
29795
29912
  omit(occurrence);
29796
- }
29797
29913
  }
29798
29914
  let total = occurrences.reduce((sum, occurrence) => sum + (occurrence.reason === "budget" ? occurrence.bytes : 0), 0);
29799
29915
  if (maxBytes > 0 && total > maxBytes) {
@@ -29827,7 +29943,7 @@ function projectRequestRichContent(messages, maxBytes) {
29827
29943
  const occurrence = byItem.get(itemIndex);
29828
29944
  return occurrence?.source === "tool" ? {
29829
29945
  type: "text",
29830
- text: occurrence.reason === "provider-rejected" ? rejectedToolImageMarker() : occurrence.reason === "invalid-image" ? invalidToolImageMarker() : toolMarker(occurrence.kind)
29946
+ text: occurrence.reason === "model-text-only" ? textOnlyImageMarker(occurrence.mediaType, occurrence.bytes) : occurrence.reason === "provider-rejected" ? rejectedToolImageMarker() : occurrence.reason === "invalid-image" ? invalidToolImageMarker() : toolMarker(occurrence.kind)
29831
29947
  } : block;
29832
29948
  });
29833
29949
  return { ...message, content };
@@ -29836,6 +29952,23 @@ function projectRequestRichContent(messages, maxBytes) {
29836
29952
  });
29837
29953
  }
29838
29954
  __name(projectRequestRichContent, "projectRequestRichContent");
29955
+ function requestHasImages(messages) {
29956
+ for (const message of messages) {
29957
+ if (message.role === "user") {
29958
+ for (const attachment of message.attachments ?? []) {
29959
+ if (attachment.type !== "stored" && attachment.type !== "document")
29960
+ return true;
29961
+ }
29962
+ continue;
29963
+ }
29964
+ if (message.role !== "tool" || !Array.isArray(message.content))
29965
+ continue;
29966
+ if (message.content.some((block) => block.type === "image"))
29967
+ return true;
29968
+ }
29969
+ return false;
29970
+ }
29971
+ __name(requestHasImages, "requestHasImages");
29839
29972
  function sameImage(image, identity) {
29840
29973
  return image.data === identity.data && image.mediaType === identity.mediaType;
29841
29974
  }
@@ -30870,6 +31003,19 @@ function* conversationExcerpt(messages) {
30870
31003
  }
30871
31004
  }
30872
31005
  __name(conversationExcerpt, "conversationExcerpt");
31006
+ var MAX_VERIFIER_HEAD_TRUNCATIONS = 3;
31007
+ var EXCERPT_TRUNCATED_PLACEHOLDER = "[earlier conversation truncated for compaction retry]";
31008
+ function truncateExcerptHead(excerpt2) {
31009
+ const body = excerpt2.startsWith(EXCERPT_TRUNCATED_PLACEHOLDER) ? excerpt2.slice(EXCERPT_TRUNCATED_PLACEHOLDER.length).trimStart() : excerpt2;
31010
+ let kept = body.slice(Math.floor(body.length / 2));
31011
+ const first = kept.charCodeAt(0);
31012
+ if (first >= 56320 && first <= 57343)
31013
+ kept = kept.slice(1);
31014
+ return `${EXCERPT_TRUNCATED_PLACEHOLDER}
31015
+
31016
+ ${kept}`;
31017
+ }
31018
+ __name(truncateExcerptHead, "truncateExcerptHead");
30873
31019
  function truncateMessages(messages, budget) {
30874
31020
  if (budget <= 0)
30875
31021
  return "";
@@ -30927,29 +31073,46 @@ async function buildVerifiedSummaryWithProvider(manager, olderMessages, provider
30927
31073
  if (!conversationExcerpt2.trim()) {
30928
31074
  return serialized;
30929
31075
  }
30930
- const verificationMessages = [
30931
- {
30932
- role: "system",
30933
- content: withInstructions(VERIFICATION_PROMPT, instructions)
30934
- },
30935
- {
30936
- role: "user",
30937
- content: `## Structured State
31076
+ let excerpt2 = conversationExcerpt2;
31077
+ let truncations = 0;
31078
+ let response;
31079
+ for (; ; ) {
31080
+ const verificationMessages = [
31081
+ {
31082
+ role: "system",
31083
+ content: withInstructions(VERIFICATION_PROMPT, instructions)
31084
+ },
31085
+ {
31086
+ role: "user",
31087
+ content: `## Structured State
30938
31088
 
30939
31089
  ${serialized}
30940
31090
 
30941
31091
  ## Conversation Excerpt
30942
31092
 
30943
- ${conversationExcerpt2}`
31093
+ ${excerpt2}`
31094
+ }
31095
+ ];
31096
+ try {
31097
+ response = await collectChatCompletion(provider.chatStream({
31098
+ model: model ?? "",
31099
+ messages: verificationMessages,
31100
+ maxTokens: config.llmVerificationMaxTokens,
31101
+ temperature: 0,
31102
+ ...signal ? { signal } : {}
31103
+ }));
31104
+ break;
31105
+ } catch (error) {
31106
+ if (signal?.aborted)
31107
+ throw error;
31108
+ if (classifyProviderError(error).code !== "context_length_exceeded")
31109
+ throw error;
31110
+ if (truncations >= MAX_VERIFIER_HEAD_TRUNCATIONS)
31111
+ return serialized;
31112
+ truncations++;
31113
+ excerpt2 = truncateExcerptHead(excerpt2);
30944
31114
  }
30945
- ];
30946
- const response = await collectChatCompletion(provider.chatStream({
30947
- model: model ?? "",
30948
- messages: verificationMessages,
30949
- maxTokens: config.llmVerificationMaxTokens,
30950
- temperature: 0,
30951
- ...signal ? { signal } : {}
30952
- }));
31115
+ }
30953
31116
  onUsage?.(response.usage);
30954
31117
  const responseText = response.message.content?.trim() ?? "";
30955
31118
  if (responseText === "COMPLETE" || responseText.length === 0) {
@@ -31172,8 +31335,7 @@ __name(resolveTaskModel, "resolveTaskModel");
31172
31335
  var COMPACTION_FAILURE_LIMIT = 3;
31173
31336
  var COMPACTION_REFILL_ITERATIONS = 3;
31174
31337
  var COMPACTION_REFILL_LIMIT = 3;
31175
- var COMPACTION_REFILL_MESSAGE = "The context filled up again right after being compacted, three times in a row. A file or tool output is probably too big for the window: read it in smaller parts, or start fresh with /clear.";
31176
- var COMPACTION_FAILURE_MESSAGE = "Automatic compaction stopped after three failed attempts. Run /compact yourself, or start fresh with /clear.";
31338
+ var COMPACTION_REFILL_MESSAGE = "The context filled up again right after being compacted, three times in a row. A file being read or a tool output is probably too large for the context window. Try reading it in smaller parts.";
31177
31339
  var CompactionBreaker = class {
31178
31340
  static {
31179
31341
  __name(this, "CompactionBreaker");
@@ -31428,11 +31590,46 @@ function measureContext(ctx) {
31428
31590
  return { tokens: estimateTokens(ctx), source: "estimate" };
31429
31591
  }
31430
31592
  __name(measureContext, "measureContext");
31431
- async function relieveOverflow(ctx) {
31593
+ var OVERFLOW_RELIEF_LIMIT = 2;
31594
+ var DEEPER_PASS_MIN_GROUPS = 3;
31595
+ function roundGroups(messages) {
31596
+ let groups = 0;
31597
+ for (const message of messages)
31598
+ if (message.role === "assistant")
31599
+ groups++;
31600
+ return groups;
31601
+ }
31602
+ __name(roundGroups, "roundGroups");
31603
+ function deepenConfig(config, messages) {
31604
+ let lastAssistant = -1;
31605
+ for (let i = messages.length - 1; i >= 0; i--) {
31606
+ if (messages[i]?.role === "assistant") {
31607
+ lastAssistant = i;
31608
+ break;
31609
+ }
31610
+ }
31611
+ const deeper = { ...config, keepRecentToolResults: 0 };
31612
+ if (lastAssistant < 0 || roundGroups(messages) < DEEPER_PASS_MIN_GROUPS)
31613
+ return deeper;
31614
+ const newest = messages.slice(lastAssistant);
31615
+ if (config.keepRecentTokens !== void 0) {
31616
+ return {
31617
+ ...deeper,
31618
+ keepRecentTokens: Math.max(1, Math.min(config.keepRecentTokens, estimateMessagesTokens(newest)))
31619
+ };
31620
+ }
31621
+ return {
31622
+ ...deeper,
31623
+ keepRecentMessages: Math.max(1, Math.min(config.keepRecentMessages, newest.length))
31624
+ };
31625
+ }
31626
+ __name(deepenConfig, "deepenConfig");
31627
+ async function relieveOverflow(ctx, options = {}) {
31628
+ clearCompactionErrorNote(ctx);
31432
31629
  const before = ctx.recorder.messages.length;
31433
31630
  const beforeChars = totalChars(ctx.recorder.messages);
31434
31631
  const beforeTokens = estimateMessagesTokens(ctx.recorder.messages);
31435
- await runCompactionCheck(ctx, { force: true });
31632
+ await runCompactionCheck(ctx, { force: true, ...options.deeper ? { deeper: true } : {} });
31436
31633
  const shed = beforeChars - totalChars(ctx.recorder.messages);
31437
31634
  const tokensShed = beforeTokens - estimateMessagesTokens(ctx.recorder.messages);
31438
31635
  const meaningful = Math.max(MIN_RELIEF_TOKENS, beforeTokens * MIN_RELIEF_FRACTION);
@@ -31456,6 +31653,23 @@ async function relieveOverflow(ctx) {
31456
31653
  return true;
31457
31654
  }
31458
31655
  __name(relieveOverflow, "relieveOverflow");
31656
+ var compactionErrors = /* @__PURE__ */ new WeakMap();
31657
+ var MAX_COMPACTION_CAUSE_CHARS = 300;
31658
+ var AUTOMATIC_COMPACTION_FAILED = " \xB7 automatic compaction failed: ";
31659
+ function noteCompactionError(ctx, error) {
31660
+ const text9 = error instanceof Error ? error.message : String(error);
31661
+ if (text9.length > 0)
31662
+ compactionErrors.set(ctx.recorder, text9.slice(0, MAX_COMPACTION_CAUSE_CHARS));
31663
+ }
31664
+ __name(noteCompactionError, "noteCompactionError");
31665
+ function compactionErrorNote(ctx) {
31666
+ return compactionErrors.get(ctx.recorder);
31667
+ }
31668
+ __name(compactionErrorNote, "compactionErrorNote");
31669
+ function clearCompactionErrorNote(ctx) {
31670
+ compactionErrors.delete(ctx.recorder);
31671
+ }
31672
+ __name(clearCompactionErrorNote, "clearCompactionErrorNote");
31459
31673
  function totalChars(messages) {
31460
31674
  let total = 0;
31461
31675
  for (const msg of messages)
@@ -31525,6 +31739,7 @@ async function applyReducer(ctx, reducer, reduction, measurement) {
31525
31739
  "namzu.runtime.reason": reduction.reason,
31526
31740
  "exception.message": message
31527
31741
  });
31742
+ noteCompactionError(ctx, error);
31528
31743
  await declined(ctx, "reducer_threw", before, message);
31529
31744
  return;
31530
31745
  }
@@ -31622,11 +31837,12 @@ async function runCompactionCheck(ctx, options) {
31622
31837
  }
31623
31838
  __name(runCompactionCheck, "runCompactionCheck");
31624
31839
  async function runCompactionCheckInner(ctx, pass, options) {
31625
- const config = ctx.compactionConfig;
31626
- if (!config)
31840
+ const configured = ctx.compactionConfig;
31841
+ if (!configured)
31627
31842
  return;
31628
- if (config.strategy === "disabled")
31843
+ if (configured.strategy === "disabled")
31629
31844
  return;
31845
+ const config = options?.deeper ? deepenConfig(configured, ctx.recorder.messages) : configured;
31630
31846
  const measured2 = measureContext(ctx);
31631
31847
  const estimatedTokens = measured2.tokens;
31632
31848
  const window2 = activeContextWindow(ctx);
@@ -31649,8 +31865,7 @@ async function runCompactionCheckInner(ctx, pass, options) {
31649
31865
  turnId: ctx.recorder.turnId,
31650
31866
  iteration: ctx.recorder.currentIteration,
31651
31867
  cause: "breaker_open",
31652
- messages: ctx.recorder.messages.length,
31653
- error: COMPACTION_FAILURE_MESSAGE
31868
+ messages: ctx.recorder.messages.length
31654
31869
  });
31655
31870
  }
31656
31871
  return;
@@ -31803,24 +32018,35 @@ async function runCompactionCheckInner(ctx, pass, options) {
31803
32018
  let compactedContent;
31804
32019
  if (config.llmVerification && manager.slotCount() < config.richStateThreshold) {
31805
32020
  const compactionModel = resolveTaskModel("compaction", ctx.taskRouter, ctx.turnConfig.model);
31806
- compactedContent = await buildVerifiedSummaryWithBoundedProvider(
31807
- manager,
31808
- olderMessages,
31809
- ctx.provider,
31810
- config,
31811
- (usage2) => ctx.recorder.accumulateUsage(usage2, {
31812
- providerId: ctx.recorder.servingProviderId,
31813
- model: compactionModel
31814
- }),
31815
- // The one model call a turn makes that the user never asked for. It
31816
- // reads a transcript and writes a summary, which is the cheapest
31817
- // thing a small model does well, and it fires on exactly the long
31818
- // runs where the primary model is most expensive. `taskRouter` had
31819
- // been accepted, validated and threaded through four types since it
31820
- // was added, and nothing ever consulted it.
31821
- compactionModel,
31822
- ctx.abortController.signal
31823
- );
32021
+ try {
32022
+ compactedContent = await buildVerifiedSummaryWithBoundedProvider(
32023
+ manager,
32024
+ olderMessages,
32025
+ ctx.provider,
32026
+ config,
32027
+ (usage2) => ctx.recorder.accumulateUsage(usage2, {
32028
+ providerId: ctx.recorder.servingProviderId,
32029
+ model: compactionModel
32030
+ }),
32031
+ // The one model call a turn makes that the user never asked for. It
32032
+ // reads a transcript and writes a summary, which is the cheapest
32033
+ // thing a small model does well, and it fires on exactly the long
32034
+ // runs where the primary model is most expensive. `taskRouter` had
32035
+ // been accepted, validated and threaded through four types since it
32036
+ // was added, and nothing ever consulted it.
32037
+ compactionModel,
32038
+ ctx.abortController.signal
32039
+ );
32040
+ } catch (error) {
32041
+ if (ctx.abortController.signal.aborted)
32042
+ throw error;
32043
+ noteCompactionError(ctx, error);
32044
+ ctx.log.warn("The compaction summary call failed \u2014 using the extracted state alone", {
32045
+ [NAMZU.TURN_ID]: ctx.recorder.turnId,
32046
+ "exception.message": error instanceof Error ? error.message : String(error)
32047
+ });
32048
+ compactedContent = serializeState(manager.getState());
32049
+ }
31824
32050
  } else {
31825
32051
  compactedContent = serializeState(manager.getState());
31826
32052
  }
@@ -33276,6 +33502,45 @@ async function* runToolReview(ctx, response, iterationNum) {
33276
33502
  }
33277
33503
  __name(runToolReview, "runToolReview");
33278
33504
 
33505
+ // ../sdk/dist/provider/image-input-refusal.js
33506
+ var IMAGE_INPUT_REFUSAL_PATTERNS = [
33507
+ // Zen: "Beam supports text input only. This conversation contains an image."
33508
+ /\btext\s+inputs?\s+only\b/i,
33509
+ /\bonly\s+(?:supports?|accepts?)\s+text\s+inputs?\b/i,
33510
+ /\bonly\s+text\s+inputs?\s+(?:is|are)\s+(?:supported|accepted|allowed)\b/i,
33511
+ // "This model is text-only", "a text-only model"
33512
+ /\btext[- ]only\s+model\b/i,
33513
+ /\bmodel\b[^.;]{0,40}\bis\s+(?:a\s+)?text[- ]only\b/i,
33514
+ // Local model servers: "<model> does not support images", "Model does not
33515
+ // support images. Please use a model that does." Also "doesn't support vision",
33516
+ // "does not support image input", "does not support multimodal inputs".
33517
+ /\b(?:does\s?n[o'’]t|do\s+not|cannot|can[’']t)\s+(?:support|accept)\s+(?:images|vision)\b(?![/\w-])/i,
33518
+ /\b(?:does\s?n[o'’]t|do\s+not|cannot|can[’']t)\s+(?:support|accept|process|handle)\s+(?:image|vision|multimodal|visual)\s+inputs?\b/i,
33519
+ // A local inference server: "image input is not supported - hint: ... mmproj". The
33520
+ // sentence must end there or name the model: "image input is not supported
33521
+ // on streaming" is a restriction of the endpoint, not of the model.
33522
+ /\b(?:image|vision|multimodal)\s+inputs?\s+(?:is|are)\s+(?:not\s+supported|unsupported)(?:\s+(?:by|for)\s+(?:this|the)\s+model)?\s*(?:$|[.;:,!)\-])/i,
33523
+ /\bimages\s+(?:is|are)\s+not\s+supported(?:\s+(?:by|for)\s+(?:this|the)\s+model)?\s*(?:$|[.;:,!)\-])/i,
33524
+ // A serving engine: "<model> is not a multimodal model"
33525
+ /\bis\s+not\s+a\s+(?:multimodal|vision)\s+model\b/i,
33526
+ // A chat-completions API: "Invalid content type. image_url is only supported by certain models."
33527
+ /\bimage_url\b.{0,40}\bonly\s+supported\s+by\s+certain\s+models\b/i,
33528
+ // A chat-completions server that only knows text parts: "unknown variant `image_url`, expected `text`"
33529
+ /\bunknown\s+variant\s+\W?image_url\W?,?\s+expected\s+\W?text\b/i
33530
+ ];
33531
+ function isImageInputRefusalMessage(text9) {
33532
+ if (!text9)
33533
+ return false;
33534
+ return IMAGE_INPUT_REFUSAL_PATTERNS.some((pattern) => pattern.test(text9));
33535
+ }
33536
+ __name(isImageInputRefusalMessage, "isImageInputRefusalMessage");
33537
+ function isImageInputRefusal(error) {
33538
+ if (!isProviderRequestError(error) || error.kind !== "bad_request")
33539
+ return false;
33540
+ return isImageInputRefusalMessage(error.detail ?? error.message);
33541
+ }
33542
+ __name(isImageInputRefusal, "isImageInputRefusal");
33543
+
33279
33544
  // ../sdk/dist/runtime/query/iteration/provider-rejected-image.js
33280
33545
  var IMAGE_REJECTION_PATTERNS = [
33281
33546
  /\binvalid[_ -]?image\b/i,
@@ -33292,6 +33557,10 @@ function classifyProviderRejectedImageError(error) {
33292
33557
  return IMAGE_REJECTION_PATTERNS.some((pattern) => pattern.test(detail)) ? "heuristic" : null;
33293
33558
  }
33294
33559
  __name(classifyProviderRejectedImageError, "classifyProviderRejectedImageError");
33560
+ function isProviderRejectedImageError(error) {
33561
+ return classifyProviderRejectedImageError(error) !== null;
33562
+ }
33563
+ __name(isProviderRejectedImageError, "isProviderRejectedImageError");
33295
33564
  function isAcceptedChunk(chunk) {
33296
33565
  if (chunk.retry !== void 0 || chunk.fallback !== void 0 || chunk.error !== void 0) {
33297
33566
  return false;
@@ -33304,17 +33573,20 @@ function throwIfAborted(signal) {
33304
33573
  throw signal.reason;
33305
33574
  }
33306
33575
  __name(throwIfAborted, "throwIfAborted");
33307
- async function* streamWithProviderRejectedImageRecovery(provider, params, onAccepted, onRequest) {
33576
+ async function* streamWithProviderRejectedImageRecovery(provider, params, onAccepted, onRequest, textOnly, repair) {
33577
+ const session = repair?.session();
33578
+ const send = /* @__PURE__ */ __name((request) => repair ? repair.stream(provider, request, session) : provider.chatStream(request), "send");
33308
33579
  const candidate = findSingleRequestImage(params.messages);
33309
33580
  onRequest?.(params.messages);
33310
- if (candidate === null) {
33311
- yield* provider.chatStream(params);
33581
+ if (candidate === null && !requestHasImages(params.messages)) {
33582
+ yield* send(params);
33312
33583
  return;
33313
33584
  }
33314
33585
  let produced = false;
33315
33586
  let confidence = null;
33587
+ let refused = null;
33316
33588
  try {
33317
- for await (const chunk of provider.chatStream(params)) {
33589
+ for await (const chunk of send(params)) {
33318
33590
  if (isAcceptedChunk(chunk))
33319
33591
  produced = true;
33320
33592
  yield chunk;
@@ -33322,11 +33594,41 @@ async function* streamWithProviderRejectedImageRecovery(provider, params, onAcce
33322
33594
  return;
33323
33595
  } catch (error) {
33324
33596
  throwIfAborted(params.signal);
33597
+ if (produced)
33598
+ throw error;
33325
33599
  confidence = classifyProviderRejectedImageError(error);
33326
- if (produced || confidence === null)
33600
+ if (confidence === null && isImageInputRefusal(error)) {
33601
+ const served = textOnly?.servedBy?.();
33602
+ refused = {
33603
+ providerId: served?.providerId ?? provider.id,
33604
+ model: served?.model ?? params.model
33605
+ };
33606
+ } else if (confidence === null || candidate === null) {
33327
33607
  throw error;
33608
+ }
33328
33609
  }
33329
33610
  throwIfAborted(params.signal);
33611
+ if (refused !== null) {
33612
+ const messages = projectRequestRichContent(params.messages, 0, { imagesReadable: false });
33613
+ onRequest?.(messages);
33614
+ let accepted2 = false;
33615
+ let reportedError = false;
33616
+ for await (const chunk of send({ ...params, messages })) {
33617
+ if (chunk.error !== void 0)
33618
+ reportedError = true;
33619
+ if (!accepted2 && isAcceptedChunk(chunk)) {
33620
+ throwIfAborted(params.signal);
33621
+ await textOnly?.onAccepted(refused);
33622
+ accepted2 = true;
33623
+ }
33624
+ yield chunk;
33625
+ }
33626
+ if (!accepted2 && !reportedError)
33627
+ await textOnly?.onAccepted(refused);
33628
+ return;
33629
+ }
33630
+ if (candidate === null)
33631
+ return;
33330
33632
  const retryParams = {
33331
33633
  ...params,
33332
33634
  messages: projectRequestWithoutImage(params.messages, candidate)
@@ -33334,7 +33636,7 @@ async function* streamWithProviderRejectedImageRecovery(provider, params, onAcce
33334
33636
  let accepted = false;
33335
33637
  let retryReportedError = false;
33336
33638
  onRequest?.(retryParams.messages);
33337
- for await (const chunk of provider.chatStream(retryParams)) {
33639
+ for await (const chunk of send(retryParams)) {
33338
33640
  if (chunk.error !== void 0)
33339
33641
  retryReportedError = true;
33340
33642
  if (!accepted && isAcceptedChunk(chunk)) {
@@ -33353,6 +33655,552 @@ async function* streamWithProviderRejectedImageRecovery(provider, params, onAcce
33353
33655
  }
33354
33656
  __name(streamWithProviderRejectedImageRecovery, "streamWithProviderRejectedImageRecovery");
33355
33657
 
33658
+ // ../sdk/dist/runtime/query/iteration/request-repair.js
33659
+ import { createHash as createHash14 } from "node:crypto";
33660
+ var MAX_REPAIRS_PER_REQUEST = 5;
33661
+ var MAX_STRIPS_PER_INDEX = 3;
33662
+ var GENERIC_MEDIA_LIMITS = [510, 255, 127];
33663
+ var PARAMETER_CODES = /* @__PURE__ */ new Set([
33664
+ "unsupported_parameter",
33665
+ "unsupported_value",
33666
+ "unknown_parameter"
33667
+ ]);
33668
+ var REASONING_CODES = /* @__PURE__ */ new Set([
33669
+ "invalid_encrypted_content",
33670
+ "invalid_reasoning",
33671
+ "invalid_signature"
33672
+ ]);
33673
+ var TOOL_PAIRING = /\btool_use\b.{0,120}\btool_result\b|\btool_result\b.{0,120}\btool_use\b|unexpected\s+`?tool_use_id`?|tool_use\s+ids?\s+must\s+be\s+unique|\btool_call_id\b|role\s+'tool'\s+must\s+be\s+a\s+response|'tool_calls'\s+must\s+be\s+followed|Expected\s+toolResult\s+blocks|function\s+call\s+turn\s+comes\s+immediately|number\s+of\s+function\s+response\s+parts/i;
33674
+ var REASONING = /\bthought[_ ]?signature\b|`?signature`?\s+in\s+`?(?:thinking|redacted_thinking)|\b(?:thinking|redacted_thinking)\s+blocks?\b.{0,160}\b(?:cannot|can['’]t|must|invalid|modified|expected)|\bexpected\s+`?(?:thinking|redacted_thinking)`?|\bencrypted[_ ]content\b|\breasoning\s+item\b|\bitem\s+'rs_[^']*'|\bof\s+type\s+'reasoning'/i;
33675
+ var TOOL_SCHEMA_PATH = /\b(?:tools?|functions?)[.[]\s*\d+|input_schema|\.properties\b|json\s+schema/i;
33676
+ var REFUSAL = "(?:unsupported|not\\s+supported|does\\s?n[o']t\\s+support|do\\s+not\\s+support|unrecognized|unknown\\s+(?:request\\s+)?(?:parameter|argument|field)|not\\s+allowed|deprecated|only\\s+the\\s+default)";
33677
+ var PARAMETER_NAMES = {
33678
+ effort: "(?:reasoning[_. -]?effort|effort)",
33679
+ thinking: "thinking",
33680
+ temperature: "temperature",
33681
+ topP: "top[_ ]?p",
33682
+ responseFormat: "(?:response_format|output_config(?:\\.format)?|json_schema|json_object|structured\\s+output)"
33683
+ };
33684
+ var PARAMETER_PATTERNS = Object.fromEntries(Object.entries(PARAMETER_NAMES).map(([name2, token]) => [
33685
+ name2,
33686
+ {
33687
+ named: new RegExp(`\\b${token}\\b`, "i"),
33688
+ refused: new RegExp(`${REFUSAL}.{0,80}\\b${token}\\b|\\b${token}\\b.{0,80}${REFUSAL}`, "i")
33689
+ }
33690
+ ]));
33691
+ var BOTH_SAMPLING = /temperature.{0,60}top[_ ]?p.{0,80}(?:cannot|can['’]t|may\s+not|should\s+not).{0,20}(?:both|together)/i;
33692
+ var IMAGE_FAULT = /\b(?:images?|pictures?|photos?)\b.{0,100}\b(?:too\s+(?:large|big)|exceeds?|larger\s+than|maximum\s+(?:size|dimensions?)|dimensions?|(?:could|can)\s?not\s+be\s+(?:processed|decoded|loaded|read|fetched|downloaded)|failed\s+to\s+(?:process|decode|load|read|download)|unsupported|not\s+supported|corrupt\w*|malformed|truncated|invalid)\b|\b(?:(?:could|can)\s?not|failed\s+to|unable\s+to)\s+(?:process|decode|load|read|download|fetch)\b.{0,60}\b(?:images?|pictures?)\b|\bunsupported\s+(?:image|media)\b|\binvalid\s+image\b/i;
33693
+ var DOCUMENT_FAULT = /\bdocument_block\b|\b(?:documents?|pdfs?)\b.{0,80}\b(?:too\s+(?:large|big)|exceeds?\s+(?:the\s+)?(?:maximum|size|page)|page\s+limit|password|corrupt\w*|(?:could|can)\s?not\s+be\s+(?:processed|read|decoded)|failed\s+to\s+(?:process|read|decode))\b|\bpassword[- ]protected\s+pdf\b|\bpdf\b.{0,40}\bpages?\b.{0,20}\b(?:limit|maximum|exceeds?)\b/i;
33694
+ var GENERIC_MEDIA = /\bunprocessable\b.{0,100}\b(?:images?|media|documents?)\b|\b(?:images?|media|documents?)\b.{0,100}\bunprocessable\b|\btoo\s+many\s+(?:images?|documents?|media|attachments?)\b|\bmedia_budget\b|\bimage_block\b/i;
33695
+ var NAMES_MEDIA = /\b(?:images?|pictures?|photos?|documents?|pdfs?|media|attachments?)\b/i;
33696
+ function wireIndexes(text9) {
33697
+ const both = /\bmessages?[.[]\s*(\d+)\s*\]?[.[]\s*content[.[]\s*(\d+)/i.exec(text9);
33698
+ if (both?.[1] !== void 0 && both[2] !== void 0) {
33699
+ return { messageIndex: Number(both[1]), contentIndex: Number(both[2]) };
33700
+ }
33701
+ const only = /\bmessages?[.[]\s*(\d+)\b/i.exec(text9);
33702
+ return only?.[1] !== void 0 ? { messageIndex: Number(only[1]) } : {};
33703
+ }
33704
+ __name(wireIndexes, "wireIndexes");
33705
+ function rejectedParameters(text9, code, params) {
33706
+ if (TOOL_SCHEMA_PATH.test(text9))
33707
+ return [];
33708
+ const structured = code !== void 0 && PARAMETER_CODES.has(code);
33709
+ const set3 = {
33710
+ effort: params.effort !== void 0,
33711
+ thinking: params.thinking !== void 0,
33712
+ temperature: params.temperature !== void 0,
33713
+ topP: params.topP !== void 0,
33714
+ responseFormat: params.responseFormat !== void 0
33715
+ };
33716
+ const found = [];
33717
+ for (const name2 of Object.keys(set3)) {
33718
+ if (!set3[name2])
33719
+ continue;
33720
+ const pattern = PARAMETER_PATTERNS[name2];
33721
+ if (structured ? pattern.named.test(text9) : pattern.refused.test(text9))
33722
+ found.push(name2);
33723
+ }
33724
+ if (found.length === 0 && set3.topP && BOTH_SAMPLING.test(text9))
33725
+ found.push("topP");
33726
+ return found;
33727
+ }
33728
+ __name(rejectedParameters, "rejectedParameters");
33729
+ function requestHasMedia(params) {
33730
+ return listMedia(params.messages).length > 0;
33731
+ }
33732
+ __name(requestHasMedia, "requestHasMedia");
33733
+ function classifyRequestRejection(error, params) {
33734
+ if (!isProviderRequestError(error) || error.kind !== "bad_request")
33735
+ return null;
33736
+ if (error.status !== void 0 && error.status !== 400 && error.status !== 413 && error.status !== 422) {
33737
+ return null;
33738
+ }
33739
+ const text9 = error.detail ?? error.message;
33740
+ const code = error.providerCode;
33741
+ if (code !== void 0 && REASONING_CODES.has(code))
33742
+ return { kind: "reasoning" };
33743
+ if (REASONING.test(text9))
33744
+ return { kind: "reasoning" };
33745
+ if (TOOL_PAIRING.test(text9))
33746
+ return { kind: "tool-pairing" };
33747
+ const parameters = rejectedParameters(text9, code, params);
33748
+ if (parameters.length > 0)
33749
+ return { kind: "parameter", parameters };
33750
+ if (TOOL_SCHEMA_PATH.test(text9))
33751
+ return null;
33752
+ if (code === "invalid_image")
33753
+ return { kind: "media", generic: false, ...wireIndexes(text9) };
33754
+ if (GENERIC_MEDIA.test(text9))
33755
+ return { kind: "media", generic: true };
33756
+ if ((error.status === 413 || error.status === 422) && NAMES_MEDIA.test(text9)) {
33757
+ return requestHasMedia(params) ? { kind: "media", generic: true } : null;
33758
+ }
33759
+ if (IMAGE_FAULT.test(text9) || DOCUMENT_FAULT.test(text9)) {
33760
+ return { kind: "media", generic: false, ...wireIndexes(text9) };
33761
+ }
33762
+ return null;
33763
+ }
33764
+ __name(classifyRequestRejection, "classifyRequestRejection");
33765
+ function isAccepted(chunk) {
33766
+ if (chunk.retry !== void 0 || chunk.fallback !== void 0 || chunk.error !== void 0) {
33767
+ return false;
33768
+ }
33769
+ return Boolean(chunk.delta.content || chunk.delta.toolCalls?.length || chunk.delta.toolCallEnd || chunk.delta.reasoning || chunk.delta.citation || chunk.finishReason !== void 0 || chunk.usage !== void 0 || chunk.replayState !== void 0 || chunk.textParts !== void 0);
33770
+ }
33771
+ __name(isAccepted, "isAccepted");
33772
+ var mediaFingerprint = /* @__PURE__ */ __name((data, mediaType) => createHash14("sha256").update(mediaType).update("\0").update(data).digest("hex"), "mediaFingerprint");
33773
+ var FAULT_NOTE = "the provider could not process it. The file may be unsupported or corrupt; do not retry reading it. If you need to inspect it, use a shell command instead.";
33774
+ var LIMIT_NOTE = "this conversation holds more files than the provider accepts at once, so the oldest are left out of the request. They are still in the conversation.";
33775
+ var removedNote = /* @__PURE__ */ __name((kind, limit) => `[${kind} removed: ${limit ? LIMIT_NOTE : FAULT_NOTE}]`, "removedNote");
33776
+ function listMedia(messages) {
33777
+ const slots = [];
33778
+ for (const [messageIndex, message] of messages.entries()) {
33779
+ if (message.role === "user") {
33780
+ for (const [itemIndex, attachment] of (message.attachments ?? []).entries()) {
33781
+ if (attachment.type === "stored")
33782
+ continue;
33783
+ slots.push({
33784
+ messageIndex,
33785
+ itemIndex,
33786
+ source: "user",
33787
+ kind: attachment.type === "document" ? "document" : "image",
33788
+ fingerprint: mediaFingerprint(attachment.data, attachment.mediaType)
33789
+ });
33790
+ }
33791
+ } else if (message.role === "tool" && Array.isArray(message.content)) {
33792
+ for (const [itemIndex, block] of message.content.entries()) {
33793
+ if (block.type !== "image" && block.type !== "document")
33794
+ continue;
33795
+ slots.push({
33796
+ messageIndex,
33797
+ itemIndex,
33798
+ source: "tool",
33799
+ kind: block.type,
33800
+ fingerprint: mediaFingerprint(block.data, block.mediaType)
33801
+ });
33802
+ }
33803
+ }
33804
+ }
33805
+ return slots;
33806
+ }
33807
+ __name(listMedia, "listMedia");
33808
+ function removeMedia(messages, slots, limit) {
33809
+ if (slots.length === 0)
33810
+ return messages;
33811
+ const byMessage = /* @__PURE__ */ new Map();
33812
+ for (const slot of slots) {
33813
+ const items = byMessage.get(slot.messageIndex) ?? /* @__PURE__ */ new Map();
33814
+ items.set(slot.itemIndex, slot);
33815
+ byMessage.set(slot.messageIndex, items);
33816
+ }
33817
+ return messages.map((message, messageIndex) => {
33818
+ const items = byMessage.get(messageIndex);
33819
+ if (!items)
33820
+ return message;
33821
+ if (message.role === "user") {
33822
+ const attachments = message.attachments ?? [];
33823
+ const kept = attachments.filter((_a2, i) => !items.has(i));
33824
+ const notes = [...items.values()].sort((a, b) => a.itemIndex - b.itemIndex).map((slot) => removedNote(slot.kind, limit)).join("\n\n");
33825
+ const { attachments: _drop, ...rest } = message;
33826
+ return {
33827
+ ...rest,
33828
+ content: message.content.length > 0 ? `${message.content}
33829
+
33830
+ ${notes}` : notes,
33831
+ ...kept.length > 0 ? { attachments: kept } : {}
33832
+ };
33833
+ }
33834
+ if (message.role === "tool" && Array.isArray(message.content)) {
33835
+ const content = message.content.map((block, i) => {
33836
+ const slot = items.get(i);
33837
+ return slot ? { type: "text", text: removedNote(slot.kind, limit) } : block;
33838
+ });
33839
+ return { ...message, content };
33840
+ }
33841
+ return message;
33842
+ });
33843
+ }
33844
+ __name(removeMedia, "removeMedia");
33845
+ function stripReasoning(messages) {
33846
+ let changed = false;
33847
+ const out = messages.map((message) => {
33848
+ if (message.role !== "assistant")
33849
+ return message;
33850
+ const assistant = message;
33851
+ const hasState = assistant.source !== void 0 && assistant.source.replayState !== void 0;
33852
+ if (assistant.reasoning === void 0 && !hasState)
33853
+ return message;
33854
+ changed = true;
33855
+ const { reasoning: _reasoning, source, ...rest } = assistant;
33856
+ if (source === void 0)
33857
+ return rest;
33858
+ const { replayState: _state, ...route } = source;
33859
+ return { ...rest, source: route };
33860
+ });
33861
+ return changed ? out : messages;
33862
+ }
33863
+ __name(stripReasoning, "stripReasoning");
33864
+ function mediaAtWireIndex(messages, slots, family, wireIndex, contentIndex) {
33865
+ if (family !== "anthropic" && family !== "openai")
33866
+ return void 0;
33867
+ const entries2 = [];
33868
+ let inToolRun = false;
33869
+ for (const [index, message2] of messages.entries()) {
33870
+ if (family === "anthropic") {
33871
+ if (message2.role === "system")
33872
+ continue;
33873
+ if (message2.role === "tool") {
33874
+ if (!inToolRun)
33875
+ entries2.push([]);
33876
+ inToolRun = true;
33877
+ entries2[entries2.length - 1]?.push(index);
33878
+ continue;
33879
+ }
33880
+ inToolRun = false;
33881
+ }
33882
+ entries2.push([index]);
33883
+ }
33884
+ const entry = entries2[wireIndex];
33885
+ if (entry === void 0)
33886
+ return void 0;
33887
+ const mine = slots.filter((slot) => entry.includes(slot.messageIndex));
33888
+ if (mine.length === 0)
33889
+ return void 0;
33890
+ if (contentIndex === void 0)
33891
+ return mine;
33892
+ const first = entry[0];
33893
+ const message = first === void 0 ? void 0 : messages[first];
33894
+ if (message?.role === "user" && !(family === "openai" && mine.some((s) => s.source === "tool"))) {
33895
+ const itemIndex = contentIndex - (message.content.length > 0 ? 1 : 0);
33896
+ const hit = mine.filter((slot) => slot.itemIndex === itemIndex);
33897
+ return hit.length > 0 ? hit : mine;
33898
+ }
33899
+ if (family === "anthropic" && message?.role === "tool") {
33900
+ const owner = entry[contentIndex];
33901
+ const hit = owner === void 0 ? [] : mine.filter((slot) => slot.messageIndex === owner);
33902
+ return hit.length > 0 ? hit : mine;
33903
+ }
33904
+ return mine;
33905
+ }
33906
+ __name(mediaAtWireIndex, "mediaAtWireIndex");
33907
+ var emptyLearned = /* @__PURE__ */ __name(() => ({
33908
+ latched: /* @__PURE__ */ new Map(),
33909
+ reasoningOff: /* @__PURE__ */ new Set(),
33910
+ rejectedMedia: /* @__PURE__ */ new Set(),
33911
+ mediaLimit: void 0
33912
+ }), "emptyLearned");
33913
+ var RequestRepair = class {
33914
+ static {
33915
+ __name(this, "RequestRepair");
33916
+ }
33917
+ hooks;
33918
+ learned = emptyLearned();
33919
+ constructor(hooks = {}) {
33920
+ this.hooks = hooks;
33921
+ }
33922
+ /** A fresh budget for one original request. */
33923
+ session() {
33924
+ return {
33925
+ spent: /* @__PURE__ */ new Set(),
33926
+ stripsByIndex: /* @__PURE__ */ new Map(),
33927
+ pending: emptyLearned(),
33928
+ repairs: 0,
33929
+ removal: void 0
33930
+ };
33931
+ }
33932
+ served(provider, params) {
33933
+ const member = this.hooks.servedBy?.();
33934
+ return {
33935
+ providerId: member?.providerId ?? params.providerRoute?.providerId ?? provider.id,
33936
+ model: member?.model ?? params.providerRoute?.model ?? params.model
33937
+ };
33938
+ }
33939
+ routeKey(provider, params) {
33940
+ const { providerId, model } = this.served(provider, params);
33941
+ return `${providerId}|${model}`;
33942
+ }
33943
+ /** Everything already confirmed, then the tool pairing the provider requires. */
33944
+ prepare(provider, params) {
33945
+ const key5 = this.routeKey(provider, params);
33946
+ let next = params;
33947
+ const latched = this.learned.latched.get(key5);
33948
+ if (latched)
33949
+ next = withoutParameters(next, latched);
33950
+ let messages = next.messages;
33951
+ if (this.learned.reasoningOff.has(key5))
33952
+ messages = stripReasoning(messages);
33953
+ messages = this.applyMediaMemory(messages);
33954
+ messages = this.pair(messages);
33955
+ return messages === next.messages ? next : { ...next, messages };
33956
+ }
33957
+ applyMediaMemory(messages) {
33958
+ const { rejectedMedia, mediaLimit } = this.learned;
33959
+ if (rejectedMedia.size === 0 && mediaLimit === void 0)
33960
+ return messages;
33961
+ const slots = listMedia(messages);
33962
+ const faulty = slots.filter((slot) => rejectedMedia.has(slot.fingerprint));
33963
+ let out = removeMedia(messages, faulty, false);
33964
+ if (mediaLimit !== void 0) {
33965
+ const rest = listMedia(out);
33966
+ if (rest.length > mediaLimit) {
33967
+ out = removeMedia(out, rest.slice(0, rest.length - mediaLimit), true);
33968
+ }
33969
+ }
33970
+ return out;
33971
+ }
33972
+ /** The shared tool-history repair, on the outgoing copy. Duplicate call ids fail closed there, so the request goes out as it is. */
33973
+ pair(messages) {
33974
+ try {
33975
+ const repaired = repairToolMessageHistory(messages);
33976
+ if (!toolHistoryRepairChanged(repaired.report))
33977
+ return messages;
33978
+ this.hooks.debug?.(`Repaired tool pairing before sending: ${JSON.stringify(repaired.report)}`);
33979
+ return repaired.messages;
33980
+ } catch (error) {
33981
+ this.hooks.debug?.(`Tool pairing could not be repaired before sending: ${error instanceof Error ? error.message : String(error)}`);
33982
+ return messages;
33983
+ }
33984
+ }
33985
+ /** What a resend that was accepted has proved. */
33986
+ commit(session) {
33987
+ const { pending: pending2 } = session;
33988
+ for (const [key5, names] of pending2.latched) {
33989
+ const set3 = this.learned.latched.get(key5) ?? /* @__PURE__ */ new Set();
33990
+ for (const name2 of names)
33991
+ set3.add(name2);
33992
+ this.learned.latched.set(key5, set3);
33993
+ }
33994
+ for (const key5 of pending2.reasoningOff)
33995
+ this.learned.reasoningOff.add(key5);
33996
+ for (const fingerprint of pending2.rejectedMedia)
33997
+ this.learned.rejectedMedia.add(fingerprint);
33998
+ if (pending2.mediaLimit !== void 0) {
33999
+ this.learned.mediaLimit = Math.min(this.learned.mediaLimit ?? pending2.mediaLimit, pending2.mediaLimit);
34000
+ }
34001
+ session.pending = emptyLearned();
34002
+ }
34003
+ /** The request to send after `rejection`, or null when nothing more can be tried. */
34004
+ next(provider, params, rejection, session) {
34005
+ const { spent, pending: pending2 } = session;
34006
+ const key5 = this.routeKey(provider, params);
34007
+ switch (rejection.kind) {
34008
+ case "tool-pairing": {
34009
+ if (spent.has("tool-pairing"))
34010
+ return null;
34011
+ spent.add("tool-pairing");
34012
+ const repaired = repairOnce(params.messages);
34013
+ if (repaired === null)
34014
+ return null;
34015
+ this.hooks.debug?.(`Retrying after a tool-history rejection (${key5})`);
34016
+ return { ...params, messages: repaired };
34017
+ }
34018
+ case "reasoning": {
34019
+ if (spent.has("reasoning"))
34020
+ return null;
34021
+ spent.add("reasoning");
34022
+ const messages = stripReasoning(params.messages);
34023
+ if (messages === params.messages)
34024
+ return null;
34025
+ pending2.reasoningOff.add(key5);
34026
+ let next = { ...params, messages };
34027
+ if (params.thinking !== void 0 && params.thinking.type !== "disabled") {
34028
+ next = withoutParameters(next, /* @__PURE__ */ new Set(["thinking"]));
34029
+ const names = pending2.latched.get(key5) ?? /* @__PURE__ */ new Set();
34030
+ names.add("thinking");
34031
+ pending2.latched.set(key5, names);
34032
+ }
34033
+ this.hooks.debug?.(`Retrying without reasoning blocks (${key5})`);
34034
+ return next;
34035
+ }
34036
+ case "parameter": {
34037
+ const fresh = rejection.parameters.filter((name2) => !spent.has(`param:${name2}`));
34038
+ if (fresh.length === 0)
34039
+ return null;
34040
+ for (const name2 of fresh)
34041
+ spent.add(`param:${name2}`);
34042
+ const names = pending2.latched.get(key5) ?? /* @__PURE__ */ new Set();
34043
+ for (const name2 of fresh)
34044
+ names.add(name2);
34045
+ pending2.latched.set(key5, names);
34046
+ this.hooks.debug?.(`Retrying without parameters the model refused (${key5}): ${fresh.join(", ")}`);
34047
+ return withoutParameters(params, new Set(fresh));
34048
+ }
34049
+ case "media":
34050
+ return this.nextWithoutMedia(provider, params, rejection, session);
34051
+ }
34052
+ }
34053
+ nextWithoutMedia(provider, params, rejection, session) {
34054
+ const { spent, stripsByIndex, pending: pending2 } = session;
34055
+ const slots = listMedia(params.messages);
34056
+ if (slots.length === 0)
34057
+ return null;
34058
+ let victims = [];
34059
+ let limited = false;
34060
+ if (!rejection.generic) {
34061
+ if (rejection.messageIndex !== void 0) {
34062
+ const used = stripsByIndex.get(rejection.messageIndex) ?? 0;
34063
+ if (used < MAX_STRIPS_PER_INDEX) {
34064
+ stripsByIndex.set(rejection.messageIndex, used + 1);
34065
+ victims = mediaAtWireIndex(params.messages, slots, this.served(provider, params).providerId, rejection.messageIndex, rejection.contentIndex) ?? [];
34066
+ }
34067
+ }
34068
+ if (victims.length === 0) {
34069
+ const newest = slots[slots.length - 1];
34070
+ if (newest === void 0)
34071
+ return null;
34072
+ const count7 = (stripsByIndex.get(-1) ?? 0) + 1;
34073
+ if (count7 > MAX_STRIPS_PER_INDEX)
34074
+ return null;
34075
+ stripsByIndex.set(-1, count7);
34076
+ victims = slots.filter((slot) => slot.messageIndex === newest.messageIndex);
34077
+ }
34078
+ } else {
34079
+ const limit = GENERIC_MEDIA_LIMITS.find((candidate) => candidate < slots.length) ?? Math.floor(slots.length / 2);
34080
+ spent.add(`limit:${limit}`);
34081
+ pending2.mediaLimit = Math.min(pending2.mediaLimit ?? limit, limit);
34082
+ victims = slots.slice(0, slots.length - limit);
34083
+ limited = true;
34084
+ }
34085
+ if (!limited)
34086
+ for (const slot of victims)
34087
+ pending2.rejectedMedia.add(slot.fingerprint);
34088
+ this.hooks.debug?.(`Retrying without ${victims.length} media the provider rejected`);
34089
+ let lastUser = -1;
34090
+ for (const [index, message] of params.messages.entries()) {
34091
+ if (message.role === "user")
34092
+ lastUser = index;
34093
+ }
34094
+ const kinds = new Set(victims.map((slot) => slot.kind));
34095
+ const removal = {
34096
+ count: victims.length,
34097
+ kind: kinds.size === 1 ? [...kinds][0] : "media",
34098
+ current: victims.some((slot) => slot.source === "user" && slot.messageIndex === lastUser),
34099
+ limit: limited
34100
+ };
34101
+ const before = session.removal;
34102
+ session.removal = before ? {
34103
+ count: before.count + removal.count,
34104
+ kind: before.kind === removal.kind ? before.kind : "media",
34105
+ current: before.current || removal.current,
34106
+ limit: before.limit && removal.limit
34107
+ } : removal;
34108
+ return { ...params, messages: removeMedia(params.messages, victims, limited) };
34109
+ }
34110
+ /**
34111
+ * Send `params`, repairing and resending a request the provider rejects as
34112
+ * invalid until it is accepted or nothing more can be changed. The original
34113
+ * rejection is thrown when nothing applies, and what the guesses taught is
34114
+ * forgotten unless a resend was accepted.
34115
+ */
34116
+ async *stream(provider, params, session = this.session()) {
34117
+ let current = this.prepare(provider, params);
34118
+ let firstError;
34119
+ for (; ; ) {
34120
+ let produced = false;
34121
+ let reported = false;
34122
+ try {
34123
+ for await (const chunk of provider.chatStream(current)) {
34124
+ if (isAccepted(chunk)) {
34125
+ produced = true;
34126
+ this.commit(session);
34127
+ if (session.removal !== void 0 && !reported) {
34128
+ reported = true;
34129
+ const removal = session.removal;
34130
+ session.removal = void 0;
34131
+ await this.hooks.onMediaRemoved?.(removal);
34132
+ }
34133
+ }
34134
+ yield chunk;
34135
+ }
34136
+ this.commit(session);
34137
+ if (session.removal !== void 0 && !reported) {
34138
+ const removal = session.removal;
34139
+ session.removal = void 0;
34140
+ await this.hooks.onMediaRemoved?.(removal);
34141
+ }
34142
+ return;
34143
+ } catch (error) {
34144
+ if (current.signal?.aborted)
34145
+ throw current.signal.reason;
34146
+ if (produced)
34147
+ throw error;
34148
+ firstError ??= error;
34149
+ const forget = /* @__PURE__ */ __name(() => {
34150
+ session.pending = emptyLearned();
34151
+ session.removal = void 0;
34152
+ throw firstError;
34153
+ }, "forget");
34154
+ if (session.repairs >= MAX_REPAIRS_PER_REQUEST)
34155
+ return forget();
34156
+ if (isHandledElsewhere(error, current))
34157
+ return forget();
34158
+ const rejection = classifyRequestRejection(error, current);
34159
+ if (rejection === null)
34160
+ return forget();
34161
+ const step = this.next(provider, current, rejection, session);
34162
+ if (step === null)
34163
+ return forget();
34164
+ session.repairs++;
34165
+ current = step;
34166
+ }
34167
+ }
34168
+ }
34169
+ };
34170
+ function repairOnce(messages) {
34171
+ try {
34172
+ const repaired = repairToolMessageHistory(messages);
34173
+ return toolHistoryRepairChanged(repaired.report) ? repaired.messages : null;
34174
+ } catch {
34175
+ return null;
34176
+ }
34177
+ }
34178
+ __name(repairOnce, "repairOnce");
34179
+ function withoutParameters(params, names) {
34180
+ if (names.size === 0)
34181
+ return params;
34182
+ const next = { ...params };
34183
+ if (names.has("effort"))
34184
+ next.effort = void 0;
34185
+ if (names.has("thinking"))
34186
+ next.thinking = void 0;
34187
+ if (names.has("temperature"))
34188
+ next.temperature = void 0;
34189
+ if (names.has("topP"))
34190
+ next.topP = void 0;
34191
+ if (names.has("responseFormat"))
34192
+ next.responseFormat = void 0;
34193
+ return next;
34194
+ }
34195
+ __name(withoutParameters, "withoutParameters");
34196
+ function isHandledElsewhere(error, params) {
34197
+ if (isProviderRejectedImageError(error) && findSingleRequestImage(params.messages) !== null) {
34198
+ return true;
34199
+ }
34200
+ return isImageInputRefusal(error);
34201
+ }
34202
+ __name(isHandledElsewhere, "isHandledElsewhere");
34203
+
33356
34204
  // ../sdk/dist/turn/preparation-context-error.js
33357
34205
  var PreparationContextError = class extends Error {
33358
34206
  static {
@@ -33857,7 +34705,7 @@ async function* streamProviderTurn(provider, params, emitEvent, drainPending, tu
33857
34705
  } : void 0;
33858
34706
  if (!imageRecovery)
33859
34707
  observeRequest?.(streamParams.messages);
33860
- const stream = imageRecovery ? streamWithProviderRejectedImageRecovery(provider, streamParams, imageRecovery.onAccepted, observeRequest) : provider.chatStream(streamParams);
34708
+ const stream = imageRecovery ? streamWithProviderRejectedImageRecovery(provider, streamParams, imageRecovery.onAccepted, observeRequest, imageRecovery.textOnly, imageRecovery.repair) : provider.chatStream(streamParams);
33861
34709
  const it = stream[Symbol.asyncIterator]();
33862
34710
  const signal = params.signal;
33863
34711
  let onAbort;
@@ -34370,6 +35218,10 @@ var DEFAULT_ANSWER_REVIEW_LIMIT = 3;
34370
35218
  var OUTPUT_CAP_MARGIN_TOKENS = 1e3;
34371
35219
  var MIN_OUTPUT_CAP_TOKENS = 3e3;
34372
35220
  var CLOSING_RESPONSE_GUIDANCE = "Give a concise response using only what the available evidence supports. Attribute unverified statements to their source instead of presenting them as observed facts. If evidence is missing or conflicting, state what cannot be established. Do not claim unfinished work is complete. Do not request any more tool calls.";
35221
+ function textOnlyKey(providerId, model) {
35222
+ return `${providerId}\0${model}`;
35223
+ }
35224
+ __name(textOnlyKey, "textOnlyKey");
34373
35225
  var IterationOrchestrator = class {
34374
35226
  static {
34375
35227
  __name(this, "IterationOrchestrator");
@@ -34405,6 +35257,67 @@ var IterationOrchestrator = class {
34405
35257
  }
34406
35258
  /** Rich tool blocks already reported; durable history is scanned every turn. */
34407
35259
  warnedRichToolResults = /* @__PURE__ */ new Set();
35260
+ /** What this run has learned about requests its provider rejects as invalid, and how to repair them. */
35261
+ requestRepair = new RequestRepair({
35262
+ debug: /* @__PURE__ */ __name((message) => this.ctx.log.debug(message), "debug"),
35263
+ onMediaRemoved: /* @__PURE__ */ __name((removal) => this.noteMediaRemoved(removal), "onMediaRemoved"),
35264
+ servedBy: /* @__PURE__ */ __name(() => this.ctx.servingMember?.(), "servedBy")
35265
+ });
35266
+ /**
35267
+ * Provider and model pairs that refused a request for holding an image; they
35268
+ * get none for the rest of the run. Keyed by both: one model id can be served
35269
+ * by two members of a fallback chain, and only the one that refused is known.
35270
+ */
35271
+ textOnlyModels = /* @__PURE__ */ new Set();
35272
+ /**
35273
+ * The member a request for `model` goes to first. A fallback chain keeps
35274
+ * serving from the member it last moved to, so that member, not the head,
35275
+ * is the one whose reading of images counts.
35276
+ */
35277
+ servingModel(model) {
35278
+ const serving = this.ctx.servingMember?.();
35279
+ return {
35280
+ providerId: serving?.providerId ?? this.ctx.provider.id,
35281
+ model: serving?.model ?? model
35282
+ };
35283
+ }
35284
+ /** Whether a request for `model` may carry images: the driver's catalogue and this run's own evidence agree. */
35285
+ modelReadsImages(model) {
35286
+ const serving = this.servingModel(model);
35287
+ return !this.textOnlyModels.has(textOnlyKey(serving.providerId, serving.model)) && modelReadsImages(this.ctx.provider, model);
35288
+ }
35289
+ /** What a request for `model` does when its model turns out to read text only. */
35290
+ textOnlyRecovery(model) {
35291
+ return {
35292
+ servedBy: /* @__PURE__ */ __name(() => this.servingModel(model), "servedBy"),
35293
+ onAccepted: /* @__PURE__ */ __name((refused) => this.noteTextOnlyModel(refused), "onAccepted")
35294
+ };
35295
+ }
35296
+ /**
35297
+ * A provider refused a request for holding an image its model cannot read, and
35298
+ * the retry without images was accepted. Stop sending images to it, and say so
35299
+ * once, so the host can remember the model beyond this run.
35300
+ */
35301
+ async noteTextOnlyModel(refused) {
35302
+ const key5 = textOnlyKey(refused.providerId, refused.model ?? "");
35303
+ if (this.textOnlyModels.has(key5))
35304
+ return;
35305
+ this.textOnlyModels.add(key5);
35306
+ const { providerId, model } = refused;
35307
+ this.ctx.log.warn("Capability mismatch: the model cannot read images", {
35308
+ [GENAI.SYSTEM]: providerId,
35309
+ [GENAI.REQUEST_MODEL]: model ?? ""
35310
+ });
35311
+ await this.ctx.emitEvent?.({
35312
+ type: "capability_warning",
35313
+ turnId: this.ctx.recorder.turnId,
35314
+ capability: "vision",
35315
+ contentSource: "history",
35316
+ providerId,
35317
+ ...model !== void 0 ? { model } : {},
35318
+ message: `Model '${model ?? "unknown"}' on provider '${providerId}' refused a request that held an image, so images are left out of its requests. They stay in the conversation and are sent again to a model that reads them.`
35319
+ });
35320
+ }
34408
35321
  /**
34409
35322
  * The previous iteration held a `stopWhen` decision open for a worker.
34410
35323
  *
@@ -34618,7 +35531,7 @@ var IterationOrchestrator = class {
34618
35531
  this.resumedToolResults = [];
34619
35532
  await this.recordToolStructuredFailure(resumedToolResults, recorder.currentIteration);
34620
35533
  await this.ctx.checkpointMgr.markLoopStart?.(recorder);
34621
- let overflowRelieved = false;
35534
+ let overflowReliefs = 0;
34622
35535
  let outputCapOverride;
34623
35536
  try {
34624
35537
  if (this.stopForStructuredRetryExhaustion())
@@ -34785,7 +35698,7 @@ var IterationOrchestrator = class {
34785
35698
  requestHistory.push(stepContextMessage(contextText));
34786
35699
  if (step.context)
34787
35700
  requestHistory.push(stepContextMessage(step.context));
34788
- const messages = projectRequestRichContent(this.projectObservations(requestHistory), this.ctx.turnConfig.maxRequestRichContentBytes ?? DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES);
35701
+ const messages = projectRequestRichContent(this.projectObservations(requestHistory), this.ctx.turnConfig.maxRequestRichContentBytes ?? DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES, { imagesReadable: this.modelReadsImages(stepModel) });
34789
35702
  appendWorkContext(shaping, messages, iterationNum, step);
34790
35703
  if (closingDirective)
34791
35704
  messages.push(closingDirective);
@@ -34891,7 +35804,9 @@ var IterationOrchestrator = class {
34891
35804
  // also races it). Inert when never aborted.
34892
35805
  signal: this.ctx.abortController.signal
34893
35806
  }, this.ctx.emitEvent, this.ctx.drainPending, recorder.turnId, iterationNum, forceFinalize, this.ctx.log, iterSpan, stepMessageId, {
34894
- onAccepted: /* @__PURE__ */ __name((identity) => this.acceptProviderRejectedImage(identity), "onAccepted")
35807
+ onAccepted: /* @__PURE__ */ __name((identity) => this.acceptProviderRejectedImage(identity), "onAccepted"),
35808
+ textOnly: this.textOnlyRecovery(stepModel),
35809
+ repair: this.requestRepair
34895
35810
  }, Boolean(this.ctx.reviewAnswer || this.ctx.structuredOutput?.review || this.ctx.advisoryCtx), recorder.sessionId);
34896
35811
  stepResponse = response;
34897
35812
  const reviewRequest = {
@@ -34917,7 +35832,8 @@ var IterationOrchestrator = class {
34917
35832
  providerId: servedBy.providerId,
34918
35833
  model: servedBy.model
34919
35834
  });
34920
- overflowRelieved = false;
35835
+ overflowReliefs = 0;
35836
+ clearCompactionErrorNote(this.ctx);
34921
35837
  outputCapOverride = void 0;
34922
35838
  if (response.finishReason !== "length")
34923
35839
  this.outputContinuations = 0;
@@ -35399,6 +36315,7 @@ ${feedback}`, "hook-feedback"));
35399
36315
  yield* this.ctx.drainPending();
35400
36316
  } catch (err) {
35401
36317
  const cancelled = this.ctx.abortController.signal.aborted;
36318
+ const sandboxStopped = err instanceof SandboxAcquisitionStopped;
35402
36319
  if (this.steps.at(-1)?.stepNumber === iterationNum) {
35403
36320
  this.ctx.log.warn("Iteration failed after its step was already recorded", {
35404
36321
  [NAMZU.TURN_ID]: recorder.turnId,
@@ -35422,7 +36339,7 @@ ${feedback}`, "hook-feedback"));
35422
36339
  startedAt: stepStartedAt,
35423
36340
  usageBefore,
35424
36341
  costBefore,
35425
- unfinished: cancelled ? { finishReason: "cancelled" } : {
36342
+ unfinished: cancelled || sandboxStopped ? { finishReason: "cancelled" } : {
35426
36343
  finishReason: "error",
35427
36344
  failure: describeStepFailure(err, this.ctx.provider.id)
35428
36345
  }
@@ -35451,19 +36368,43 @@ ${feedback}`, "hook-feedback"));
35451
36368
  continue;
35452
36369
  }
35453
36370
  }
35454
- if (!overflowRelieved && !(err instanceof AnswerReviewFailure) && classifyProviderError(err, this.ctx.provider.id).code === "context_length_exceeded") {
35455
- overflowRelieved = true;
35456
- const shed = await relieveOverflow(this.ctx);
36371
+ if (!(err instanceof AnswerReviewFailure) && classifyProviderError(err, this.ctx.provider.id).code === "context_length_exceeded") {
36372
+ if (overflowReliefs === 0 && await stopOnRefill(this.ctx)) {
36373
+ if (iterationActivity) {
36374
+ this.ctx.activityStore.fail(iterationActivity.id, toErrorMessage(err));
36375
+ }
36376
+ if (this.stopForCompactionBreaker())
36377
+ break;
36378
+ }
36379
+ let shed = false;
36380
+ while (!shed && overflowReliefs < OVERFLOW_RELIEF_LIMIT) {
36381
+ overflowReliefs++;
36382
+ shed = await relieveOverflow(this.ctx, { deeper: overflowReliefs > 1 });
36383
+ }
35457
36384
  if (shed) {
36385
+ compactionBreaker(this.ctx)?.recordCompaction(iterationNum);
35458
36386
  this.ctx.log.info("Retrying the turn after relieving a context overflow", {
35459
36387
  [NAMZU.TURN_ID]: recorder.turnId,
35460
- [NAMZU.ITERATION]: iterationNum
36388
+ [NAMZU.ITERATION]: iterationNum,
36389
+ "namzu.runtime.relief_rung": overflowReliefs
35461
36390
  });
35462
36391
  if (iterationActivity) {
35463
36392
  this.ctx.activityStore.complete(iterationActivity.id);
35464
36393
  }
35465
36394
  continue;
35466
36395
  }
36396
+ const cause = compactionErrorNote(this.ctx);
36397
+ if (cause !== void 0 && err instanceof Error) {
36398
+ try {
36399
+ err.message = `${err.message}${AUTOMATIC_COMPACTION_FAILED}${cause}`;
36400
+ } catch {
36401
+ }
36402
+ }
36403
+ }
36404
+ if (sandboxStopped) {
36405
+ if (iterationActivity)
36406
+ this.ctx.activityStore.complete(iterationActivity.id);
36407
+ throw err;
35467
36408
  }
35468
36409
  if (iterationActivity) {
35469
36410
  this.ctx.activityStore.fail(iterationActivity.id, toErrorMessage(err));
@@ -35948,6 +36889,25 @@ ${feedback}`, "hook-feedback"));
35948
36889
  return false;
35949
36890
  return this.ctx.taskGateway.listTasks().some((t) => t.state !== "completed" && t.state !== "failed" && t.state !== "canceled");
35950
36891
  }
36892
+ /** Media the provider could not process was left out of a request that then went through. */
36893
+ async noteMediaRemoved(removal) {
36894
+ this.ctx.log.warn("Media the provider rejected was left out of the request", {
36895
+ [GENAI.SYSTEM]: this.ctx.provider.id,
36896
+ "namzu.request.media_removed": removal.count
36897
+ });
36898
+ const noun = removal.count === 1 ? "a file" : `${removal.count} files`;
36899
+ const it = removal.count === 1 ? "it" : "they";
36900
+ await this.ctx.emitEvent?.({
36901
+ type: "capability_warning",
36902
+ turnId: this.ctx.recorder.turnId,
36903
+ capability: removal.kind === "document" ? "documents" : "vision",
36904
+ // The person's own latest attachment is named as such; a count limit is
36905
+ // not a fault in any file.
36906
+ contentSource: removal.current ? "media-removed-current" : removal.limit ? "media-limit" : "media-removed",
36907
+ providerId: this.ctx.provider.id,
36908
+ message: removal.limit ? `The conversation holds more files than the provider accepts at once, so ${noun} (the oldest) ${removal.count === 1 ? "was" : "were"} left out of the request. The conversation still holds ${it}.` : `The provider could not process ${noun}${removal.current ? " attached to your latest message" : " in this conversation"}, so ${it} ${removal.count === 1 ? "was" : "were"} left out of the request. The conversation still holds ${it}.`
36909
+ });
36910
+ }
35951
36911
  async acceptProviderRejectedImage(identity) {
35952
36912
  const repaired = markProviderRejectedImage(this.ctx.recorder.messages, identity);
35953
36913
  if (repaired.count === 0) {
@@ -35983,7 +36943,7 @@ ${feedback}`, "hook-feedback"));
35983
36943
  ...workingMemory.history,
35984
36944
  ...workingMemory.context ? [workingMemory.context] : []
35985
36945
  ];
35986
- const finalMessages = projectRequestRichContent(this.projectObservations(finalHistory), this.ctx.turnConfig.maxRequestRichContentBytes ?? DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES);
36946
+ const finalMessages = projectRequestRichContent(this.projectObservations(finalHistory), this.ctx.turnConfig.maxRequestRichContentBytes ?? DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES, { imagesReadable: this.modelReadsImages(model) });
35987
36947
  appendWorkContext(this.stepShaping(), finalMessages, this.steps.length + 1, { model });
35988
36948
  finalMessages.push(createRuntimeContextMessage(`[SYSTEM] Turn is ending due to ${reason2}. ${CLOSING_RESPONSE_GUIDANCE}`, "limit-finalization"));
35989
36949
  await this.reportUnsupportedToolResults(finalMessages);
@@ -36017,7 +36977,7 @@ ${feedback}`, "hook-feedback"));
36017
36977
  // stream to completion.
36018
36978
  signal: this.ctx.abortController.signal
36019
36979
  };
36020
- const response = await collectChatCompletion(streamWithProviderRejectedImageRecovery(this.ctx.provider, finalParams, (identity) => this.acceptProviderRejectedImage(identity)));
36980
+ const response = await collectChatCompletion(streamWithProviderRejectedImageRecovery(this.ctx.provider, finalParams, (identity) => this.acceptProviderRejectedImage(identity), void 0, this.textOnlyRecovery(model), this.requestRepair));
36021
36981
  const servingMember = this.ctx.servingMember?.() ?? requestedMember;
36022
36982
  const servedBy = {
36023
36983
  providerId: servingMember.providerId,
@@ -36277,6 +37237,16 @@ function withProviderFallback(members, options = {}) {
36277
37237
  // always present on a multi-member wrapper: `undefined` is its honest
36278
37238
  // answer when any member cannot enumerate its selected model.
36279
37239
  supportsHostedWebSearchFor: /* @__PURE__ */ __name((model, mode) => members.every((member) => member.provider.capabilities?.supportsHostedWebSearch === true && (member.provider.supportsHostedWebSearchFor?.(member.model ?? model, mode) ?? true)), "supportsHostedWebSearchFor"),
37240
+ // Answered for the member the next request goes to first, the one the
37241
+ // cursor rests on (it never rewinds). Unlike the head's other
37242
+ // declarations this costs nothing to keep current, and the head's answer
37243
+ // would strip images from a vision member serving behind a text-only head.
37244
+ // A request that falls over mid-call to a member that cannot read images is
37245
+ // refused there, and the runtime sends it again without them.
37246
+ supportsImageInputFor: /* @__PURE__ */ __name((model) => {
37247
+ const serving = members[cursor] ?? first;
37248
+ return serving.provider.supportsImageInputFor?.(serving.model ?? model) ?? true;
37249
+ }, "supportsImageInputFor"),
36280
37250
  reasoningEffortLevelsFor: /* @__PURE__ */ __name((model, thinking) => commonReasoningEffortLevels(members, model, thinking), "reasoningEffortLevelsFor"),
36281
37251
  // Present on the chain wrapper for the same reason the menu method is:
36282
37252
  // `undefined` is the honest answer when a member cannot answer, defaults
@@ -36334,6 +37304,11 @@ var DEFAULT_PROVIDER_RETRY = {
36334
37304
  maxDelayMs: 16e3,
36335
37305
  maxRetryAfterMs: 6e4
36336
37306
  };
37307
+ function isReasoningOnly(chunk) {
37308
+ const d = chunk.delta;
37309
+ return d.reasoning !== void 0 && !d.content && !d.toolCalls?.length && d.toolCallEnd === void 0 && d.hostedTool === void 0 && d.citation === void 0 && d.textPart === void 0 && chunk.textParts === void 0 && chunk.finishReason === void 0;
37310
+ }
37311
+ __name(isReasoningOnly, "isReasoningOnly");
36337
37312
  function withProviderRetry(provider, options = {}) {
36338
37313
  const config = {
36339
37314
  ...DEFAULT_PROVIDER_RETRY,
@@ -36348,12 +37323,17 @@ function withProviderRetry(provider, options = {}) {
36348
37323
  async function* chatStream(params) {
36349
37324
  for (let attempt = 0; ; attempt++) {
36350
37325
  let produced = false;
37326
+ let reasoned = false;
36351
37327
  let acted = false;
36352
37328
  try {
36353
37329
  for await (const chunk of provider.chatStream(params)) {
36354
37330
  const isErrorOnly = chunk.error !== void 0 && !chunk.delta.content && !chunk.delta.toolCalls?.length;
36355
- if (!isErrorOnly)
36356
- produced = true;
37331
+ if (!isErrorOnly) {
37332
+ if (isReasoningOnly(chunk))
37333
+ reasoned = true;
37334
+ else
37335
+ produced = true;
37336
+ }
36357
37337
  if (chunk.delta.toolCalls?.length || chunk.delta.toolCallEnd || chunk.delta.hostedTool) {
36358
37338
  acted = true;
36359
37339
  }
@@ -36370,7 +37350,7 @@ function withProviderRetry(provider, options = {}) {
36370
37350
  throw err;
36371
37351
  const classified = classifyProviderError(err, provider.id);
36372
37352
  const exhausted = attempt >= config.maxRetries;
36373
- const restartable = produced && config.retryMidStream === true && !acted;
37353
+ const restartable = produced && config.retryMidStream === true && !acted || !produced && reasoned;
36374
37354
  if (produced && !restartable || !classified.retryable || exhausted) {
36375
37355
  log?.warn("Provider call failed", {
36376
37356
  [GENAI.SYSTEM]: provider.id,
@@ -36449,6 +37429,9 @@ function withProviderRetry(provider, options = {}) {
36449
37429
  ...provider.supportsHostedWebSearchFor ? {
36450
37430
  supportsHostedWebSearchFor: /* @__PURE__ */ __name((model, mode) => provider.supportsHostedWebSearchFor?.(model, mode) ?? false, "supportsHostedWebSearchFor")
36451
37431
  } : {},
37432
+ ...provider.supportsImageInputFor ? {
37433
+ supportsImageInputFor: /* @__PURE__ */ __name((model) => provider.supportsImageInputFor?.(model) ?? true, "supportsImageInputFor")
37434
+ } : {},
36452
37435
  ...provider.reasoningEffortLevelsFor ? {
36453
37436
  reasoningEffortLevelsFor: /* @__PURE__ */ __name((model, thinking) => provider.reasoningEffortLevelsFor?.(model, thinking), "reasoningEffortLevelsFor")
36454
37437
  } : {},
@@ -37452,7 +38435,7 @@ import { lstat as lstat3 } from "node:fs/promises";
37452
38435
  import { resolve as resolve5 } from "node:path";
37453
38436
 
37454
38437
  // ../sdk/dist/store/evidence/index-page.js
37455
- import { createHash as createHash14, createHmac, timingSafeEqual } from "node:crypto";
38438
+ import { createHash as createHash15, createHmac, timingSafeEqual } from "node:crypto";
37456
38439
 
37457
38440
  // ../sdk/dist/store/evidence/compaction-provenance.js
37458
38441
  function record(value) {
@@ -37567,7 +38550,7 @@ var positionSchema = external_exports.object({
37567
38550
  textIndex: integer.default(0)
37568
38551
  });
37569
38552
  function evidenceSeal(sessionStart, sourceKey) {
37570
- const key5 = createHash14("sha256").update("namzu-session-evidence-v1\n").update(sessionStart).digest();
38553
+ const key5 = createHash15("sha256").update("namzu-session-evidence-v1\n").update(sessionStart).digest();
37571
38554
  const mac = /* @__PURE__ */ __name((value) => createHmac("sha256", key5).update(`${sourceKey}
37572
38555
  ${value}`).digest(), "mac");
37573
38556
  return {
@@ -41554,7 +42537,7 @@ function lastUnansweredBatch(messages) {
41554
42537
  __name(lastUnansweredBatch, "lastUnansweredBatch");
41555
42538
 
41556
42539
  // ../sdk/dist/runtime/query/executor.js
41557
- import { createHash as createHash15 } from "node:crypto";
42540
+ import { createHash as createHash16 } from "node:crypto";
41558
42541
  import { join as join16 } from "node:path";
41559
42542
 
41560
42543
  // ../sdk/dist/authorization/program.js
@@ -44188,6 +45171,7 @@ var ToolExecutor = class {
44188
45171
  /** Set per turn by the orchestrator; see {@link setStepAllowedTools}. */
44189
45172
  stepAllowedTools;
44190
45173
  fileReadTracker;
45174
+ sandboxGate;
44191
45175
  /** A ledger is rebuilt from history at most once; a second pass would re-append its chains. */
44192
45176
  fileObservationsSeeded = false;
44193
45177
  constructor(config, activityStore, emitEvent, log, probes = probe) {
@@ -44207,6 +45191,22 @@ var ToolExecutor = class {
44207
45191
  }
44208
45192
  setSandbox(sandbox) {
44209
45193
  this.config = { ...this.config, sandbox };
45194
+ this.sandboxGate = void 0;
45195
+ }
45196
+ /**
45197
+ * Hold tool admission until a sandbox that is still being acquired exists.
45198
+ * The gate rejects when none will, and the turn settles that rejection. It
45199
+ * is cleared by {@link setSandbox}, so a turn pays the check once.
45200
+ */
45201
+ setSandboxGate(gate) {
45202
+ this.sandboxGate = gate;
45203
+ }
45204
+ async awaitSandbox() {
45205
+ await this.sandboxGate?.();
45206
+ }
45207
+ /** True once the turn has a sandbox, or is certain to get one before a tool runs. */
45208
+ get sandboxed() {
45209
+ return this.config.sandbox !== void 0 || this.sandboxGate !== void 0;
44210
45210
  }
44211
45211
  /** Classify only the exact successful result executed by this executor. */
44212
45212
  recordedObservationKey(call2, message) {
@@ -44214,7 +45214,7 @@ var ToolExecutor = class {
44214
45214
  return recorded !== void 0 && message.toolCallId === call2.id && !message.isError && typeof message.content === "string" && this.config.tools.get(recorded.toolName) === recorded.definition && recorded.fingerprint === this.observationFingerprint(call2, message.content) ? recorded.inputFingerprint : void 0;
44215
45215
  }
44216
45216
  observationFingerprint(call2, content) {
44217
- return createHash15("sha256").update(JSON.stringify([call2.function.name, call2.function.arguments, content])).digest("hex");
45217
+ return createHash16("sha256").update(JSON.stringify([call2.function.name, call2.function.arguments, content])).digest("hex");
44218
45218
  }
44219
45219
  recordExecutedObservation(call2, toolName, definition, input, content) {
44220
45220
  if (typeof content !== "string" || this.config.tools.get(toolName) !== definition)
@@ -44226,7 +45226,7 @@ var ToolExecutor = class {
44226
45226
  toolName,
44227
45227
  definition,
44228
45228
  fingerprint: this.observationFingerprint(call2, content),
44229
- inputFingerprint: createHash15("sha256").update(JSON.stringify([toolName, input])).digest("hex")
45229
+ inputFingerprint: createHash16("sha256").update(JSON.stringify([toolName, input])).digest("hex")
44230
45230
  });
44231
45231
  } catch {
44232
45232
  }
@@ -44264,7 +45264,7 @@ var ToolExecutor = class {
44264
45264
  }
44265
45265
  /** Request-only evidence from the same ledger used by mutation admission. No filesystem I/O. */
44266
45266
  describeFileEvidence(messages) {
44267
- return describeVisibleFileEvidence(messages, this.fileReadTracker, this.config.workingDirectory, this.config.sandbox !== void 0);
45267
+ return describeVisibleFileEvidence(messages, this.fileReadTracker, this.config.workingDirectory, this.sandboxed);
44268
45268
  }
44269
45269
  /**
44270
45270
  * Span that this executor's tool spans should hang off — the current
@@ -44423,7 +45423,7 @@ var ToolExecutor = class {
44423
45423
  commandDialect(toolName) {
44424
45424
  const tool = this.config.tools.get(toolName);
44425
45425
  return tool?.commandDialect?.({
44426
- sandboxed: this.config.sandbox !== void 0
45426
+ sandboxed: this.sandboxed
44427
45427
  }) ?? "sh";
44428
45428
  }
44429
45429
  /**
@@ -44443,6 +45443,8 @@ var ToolExecutor = class {
44443
45443
  */
44444
45444
  async prepareBatchForReview(response, hostModifiedCallIds) {
44445
45445
  assertUniqueToolCallIds(response.message.toolCalls ?? []);
45446
+ if ((response.message.toolCalls ?? []).length > 0)
45447
+ await this.awaitSandbox();
44446
45448
  const calls = /* @__PURE__ */ new Map();
44447
45449
  const escalations = /* @__PURE__ */ new Map();
44448
45450
  for (const toolCall of response.message.toolCalls ?? []) {
@@ -44474,7 +45476,7 @@ var ToolExecutor = class {
44474
45476
  if (!tool || call2.input === null || typeof call2.input !== "object")
44475
45477
  return void 0;
44476
45478
  const input = call2.input;
44477
- const sandboxed = this.config.sandbox !== void 0;
45479
+ const sandboxed = this.sandboxed;
44478
45480
  let outsidePaths;
44479
45481
  if (this.config.outsideRootAccess === "review" && !sandboxed && tool.pathArgument !== void 0) {
44480
45482
  const value = input[tool.pathArgument];
@@ -44612,6 +45614,8 @@ var ToolExecutor = class {
44612
45614
  return { messages: [], results: [], observations: [] };
44613
45615
  }
44614
45616
  assertUniqueToolCallIds(toolCalls);
45617
+ if (toolCalls.length > 0)
45618
+ await this.awaitSandbox();
44615
45619
  this.batchMode = this.resolvePermissionMode();
44616
45620
  try {
44617
45621
  const owned = preparedBatch;
@@ -46635,6 +47639,9 @@ async function* query(params) {
46635
47639
  [GENAI.SYSTEM]: params.provider.id
46636
47640
  });
46637
47641
  let sandbox;
47642
+ let deferredSandbox;
47643
+ let applyAcquisitionStop = /* @__PURE__ */ __name(() => {
47644
+ }, "applyAcquisitionStop");
46638
47645
  let pendingResume = null;
46639
47646
  let pendingResumeAssistantId;
46640
47647
  let answeredParkId;
@@ -46878,6 +47885,14 @@ ${segments.dynamic}` : segments.static;
46878
47885
  applyLifecycleHookResults("turn_start", hookResults);
46879
47886
  yield* eventTranslator.drainPending();
46880
47887
  }
47888
+ const acquireMode = turnConfig.sandbox?.acquire ?? "eager";
47889
+ if (acquireMode !== "eager" && acquireMode !== "concurrent" && acquireMode !== "on-first-use") {
47890
+ throw new NamzuError({
47891
+ code: "invalid_config",
47892
+ message: `sandbox.acquire must be 'eager', 'concurrent' or 'on-first-use'; received ${String(acquireMode)}`,
47893
+ details: { acquire: String(acquireMode) }
47894
+ });
47895
+ }
46881
47896
  if (params.sandboxProvider) {
46882
47897
  const rootAtCwd = turnConfig.sandbox?.workspace === "working-directory";
46883
47898
  if (rootAtCwd && params.workingDirectory === void 0) {
@@ -46897,8 +47912,9 @@ ${segments.dynamic}` : segments.static;
46897
47912
  }
46898
47913
  });
46899
47914
  }
46900
- const acquisition = await acquireSandbox({
46901
- provider: params.sandboxProvider,
47915
+ const sandboxProvider = params.sandboxProvider;
47916
+ const startAcquisition = /* @__PURE__ */ __name((signal) => acquireSandbox({
47917
+ provider: sandboxProvider,
46902
47918
  config: {
46903
47919
  ...rootAtCwd ? { workingDirectory: ctx.cwd } : {},
46904
47920
  ...rootAtCwd && params.additionalDirectories?.length ? { additionalDirectories: params.additionalDirectories } : {},
@@ -46906,7 +47922,7 @@ ${segments.dynamic}` : segments.static;
46906
47922
  memoryLimitMb: turnConfig.sandbox?.memoryLimitMb,
46907
47923
  maxProcesses: turnConfig.sandbox?.maxProcesses
46908
47924
  },
46909
- signal: ctx.abortController.signal,
47925
+ signal,
46910
47926
  timeoutMs: guard.remainingUntilTimeoutMs(),
46911
47927
  teardownTimeoutMs: sandboxTeardownTimeoutMs,
46912
47928
  onLateTeardown: /* @__PURE__ */ __name((result) => {
@@ -46921,12 +47937,29 @@ ${segments.dynamic}` : segments.static;
46921
47937
  ...errorAttributes(result.error)
46922
47938
  });
46923
47939
  }, "onLateTeardown")
46924
- });
46925
- if (acquisition.kind !== "created") {
47940
+ }), "startAcquisition");
47941
+ const publishSandbox = /* @__PURE__ */ __name(async (acquired) => {
47942
+ sandbox = acquired;
47943
+ toolExecutor.setSandbox(acquired);
47944
+ await eventTranslator.emitEvent({
47945
+ type: "sandbox_created",
47946
+ turnId: ctx.turnId,
47947
+ sandboxId: acquired.id,
47948
+ environment: acquired.environment
47949
+ });
47950
+ }, "publishSandbox");
47951
+ const logSandboxCreated = /* @__PURE__ */ __name((acquired) => {
47952
+ ctx.log.info("Sandbox created for run", {
47953
+ "namzu.sandbox.id": acquired.id,
47954
+ "namzu.execution.environment": acquired.environment,
47955
+ "namzu.runtime.root_dir": acquired.rootDir
47956
+ });
47957
+ }, "logSandboxCreated");
47958
+ applyAcquisitionStop = /* @__PURE__ */ __name((acquisition) => {
46926
47959
  if (acquisition.createPending) {
46927
47960
  ctx.log.warn("Sandbox creation was unsettled when the turn stopped; any returned handle will be released, but a remote allocation hidden behind a lost response requires provider-side reconciliation or a fleet reaper", {
46928
47961
  [NAMZU.TURN_ID]: ctx.turnId,
46929
- "namzu.sandbox.provider_id": params.sandboxProvider.id
47962
+ "namzu.sandbox.provider_id": sandboxProvider.id
46930
47963
  });
46931
47964
  }
46932
47965
  if (acquisition.kind === "cancelled") {
@@ -46935,28 +47968,36 @@ ${segments.dynamic}` : segments.static;
46935
47968
  ctx.recorder.setStopReason("timeout");
46936
47969
  ctx.log.warn("Sandbox creation exhausted the turn timeout", {
46937
47970
  [NAMZU.TURN_ID]: ctx.turnId,
46938
- "namzu.sandbox.provider_id": params.sandboxProvider.id,
47971
+ "namzu.sandbox.provider_id": sandboxProvider.id,
46939
47972
  ...errorAttributes(acquisition.error)
46940
47973
  });
46941
47974
  }
46942
- yield* resultAssembler.completeTurn(rootSpan);
46943
- settled = true;
46944
- return await resultAssembler.finalize();
47975
+ }, "applyAcquisitionStop");
47976
+ if (acquireMode === "eager") {
47977
+ const acquisition = await startAcquisition(ctx.abortController.signal);
47978
+ if (acquisition.kind !== "created") {
47979
+ applyAcquisitionStop(acquisition);
47980
+ yield* resultAssembler.completeTurn(rootSpan);
47981
+ settled = true;
47982
+ return await resultAssembler.finalize();
47983
+ }
47984
+ await publishSandbox(acquisition.sandbox);
47985
+ yield* eventTranslator.drainPending();
47986
+ logSandboxCreated(acquisition.sandbox);
47987
+ } else {
47988
+ const deferred2 = createDeferredSandbox({
47989
+ turnSignal: ctx.abortController.signal,
47990
+ acquire: startAcquisition,
47991
+ publish: /* @__PURE__ */ __name(async (acquired) => {
47992
+ await publishSandbox(acquired);
47993
+ logSandboxCreated(acquired);
47994
+ }, "publish")
47995
+ });
47996
+ deferredSandbox = deferred2;
47997
+ toolExecutor.setSandboxGate(() => deferred2.ensure());
47998
+ if (acquireMode === "concurrent")
47999
+ deferred2.start();
46945
48000
  }
46946
- sandbox = acquisition.sandbox;
46947
- toolExecutor.setSandbox(sandbox);
46948
- await eventTranslator.emitEvent({
46949
- type: "sandbox_created",
46950
- turnId: ctx.turnId,
46951
- sandboxId: sandbox.id,
46952
- environment: sandbox.environment
46953
- });
46954
- yield* eventTranslator.drainPending();
46955
- ctx.log.info("Sandbox created for run", {
46956
- "namzu.sandbox.id": sandbox.id,
46957
- "namzu.execution.environment": sandbox.environment,
46958
- "namzu.runtime.root_dir": sandbox.rootDir
46959
- });
46960
48001
  }
46961
48002
  const inputVerdict = await runInputGuardrails(params.inputGuardrails, {
46962
48003
  sessionId: ctx.sessionId,
@@ -47014,6 +48055,10 @@ ${segments.dynamic}` : segments.static;
47014
48055
  });
47015
48056
  }
47016
48057
  yield* iterationOrchestrator.runLoop();
48058
+ if (deferredSandbox) {
48059
+ await deferredSandbox.settle();
48060
+ yield* eventTranslator.drainPending();
48061
+ }
47017
48062
  yield* finalizeTurn({
47018
48063
  ctx,
47019
48064
  params,
@@ -47025,6 +48070,13 @@ ${segments.dynamic}` : segments.static;
47025
48070
  rootSpan
47026
48071
  });
47027
48072
  } catch (err) {
48073
+ if (err instanceof SandboxAcquisitionStopped) {
48074
+ applyAcquisitionStop(err.acquisition);
48075
+ yield* eventTranslator.drainPending();
48076
+ yield* resultAssembler.completeTurn(rootSpan);
48077
+ settled = true;
48078
+ return await resultAssembler.finalize();
48079
+ }
47028
48080
  if (isTurnInProgressError(err) && !ctx.recorder.isActive)
47029
48081
  throw err;
47030
48082
  ctx.recorder.setSteps(iterationOrchestrator.getSteps());
@@ -47032,6 +48084,7 @@ ${segments.dynamic}` : segments.static;
47032
48084
  yield* eventTranslator.drainPending();
47033
48085
  yield* resultAssembler.handleError(err, rootSpan);
47034
48086
  } finally {
48087
+ await deferredSandbox?.cancel();
47035
48088
  yield* releaseTurnResources({
47036
48089
  ctx,
47037
48090
  eventTranslator,
@@ -50106,7 +51159,7 @@ var LocalExecutionContext = class extends BaseExecutionContext {
50106
51159
  };
50107
51160
 
50108
51161
  // ../sdk/dist/turn/workspace-fingerprint.js
50109
- import { createHash as createHash16 } from "node:crypto";
51162
+ import { createHash as createHash17 } from "node:crypto";
50110
51163
  import { lstat as lstat4, readFile as readFile11, readlink } from "node:fs/promises";
50111
51164
  import { join as join20 } from "node:path";
50112
51165
  var NODE_FS = { lstat: lstat4, readlink, readFile: readFile11 };
@@ -50122,7 +51175,7 @@ async function untrackedEntry(cwd, rel, fs) {
50122
51175
  if (!stats.isFile())
50123
51176
  return `? ${rel}`;
50124
51177
  const body = await fs.readFile(abs);
50125
- return `F ${rel}\0${createHash16("sha256").update(body).digest("hex")}`;
51178
+ return `F ${rel}\0${createHash17("sha256").update(body).digest("hex")}`;
50126
51179
  } catch {
50127
51180
  return null;
50128
51181
  }
@@ -50167,7 +51220,7 @@ async function fingerprintWorkspace(options) {
50167
51220
  return null;
50168
51221
  parts.push(entry);
50169
51222
  }
50170
- const hash2 = createHash16("sha256");
51223
+ const hash2 = createHash17("sha256");
50171
51224
  for (const part2 of parts)
50172
51225
  hash2.update(`${Buffer.byteLength(part2, "utf8")}:${part2}`);
50173
51226
  return hash2.digest("hex");
@@ -50314,7 +51367,7 @@ Check the execution problem and any partial effects before retrying. Do not clai
50314
51367
  __name(createCommandGate, "createCommandGate");
50315
51368
 
50316
51369
  // ../sdk/dist/turn/json-claim-verifier.js
50317
- import { createHash as createHash17, randomUUID as randomUUID3 } from "node:crypto";
51370
+ import { createHash as createHash18, randomUUID as randomUUID3 } from "node:crypto";
50318
51371
  import { performance as performance2 } from "node:perf_hooks";
50319
51372
  function scalar(value) {
50320
51373
  return value === null || typeof value === "boolean" || typeof value === "string" && value.length <= 2e3 || typeof value === "number" && Number.isSafeInteger(value);
@@ -50447,7 +51500,7 @@ function createJsonClaimVerifier(options) {
50447
51500
  requestId: request.requestId,
50448
51501
  observedAt: observation.observedAt,
50449
51502
  bytes: bytes.byteLength,
50450
- sha256: createHash17("sha256").update(bytes).digest("hex")
51503
+ sha256: createHash18("sha256").update(bytes).digest("hex")
50451
51504
  });
50452
51505
  }
50453
51506
  ensureActive();
@@ -51363,7 +52416,7 @@ var DiskTaskStore = class {
51363
52416
  };
51364
52417
 
51365
52418
  // ../sdk/dist/store/memory/markdown.js
51366
- import { createHash as createHash19 } from "node:crypto";
52419
+ import { createHash as createHash20 } from "node:crypto";
51367
52420
  import { lstat as lstat6, mkdir as mkdir13, readFile as readFile14, readdir as readdir8, realpath as realpath5, rename as rename6, unlink as unlink11 } from "node:fs/promises";
51368
52421
  import { dirname as dirname14, join as join24, resolve as resolve10 } from "node:path";
51369
52422
 
@@ -51664,7 +52717,7 @@ async function acquireMemoryOperationLock(path2, timeoutMs) {
51664
52717
  __name(acquireMemoryOperationLock, "acquireMemoryOperationLock");
51665
52718
 
51666
52719
  // ../sdk/dist/store/memory/revision.js
51667
- import { createHash as createHash18 } from "node:crypto";
52720
+ import { createHash as createHash19 } from "node:crypto";
51668
52721
  var MemoryRevisionUnavailableError = class extends Error {
51669
52722
  static {
51670
52723
  __name(this, "MemoryRevisionUnavailableError");
@@ -51770,7 +52823,7 @@ function canonicalRecord(record3) {
51770
52823
  }
51771
52824
  __name(canonicalRecord, "canonicalRecord");
51772
52825
  function memoryRevision(record3) {
51773
- return `m2:${createHash18("sha256").update(canonicalRecord(record3)).digest("hex")}`;
52826
+ return `m2:${createHash19("sha256").update(canonicalRecord(record3)).digest("hex")}`;
51774
52827
  }
51775
52828
  __name(memoryRevision, "memoryRevision");
51776
52829
  var MemoryRevisionConflictError = class extends NamzuError {
@@ -51819,7 +52872,7 @@ function invalidFile(file, reason2, cause) {
51819
52872
  }
51820
52873
  __name(invalidFile, "invalidFile");
51821
52874
  function derivedMemoryId(name2) {
51822
- const hex2 = createHash19("sha256").update(`namzu-memory-name:${name2}`).digest("hex");
52875
+ const hex2 = createHash20("sha256").update(`namzu-memory-name:${name2}`).digest("hex");
51823
52876
  const variant = (Number.parseInt(hex2[16] ?? "0", 16) & 3 | 8).toString(16);
51824
52877
  return `${hex2.slice(0, 8)}-${hex2.slice(8, 12)}-8${hex2.slice(13, 16)}-${variant}${hex2.slice(17, 20)}-${hex2.slice(20, 32)}`;
51825
52878
  }
@@ -57295,7 +58348,7 @@ async function resolveMcpEra(input) {
57295
58348
  __name(resolveMcpEra, "resolveMcpEra");
57296
58349
 
57297
58350
  // ../sdk/dist/version.js
57298
- var VERSION2 = "52.0.0";
58351
+ var VERSION2 = "52.1.0";
57299
58352
 
57300
58353
  // ../sdk/dist/connector/mcp/client.js
57301
58354
  var MAX_LIST_PAGES = 100;
@@ -58621,7 +59674,7 @@ var MCPClient = class {
58621
59674
  };
58622
59675
 
58623
59676
  // ../sdk/dist/connector/mcp/policy.js
58624
- import { createHash as createHash20 } from "node:crypto";
59677
+ import { createHash as createHash21 } from "node:crypto";
58625
59678
  function applyToolPolicy(tools, policy) {
58626
59679
  return applyNamePolicy(tools, policy);
58627
59680
  }
@@ -58661,7 +59714,7 @@ function toolsHash(tools) {
58661
59714
  // fingerprint built to catch exactly that rug-pull saw nothing.
58662
59715
  annotations: stableStringify2(tool.annotations)
58663
59716
  }));
58664
- return createHash20("sha256").update(JSON.stringify(canonical2)).digest("hex");
59717
+ return createHash21("sha256").update(JSON.stringify(canonical2)).digest("hex");
58665
59718
  }
58666
59719
  __name(toolsHash, "toolsHash");
58667
59720
  function diffTools(before, after) {
@@ -58947,7 +60000,7 @@ function mcpPromptToToolDefinition(prompt, client, serverName) {
58947
60000
  __name(mcpPromptToToolDefinition, "mcpPromptToToolDefinition");
58948
60001
 
58949
60002
  // ../sdk/dist/connector/mcp/mcp-toolset.js
58950
- import { createHash as createHash21 } from "node:crypto";
60003
+ import { createHash as createHash22 } from "node:crypto";
58951
60004
 
58952
60005
  // ../sdk/dist/connector/mcp/reconnect.js
58953
60006
  var DEFAULTS = {
@@ -59074,7 +60127,7 @@ function mcpToolsetName(serverName, ...segments) {
59074
60127
  const full = ["mcp", serverName, ...segments].join("__");
59075
60128
  if (full.length <= MCP_TOOLSET_NAME_MAX_LENGTH)
59076
60129
  return full;
59077
- const hash2 = createHash21("sha256").update(full).digest("hex").slice(0, 8);
60130
+ const hash2 = createHash22("sha256").update(full).digest("hex").slice(0, 8);
59078
60131
  const suffix = `_${hash2}`;
59079
60132
  return `${full.slice(0, MCP_TOOLSET_NAME_MAX_LENGTH - suffix.length)}${suffix}`;
59080
60133
  }
@@ -60469,7 +61522,7 @@ var CODING_AGENT_HYPERMODE_DOCTRINE = `### Hypermode
60469
61522
  This session has hypermode on: treat delegation through \`Agent\` as the default for substantive work, not the exception. Before doing multi-step work yourself, ask whether an independent piece of it \u2014 a lookup, a draft, a check \u2014 could run as its own delegation, and prefer delegating it when the answer is yes. This changes only how eagerly you reach for \`Agent\` on work you would otherwise do inline; it does not mount a roster or start any delegation by itself. Agents in the same phase are launched in the same response, each with \`run_in_background: true\` when you mean to wait for them together; a phase is never started one agent at a time.`;
60470
61523
 
60471
61524
  // ../sdk/dist/manager/resident/learning.js
60472
- import { createHash as createHash22 } from "node:crypto";
61525
+ import { createHash as createHash23 } from "node:crypto";
60473
61526
  var label = external_exports.string().trim().min(1).max(256);
60474
61527
  var name = external_exports.string().regex(/^[a-z0-9][a-z0-9_-]{0,63}$/);
60475
61528
  var digest3 = external_exports.string().regex(/^[a-f0-9]{64}$/);
@@ -60622,7 +61675,7 @@ function reviseResidentProfile(current, input) {
60622
61675
  __name(reviseResidentProfile, "reviseResidentProfile");
60623
61676
  function hashResidentSkill(input) {
60624
61677
  const candidate = candidateSchema.parse(input);
60625
- return createHash22("sha256").update(JSON.stringify([
61678
+ return createHash23("sha256").update(JSON.stringify([
60626
61679
  candidate.name,
60627
61680
  candidate.description,
60628
61681
  candidate.body,
@@ -60662,13 +61715,13 @@ function promoteResidentSkill(current, input, evaluation, inputEvidence) {
60662
61715
  verification: {
60663
61716
  baselineHash,
60664
61717
  candidateHash: hash2,
60665
- evidenceDigest: createHash22("sha256").update(JSON.stringify({ ...evaluation, protection })).digest("hex"),
61718
+ evidenceDigest: createHash23("sha256").update(JSON.stringify({ ...evaluation, protection })).digest("hex"),
60666
61719
  verificationTasks: review.verification.tasks.length,
60667
61720
  confirmationTasks: review.confirmation?.tasks.length ?? 0,
60668
61721
  protection: {
60669
61722
  verificationTasks: protection.verification.length,
60670
61723
  confirmationTasks: protection.confirmation.length,
60671
- planDigest: createHash22("sha256").update(JSON.stringify(protection)).digest("hex")
61724
+ planDigest: createHash23("sha256").update(JSON.stringify(protection)).digest("hex")
60672
61725
  }
60673
61726
  }
60674
61727
  };
@@ -61365,7 +62418,7 @@ function cancelResponseBody(response, reason2) {
61365
62418
  __name(cancelResponseBody, "cancelResponseBody");
61366
62419
 
61367
62420
  // ../sdk/dist/manager/resident/store.js
61368
- import { createHash as createHash23, randomUUID as randomUUID6 } from "node:crypto";
62421
+ import { createHash as createHash24, randomUUID as randomUUID6 } from "node:crypto";
61369
62422
  var text5 = external_exports.string().trim().min(1).max(8e3);
61370
62423
  var time = external_exports.number().int().nonnegative().safe();
61371
62424
  var MAX_WAKE_EVIDENCE_CHARS = 16e3;
@@ -61412,7 +62465,7 @@ var residentStateSchema = external_exports.object({
61412
62465
  });
61413
62466
  function residentKeySegment(key5) {
61414
62467
  const encoded = revisionFileSegment(key5);
61415
- return encoded.length <= 255 ? encoded : `~sha256-${createHash23("sha256").update(encoded).digest("hex")}`;
62468
+ return encoded.length <= 255 ? encoded : `~sha256-${createHash24("sha256").update(encoded).digest("hex")}`;
61416
62469
  }
61417
62470
  __name(residentKeySegment, "residentKeySegment");
61418
62471
  var ResidentConflictError = class extends Error {
@@ -62793,7 +63846,7 @@ var PAL_WORK_GUIDANCE = [
62793
63846
  ].join("\n\n");
62794
63847
 
62795
63848
  // ../sdk/dist/pals/reference-images.js
62796
- import { createHash as createHash24, randomUUID as randomUUID8 } from "node:crypto";
63849
+ import { createHash as createHash25, randomUUID as randomUUID8 } from "node:crypto";
62797
63850
  import { posix } from "node:path";
62798
63851
  var MAX_IMAGES = 8;
62799
63852
  var MAX_IMAGE_BYTES = 3 * 1024 * 1024;
@@ -62837,7 +63890,7 @@ function preparePalReferenceImages(attachments) {
62837
63890
  attachmentIndex: index + 1,
62838
63891
  mediaType: attachment.mediaType,
62839
63892
  data: attachment.data,
62840
- sha256: createHash24("sha256").update(bytes).digest("hex"),
63893
+ sha256: createHash25("sha256").update(bytes).digest("hex"),
62841
63894
  bytes: bytes.length
62842
63895
  }));
62843
63896
  }
@@ -63018,7 +64071,7 @@ __name(createPalReferenceImageTool, "createPalReferenceImageTool");
63018
64071
  import { isDeepStrictEqual as isDeepStrictEqual5 } from "node:util";
63019
64072
 
63020
64073
  // ../sdk/dist/pals/communication/schema.js
63021
- import { createHash as createHash25 } from "node:crypto";
64074
+ import { createHash as createHash26 } from "node:crypto";
63022
64075
  var id2 = external_exports.string().uuid();
63023
64076
  var sessionId3 = external_exports.custom((s) => isEntityId(s, "session"));
63024
64077
  var turnId4 = external_exports.custom((s) => isEntityId(s, "turn"));
@@ -63113,7 +64166,7 @@ function freezeCommunicationValue(value) {
63113
64166
  }
63114
64167
  __name(freezeCommunicationValue, "freezeCommunicationValue");
63115
64168
  function hash(value) {
63116
- return createHash25("sha256").update(JSON.stringify(value)).digest("hex");
64169
+ return createHash26("sha256").update(JSON.stringify(value)).digest("hex");
63117
64170
  }
63118
64171
  __name(hash, "hash");
63119
64172
  function addressTuple(value) {
@@ -63772,7 +64825,7 @@ __name(createPalOperatorMessagingTools, "createPalOperatorMessagingTools");
63772
64825
  import { posix as posix2, win32 as win322 } from "node:path";
63773
64826
 
63774
64827
  // ../sdk/dist/runtime/harness-session/journal.js
63775
- import { createHash as createHash26, randomUUID as randomUUID9 } from "node:crypto";
64828
+ import { createHash as createHash27, randomUUID as randomUUID9 } from "node:crypto";
63776
64829
  var HarnessSessionError = class extends Error {
63777
64830
  static {
63778
64831
  __name(this, "HarnessSessionError");
@@ -63792,7 +64845,7 @@ function harnessDigest(value) {
63792
64845
  return v;
63793
64846
  return Object.fromEntries(Object.entries(v).sort(([a], [b]) => a.localeCompare(b)).map(([k, entry]) => [k, canonical2(entry)]));
63794
64847
  }, "canonical");
63795
- return createHash26("sha256").update(JSON.stringify(canonical2(value))).digest("hex");
64848
+ return createHash27("sha256").update(JSON.stringify(canonical2(value))).digest("hex");
63796
64849
  }
63797
64850
  __name(harnessDigest, "harnessDigest");
63798
64851
  var HarnessJournal = class {
@@ -65648,11 +66701,11 @@ var WorkflowScriptError = class extends Error {
65648
66701
  };
65649
66702
 
65650
66703
  // ../sdk/dist/execution/workflow/journal.js
65651
- import { createHash as createHash27 } from "node:crypto";
66704
+ import { createHash as createHash28 } from "node:crypto";
65652
66705
  import { appendFile, mkdir as mkdir15, writeFile as writeFile5 } from "node:fs/promises";
65653
66706
  import { join as join28 } from "node:path";
65654
66707
  function sha2563(text9) {
65655
- return createHash27("sha256").update(text9).digest("hex");
66708
+ return createHash28("sha256").update(text9).digest("hex");
65656
66709
  }
65657
66710
  __name(sha2563, "sha256");
65658
66711
  function preview(text9, max = 500) {
@@ -76742,7 +77795,7 @@ var ResidentHost = class {
76742
77795
  };
76743
77796
 
76744
77797
  // ../sdk/dist/manager/resident/learning-cycle.js
76745
- import { createHash as createHash28, randomUUID as randomUUID12 } from "node:crypto";
77798
+ import { createHash as createHash29, randomUUID as randomUUID12 } from "node:crypto";
76746
77799
  var receiptSchema3 = external_exports.object({
76747
77800
  /** The session and turn of the execution this usage belongs to; one receipt per turn. */
76748
77801
  sessionId: external_exports.string().uuid(),
@@ -76911,7 +77964,7 @@ async function runResidentLearningCycle(options) {
76911
77964
  });
76912
77965
  await append("exploration", {
76913
77966
  observations: exploration,
76914
- digest: createHash28("sha256").update(JSON.stringify(exploration)).digest("hex")
77967
+ digest: createHash29("sha256").update(JSON.stringify(exploration)).digest("hex")
76915
77968
  }, "explore");
76916
77969
  const problem2 = resourceProblem(true);
76917
77970
  if (problem2)
@@ -76953,7 +78006,7 @@ async function runResidentLearningCycle(options) {
76953
78006
  await append("evaluation", {
76954
78007
  baselineRevision,
76955
78008
  candidateRevision,
76956
- digest: createHash28("sha256").update(JSON.stringify(batch)).digest("hex"),
78009
+ digest: createHash29("sha256").update(JSON.stringify(batch)).digest("hex"),
76957
78010
  baselineTrajectories: batch.baseline.map((t) => t.trajectoryId),
76958
78011
  candidateTrajectories: batch.candidate.map((t) => t.trajectoryId)
76959
78012
  }, name2);
@@ -77248,7 +78301,7 @@ function createResidentToolEvidenceSource(options) {
77248
78301
  __name(createResidentToolEvidenceSource, "createResidentToolEvidenceSource");
77249
78302
 
77250
78303
  // ../sdk/dist/manager/resident/learning-store.js
77251
- import { createHash as createHash29, randomUUID as randomUUID13 } from "node:crypto";
78304
+ import { createHash as createHash30, randomUUID as randomUUID13 } from "node:crypto";
77252
78305
  import { closeSync as closeSync2, existsSync as existsSync5, fsyncSync as fsyncSync2, linkSync as linkSync2, lstatSync as lstatSync4, mkdirSync as mkdirSync4, openSync as openSync2, readFileSync as readFileSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "node:fs";
77253
78306
  import { createRequire as createRequire3 } from "node:module";
77254
78307
  import { dirname as dirname19, join as join35, resolve as resolve21 } from "node:path";
@@ -77277,7 +78330,7 @@ var learningObservationSchema = learningTargetSchema.extend({
77277
78330
 
77278
78331
  // ../sdk/dist/manager/resident/learning-store.js
77279
78332
  var uuid3 = external_exports.string().uuid().transform((id3) => id3.toLowerCase());
77280
- var digest6 = /* @__PURE__ */ __name((text9) => createHash29("sha256").update(text9).digest("hex"), "digest");
78333
+ var digest6 = /* @__PURE__ */ __name((text9) => createHash30("sha256").update(text9).digest("hex"), "digest");
77281
78334
  var MAX_EVENT_BYTES = 256 * 1024;
77282
78335
  var MAX_ARTIFACT_BYTES = 8 * 1024 * 1024;
77283
78336
  var MAX_EVENTS = 4096;
@@ -77952,7 +79005,7 @@ function parsePeerAddress(address2) {
77952
79005
  __name(parsePeerAddress, "parsePeerAddress");
77953
79006
 
77954
79007
  // ../sdk/dist/peers/record.js
77955
- import { createHash as createHash30 } from "node:crypto";
79008
+ import { createHash as createHash31 } from "node:crypto";
77956
79009
 
77957
79010
  // ../sdk/dist/peers/protocol.js
77958
79011
  var PEER_PROTOCOL_VERSION = "namzu-peer/1";
@@ -78071,7 +79124,7 @@ var PeerRecordSchema = external_exports.object({
78071
79124
  }).strict();
78072
79125
  var PEER_REF_HEX_LENGTH = 6;
78073
79126
  function derivePeerRef(sessionId5) {
78074
- return createHash30("sha256").update(sessionId5, "utf8").digest("hex").slice(0, PEER_REF_HEX_LENGTH);
79127
+ return createHash31("sha256").update(sessionId5, "utf8").digest("hex").slice(0, PEER_REF_HEX_LENGTH);
78075
79128
  }
78076
79129
  __name(derivePeerRef, "derivePeerRef");
78077
79130
 
@@ -80088,10 +81141,10 @@ var DiskPalMessagePolicy = class {
80088
81141
  };
80089
81142
 
80090
81143
  // ../sdk/dist/pals/activity/source.js
80091
- import { createHash as createHash32 } from "node:crypto";
81144
+ import { createHash as createHash33 } from "node:crypto";
80092
81145
 
80093
81146
  // ../sdk/dist/pals/activity/projection.js
80094
- import { createHash as createHash31 } from "node:crypto";
81147
+ import { createHash as createHash32 } from "node:crypto";
80095
81148
  var activityId2 = external_exports.custom((value) => isEntityId(value, "activity"));
80096
81149
  var checkpointId3 = external_exports.custom((value) => isEntityId(value, "checkpoint"));
80097
81150
  var toolUseId2 = external_exports.string().min(1).max(512).regex(/^[A-Za-z0-9_.:-]+$/);
@@ -80150,7 +81203,7 @@ function projectPalActivity(entry, scopeHash) {
80150
81203
  return null;
80151
81204
  }
80152
81205
  return Object.freeze({
80153
- id: createHash31("sha256").update(JSON.stringify(["pal-activity/1", scopeHash, pointer2])).digest("hex"),
81206
+ id: createHash32("sha256").update(JSON.stringify(["pal-activity/1", scopeHash, pointer2])).digest("hex"),
80154
81207
  type: record3.type,
80155
81208
  sessionId: record3.sessionId,
80156
81209
  ..."turnId" in record3 ? { turnId: record3.turnId } : {},
@@ -80244,7 +81297,7 @@ function createPalActivitySource(options) {
80244
81297
  if (definition.id !== scope.palId || definition.revision !== scope.profileRevision)
80245
81298
  throw new PalActivityIntegrityError();
80246
81299
  const workspace = definition.workspace;
80247
- const scopeHash = createHash32("sha256").update(JSON.stringify([
81300
+ const scopeHash = createHash33("sha256").update(JSON.stringify([
80248
81301
  "pal-activity/1",
80249
81302
  scope.tenantId,
80250
81303
  scope.projectId,
@@ -81091,7 +82144,7 @@ async function publishPalActivityOnce(options, id3, input) {
81091
82144
  __name(publishPalActivityOnce, "publishPalActivityOnce");
81092
82145
 
81093
82146
  // ../sdk/dist/pals/activity/causality.js
81094
- import { createHash as createHash33 } from "node:crypto";
82147
+ import { createHash as createHash34 } from "node:crypto";
81095
82148
  import { isDeepStrictEqual as isDeepStrictEqual12 } from "node:util";
81096
82149
  var requestMarkerSchema = external_exports.object({
81097
82150
  type: external_exports.literal("request_envelope"),
@@ -81170,7 +82223,7 @@ function createPalActivityCausalityResolver(options) {
81170
82223
  const root = entries2[0]?.record;
81171
82224
  if (root?.type !== "session_started" || root.parent || root.forkedFrom || root.tenantId !== scope.tenantId || root.projectId !== scope.projectId || root.cwd !== workspace || root.origin?.protocol !== "desktop" || root.origin.externalSessionId !== JSON.stringify(["namzu-pal", scope.palId, scope.profileRevision, scope.sessionId]))
81172
82225
  unavailable3();
81173
- const scopeHash = createHash33("sha256").update(JSON.stringify([
82226
+ const scopeHash = createHash34("sha256").update(JSON.stringify([
81174
82227
  "pal-activity/1",
81175
82228
  scope.tenantId,
81176
82229
  scope.projectId,
@@ -81236,7 +82289,7 @@ function createPalActivityCausalityResolver(options) {
81236
82289
  __name(createPalActivityCausalityResolver, "createPalActivityCausalityResolver");
81237
82290
 
81238
82291
  // ../sdk/dist/tools/builtins/skill.js
81239
- import { createHash as createHash34 } from "node:crypto";
82292
+ import { createHash as createHash35 } from "node:crypto";
81240
82293
  var inputSchema6 = external_exports.object({
81241
82294
  name: external_exports.string().min(1).optional().describe("The skill to load, exactly as listed in the available-skills manifest. Omit it to list model-invocable skills."),
81242
82295
  cursor: external_exports.string().max(160).optional().describe("Opaque continuation cursor returned by an earlier call in the same mode.")
@@ -81246,7 +82299,7 @@ var LIST_CURSOR_PATTERN = /^v1\.list\.(0|[1-9][0-9]*)\.([01])\.([A-Za-z0-9_-]{43
81246
82299
  var MAX_SKILLS_PER_PAGE = 20;
81247
82300
  var OVERSIZED_CATALOG_WARNING = "Some skills were omitted because their metadata is too large for this response budget.";
81248
82301
  function snapshotDigest(snapshot) {
81249
- return createHash34("sha256").update(JSON.stringify({
82302
+ return createHash35("sha256").update(JSON.stringify({
81250
82303
  version: 1,
81251
82304
  name: snapshot.name,
81252
82305
  body: snapshot.body,
@@ -81290,7 +82343,7 @@ function activeOutputCap(maxChars) {
81290
82343
  }
81291
82344
  __name(activeOutputCap, "activeOutputCap");
81292
82345
  function listDigest(skills, maxChars) {
81293
- return createHash34("sha256").update(JSON.stringify({ version: 1, kind: "list", maxChars: maxChars ?? null, skills })).digest("base64url");
82346
+ return createHash35("sha256").update(JSON.stringify({ version: 1, kind: "list", maxChars: maxChars ?? null, skills })).digest("base64url");
81294
82347
  }
81295
82348
  __name(listDigest, "listDigest");
81296
82349
  function serializeListPage(page) {
@@ -81899,7 +82952,7 @@ var webGuidanceContribution = {
81899
82952
  };
81900
82953
 
81901
82954
  // ../sdk/dist/tools/builtins/view-image.js
81902
- import { createHash as createHash35 } from "node:crypto";
82955
+ import { createHash as createHash36 } from "node:crypto";
81903
82956
  import { open as open12 } from "node:fs/promises";
81904
82957
  import { inflateSync } from "node:zlib";
81905
82958
 
@@ -82430,7 +83483,7 @@ ${validation === "container" ? "The complete container and dimensions were valid
82430
83483
  width: image.width,
82431
83484
  height: image.height,
82432
83485
  sourceBytes: artifact.bytes.length,
82433
- sha256: createHash35("sha256").update(artifact.bytes).digest("hex"),
83486
+ sha256: createHash36("sha256").update(artifact.bytes).digest("hex"),
82434
83487
  validation
82435
83488
  }
82436
83489
  };
@@ -82595,10 +83648,14 @@ var DEFAULT_MAX_BATCH_ACTIONS = 20;
82595
83648
  var DEFAULT_MAX_WAIT_MS = 1e4;
82596
83649
  var MAX_LISTED_WINDOWS = 50;
82597
83650
  var MAX_UI_SNAPSHOT_CHARS = 14e3;
82598
- function computerUseUnavailableReason(provider) {
82599
- if (resolveProviderCapabilities(provider).supportsToolResultImages)
82600
- return void 0;
82601
- return `The ${provider.id} provider cannot return images in tool results, so the model would never see a screenshot. Use a provider that can (for example Anthropic, Codex or Google) for computer use.`;
83651
+ function computerUseUnavailableReason(provider, model) {
83652
+ if (!resolveProviderCapabilities(provider).supportsToolResultImages) {
83653
+ return `The ${provider.id} provider cannot return images in tool results, so the model would never see a screenshot. Use a provider that can (for example Anthropic, Codex or Google) for computer use.`;
83654
+ }
83655
+ if (model !== void 0 && !modelReadsImages(provider, model)) {
83656
+ return `The model ${model} cannot read images, so it would never see a screenshot. Use a model that reads images for computer use.`;
83657
+ }
83658
+ return void 0;
82602
83659
  }
82603
83660
  __name(computerUseUnavailableReason, "computerUseUnavailableReason");
82604
83661
  var pointSchema = external_exports.object({
@@ -88617,6 +89674,7 @@ export {
88617
89674
  InMemorySessionLog,
88618
89675
  PromptContributionRegistry,
88619
89676
  resolveProviderCapabilities,
89677
+ modelReadsImages,
88620
89678
  SearchToolsTool,
88621
89679
  isTerminalTaskStatus,
88622
89680
  selectTaskContext,
@@ -88649,6 +89707,7 @@ export {
88649
89707
  isReviewExempt,
88650
89708
  batchNeedsReview,
88651
89709
  createReviewHandler,
89710
+ isImageInputRefusalMessage,
88652
89711
  withProviderFallback,
88653
89712
  buildProbeContext,
88654
89713
  probe,
@@ -88825,4 +89884,4 @@ export {
88825
89884
  buildResidentToolEvidenceTools,
88826
89885
  createPalMessagingTools
88827
89886
  };
88828
- //# sourceMappingURL=chunk-5J3T7DNL.js.map
89887
+ //# sourceMappingURL=chunk-FLUVTAXY.js.map