chainlesschain 0.166.97 → 0.166.99

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 (188) hide show
  1. package/README.md +20 -23
  2. package/package.json +3 -3
  3. package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
  4. package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
  5. package/src/assets/web-panel/assets/{AIOps-BB9kKNVw.js → AIOps-BUgaCgVU.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-DTg-lWE0.js → ActionButton-b0MpUSSZ.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-BWUZ0Tpc.js → Analytics-hbXTvHqO.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-Dj8WDnCf.js → AppLayout-CLQoAVu4.js} +5 -5
  9. package/src/assets/web-panel/assets/{Artifacts-x8NiiPTg.js → Artifacts-ytHzl2L2.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-q7otRAqO.js → Audit-BuhkLm0C.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-f6qlO2au.js → BackgroundAgents-CS81hxZV.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-BbuX9qQS.js → Backup-DzR-_Qvi.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-amgV-Y0y.js → BaseInput-r8Ku_lYw.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-CZW3DW7j.js → Chat-C3Uxtoaa.js} +5 -5
  15. package/src/assets/web-panel/assets/ChatBubbleRenderer-RvblDu77.js +1 -0
  16. package/src/assets/web-panel/assets/{Checkbox-DXHXC52i.js → Checkbox-BnG2P5yc.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-DQh47r4e.js → Codegen-BdgU6HZy.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-lBOOXCD7.js → Col-DT8t9wmf.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-BNFPnBu9.js → Community-ChkxR5oe.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-7MOWfBGb.js → Compact-DIwLeTk3.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-x0UA-rxk.js → Compliance-CAqzGLvW.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-C_eLfk_Q.js → Cowork-Bb3jejMG.js} +2 -2
  23. package/src/assets/web-panel/assets/{Cron-BP2-_Fja.js → Cron-BYRkZLta.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-Dn-e1217.js → Crosschain-BD6z227t.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-D_jverif.js → DID-DA3G5Wgo.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-BysweBms.js → Dashboard-yaZePHOu.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-osJi0Pci.js → Dropdown-BqY5MBx2.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-C72k1SKQ.js → EmailListRenderer-cIWwOgHm.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-CAtA1F9s.js → EvolutionSettings-zvV6ymca.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-Bi0luzvO.js → FamilyGuardDashboard-CAmh1U2b.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-CIwntDLI.js → Federation-5qd2LCg8.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-DRfwhPW-.js → FormItemContext-Bdkj1sRJ.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-COJTzZ61.js → GenericCardRenderer-B-gWN2P3.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-CwsR46lj.js → Git-BEMh_NGd.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-B1U-u9BN.js → Governance-qLGvA2Hw.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-vPsdYTS_.js → Inference-DblBwYuW.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-CVDRZM5h.js → KnowledgeGraph-BISegVD_.js} +1 -1
  38. package/src/assets/web-panel/assets/Logs-BD2UR7kE.js +2 -0
  39. package/src/assets/web-panel/assets/MarkdownRenderer-B-TlDCmr.js +1 -0
  40. package/src/assets/web-panel/assets/{Marketplace-CtxYHchd.js → Marketplace-CHKXMOkH.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-BkfCbpAk.js → McpTools-B5G1elqd.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-COp-8Z20.js → Memory-O5Ib0uTR.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-7fX-n_xn.js → MobileBridge-BaGYL7rT.js} +1 -1
  44. package/src/assets/web-panel/assets/MobileProjects-Dsctbob8.js +1 -0
  45. package/src/assets/web-panel/assets/{Mtc-CLXFZ5dV.js → Mtc-CNjJ97jg.js} +5 -5
  46. package/src/assets/web-panel/assets/{MtcAudit-yJ4eP1wB.js → MtcAudit-DjBN-Wqz.js} +5 -5
  47. package/src/assets/web-panel/assets/{Multisig-Cwb_qTh0.js → Multisig-B850R9lO.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-CkuojSSJ.js → NLProgramming-Bn8sbFfV.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-ju-QtUhJ.js → Notes-BpLmMp3Q.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-DjryXIC3.js → NotificationSettings-Dbk97rjb.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-B4KNF8xr.js → OrderTableRenderer-BOBX_I72.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-6-EtcVaO.js → Organization-B45DpOuE.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-BKja8nqr.js → Overflow-DmKH7eer.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-BX20f9uL.js → P2P-CC4FaXTl.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-C9zwOEUo.js → PdhVaultBrowser-C2SgP4PI.js} +3 -3
  56. package/src/assets/web-panel/assets/{Permissions-YQjQVrfE.js → Permissions-BQB4QFj_.js} +3 -3
  57. package/src/assets/web-panel/assets/{PersonalDataHub-yZYclXxq.js → PersonalDataHub-Dy6GGpn4.js} +3 -3
  58. package/src/assets/web-panel/assets/{Pipeline-ChZCCXAI.js → Pipeline-B9HB5pRc.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-Ds7R-a0H.js → Privacy-D7pOmg-p.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-B3qz_xab.js → ProjectInit-DglBqvec.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-BlwNctdF.js → ProjectSettings-Bho22znM.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-BxtYpNl7.js → Projects-C0bSuM8U.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-BE_1SS_-.js → Providers-BgAgo1Yr.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-CMQ25oLb.js → QrScannerModal-C2fBjCC8.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-DQRFLDeP.js → QuickAsk-C8MiF-rk.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-ChVra4Pk.js → Recommend-D_TzHdQf.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-9vPBIowJ.js → RemoteSession-BHO7b6xE.js} +2 -2
  68. package/src/assets/web-panel/assets/{Reputation-MdbWbyQQ.js → Reputation-BPxNmNhD.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-JLcBncLR.js → Row-fwhot5Bk.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-CnMXnpFv.js → RssFeed-CZbD1B-5.js} +2 -2
  71. package/src/assets/web-panel/assets/{Search-Cf5ISVUe.js → Search-BRs6YpAE.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-CywFo2EM.js → Security-CB344tKC.js} +4 -4
  73. package/src/assets/web-panel/assets/{Services-CLYnSCG3.js → Services-Beo-7fEl.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-BtbhOlo1.js → Skeleton-CDXx96vD.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-DPeqcIo2.js → Skills-b-mQTJK4.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-BRb4SqDn.js → Sla-BvjP-IS9.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-0Wuxts-7.js → SpeechSettings-C6wsV-cO.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-BXtsOjXL.js → SyncSettings-BQZoko-e.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-D455Wfhx.js → Tasks-6Z0rJJVO.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-LGc4O0fj.js → Templates-Cc9IXtEQ.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-DA--0GFz.js → Tenant-BLc7AjOI.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-DQsA0xCq.js → Terminal-CUN49v85.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-VH8AuSLp.js → TimelineRenderer-CX-SksHN.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-B8RyzFRN.js → Tokens-Btrm0-rK.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-CA7lVVEf.js → Trigger-CIboUvKe.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-wUoRRLg9.js → Trust-Rv9jEs5v.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-ByoT_alW.js → UkeySign-B_xomdD5.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-D9fgAxJV.js → VideoEditing-CrvWeMow.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-CRkTndvj.js → Wallet-BjvWgk_7.js} +3 -3
  90. package/src/assets/web-panel/assets/{WebAuthn-VwmHOxJK.js → WebAuthn-CwfpFw92.js} +3 -3
  91. package/src/assets/web-panel/assets/{WorkflowEditor-Z0bPZc2O.js → WorkflowEditor-Dkk2QsOe.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-CfX_5qUm.js → chat-Dah1DVes.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-BK7mXUnR.js → colors-JEpgQ10k.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-Uq755CeO.js → compact-item--DuG_cxf.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-DWXq8Qnk.js → createContext-BJ_GZvon.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-B6kQEceX.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-BXgy5JZA.js → hasIn-yZRLDmWK.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-LsBPnXHh.js → index-1QZASeW1.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-DSb7SKp5.js → index-9L3Pg2tc.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-H13lvPme.js → index-BKl40wrO.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-TDPkVyse.js → index-BM7xJKGD.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CRLOeoFE.js → index-BUjyj7qR.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-JX7mXB5a.js → index-BWkKE8Oj.js} +3 -3
  104. package/src/assets/web-panel/assets/{index-VPLA-GO7.js → index-Bdg_nWD1.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-Bt3tjvj-.js → index-C56b8e9s.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-C3VnhfYU.js → index-C6ohEAEV.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DuhlVXh4.js → index-C8nXkCMf.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BZD1My0S.js → index-CFj7ylAJ.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-BxSClhg5.js → index-CJLz3SpM.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CGy7b2rd.js → index-CQedFuDw.js} +1 -1
  111. package/src/assets/web-panel/assets/index-CSeiH6HA.js +1 -0
  112. package/src/assets/web-panel/assets/index-CayGTz6d.js +1 -0
  113. package/src/assets/web-panel/assets/{index-CqJw5WsH.js → index-CjuD8smQ.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-9XsaovMH.js → index-Cmr0AzcK.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-Dg9P9EDV.js → index-CxB49Mow.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-QXKuGlOS.js → index-D6Le2m3d.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CarQiRSA.js → index-DFJbJ8rs.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BRQSkXde.js → index-DQ4Fch3e.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-C8e4SYX4.js → index-DZBesaCN.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Ait-_UUh.js → index-DaDLWIWo.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DbjUfyVq.js → index-DbMGGcpZ.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-p3BlIre2.js → index-DddwZCT9.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DdwC1i3O.js → index-DemMuw7n.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-_I4nSJFc.js → index-DhX48E81.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-wYTro42F.js → index-Dq-8PFhL.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-XdoslBhl.js → index-DroaQypF.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-DiVH_NiY.js → index-DxnkldGo.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CfYb8FjC.js → index-IjOa5lYn.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-B09haI0M.js → index-L9CFyRIi.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-Y77S-ZC0.js → index-VIgVth92.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-D4yvdQCj.js → index-asia_JPc.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-VrR8eMCk.js → index-cHx5KzUt.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-D63nsr0a.js → index-kZE-K3ZO.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-Ct41B4y4.js → index-o2qO_dYf.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-CUR7dnMg.js → index-rkvSOceQ.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-D-8lN1rG.js → index-vdTrEOj7.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-DTuF67Yy.js → initDefaultProps-anKyyjGc.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-DZasLgsl.js → motion-Cqp0nx5A.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-pPR4O1Du.js → move-Ca3mgkM2.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-Dc7fidhm.js → mtc-parser-BmwuhJ3z.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-CZ1IcubN.js → omit-C9Mf05WJ.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-BMtJilhr.js → pickAttrs-2PbxB9Ds.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-D0EXaZA7.js → placementArrow-CTVbOFHt.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-HftdThc5.js → responsiveObserve-Nrm8Vbmr.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-CT1JEPWV.js → slide-Dh4r1zqR.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-rwE-IPZB.js → statusUtils-vzNoQL-r.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-B2B8XHVq.js → styleChecker-BXpGfNkI.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-TXNvIFVa.js → useFlexGapSupport-CVWBRdhs.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-BcWgJKvf.js → useFs-BJWMLffI.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-DWBDnOSR.js → usePersonalDataHub-CWCe5VHG.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-Cf_LjUuu.js → vnode-D-NBEb8m.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-DM2Bfuyl.js → zoom-C0mnhfGf.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/commands/eval.js +79 -3
  155. package/src/commands/llm.js +40 -5
  156. package/src/data/changelog.json +26 -0
  157. package/src/lib/context-memory-kernel/message-adapter.js +41 -24
  158. package/src/lib/context-memory-kernel/segmented-memory-port.js +18 -0
  159. package/src/lib/cost-budget.js +8 -0
  160. package/src/lib/eval/runner.js +22 -1
  161. package/src/lib/eval/verify01-contracts.js +106 -51
  162. package/src/lib/eval/verify01-execution.js +148 -166
  163. package/src/lib/eval/verify01-host-evidence.js +34 -2
  164. package/src/lib/eval/verify01-workspace.js +302 -0
  165. package/src/lib/execution-location-failure-site.js +18 -0
  166. package/src/lib/execution-location-target.js +10 -0
  167. package/src/lib/llm-connection-probe.js +147 -6
  168. package/src/lib/llm-pricing.js +61 -7
  169. package/src/lib/model-capabilities.js +10 -2
  170. package/src/lib/model-catalog-review.js +1 -0
  171. package/src/lib/model-context-catalog.js +26 -1
  172. package/src/lib/provider-http-error.js +30 -11
  173. package/src/lib/provider-options.js +38 -1
  174. package/src/lib/search-command.js +4 -1
  175. package/src/lib/stream-retry.js +14 -1
  176. package/src/lib/task-progress-tracker.js +1 -0
  177. package/src/lib/usage-pricing-context.js +100 -10
  178. package/src/runtime/agent-core.js +95 -18
  179. package/src/runtime/headless-runner.js +47 -20
  180. package/src/runtime/headless-stream.js +32 -10
  181. package/src/runtime/provider-stream-state.js +7 -0
  182. package/src/assets/web-panel/assets/ChatBubbleRenderer-DgMYDmBW.js +0 -1
  183. package/src/assets/web-panel/assets/Logs-YRslKbRL.js +0 -2
  184. package/src/assets/web-panel/assets/MarkdownRenderer-CUBuc97a.js +0 -1
  185. package/src/assets/web-panel/assets/MobileProjects-DUyTVgId.js +0 -1
  186. package/src/assets/web-panel/assets/devWarning-CbtBfs7a.js +0 -1
  187. package/src/assets/web-panel/assets/index-CicoHC0s.js +0 -1
  188. package/src/assets/web-panel/assets/index-DttyUwDx.js +0 -1
@@ -98,15 +98,17 @@ export function resolveAgentOutputBudget({
98
98
  const effectiveModel = model || "claude-sonnet-4-6";
99
99
  const { maxTokens } = mergeProviderOptions("anthropic", effectiveModel);
100
100
  const defaultCap = maxTokens || 8192;
101
+ const explicitCap =
102
+ effectiveModel === "claude-haiku-5-5" ? 128000 : defaultCap;
101
103
  const requestMaxOutputTokens =
102
- requested === null ? defaultCap : Math.min(defaultCap, requested);
104
+ requested === null ? defaultCap : Math.min(explicitCap, requested);
103
105
  return Object.freeze({
104
106
  requestMaxOutputTokens,
105
107
  plannedOutputReserveTokens: requestMaxOutputTokens,
106
108
  outputReserveSource:
107
109
  requested === null
108
110
  ? "anthropic-request-default"
109
- : requested > defaultCap
111
+ : requested > explicitCap
110
112
  ? "anthropic-request-clamp"
111
113
  : "explicit-request-cap",
112
114
  });
@@ -271,6 +273,12 @@ export function resolveModelCapabilityProfile({
271
273
  runtimeVerified: false,
272
274
  ...output,
273
275
  advertisedMaxOutputTokens: documented?.advertisedMaxOutputTokens ?? null,
276
+ ...(documented?.adaptiveThinkingDefault
277
+ ? {
278
+ adaptiveThinkingDefault: true,
279
+ defaultReasoningEffort: documented.defaultReasoningEffort,
280
+ }
281
+ : {}),
274
282
  ...(documented?.reasoningEfforts
275
283
  ? { reasoningEfforts: [...documented.reasoningEfforts] }
276
284
  : {}),
@@ -92,6 +92,7 @@ export function reviewModelCatalog(review, snapshots = {}) {
92
92
  for (const field of [
93
93
  "cacheReadMultiplier",
94
94
  "cacheWriteMultiplier",
95
+ "cacheWrite1hMultiplier",
95
96
  "longContext",
96
97
  "serviceMultipliers",
97
98
  ]) {
@@ -144,13 +144,38 @@ export const DOCUMENTED_OPENAI_MODELS = Object.freeze({
144
144
  });
145
145
 
146
146
  export const DOCUMENTED_ANTHROPIC_MODELS = Object.freeze({
147
+ "claude-haiku-5-5": Object.freeze({
148
+ contextWindowTokens: 1000000,
149
+ advertisedMaxOutputTokens: 128000,
150
+ reasoningEfforts: Object.freeze(["low", "medium", "high", "xhigh", "max"]),
151
+ defaultReasoningEffort: "medium",
152
+ adaptiveThinkingDefault: true,
153
+ pricing: Object.freeze({ in: 0.1, out: 0.5 }),
154
+ pricingTerms: Object.freeze({
155
+ cacheReadMultiplier: 0.1,
156
+ cacheWriteMultiplier: 1.25,
157
+ cacheWrite1hMultiplier: 2,
158
+ longContext: Object.freeze({
159
+ threshold: 100000,
160
+ inputMultiplier: 5,
161
+ outputMultiplier: 5,
162
+ }),
163
+ serviceMultipliers: Object.freeze({ standard: 1, default: 1 }),
164
+ }),
165
+ sources: Object.freeze([
166
+ "https://platform.claude.com/docs/en/models/haiku-5-5/overview",
167
+ "https://platform.claude.com/docs/en/models/haiku-5-5/migration-guide",
168
+ "https://platform.claude.com/docs/en/about-claude/pricing",
169
+ ]),
170
+ }),
147
171
  "claude-sonnet-5-5": Object.freeze({
148
172
  contextWindowTokens: 1000000,
149
173
  advertisedMaxOutputTokens: null,
150
174
  pricing: Object.freeze({ in: 2, out: 10 }),
151
- pricingTerms: Object.freeze({ cacheReadMultiplier: 0.1 }),
175
+ pricingTerms: Object.freeze({ cacheReadMultiplier: 0.05 }),
152
176
  sources: Object.freeze([
153
177
  "https://code.claude.com/docs/en/changelog#2-1-284",
178
+ "https://platform.claude.com/docs/en/about-claude/pricing",
154
179
  ]),
155
180
  }),
156
181
  "claude-opus-5-5": Object.freeze({
@@ -3,9 +3,14 @@
3
3
  * Keep structured provider diagnostics while redacting credential-shaped text.
4
4
  */
5
5
 
6
- function safePart(value) {
6
+ function safePart(value, secrets = []) {
7
7
  if (value == null) return "";
8
- return String(value)
8
+ let text = String(value);
9
+ for (const secret of secrets) {
10
+ if (typeof secret === "string" && secret)
11
+ text = text.replaceAll(secret, "***");
12
+ }
13
+ return text
9
14
  .replace(/\s+/g, " ")
10
15
  .replace(/\b(Bearer\s+)[A-Za-z0-9._~+/-]+=*\b/gi, "$1***")
11
16
  .replace(/\bsk-[A-Za-z0-9_-]{8,}\b/gi, "sk-***")
@@ -13,21 +18,24 @@ function safePart(value) {
13
18
  .slice(0, 400);
14
19
  }
15
20
 
16
- function errorDetail(payload) {
21
+ function errorDetail(payload, secrets) {
17
22
  if (payload == null) return { code: "", message: "" };
18
23
  const raw =
19
24
  typeof payload === "object" && payload.error != null
20
25
  ? payload.error
21
26
  : payload;
22
27
  if (typeof raw === "string") {
23
- return { code: "", message: safePart(raw) };
28
+ return { code: "", message: safePart(raw, secrets) };
24
29
  }
25
30
  if (!raw || typeof raw !== "object") {
26
- return { code: "", message: safePart(raw) };
31
+ return { code: "", message: safePart(raw, secrets) };
27
32
  }
28
33
  return {
29
- code: safePart(raw.code || raw.type),
30
- message: safePart(raw.message || raw.error_description || raw.detail),
34
+ code: safePart(raw.code || raw.type, secrets),
35
+ message: safePart(
36
+ raw.message || raw.error_description || raw.detail,
37
+ secrets,
38
+ ),
31
39
  };
32
40
  }
33
41
 
@@ -36,9 +44,14 @@ function errorDetail(payload) {
36
44
  * accounts and model-access denials. Preserve the safe code/message so clients
37
45
  * can show the real corrective action.
38
46
  */
39
- export function formatProviderHttpError(provider, status, payload = null) {
47
+ export function formatProviderHttpError(
48
+ provider,
49
+ status,
50
+ payload = null,
51
+ { secrets = [] } = {},
52
+ ) {
40
53
  const base = `${provider} API error: HTTP ${status}`;
41
- const detail = errorDetail(payload);
54
+ const detail = errorDetail(payload, secrets);
42
55
  const detailText = [detail.code, detail.message].filter(Boolean).join(": ");
43
56
  const detailSentence = detailText.replace(/[.!?]+$/, "");
44
57
  const classified = `${detail.code} ${detail.message}`.toLowerCase();
@@ -76,7 +89,11 @@ export function formatProviderHttpError(provider, status, payload = null) {
76
89
  return detailSentence ? `${base} — ${detailSentence}` : base;
77
90
  }
78
91
 
79
- export async function formatProviderResponseError(provider, response) {
92
+ export async function formatProviderResponseError(
93
+ provider,
94
+ response,
95
+ { secrets = [] } = {},
96
+ ) {
80
97
  let payload = null;
81
98
  try {
82
99
  const text = await response.text();
@@ -90,5 +107,7 @@ export async function formatProviderResponseError(provider, response) {
90
107
  } catch {
91
108
  // A broken/empty body still retains the HTTP status diagnosis.
92
109
  }
93
- return formatProviderHttpError(provider, response.status, payload);
110
+ return formatProviderHttpError(provider, response.status, payload, {
111
+ secrets,
112
+ });
94
113
  }
@@ -78,7 +78,11 @@ export function inferModelOverrides(modelId) {
78
78
  return { maxTokens: 16384 };
79
79
  }
80
80
 
81
- // Claude Haiku — cheaper, smaller output by default.
81
+ if (modelId === "claude-haiku-5-5") {
82
+ return { maxTokens: 4096, temperature: undefined };
83
+ }
84
+
85
+ // Older Claude Haiku — smaller output by default.
82
86
  if (id.includes("haiku")) {
83
87
  return { maxTokens: 4096 };
84
88
  }
@@ -136,6 +140,39 @@ export function mergeProviderOptions(provider, modelId, callOverrides = {}) {
136
140
  return deepMerge(defaults, modelLayer, callOverrides || {});
137
141
  }
138
142
 
143
+ /** Exact Haiku 5.5 request contract; null leaves older model behavior intact. */
144
+ export function haiku55ThinkingParams(model, options = {}) {
145
+ if (model !== "claude-haiku-5-5") return null;
146
+ if (options.thinkingBudget != null) {
147
+ throw new TypeError(
148
+ "Haiku 5.5 supports adaptive thinking, not thinkingBudget",
149
+ );
150
+ }
151
+ const intensity = {
152
+ think: "medium",
153
+ hard: "high",
154
+ "think-hard": "high",
155
+ harder: "high",
156
+ ultra: "xhigh",
157
+ ultrathink: "xhigh",
158
+ true: "high",
159
+ };
160
+ const effort =
161
+ options.thinkingEffort ?? intensity[options.thinking] ?? "medium";
162
+ if (!["low", "medium", "high", "xhigh", "max"].includes(effort)) {
163
+ throw new TypeError(`Unsupported Haiku 5.5 reasoning effort: ${effort}`);
164
+ }
165
+ if (options.thinking === false && ["xhigh", "max"].includes(effort)) {
166
+ throw new TypeError(
167
+ "Haiku 5.5 cannot disable thinking at xhigh or max effort",
168
+ );
169
+ }
170
+ return {
171
+ thinking: { type: options.thinking === false ? "disabled" : "adaptive" },
172
+ output_config: { effort },
173
+ };
174
+ }
175
+
139
176
  // =====================================================================
140
177
  // provider-options V2 governance overlay (iter27)
141
178
  // =====================================================================
@@ -37,7 +37,10 @@ export function buildSearchCommand({
37
37
  isContent,
38
38
  platform = process.platform,
39
39
  }) {
40
- const pat = String(pattern ?? "");
40
+ if (typeof pattern !== "string" || pattern.length === 0) {
41
+ return { error: "search_files requires a non-empty string pattern" };
42
+ }
43
+ const pat = pattern;
41
44
 
42
45
  if (platform === "win32") {
43
46
  // cmd.exe has no reliable way to escape an embedded double-quote, and the
@@ -61,6 +61,20 @@ export function isRetryableStreamError(err, signal) {
61
61
  if (isAbortError(err)) return false;
62
62
  if (signal && signal.aborted) return false;
63
63
  if (!err) return false;
64
+ const msg = String(err.message || err).toLowerCase();
65
+ // A provider verdict stays terminal even when its detail mentions a timeout,
66
+ // reset or network failure. Inspect it before transport codes and wording so
67
+ // formatted HTTP diagnostics and failed Responses cannot trigger a replay.
68
+ if (
69
+ err.code === "CC_OPENAI_RESPONSES_FAILED" ||
70
+ err.cause?.code === "CC_OPENAI_RESPONSES_FAILED" ||
71
+ [err.status, err.statusCode, err.cause?.status, err.cause?.statusCode].some(
72
+ (status) => Number.isInteger(status) && status >= 400 && status <= 599,
73
+ ) ||
74
+ /\bhttp\s+[45]\d{2}\b/.test(msg)
75
+ ) {
76
+ return false;
77
+ }
64
78
  const code = String(err.code || err.cause?.code || "").toUpperCase();
65
79
  if (
66
80
  [
@@ -76,7 +90,6 @@ export function isRetryableStreamError(err, signal) {
76
90
  ) {
77
91
  return true;
78
92
  }
79
- const msg = String(err.message || err).toLowerCase();
80
93
  return /econnreset|etimedout|econnrefused|eai_again|socket hang ?up|terminated|fetch failed|network error|timed?\s*out|premature close/.test(
81
94
  msg,
82
95
  );
@@ -470,6 +470,7 @@ export class TaskProgressTracker {
470
470
  guidance:
471
471
  message +
472
472
  " For an implementation task, make the smallest justified, authorized change and validate it. " +
473
+ "If the user requested new or updated tests, actual test changes and focused validation remain required; reading tests or passing an existing baseline does not fulfill that request. Name the concrete missing fact before another read. " +
473
474
  "For a bug fix, state the observed failure, your leading root-cause hypothesis and the smallest test that can disprove it. Run that focused reproduction or diagnostic next; use its actual output to choose the next step. Do not keep reading adjacent files without naming the specific missing fact. A timeout alone does not establish that increasing the timeout is the fix. " +
474
475
  DIAGNOSTIC_WORKFLOW_GUIDANCE +
475
476
  " " +
@@ -1,11 +1,52 @@
1
1
  import {
2
2
  DOCUMENTED_OPENAI_MODELS,
3
+ DOCUMENTED_ANTHROPIC_MODELS,
3
4
  GPT6_PRICING_TERMS,
4
5
  } from "./model-context-catalog.js";
5
6
 
7
+ /** Keep TTL evidence distinct from the aggregate cache-write count. */
8
+ export function projectCacheCreationUsage(usage = {}) {
9
+ if (usage.cacheCreationInvalid === true)
10
+ return { cacheCreationInvalid: true };
11
+ if (
12
+ Object.hasOwn(usage, "cache_creation_input_tokens") &&
13
+ Object.hasOwn(usage, "cacheCreationTokens") &&
14
+ usage.cache_creation_input_tokens !== usage.cacheCreationTokens
15
+ )
16
+ return { cacheCreationInvalid: true };
17
+ const nested = usage.cache_creation;
18
+ const hasFlat =
19
+ Object.hasOwn(usage, "cacheCreation5mTokens") ||
20
+ Object.hasOwn(usage, "cacheCreation1hTokens");
21
+ if (!Object.hasOwn(usage, "cache_creation") && !hasFlat) return {};
22
+ if (
23
+ Object.hasOwn(usage, "cache_creation") &&
24
+ (nested === null || typeof nested !== "object" || Array.isArray(nested))
25
+ )
26
+ return { cacheCreationInvalid: true };
27
+ const five = nested?.ephemeral_5m_input_tokens ?? usage.cacheCreation5mTokens;
28
+ const hour = nested?.ephemeral_1h_input_tokens ?? usage.cacheCreation1hTokens;
29
+ const total = usage.cache_creation_input_tokens ?? usage.cacheCreationTokens;
30
+ if (
31
+ ![five, hour, total].every(
32
+ (value) => Number.isSafeInteger(value) && value >= 0,
33
+ ) ||
34
+ five + hour !== total ||
35
+ (hasFlat &&
36
+ nested != null &&
37
+ (five !== usage.cacheCreation5mTokens ||
38
+ hour !== usage.cacheCreation1hTokens))
39
+ ) {
40
+ return { cacheCreationInvalid: true };
41
+ }
42
+ return { cacheCreation5mTokens: five, cacheCreation1hTokens: hour };
43
+ }
44
+
6
45
  /** Only bounded, non-secret pricing labels may enter the durable usage ledger. */
7
46
  export function projectUsagePricingContext(usage = {}) {
8
- const projected = {};
47
+ const projected = projectCacheCreationUsage(usage);
48
+ if (usage.pricingContextInvalid === true)
49
+ projected.pricingContextInvalid = true;
9
50
  for (const [key, alias] of [
10
51
  ["service_tier", "serviceTier"],
11
52
  ["regional_processing", "regionalProcessing"],
@@ -31,23 +72,56 @@ export function projectUsagePricingContext(usage = {}) {
31
72
  projected[key] = value;
32
73
  }
33
74
  }
75
+ if (Object.hasOwn(usage, "inference_geo")) {
76
+ const geo = usage.inference_geo;
77
+ if (geo !== "us" && geo !== "global") {
78
+ projected.inference_geo = "unknown";
79
+ projected.pricingContextInvalid = true;
80
+ } else {
81
+ if (
82
+ Object.hasOwn(projected, "regional_processing") &&
83
+ projected.regional_processing !== (geo === "us")
84
+ ) {
85
+ throw new TypeError(
86
+ "usage inference_geo conflicts with regional processing",
87
+ );
88
+ }
89
+ projected.inference_geo = geo;
90
+ projected.regional_processing = geo === "us";
91
+ }
92
+ }
34
93
  return projected;
35
94
  }
36
95
 
37
96
  /** Preserve per-request thresholds in a bounded set of aggregate price buckets. */
38
97
  export function mergeUsagePricingBucket(entry, usage) {
39
- if (
40
- String(entry.provider).toLowerCase() !== "openai" ||
41
- !DOCUMENTED_OPENAI_MODELS[String(entry.model).toLowerCase()]?.pricing
42
- )
43
- return;
98
+ const provider = String(entry.provider).toLowerCase();
99
+ const model = String(entry.model).toLowerCase();
100
+ const terms =
101
+ provider === "openai" && DOCUMENTED_OPENAI_MODELS[model]?.pricing
102
+ ? GPT6_PRICING_TERMS
103
+ : provider === "anthropic"
104
+ ? DOCUMENTED_ANTHROPIC_MODELS[model]?.pricingTerms
105
+ : null;
106
+ if (!terms?.longContext) return;
44
107
  const metadata = projectUsagePricingContext(usage);
108
+ const pricingContextInvalid =
109
+ metadata.pricingContextInvalid === true ||
110
+ (provider === "anthropic" &&
111
+ model === "claude-haiku-5-5" &&
112
+ metadata.regional_processing == null);
45
113
  const promptTokens =
46
114
  usage.requestInputTokens ??
47
115
  usage.inputTokens +
48
116
  (usage.cacheReadTokens || 0) +
49
117
  (usage.cacheCreationTokens || 0);
50
- const long = promptTokens > GPT6_PRICING_TERMS.longContext.threshold;
118
+ const long = promptTokens > terms.longContext.threshold;
119
+ const cache = projectCacheCreationUsage(usage);
120
+ const cacheEvidence = cache.cacheCreationInvalid
121
+ ? "invalid"
122
+ : cache.cacheCreation5mTokens != null
123
+ ? "split"
124
+ : "missing";
51
125
  const serviceTier = metadata.service_tier || "standard";
52
126
  const regionalProcessing = metadata.regional_processing === true;
53
127
  entry.pricingBuckets ||= [];
@@ -55,8 +129,9 @@ export function mergeUsagePricingBucket(entry, usage) {
55
129
  (item) =>
56
130
  item.serviceTier === serviceTier &&
57
131
  item.regionalProcessing === regionalProcessing &&
58
- item.requestInputTokens > GPT6_PRICING_TERMS.longContext.threshold ===
59
- long,
132
+ (item.pricingContextInvalid === true) === pricingContextInvalid &&
133
+ (item.cacheEvidence || "missing") === cacheEvidence &&
134
+ item.requestInputTokens > terms.longContext.threshold === long,
60
135
  );
61
136
  if (!bucket) {
62
137
  bucket = {
@@ -69,6 +144,18 @@ export function mergeUsagePricingBucket(entry, usage) {
69
144
  serviceTier,
70
145
  regionalProcessing,
71
146
  requestInputTokens: promptTokens,
147
+ ...(pricingContextInvalid ? { pricingContextInvalid: true } : {}),
148
+ ...(provider === "anthropic"
149
+ ? {
150
+ cacheEvidence,
151
+ ...(cacheEvidence === "split"
152
+ ? { cacheCreation5mTokens: 0, cacheCreation1hTokens: 0 }
153
+ : {}),
154
+ ...(cacheEvidence === "invalid"
155
+ ? { cacheCreationInvalid: true }
156
+ : {}),
157
+ }
158
+ : {}),
72
159
  };
73
160
  entry.pricingBuckets.push(bucket);
74
161
  }
@@ -79,8 +166,11 @@ export function mergeUsagePricingBucket(entry, usage) {
79
166
  "cacheCreationTokens",
80
167
  "totalTokens",
81
168
  "calls",
169
+ ...(cacheEvidence === "split"
170
+ ? ["cacheCreation5mTokens", "cacheCreation1hTokens"]
171
+ : []),
82
172
  ]) {
83
- const value = usage[key] ?? (key === "calls" ? 1 : 0);
173
+ const value = cache[key] ?? usage[key] ?? (key === "calls" ? 1 : 0);
84
174
  if (
85
175
  !Number.isSafeInteger(value) ||
86
176
  value < 0 ||
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  import fs from "fs";
18
+ import { isUtf8 } from "node:buffer";
18
19
  import {
19
20
  _isNonNegativeSafeInteger,
20
21
  _providerUsageCount,
@@ -59,6 +60,8 @@ import {
59
60
  TASK_RECOVERY_TOOLS,
60
61
  } from "../lib/task-progress-tracker.js";
61
62
  import { TOOL_RECOVERY_PAUSED_CODE } from "../lib/tool-recovery-result.js";
63
+ import { haiku55ThinkingParams } from "../lib/provider-options.js";
64
+ import { projectUsagePricingContext } from "../lib/usage-pricing-context.js";
62
65
  import broker from "../lib/process-execution-broker/index.js";
63
66
  import os from "os";
64
67
  import { createHash, randomUUID } from "node:crypto";
@@ -2024,6 +2027,20 @@ function applyLiteralEdit(content, oldStr, newStr, replaceAll) {
2024
2027
  return { count, newContent };
2025
2028
  }
2026
2029
 
2030
+ // Edits derive their output from the entire existing file. A replacement
2031
+ // decoder would silently rewrite unrelated legacy or malformed bytes.
2032
+ function readUtf8ForEdit(filePath) {
2033
+ const bytes = fs.readFileSync(filePath);
2034
+ if (!isUtf8(bytes)) {
2035
+ return {
2036
+ error: "File is not valid UTF-8; text edits require valid UTF-8 bytes.",
2037
+ code: "CC_EDIT_INVALID_UTF8",
2038
+ };
2039
+ }
2040
+ // Buffer decoding preserves a valid UTF-8 BOM and literal U+FFFD characters.
2041
+ return { content: bytes.toString("utf8") };
2042
+ }
2043
+
2027
2044
  /**
2028
2045
  * Compute the content an edit tool WOULD write, without writing it — the
2029
2046
  * left/right sides for an IDE diff review. Mirrors the corresponding
@@ -2085,7 +2102,9 @@ export function computeProposedEdit(name, args = {}, cwd = process.cwd()) {
2085
2102
  }
2086
2103
  if (name === "edit_file") {
2087
2104
  if (!fs.existsSync(filePath)) return null;
2088
- const content = fs.readFileSync(filePath, "utf8");
2105
+ const decoded = readUtf8ForEdit(filePath);
2106
+ if (decoded.error) return null;
2107
+ const content = decoded.content;
2089
2108
  if (
2090
2109
  typeof args.old_string !== "string" ||
2091
2110
  args.old_string === "" ||
@@ -2113,7 +2132,9 @@ export function computeProposedEdit(name, args = {}, cwd = process.cwd()) {
2113
2132
  if (name === "edit_file_hashed") {
2114
2133
  if (!fs.existsSync(filePath)) return null;
2115
2134
  if (!args.anchor_hash || typeof args.new_line !== "string") return null;
2116
- const original = fs.readFileSync(filePath, "utf8");
2135
+ const decoded = readUtf8ForEdit(filePath);
2136
+ if (decoded.error) return null;
2137
+ const original = decoded.content;
2117
2138
  const result = replaceByHash(original, {
2118
2139
  anchorHash: args.anchor_hash,
2119
2140
  expectedLine: args.expected_line,
@@ -5835,7 +5856,9 @@ async function executeToolInner(
5835
5856
  if (!fs.existsSync(filePath)) {
5836
5857
  return attachDescriptor({ error: `Notebook not found: ${filePath}` });
5837
5858
  }
5838
- const original = fs.readFileSync(filePath, "utf8");
5859
+ const decoded = readUtf8ForEdit(filePath);
5860
+ if (decoded.error) return attachDescriptor(decoded);
5861
+ const original = decoded.content;
5839
5862
  const res = editNotebookCell(original, args);
5840
5863
  if (res.error) return attachDescriptor({ error: res.error });
5841
5864
  const wrote = writeFileVerified(filePath, res.text);
@@ -5871,7 +5894,9 @@ async function executeToolInner(
5871
5894
  }
5872
5895
  const staleEdit = _checkFileFreshness(filePath);
5873
5896
  if (staleEdit) return attachDescriptor({ error: staleEdit });
5874
- const content = fs.readFileSync(filePath, "utf8");
5897
+ const decoded = readUtf8ForEdit(filePath);
5898
+ if (decoded.error) return attachDescriptor(decoded);
5899
+ const content = decoded.content;
5875
5900
  const replaceAll = args.replace_all === true;
5876
5901
  const { count, newContent } = applyLiteralEdit(
5877
5902
  content,
@@ -5971,7 +5996,9 @@ async function executeToolInner(
5971
5996
  }
5972
5997
  const staleHashed = _checkFileFreshness(filePath);
5973
5998
  if (staleHashed) return attachDescriptor({ error: staleHashed });
5974
- const original = fs.readFileSync(filePath, "utf8");
5999
+ const decoded = readUtf8ForEdit(filePath);
6000
+ if (decoded.error) return attachDescriptor(decoded);
6001
+ const original = decoded.content;
5975
6002
  const result = replaceByHash(original, {
5976
6003
  anchorHash: args.anchor_hash,
5977
6004
  expectedLine: args.expected_line,
@@ -11962,10 +11989,16 @@ export async function chatWithTools(rawMessages, options) {
11962
11989
  messages: _toAnthropicMessages(otherMsgs),
11963
11990
  tools: anthropicTools,
11964
11991
  };
11965
- // Extended thinking — OPT-IN via options.thinking; off by default so the
11966
- // request is byte-identical to before. Model-aware (adaptive+effort on Opus
11967
- // 4.6+/Sonnet 4.6, legacy enabled+budget else; nothing on Haiku). temperature
11968
- // is never sent. RUNTIME-UNVERIFIED: no Anthropic key here to E2E the
11992
+ if (
11993
+ effModel.toLowerCase() === "claude-haiku-5-5" &&
11994
+ body.messages.at(-1)?.role === "assistant"
11995
+ ) {
11996
+ throw new TypeError("Haiku 5.5 does not support assistant prefill.");
11997
+ }
11998
+ // Legacy models retain opt-in thinking. Exact Haiku 5.5 uses its documented
11999
+ // adaptive/medium default and accepts an explicit disabled setting.
12000
+ // Sampling parameters are never sent. RUNTIME-UNVERIFIED: no Anthropic key
12001
+ // here to E2E the
11969
12002
  // thinking-block signature replay (see cli_claude_code_parity_landed memory).
11970
12003
  const thinkingParams = _anthropicThinkingParams(
11971
12004
  effModel,
@@ -12046,6 +12079,11 @@ export async function chatWithTools(rawMessages, options) {
12046
12079
  const data = await response.json();
12047
12080
  const normalized = _normalizeAnthropicResponse(data);
12048
12081
  if (_hasCompleteProviderUsage(data.usage)) {
12082
+ const cacheCreationTokens = _optionalProviderUsageCount(
12083
+ data.usage,
12084
+ "cache_creation_input_tokens",
12085
+ "cache_creation_tokens",
12086
+ );
12049
12087
  normalized.usage = {
12050
12088
  // With prompt caching, Anthropic splits input into uncached
12051
12089
  // `input_tokens` + cache read/write — capture all three so cost
@@ -12066,11 +12104,11 @@ export async function chatWithTools(rawMessages, options) {
12066
12104
  "cache_read_input_tokens",
12067
12105
  "cache_read_tokens",
12068
12106
  ),
12069
- cache_creation_input_tokens: _optionalProviderUsageCount(
12070
- data.usage,
12071
- "cache_creation_input_tokens",
12072
- "cache_creation_tokens",
12073
- ),
12107
+ cache_creation_input_tokens: cacheCreationTokens,
12108
+ ...projectUsagePricingContext({
12109
+ ...data.usage,
12110
+ cache_creation_input_tokens: cacheCreationTokens,
12111
+ }),
12074
12112
  };
12075
12113
  }
12076
12114
  return normalized;
@@ -13067,11 +13105,12 @@ export function _openAIResponsesReasoningParams(
13067
13105
 
13068
13106
  /**
13069
13107
  * Decide the Anthropic `thinking` request params for a model. Returns null
13070
- * (off) unless the caller opts in via options.thinking (true | "think" |
13071
- * "hard" | "ultra"). Model-aware per the Claude API:
13108
+ * (off) on legacy models unless the caller opts in via options.thinking
13109
+ * (true | "think" | "hard" | "ultra"). Model-aware per the Claude API:
13110
+ * - exact Haiku 5.5 → adaptive/medium by default, explicitly disableable
13072
13111
  * - Opus 4.6/4.7/4.8, Sonnet 4.6 → adaptive thinking + output_config.effort
13073
13112
  * - Sonnet 4.5 / Opus 4.0-4.5 / older → legacy enabled+budget (< max_tokens)
13074
- * - anything else (e.g. Haiku) → null (no thinking)
13113
+ * - other models, including older Haiku → null (no explicit thinking)
13075
13114
  * temperature is never added (it 400s on Opus 4.7/4.8). Note: `xhigh`/`max`
13076
13115
  * effort are Opus-tier — on Sonnet they may error; left to the caller's intent.
13077
13116
  * RUNTIME-UNVERIFIED — no Anthropic key to validate the wire shape live.
@@ -13082,9 +13121,10 @@ export function _anthropicThinkingParams(
13082
13121
  options = {},
13083
13122
  maxTokens = 8192,
13084
13123
  ) {
13124
+ const m = String(model || "").toLowerCase();
13125
+ if (m === "claude-haiku-5-5") return haiku55ThinkingParams(m, options);
13085
13126
  const want = options?.thinking;
13086
13127
  if (!want) return null; // off by default → request unchanged
13087
- const m = String(model || "").toLowerCase();
13088
13128
  const adaptive = /opus-4-(6|7|8)/.test(m) || /sonnet-4-6/.test(m);
13089
13129
  const legacy =
13090
13130
  /sonnet-4-5/.test(m) ||
@@ -15405,6 +15445,27 @@ export async function* agentLoop(messages, options) {
15405
15445
  }
15406
15446
  }
15407
15447
  const contextMemoryTrustedSystemIndexes = [];
15448
+ if (Number.isFinite(budget.limit)) {
15449
+ // consume() already charged this dispatch. The current request may still
15450
+ // act even when no further provider request remains. Rebuild this hint
15451
+ // after compaction and rejection-only turns; do not persist it in history.
15452
+ const furtherRequests = budget.remaining();
15453
+ // Keep the stable conversation prefix ahead of this changing counter.
15454
+ // The canonical planner protects the last conversational user bundle
15455
+ // even when trusted ephemeral system guidance follows it.
15456
+ callMessages = [
15457
+ ...callMessages,
15458
+ {
15459
+ role: "system",
15460
+ content:
15461
+ `Execution budget: this request plus ${furtherRequests} further model requests. ` +
15462
+ "For requested changes, reserve requests for implementation, focused validation, and repair or an accurate unfinished-work report. " +
15463
+ "Reading or an existing passing baseline does not deliver requested changes. " +
15464
+ "For research or monitoring, use the remaining requests for evidence and the requested answer; do not create files just to show activity.",
15465
+ },
15466
+ ];
15467
+ contextMemoryTrustedSystemIndexes.push(callMessages.length - 1);
15468
+ }
15408
15469
  if (prActionTask && !prInvestigationExhausted) {
15409
15470
  callMessages = [
15410
15471
  ...callMessages,
@@ -16299,11 +16360,27 @@ export async function* agentLoop(messages, options) {
16299
16360
  toolName,
16300
16361
  earlyAuthorityDenial,
16301
16362
  );
16363
+ const preExecutionDenied =
16364
+ earlyAuthorityDenial.code === TOOL_RECOVERY_PAUSED_CODE;
16365
+ if (preExecutionDenied) {
16366
+ // Declare the rejected request without an execution/ledger boundary
16367
+ // or its arguments. Consumers can pair the refusal by provider ID.
16368
+ yield {
16369
+ type: "tool-pre-execution-denied",
16370
+ tool: toolName,
16371
+ tool_use_id: call.id,
16372
+ turn_id: `${runId}:t${budget.consumed}`,
16373
+ preExecutionDenied: true,
16374
+ execution_started: false,
16375
+ };
16376
+ }
16302
16377
  yield {
16303
16378
  type: "tool-result",
16304
16379
  tool: toolName,
16305
16380
  result: earlyAuthorityDenial,
16306
16381
  error: earlyAuthorityDenial.error,
16382
+ execution_started: false,
16383
+ ...(preExecutionDenied ? { preExecutionDenied: true } : {}),
16307
16384
  tool_use_id: call.id,
16308
16385
  turn_id: `${runId}:t${budget.consumed}`,
16309
16386
  permission_decision_id: decision?.id || null,