chainlesschain 0.166.98 → 0.166.100

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 (179) hide show
  1. package/README.md +19 -23
  2. package/package.json +1 -1
  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-DCIQFtF1.js → AIOps-Cd4iUOPt.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-BxhHU3nE.js → ActionButton--ucr-zko.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-DdM_307O.js → Analytics-DbejYMWk.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-C43-kSrh.js → AppLayout-CLgKxeGw.js} +5 -5
  9. package/src/assets/web-panel/assets/{Artifacts-B2Vp2Am6.js → Artifacts-CTT5BIL5.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-s-lYUfOp.js → Audit-DP-WBWe9.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-DTE7Kzio.js → BackgroundAgents-B6VqheJk.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-9k1q4Mt6.js → Backup-VWJK5zim.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-DlpUtK5R.js → BaseInput-YGFO9RHd.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-CR9S8Rmb.js → Chat-CVfydnCd.js} +5 -5
  15. package/src/assets/web-panel/assets/ChatBubbleRenderer-BICpB-qU.js +1 -0
  16. package/src/assets/web-panel/assets/{Checkbox-DpFRu7Df.js → Checkbox-Bd5vKRMk.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-BIl72E4Y.js → Codegen-DHNgPHvg.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-91tl_err.js → Col-CA2BYQ8T.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-CswahO9-.js → Community-DnKJ-qpI.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-D9pfHmaM.js → Compact-C9BZ8t4r.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-CXSZzAO9.js → Compliance-ByyQ2FOl.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-CuT9RWTn.js → Cowork-rXTwXE_c.js} +2 -2
  23. package/src/assets/web-panel/assets/{Cron-B71aJWDV.js → Cron-BuW-HODy.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-CcUuWyx8.js → Crosschain-OudNtbYW.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-CtVVGOPL.js → DID-BQ6BxYNN.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-CV7ZCYQq.js → Dashboard-Cz5HG8tz.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-DKHxwLgE.js → Dropdown-BzclHOVv.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-Bd03UIvv.js → EmailListRenderer-CbJETFdy.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-CTrG03B_.js → EvolutionSettings-Dx_pJG3d.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DXS4bS6Q.js → FamilyGuardDashboard-6JCS1MNg.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-BODG2Szj.js → Federation-BrPkMYaf.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-D32ccUqD.js → FormItemContext-Bhc9pobs.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-ClsyrKvF.js → GenericCardRenderer-BxOh07uQ.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-DcM2yhbL.js → Git-D_idoujr.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-BhUzM87n.js → Governance-ZGfIRE-x.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-Dq1n0Ifg.js → Inference-DpAmcwbw.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-dmmPwEks.js → KnowledgeGraph-D1S1UTgP.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-CBSYrPmh.js → Logs-2sc8V5XV.js} +2 -2
  39. package/src/assets/web-panel/assets/MarkdownRenderer-575jjYE6.js +1 -0
  40. package/src/assets/web-panel/assets/{Marketplace-Cfw7XLck.js → Marketplace-0xlFUKbe.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-CNrZRy4n.js → McpTools-D25eJLGm.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-BESjTxdd.js → Memory-BLRGd9hM.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-Boyjo07i.js → MobileBridge-zpFINGzn.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-BmxmpTWz.js → MobileProjects-Cbyd-8kx.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-CBkrD0Fq.js → Mtc-DgXgUlHc.js} +2 -2
  46. package/src/assets/web-panel/assets/{MtcAudit-BA7cAK8h.js → MtcAudit-DzcL-dKH.js} +2 -2
  47. package/src/assets/web-panel/assets/{Multisig-m0RGzkKO.js → Multisig-C3OrZ6VN.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-D_TgzifU.js → NLProgramming-Bqp_vWA7.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-Dr-Yr9LL.js → Notes-Dyn45-Ht.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-DGanpkqO.js → NotificationSettings-CLjafGZr.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-D1FX50QY.js → OrderTableRenderer-Bx8wMauC.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-DRbPg-gs.js → Organization-5gr9hyLm.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-flEO37z6.js → Overflow-BRdU02hT.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-DqfqFbCW.js → P2P-DIi7fzh6.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-Cmi5a5dW.js → PdhVaultBrowser-BCbS1KpA.js} +3 -3
  56. package/src/assets/web-panel/assets/{Permissions-DBVRlvBW.js → Permissions-BjeP9VtA.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-gQqjPr9X.js → PersonalDataHub-y8PXOQUc.js} +4 -4
  58. package/src/assets/web-panel/assets/{Pipeline-6HlifUc9.js → Pipeline-B0fL5uxY.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-bm_2-Zwg.js → Privacy-C8jCDn8Z.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-BJW3isuq.js → ProjectInit-B_L6Dc6V.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-DD3yolz7.js → ProjectSettings-Bb1CYbZh.js} +2 -2
  62. package/src/assets/web-panel/assets/Projects-CUSV10Cn.js +1 -0
  63. package/src/assets/web-panel/assets/{Providers-CQA6WAK7.js → Providers-mBSTDJ0E.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-DOAwp5Xo.js → QrScannerModal-CHxgalvt.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-qeFXsAZT.js → QuickAsk-DI9KIMEV.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-zDWXwZN8.js → Recommend-B5_zW1JH.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-toe6Ip06.js → RemoteSession-BkH4bmM5.js} +3 -3
  68. package/src/assets/web-panel/assets/{Reputation-DRDi_Eqp.js → Reputation-DJrAqwAq.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-Do2UbYkf.js → Row-xZ3MAM34.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-B57C6_Sa.js → RssFeed-CCsrLLiu.js} +3 -3
  71. package/src/assets/web-panel/assets/{Search-DfDyBpe9.js → Search-CTCRKvaP.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-CulNxeAM.js → Security-D7joyfp2.js} +4 -4
  73. package/src/assets/web-panel/assets/{Services-COfAYvs4.js → Services-oqHPmTG4.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-0fn0T146.js → Skeleton-BR_32bTG.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-pPQgAhvJ.js → Skills-BoRz9mln.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-CIsRmePR.js → Sla-UAGUHZ9b.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-Bn01d-8b.js → SpeechSettings-DeP_rMgv.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-Cx_Znk7L.js → SyncSettings-CSzzMmeA.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-DvaskzpG.js → Tasks-CcqOLsLB.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-DmHCEiDO.js → Templates-cDbkGSDG.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-CqHyvnbW.js → Tenant-DmOy58cq.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-DTt3yqWL.js → Terminal-CsRZH5vr.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-BhkIxcR3.js → TimelineRenderer-BgJrk6HG.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-mhjYcBBP.js → Tokens-CCQglKDE.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-CdlMQfwX.js → Trigger-t-Gt3oBY.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-Bzovg_Gw.js → Trust-DQgu2kI0.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-ph3EuYi7.js → UkeySign-Cod2WUGj.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-Bo2B4VZE.js → VideoEditing-SGN5zaVK.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-BQTKsSUT.js → Wallet-CnLEL-LD.js} +3 -3
  90. package/src/assets/web-panel/assets/{WebAuthn-nJxsXNHV.js → WebAuthn-C2keUpD6.js} +4 -4
  91. package/src/assets/web-panel/assets/{WorkflowEditor-CjH8g2N7.js → WorkflowEditor-B1GvrwWJ.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-CkbNmnQD.js → chat-1E9_P_qY.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-BY9JcObR.js → colors-DuU6Os4q.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-Dzzq-d8n.js → compact-item-C5NfOAcM.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-DiJxxdTx.js → createContext-D4Fxz9qQ.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-zDWbYMr7.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-DaXPOw3D.js → hasIn-C6C49iFk.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-Uh9SjtgW.js → index-AO6iDCSL.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-B4Sf1AMk.js → index-B-bb-R99.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-cu1J4avY.js → index-B5lzRoHp.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DaylJfw6.js → index-BBVqlelF.js} +1 -1
  102. package/src/assets/web-panel/assets/index-BPBsZZnT.js +1 -0
  103. package/src/assets/web-panel/assets/{index-CWLpEg34.js → index-BU5mPkNX.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-LRZSVBxC.js → index-BULggEX6.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-Djeh6rAb.js → index-BVE2wCeb.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-B31oMRmK.js → index-BYg1dtne.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DSqQyS9-.js → index-BZKRZYTX.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CnLO1_yN.js → index-B_ON9La1.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Jmlk_lDX.js → index-Bk-paNL3.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BQvtlYUd.js → index-BlHkc48f.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BvgMt6Io.js → index-BmvU4Tp_.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CbOOm8I8.js → index-BsH8mFp4.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-C_OMH_FT.js → index-Bu6qMjf4.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-BycyBM6g.js → index-C2nO02uW.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BlWg1bRA.js → index-C7mh6xlu.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-i9eu2Kir.js → index-CDVwN9Sv.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DWT9-E5b.js → index-CJS6GTpv.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CqOkm6kW.js → index-CQJoh5rw.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-7YVCjSqG.js → index-CXb8gEWh.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DDnqjZa2.js → index-CXn-e3ki.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-Igq-72Ep.js → index-CpiOzt7U.js} +1 -1
  122. package/src/assets/web-panel/assets/index-CtGQDg7m.js +1 -0
  123. package/src/assets/web-panel/assets/{index-BqCHe05H.js → index-D1TXgNPA.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-D_Eoh740.js → index-DFK6PTGJ.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-EiaWq1TH.js → index-DP2DCKD-.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CVblRqUN.js → index-DPzunJER.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-Bhsxh-rH.js → index-DSypQU1h.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DbmHmeP-.js → index-DZgT7pH-.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-dC2JACyJ.js → index-Dh-vezHe.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BHeHyLRM.js → index-DpaGe-dr.js} +3 -3
  131. package/src/assets/web-panel/assets/{index-6Z6Z4UwN.js → index-HQXFl8fh.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-BGvIb1Sr.js → index-bW6vfpLH.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-DObXhPhH.js → index-cnDfwWU5.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-Dl8U-0hn.js → index-gh11zJ9h.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-CAzfu6k5.js → index-jFg3CPlQ.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-C6XSCXeb.js → index-lNmDaf3J.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-B0WuG3fa.js → initDefaultProps-3DSfnIpD.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-1r5YB22w.js → motion-DxGLmgA0.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-CvtXWA_V.js → move-DrlLG6m5.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-ChedmEE_.js → mtc-parser-BITbrJSb.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-DpEA3MP0.js → omit-D7k5vIbk.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-BWgrUZF6.js → pickAttrs-BJSvYFWo.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-BWfo_VbI.js → placementArrow-Bf4to1jA.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-CRft03Vk.js → responsiveObserve-BXzeyzTa.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-l5LeXusH.js → slide-DLzNUNdj.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-CCEC0JR-.js → statusUtils-wBBnrRm_.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-Bw5Gw_2w.js → styleChecker-BnmJzXNr.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-BAuxWB7K.js → useFlexGapSupport-DrN8MrJb.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-CxUP97Cw.js → useFs-dnkYGkjY.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-BJDjT4Sy.js → usePersonalDataHub-k_xkv7-k.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-BcCsFzIs.js → vnode-B-v8PXpK.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-MLmG09h6.js → zoom-Coue8wAK.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/data/changelog.json +26 -0
  155. package/src/harness/worktree-isolator.js +20 -8
  156. package/src/lib/chat-core.js +57 -25
  157. package/src/lib/cost-budget.js +8 -0
  158. package/src/lib/eval/verify01-execution-window.js +70 -0
  159. package/src/lib/eval/verify01-execution.js +9 -1
  160. package/src/lib/eval/verify01-host-capture.js +6 -2
  161. package/src/lib/llm-pricing.js +61 -7
  162. package/src/lib/model-capabilities.js +10 -2
  163. package/src/lib/model-catalog-review.js +1 -0
  164. package/src/lib/model-context-catalog.js +26 -1
  165. package/src/lib/provider-http-error.js +16 -0
  166. package/src/lib/provider-options.js +38 -1
  167. package/src/lib/search-command.js +4 -1
  168. package/src/lib/stream-retry.js +209 -2
  169. package/src/lib/usage-pricing-context.js +100 -10
  170. package/src/runtime/agent-core.js +170 -38
  171. package/src/runtime/headless-runner.js +17 -0
  172. package/src/runtime/headless-stream.js +17 -0
  173. package/src/runtime/provider-stream-state.js +7 -0
  174. package/src/assets/web-panel/assets/ChatBubbleRenderer-Xtgfw3-c.js +0 -1
  175. package/src/assets/web-panel/assets/MarkdownRenderer-CRoDI77y.js +0 -1
  176. package/src/assets/web-panel/assets/Projects-BF3GtWny.js +0 -1
  177. package/src/assets/web-panel/assets/devWarning-D502_Z3w.js +0 -1
  178. package/src/assets/web-panel/assets/index-BrQ4nI4W.js +0 -1
  179. package/src/assets/web-panel/assets/index-C0_sewGO.js +0 -1
@@ -216,13 +216,18 @@ export function normalizePricingTerms(value) {
216
216
  const allowed = new Set([
217
217
  "cacheReadMultiplier",
218
218
  "cacheWriteMultiplier",
219
+ "cacheWrite1hMultiplier",
219
220
  "longContext",
220
221
  "serviceMultipliers",
221
222
  ]);
222
223
  if (!object(value) || Reflect.ownKeys(value).some((key) => !allowed.has(key)))
223
224
  fail();
224
225
  const result = {};
225
- for (const key of ["cacheReadMultiplier", "cacheWriteMultiplier"]) {
226
+ for (const key of [
227
+ "cacheReadMultiplier",
228
+ "cacheWriteMultiplier",
229
+ "cacheWrite1hMultiplier",
230
+ ]) {
226
231
  if (!Object.hasOwn(value, key)) continue;
227
232
  if (!finite(value[key])) fail();
228
233
  result[key] = value[key];
@@ -289,8 +294,15 @@ export function lookupRate(provider, model, table = PRICE_TABLE) {
289
294
  // An unrecognized new generation must not inherit an older family price.
290
295
  // Explicit operator overrides remain authoritative.
291
296
  if (
292
- ["opus", "sonnet"].includes(e.match) &&
293
- Number(/^claude-(?:opus|sonnet)-(\d+)(?:[.-]|$)/u.exec(m)?.[1]) >= 5 &&
297
+ e.match === "haiku" &&
298
+ /(?:^|[.:/])(?:claude-)?haiku-(?:[5-9]|\d{2,})(?:[.-]|$)/u.test(m) &&
299
+ !e.explicitOverride
300
+ )
301
+ continue;
302
+ if (
303
+ ["opus", "sonnet", "haiku"].includes(e.match) &&
304
+ Number(/^claude-(?:opus|sonnet|haiku)-(\d+)(?:[.-]|$)/u.exec(m)?.[1]) >=
305
+ 5 &&
294
306
  !e.explicitOverride
295
307
  )
296
308
  continue;
@@ -337,18 +349,42 @@ export function estimateCost({
337
349
  outputTokens = 0,
338
350
  cacheReadTokens = 0,
339
351
  cacheCreationTokens = 0,
352
+ cacheCreation5mTokens,
353
+ cacheCreation1hTokens,
354
+ cacheCreationInvalid = false,
355
+ pricingContextInvalid = false,
340
356
  requestInputTokens,
341
357
  serviceTier = "standard",
342
358
  regionalProcessing = false,
343
359
  table,
344
360
  } = {}) {
345
361
  const rate = lookupRate(provider, model, table);
362
+ const splitPresent =
363
+ cacheCreation5mTokens != null || cacheCreation1hTokens != null;
364
+ const splitValid =
365
+ splitPresent &&
366
+ Number.isSafeInteger(cacheCreation5mTokens) &&
367
+ cacheCreation5mTokens >= 0 &&
368
+ Number.isSafeInteger(cacheCreation1hTokens) &&
369
+ cacheCreation1hTokens >= 0 &&
370
+ cacheCreation5mTokens + cacheCreation1hTokens === cacheCreationTokens;
371
+ const missingCacheEvidence =
372
+ cacheCreationInvalid ||
373
+ (splitPresent && !splitValid) ||
374
+ (rate?.terms?.cacheWrite1hMultiplier != null &&
375
+ cacheCreationTokens > 0 &&
376
+ !splitValid);
346
377
  const tierMultiplier = rate?.terms?.serviceMultipliers
347
378
  ? Object.hasOwn(rate.terms.serviceMultipliers, serviceTier)
348
379
  ? rate.terms.serviceMultipliers[serviceTier]
349
380
  : null
350
381
  : 1;
351
- if (!rate || tierMultiplier == null) {
382
+ if (
383
+ !rate ||
384
+ tierMultiplier == null ||
385
+ missingCacheEvidence ||
386
+ pricingContextInvalid
387
+ ) {
352
388
  return {
353
389
  inputCost: 0,
354
390
  outputCost: 0,
@@ -384,9 +420,14 @@ export function estimateCost({
384
420
  inputMultiplier *
385
421
  multiplier;
386
422
  const cacheCreationCost =
387
- (Number(cacheCreationTokens) / 1e6) *
423
+ ((splitValid
424
+ ? cacheCreation5mTokens *
425
+ (rate.terms?.cacheWriteMultiplier ?? CACHE_WRITE_MULTIPLIER) +
426
+ cacheCreation1hTokens * (rate.terms?.cacheWrite1hMultiplier ?? 2)
427
+ : Number(cacheCreationTokens) *
428
+ (rate.terms?.cacheWriteMultiplier ?? CACHE_WRITE_MULTIPLIER)) /
429
+ 1e6) *
388
430
  rate.in *
389
- (rate.terms?.cacheWriteMultiplier ?? CACHE_WRITE_MULTIPLIER) *
390
431
  inputMultiplier *
391
432
  multiplier;
392
433
  return {
@@ -419,6 +460,15 @@ export function priceRollup(aggregate, { table } = {}) {
419
460
  outputTokens: row.outputTokens,
420
461
  cacheReadTokens: row.cacheReadTokens,
421
462
  cacheCreationTokens: row.cacheCreationTokens,
463
+ cacheCreation5mTokens: row.cacheCreation5mTokens,
464
+ cacheCreation1hTokens: row.cacheCreation1hTokens,
465
+ cacheCreationInvalid: row.cacheCreationInvalid,
466
+ pricingContextInvalid:
467
+ row.pricingContextInvalid === true ||
468
+ (String(row.provider).toLowerCase() === "anthropic" &&
469
+ String(row.model).toLowerCase() === "claude-haiku-5-5" &&
470
+ row.regionalProcessing == null &&
471
+ row.regional_processing == null),
422
472
  serviceTier: row.serviceTier ?? row.service_tier ?? "standard",
423
473
  regionalProcessing:
424
474
  row.regionalProcessing ?? row.regional_processing ?? false,
@@ -479,7 +529,11 @@ export function priceRollup(aggregate, { table } = {}) {
479
529
  for (const row of byModel) {
480
530
  if (row.matched) {
481
531
  totalCost += row.cost;
482
- } else if (row.totalTokens > 0) {
532
+ } else if (
533
+ row.totalTokens > 0 ||
534
+ row.cacheReadTokens > 0 ||
535
+ row.cacheCreationTokens > 0
536
+ ) {
483
537
  unpriced.push({
484
538
  provider: row.provider,
485
539
  model: row.model,
@@ -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,6 +3,11 @@
3
3
  * Keep structured provider diagnostics while redacting credential-shaped text.
4
4
  */
5
5
 
6
+ import {
7
+ attachStreamRetryMetadata,
8
+ captureStreamRetryMetadata,
9
+ } from "./stream-retry.js";
10
+
6
11
  function safePart(value, secrets = []) {
7
12
  if (value == null) return "";
8
13
  let text = String(value);
@@ -111,3 +116,14 @@ export async function formatProviderResponseError(
111
116
  secrets,
112
117
  });
113
118
  }
119
+
120
+ /** Keep response status authoritative even if reading its error body fails. */
121
+ export async function createProviderResponseError(provider, response, options) {
122
+ const metadata = captureStreamRetryMetadata(response);
123
+ let message = await formatProviderResponseError(provider, response, options);
124
+ const remaining = metadata.retryAfterAt - Date.now();
125
+ if (Number.isFinite(remaining) && remaining > 0) {
126
+ message += ` Retry-After: wait at least ${Math.ceil(remaining / 1000)}s before an explicit retry.`;
127
+ }
128
+ return attachStreamRetryMetadata(new Error(message), metadata);
129
+ }
@@ -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
@@ -12,11 +12,196 @@
12
12
  * agent runtime.
13
13
  */
14
14
 
15
- import { isAbortError } from "./abort-utils.js";
15
+ import {
16
+ createAbortError,
17
+ isAbortError,
18
+ raceWithAbort,
19
+ throwIfAborted,
20
+ } from "./abort-utils.js";
16
21
 
17
22
  /** Bounded auto-retry budget for streaming connection drops (Claude-Code 2.1.181). */
18
23
  export const STREAM_RETRY_MAX = 2;
19
24
  export const STREAM_RETRY_BASE_MS = 400;
25
+ export const STREAM_RETRY_MAX_DELAY_MS = 60_000;
26
+
27
+ function isFailureStatus(status) {
28
+ return Number.isInteger(status) && status >= 400 && status <= 599;
29
+ }
30
+
31
+ function retryAfterHeader(headers) {
32
+ if (!headers) return undefined;
33
+ if (typeof headers.get === "function") return headers.get("retry-after");
34
+ const entries = Object.entries(headers).filter(
35
+ ([name]) => name.toLowerCase() === "retry-after",
36
+ );
37
+ // Multiple spellings or a list of values are ambiguous, not a delay.
38
+ return entries.length === 1 ? entries[0][1] : undefined;
39
+ }
40
+
41
+ function httpDate(value, now) {
42
+ // Accept the three HTTP-date wire formats, not Date.parse's permissive
43
+ // numeric/local-date syntax (e.g. "-1", "1.5", or "2026-10-12").
44
+ const weekday = "(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)";
45
+ const month = "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)";
46
+ let match = new RegExp(
47
+ `^(${weekday}), (\\d{2}) ${month} (\\d{4}) (\\d{2}):(\\d{2}):(\\d{2}) GMT$`,
48
+ ).exec(value);
49
+ let day, monthName, year, hour, minute, second, dayName;
50
+ if (match) {
51
+ [, dayName, day, monthName, year, hour, minute, second] = match;
52
+ } else {
53
+ match = new RegExp(
54
+ `^(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (\\d{2})-${month}-(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2}) GMT$`,
55
+ ).exec(value);
56
+ if (match) {
57
+ [, dayName, day, monthName, year, hour, minute, second] = match;
58
+ const currentYear = new Date(now).getUTCFullYear();
59
+ year = Math.floor(currentYear / 100) * 100 + Number(year);
60
+ if (year > currentYear + 50) year -= 100;
61
+ } else {
62
+ match = new RegExp(
63
+ `^(${weekday}) ${month} ( [1-9]|[12]\\d|3[01]) (\\d{2}):(\\d{2}):(\\d{2}) (\\d{4})$`,
64
+ ).exec(value);
65
+ if (!match) return undefined;
66
+ [, dayName, monthName, day, hour, minute, second, year] = match;
67
+ }
68
+ }
69
+ const months = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" ");
70
+ const monthIndex = months.indexOf(monthName);
71
+ const date = new Date(0);
72
+ date.setUTCFullYear(Number(year), monthIndex, Number(day));
73
+ date.setUTCHours(Number(hour), Number(minute), Number(second), 0);
74
+ // Reject normalized invalid calendar dates/times and mismatched weekdays.
75
+ if (
76
+ date.getUTCFullYear() !== Number(year) ||
77
+ date.getUTCMonth() !== monthIndex ||
78
+ date.getUTCDate() !== Number(day) ||
79
+ date.getUTCHours() !== Number(hour) ||
80
+ date.getUTCMinutes() !== Number(minute) ||
81
+ date.getUTCSeconds() !== Number(second) ||
82
+ date.toUTCString().slice(0, 3) !== dayName.slice(0, 3)
83
+ ) {
84
+ return undefined;
85
+ }
86
+ return date.getTime();
87
+ }
88
+
89
+ /** Capture a deadline when headers arrive, before reading a slow response body.
90
+ * No metadata here grants permission to retry an HTTP/provider verdict.
91
+ */
92
+ export function captureStreamRetryMetadata(response, now = Date.now()) {
93
+ const metadata = {};
94
+ if (Number.isInteger(response?.status)) metadata.status = response.status;
95
+ const raw = retryAfterHeader(response?.headers);
96
+ if (typeof raw !== "string" || !Number.isFinite(now)) return metadata;
97
+ const value = raw.trim();
98
+ if (/^\d+$/.test(value)) {
99
+ const seconds = Number(value);
100
+ const deadline = now + seconds * 1000;
101
+ // A valid but unrepresentably large delay is a refusal to retry within our
102
+ // budget, NOT a missing header. Infinity is an internal fail-closed sentinel.
103
+ metadata.retryAfterAt = Number.isSafeInteger(deadline)
104
+ ? deadline
105
+ : Infinity;
106
+ } else {
107
+ const deadline = httpDate(value, now);
108
+ if (deadline !== undefined) metadata.retryAfterAt = deadline;
109
+ }
110
+ return metadata;
111
+ }
112
+
113
+ /** Preserve the original Error identity/code and the strongest known verdict. */
114
+ export function attachStreamRetryMetadata(error, metadata = {}) {
115
+ if (!error || (typeof error !== "object" && typeof error !== "function"))
116
+ return error;
117
+ const hasFailureStatus = [
118
+ error.status,
119
+ error.statusCode,
120
+ error.cause?.status,
121
+ error.cause?.statusCode,
122
+ ].some(isFailureStatus);
123
+ if (!hasFailureStatus && Number.isInteger(metadata.status)) {
124
+ error.status = metadata.status;
125
+ }
126
+ if (
127
+ typeof metadata.retryAfterAt === "number" &&
128
+ !Number.isNaN(metadata.retryAfterAt) &&
129
+ metadata.retryAfterAt !== -Infinity
130
+ ) {
131
+ const previous = [error.retryAfterAt, error.cause?.retryAfterAt].filter(
132
+ (value) => typeof value === "number" && !Number.isNaN(value),
133
+ );
134
+ error.retryAfterAt = Math.max(metadata.retryAfterAt, ...previous);
135
+ }
136
+ return error;
137
+ }
138
+
139
+ /** Resolve the wait AFTER retry eligibility is checked; null means give up.
140
+ * Never clamp a server deadline to a shorter wait or authorize an HTTP replay.
141
+ * Attempt 1 is the first retry, matching the existing retry observer contract.
142
+ */
143
+ export function resolveStreamRetryDelay(error, attempt, options = {}) {
144
+ const base = options.baseDelayMs ?? STREAM_RETRY_BASE_MS;
145
+ const now = options.now ?? Date.now();
146
+ const max = options.maxDelayMs ?? STREAM_RETRY_MAX_DELAY_MS;
147
+ if (
148
+ !Number.isInteger(attempt) ||
149
+ attempt < 1 ||
150
+ !Number.isFinite(base) ||
151
+ base < 0 ||
152
+ !Number.isFinite(now) ||
153
+ !Number.isFinite(max) ||
154
+ max < 0
155
+ )
156
+ return null;
157
+ const deadlines = [error?.retryAfterAt, error?.cause?.retryAfterAt].filter(
158
+ (value) => typeof value === "number" && !Number.isNaN(value),
159
+ );
160
+ const delay = Math.ceil(
161
+ Math.max(base * 2 ** (attempt - 1), 0, ...deadlines.map((at) => at - now)),
162
+ );
163
+ // Node clamps overflowing setTimeout delays to 1ms. Reject rather than
164
+ // accidentally turning a requested long delay into an immediate replay.
165
+ return Number.isFinite(delay) && delay <= max && delay <= 2_147_483_647
166
+ ? delay
167
+ : null;
168
+ }
169
+
170
+ /** Wait without keeping an obsolete backoff alive after user cancellation. */
171
+ export async function waitForStreamRetry(ms, signal, { sleep } = {}) {
172
+ throwIfAborted(signal);
173
+ if (!Number.isFinite(ms) || ms < 0 || ms > 2_147_483_647)
174
+ throw new RangeError("Invalid streaming retry delay");
175
+ if (sleep) {
176
+ await raceWithAbort(
177
+ Promise.resolve().then(() => {
178
+ throwIfAborted(signal);
179
+ return sleep(ms);
180
+ }),
181
+ signal,
182
+ );
183
+ throwIfAborted(signal);
184
+ return;
185
+ }
186
+ await new Promise((resolve, reject) => {
187
+ let timer;
188
+ const cleanup = () => {
189
+ clearTimeout(timer);
190
+ signal?.removeEventListener?.("abort", onAbort);
191
+ };
192
+ const onAbort = () => {
193
+ cleanup();
194
+ reject(signal.reason || createAbortError());
195
+ };
196
+ timer = setTimeout(() => {
197
+ cleanup();
198
+ resolve();
199
+ }, ms);
200
+ signal?.addEventListener?.("abort", onAbort, { once: true });
201
+ if (signal?.aborted) onAbort();
202
+ });
203
+ throwIfAborted(signal);
204
+ }
20
205
 
21
206
  /**
22
207
  * Hard ceiling on the *configurable* retry budget (Claude-Code 2.1.186:
@@ -61,6 +246,29 @@ export function isRetryableStreamError(err, signal) {
61
246
  if (isAbortError(err)) return false;
62
247
  if (signal && signal.aborted) return false;
63
248
  if (!err) return false;
249
+ if (
250
+ [err, err.cause].some(
251
+ (error) =>
252
+ error?.noReplay === true ||
253
+ error?.streamOutputVisible === true ||
254
+ error?.isOutputBackpressureFailure === true,
255
+ )
256
+ )
257
+ return false;
258
+ const msg = String(err.message || err).toLowerCase();
259
+ // A provider verdict stays terminal even when its detail mentions a timeout,
260
+ // reset or network failure. Inspect it before transport codes and wording so
261
+ // formatted HTTP diagnostics and failed Responses cannot trigger a replay.
262
+ if (
263
+ err.code === "CC_OPENAI_RESPONSES_FAILED" ||
264
+ err.cause?.code === "CC_OPENAI_RESPONSES_FAILED" ||
265
+ [err.status, err.statusCode, err.cause?.status, err.cause?.statusCode].some(
266
+ (status) => Number.isInteger(status) && status >= 400 && status <= 599,
267
+ ) ||
268
+ /\bhttp\s+[45]\d{2}\b/.test(msg)
269
+ ) {
270
+ return false;
271
+ }
64
272
  const code = String(err.code || err.cause?.code || "").toUpperCase();
65
273
  if (
66
274
  [
@@ -76,7 +284,6 @@ export function isRetryableStreamError(err, signal) {
76
284
  ) {
77
285
  return true;
78
286
  }
79
- const msg = String(err.message || err).toLowerCase();
80
287
  return /econnreset|etimedout|econnrefused|eai_again|socket hang ?up|terminated|fetch failed|network error|timed?\s*out|premature close/.test(
81
288
  msg,
82
289
  );