chainlesschain 0.166.99 → 0.166.101

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 (176) hide show
  1. package/README.md +7 -8
  2. package/package.json +2 -2
  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-BUgaCgVU.js → AIOps-BjBS_29I.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-b0MpUSSZ.js → ActionButton-CUnnQUaj.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-hbXTvHqO.js → Analytics-BqYZxgnY.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-CLQoAVu4.js → AppLayout-m8B886ka.js} +4 -4
  9. package/src/assets/web-panel/assets/{Artifacts-ytHzl2L2.js → Artifacts-JEOxU3Ug.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-BuhkLm0C.js → Audit-DAXS5c9J.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-CS81hxZV.js → BackgroundAgents-e3a9XHw3.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-DzR-_Qvi.js → Backup-D3Qmp68h.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-r8Ku_lYw.js → BaseInput-C7CXyiUl.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-C3Uxtoaa.js → Chat-2AHlAGi8.js} +6 -6
  15. package/src/assets/web-panel/assets/ChatBubbleRenderer-D3KsyCUV.js +1 -0
  16. package/src/assets/web-panel/assets/{Checkbox-BnG2P5yc.js → Checkbox-YfBuQlBH.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-BdgU6HZy.js → Codegen-DCCQDfTL.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-DT8t9wmf.js → Col-03i2WfrV.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-ChkxR5oe.js → Community-CJQIpng6.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-DIwLeTk3.js → Compact-CCtcQ2pq.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-CAqzGLvW.js → Compliance-Vxl7ZszJ.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-Bb3jejMG.js → Cowork-DN-BwA8I.js} +2 -2
  23. package/src/assets/web-panel/assets/{Cron-BYRkZLta.js → Cron-Dc2Q46X7.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-BD6z227t.js → Crosschain-CQCblsl-.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-DA3G5Wgo.js → DID-YYvqUR8C.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-yaZePHOu.js → Dashboard-Cafy3DZT.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-BqY5MBx2.js → Dropdown-BOyYpIpv.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-cIWwOgHm.js → EmailListRenderer-B7NYjc1j.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-zvV6ymca.js → EvolutionSettings-C5wfxztf.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-CAmh1U2b.js → FamilyGuardDashboard-aA7KnDGK.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-5qd2LCg8.js → Federation-DlgXUu1L.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-Bdkj1sRJ.js → FormItemContext-B5YsrLDg.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-B-gWN2P3.js → GenericCardRenderer-DaWojPFw.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-BEMh_NGd.js → Git-dkhh6Fx2.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-qLGvA2Hw.js → Governance-Cz6vmkjc.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-DblBwYuW.js → Inference-DWt0hbh8.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-BISegVD_.js → KnowledgeGraph-BZJ0Z-nL.js} +1 -1
  38. package/src/assets/web-panel/assets/Logs-BaBBmL1A.js +2 -0
  39. package/src/assets/web-panel/assets/MarkdownRenderer-C1yByobo.js +1 -0
  40. package/src/assets/web-panel/assets/{Marketplace-CHKXMOkH.js → Marketplace-ct8sgQ0s.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-B5G1elqd.js → McpTools-CXKCRGYQ.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-O5Ib0uTR.js → Memory-O7ZwlS6a.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-BaGYL7rT.js → MobileBridge-By12C-eC.js} +1 -1
  44. package/src/assets/web-panel/assets/MobileProjects-Ba-EVdex.js +1 -0
  45. package/src/assets/web-panel/assets/{Mtc-CNjJ97jg.js → Mtc-g-932zV2.js} +2 -2
  46. package/src/assets/web-panel/assets/{MtcAudit-DjBN-Wqz.js → MtcAudit-BW8hB0ly.js} +4 -4
  47. package/src/assets/web-panel/assets/{Multisig-B850R9lO.js → Multisig-zspLaMbT.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-Bn8sbFfV.js → NLProgramming-dJeUPDoq.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-BpLmMp3Q.js → Notes-C4msiRQL.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-Dbk97rjb.js → NotificationSettings-MOCHM-qg.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-BOBX_I72.js → OrderTableRenderer-CX0T66NM.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-B45DpOuE.js → Organization-DOZurBfk.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-DmKH7eer.js → Overflow-qOT9BhUp.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-CC4FaXTl.js → P2P-BMoy7Eo4.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-C2SgP4PI.js → PdhVaultBrowser-ByyV1q-D.js} +3 -3
  56. package/src/assets/web-panel/assets/{Permissions-BQB4QFj_.js → Permissions-6Qyro4ye.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-Dy6GGpn4.js → PersonalDataHub-DR3DRNSX.js} +4 -4
  58. package/src/assets/web-panel/assets/{Pipeline-B9HB5pRc.js → Pipeline-Cr6TTdud.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-D7pOmg-p.js → Privacy-B70otG0l.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-DglBqvec.js → ProjectInit-BHCqxoSk.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-Bho22znM.js → ProjectSettings-B80GZpZk.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-C0bSuM8U.js → Projects-cq-b9-fQ.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-BgAgo1Yr.js → Providers-dsVTimHa.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-C2fBjCC8.js → QrScannerModal-DRJ8YepZ.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-C8MiF-rk.js → QuickAsk-BSXdEjIB.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-D_TzHdQf.js → Recommend-CQLJGyKC.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-BHO7b6xE.js → RemoteSession-BF9WUFVZ.js} +2 -2
  68. package/src/assets/web-panel/assets/{Reputation-BPxNmNhD.js → Reputation-Cy9o5tvW.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-fwhot5Bk.js → Row-BP346_3b.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-CZbD1B-5.js → RssFeed-BKulxXf3.js} +3 -3
  71. package/src/assets/web-panel/assets/{Search-BRs6YpAE.js → Search-EemQj2Dv.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-CB344tKC.js → Security-DcWPAwwk.js} +4 -4
  73. package/src/assets/web-panel/assets/{Services-Beo-7fEl.js → Services-Bltqciay.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-CDXx96vD.js → Skeleton-BwRyOGY8.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-b-mQTJK4.js → Skills-D98qlvpJ.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-BvjP-IS9.js → Sla-BUTtBMY0.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-C6wsV-cO.js → SpeechSettings-C7kcY_98.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-BQZoko-e.js → SyncSettings-Bsk6lKvT.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-6Z0rJJVO.js → Tasks-DvSrtz0P.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-Cc9IXtEQ.js → Templates-BUM6LwPs.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-BLc7AjOI.js → Tenant-D9TkOm7z.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-CUN49v85.js → Terminal-CP8ZVErN.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-CX-SksHN.js → TimelineRenderer-V3SoKZ1T.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-Btrm0-rK.js → Tokens-CCRlUTOA.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-CIboUvKe.js → Trigger-CznUcPme.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-Rv9jEs5v.js → Trust-D1GIk_NF.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-B_xomdD5.js → UkeySign-DHtvtyC-.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-CrvWeMow.js → VideoEditing-CVxdaJIq.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-BjvWgk_7.js → Wallet-D221OjyE.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-CwfpFw92.js → WebAuthn-Cw0-ESsq.js} +5 -5
  91. package/src/assets/web-panel/assets/{WorkflowEditor-Dkk2QsOe.js → WorkflowEditor-ZYScrBx3.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-Dah1DVes.js → chat-BU0e1obR.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-JEpgQ10k.js → colors-gzYweuha.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item--DuG_cxf.js → compact-item-ChAXal_k.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-BJ_GZvon.js → createContext-of3FolD7.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-Pa13TVrO.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-yZRLDmWK.js → hasIn-4PsK_Kx8.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DQ4Fch3e.js → index-1dzYRBbg.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-L9CFyRIi.js → index-B5L7zddz.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DxnkldGo.js → index-BOeX7BzS.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-D6Le2m3d.js → index-BdxRVNPY.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DaDLWIWo.js → index-BfI4dXbi.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-o2qO_dYf.js → index-Bftq5rJR.js} +1 -1
  104. package/src/assets/web-panel/assets/index-BhQg-v6V.js +1 -0
  105. package/src/assets/web-panel/assets/{index-DhX48E81.js → index-By-pper5.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-Bdg_nWD1.js → index-CCLsbul3.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-cHx5KzUt.js → index-CGFL59q4.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DemMuw7n.js → index-CHv_63Cp.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DZBesaCN.js → index-CO2owKe0.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CxB49Mow.js → index-CeEE_SGZ.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BKl40wrO.js → index-Cn1clrxx.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-VIgVth92.js → index-Cx4Z6nUl.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-kZE-K3ZO.js → index-CxzBcXOa.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-rkvSOceQ.js → index-CyDQNprx.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-Cmr0AzcK.js → index-D-Zss5KL.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DddwZCT9.js → index-D1PGrfHE.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BUjyj7qR.js → index-DDYj14Q4.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CjuD8smQ.js → index-DEB5fQqG.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-asia_JPc.js → index-DEXBckNR.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DFJbJ8rs.js → index-DEzjUgkl.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CFj7ylAJ.js → index-DJVrzXtk.js} +1 -1
  122. package/src/assets/web-panel/assets/index-DUD5o-vW.js +1 -0
  123. package/src/assets/web-panel/assets/{index-DroaQypF.js → index-DZ0oKtBg.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DbMGGcpZ.js → index-D_5LTPMH.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-IjOa5lYn.js → index-D_9k680X.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-vdTrEOj7.js → index-D_ialOHx.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-9L3Pg2tc.js → index-DjRAIRX7.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Dq-8PFhL.js → index-Djfgsjfy.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CJLz3SpM.js → index-DsoV9rzn.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BWkKE8Oj.js → index-Dy0ojH6G.js} +3 -3
  131. package/src/assets/web-panel/assets/{index-C8nXkCMf.js → index-E8oDMSAo.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-C56b8e9s.js → index-Ef5YkVAn.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-C6ohEAEV.js → index-Wr91cnWr.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-1QZASeW1.js → index-cFkMIx1x.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-BM7xJKGD.js → index-wo0De0iG.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-CQedFuDw.js → index-yMf7zmWv.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-anKyyjGc.js → initDefaultProps-D0Bx6pgr.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-Cqp0nx5A.js → motion-BnLuJqJ5.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-Ca3mgkM2.js → move-Bxpq9xgR.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-BmwuhJ3z.js → mtc-parser-BdmrNhOs.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-C9Mf05WJ.js → omit-tjJD34BZ.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-2PbxB9Ds.js → pickAttrs-CMFzLt7b.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-CTVbOFHt.js → placementArrow-BZf6O3cd.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-Nrm8Vbmr.js → responsiveObserve-DFDLazsV.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-Dh4r1zqR.js → slide-CMbTvp4Y.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-vzNoQL-r.js → statusUtils-FOan8MI7.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-BXpGfNkI.js → styleChecker-DTABspd4.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-CVWBRdhs.js → useFlexGapSupport-CNHXWBpY.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-BJWMLffI.js → useFs-5K-c_RoL.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-CWCe5VHG.js → usePersonalDataHub-Di0hL4G-.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-D-NBEb8m.js → vnode-DTyDv4ja.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-C0mnhfGf.js → zoom-ontRt8ft.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/commands/eval.js +11 -8
  155. package/src/data/changelog.json +26 -0
  156. package/src/harness/provider-backed-compaction.js +13 -5
  157. package/src/harness/worktree-isolator.js +20 -8
  158. package/src/lib/chat-core.js +57 -25
  159. package/src/lib/context-memory-kernel/live-compaction.js +142 -61
  160. package/src/lib/eval/verify01-execution-window.js +70 -0
  161. package/src/lib/eval/verify01-execution.js +9 -1
  162. package/src/lib/eval/verify01-host-capture.js +6 -2
  163. package/src/lib/formal-budget-authority.js +533 -0
  164. package/src/lib/formal-budget-contract.js +609 -0
  165. package/src/lib/formal-budget-transport.js +345 -0
  166. package/src/lib/provider-http-error.js +16 -0
  167. package/src/lib/stream-retry.js +195 -1
  168. package/src/runtime/agent-core.js +272 -32
  169. package/src/runtime/headless-stream.js +136 -4
  170. package/src/assets/web-panel/assets/ChatBubbleRenderer-RvblDu77.js +0 -1
  171. package/src/assets/web-panel/assets/Logs-BD2UR7kE.js +0 -2
  172. package/src/assets/web-panel/assets/MarkdownRenderer-B-TlDCmr.js +0 -1
  173. package/src/assets/web-panel/assets/MobileProjects-Dsctbob8.js +0 -1
  174. package/src/assets/web-panel/assets/devWarning-B6kQEceX.js +0 -1
  175. package/src/assets/web-panel/assets/index-CSeiH6HA.js +0 -1
  176. package/src/assets/web-panel/assets/index-CayGTz6d.js +0 -1
@@ -156,6 +156,10 @@ import {
156
156
  isRetryableStreamError,
157
157
  STREAM_RETRY_BASE_MS,
158
158
  resolveStreamRetryMax,
159
+ captureStreamRetryMetadata,
160
+ attachStreamRetryMetadata,
161
+ resolveStreamRetryDelay,
162
+ waitForStreamRetry,
159
163
  } from "../lib/stream-retry.js";
160
164
  import {
161
165
  annotateLines,
@@ -184,7 +188,7 @@ import {
184
188
  } from "../lib/unattended-action-policy.js";
185
189
  import {
186
190
  formatProviderHttpError,
187
- formatProviderResponseError,
191
+ createProviderResponseError,
188
192
  } from "../lib/provider-http-error.js";
189
193
  import { buildPermissionDecision } from "../lib/permission-decision.js";
190
194
  import { resolveSandboxPolicyPath } from "../lib/agent-sandbox.js";
@@ -194,6 +198,7 @@ import {
194
198
  settleManagedToolCheckpoint,
195
199
  } from "../lib/managed-tool-checkpoint.js";
196
200
  import { sessionBudgetAdmissionError } from "../lib/session-budget-production-root.js";
201
+ import { projectRuntimeTokenUsage } from "../lib/runtime-usage-ledger.js";
197
202
  import {
198
203
  createMcpCallLedger,
199
204
  McpEffect,
@@ -11856,6 +11861,11 @@ export async function chatWithTools(rawMessages, options) {
11856
11861
 
11857
11862
  throwIfAborted(signal);
11858
11863
 
11864
+ // Host accounting starts only after request admission. A rejected model
11865
+ // projection never reaches the provider; failures after this boundary must
11866
+ // still retain conservative usage accounting regardless of error metadata.
11867
+ await options.onProviderCallStart?.();
11868
+
11859
11869
  if (provider === "ollama") {
11860
11870
  const apiUrl = `${baseUrl}/api/chat`;
11861
11871
  // Multimodal (`cc agent --image`): ollama wants `{content, images:[base64]}`
@@ -11920,7 +11930,7 @@ export async function chatWithTools(rawMessages, options) {
11920
11930
  }),
11921
11931
  });
11922
11932
  if (!response.ok) {
11923
- throw new Error(await formatProviderResponseError("ollama", response));
11933
+ throw await createProviderResponseError("ollama", response);
11924
11934
  }
11925
11935
  const data = await response.json();
11926
11936
  if (
@@ -12073,7 +12083,7 @@ export async function chatWithTools(rawMessages, options) {
12073
12083
  });
12074
12084
 
12075
12085
  if (!response.ok) {
12076
- throw new Error(await formatProviderResponseError("anthropic", response));
12086
+ throw await createProviderResponseError("anthropic", response);
12077
12087
  }
12078
12088
 
12079
12089
  const data = await response.json();
@@ -12229,7 +12239,7 @@ export async function chatWithTools(rawMessages, options) {
12229
12239
  body: JSON.stringify(responseBody),
12230
12240
  });
12231
12241
  if (!response.ok) {
12232
- throw new Error(await formatProviderResponseError(provider, response));
12242
+ throw await createProviderResponseError(provider, response);
12233
12243
  }
12234
12244
  const data = await response.json();
12235
12245
  const out = normalizeOpenAIResponsesResponse(data);
@@ -12310,7 +12320,7 @@ export async function chatWithTools(rawMessages, options) {
12310
12320
  });
12311
12321
 
12312
12322
  if (!response.ok) {
12313
- throw new Error(await formatProviderResponseError(provider, response));
12323
+ throw await createProviderResponseError(provider, response);
12314
12324
  }
12315
12325
 
12316
12326
  const data = await response.json();
@@ -12397,9 +12407,11 @@ function _ollamaInitState() {
12397
12407
 
12398
12408
  function _streamUiCallbacks(onToken, onThinking) {
12399
12409
  let pending = [];
12410
+ let visible = false;
12400
12411
  const capture = (callback) =>
12401
12412
  typeof callback === "function"
12402
12413
  ? (value) => {
12414
+ if (typeof value === "string" && value.length > 0) visible = true;
12403
12415
  try {
12404
12416
  const result = callback(value);
12405
12417
  if (result && typeof result.then === "function") {
@@ -12413,6 +12425,7 @@ function _streamUiCallbacks(onToken, onThinking) {
12413
12425
  return {
12414
12426
  onToken: capture(onToken),
12415
12427
  onThinking: capture(onThinking),
12428
+ hasVisibleOutput: () => visible,
12416
12429
  async settle() {
12417
12430
  if (pending.length === 0) return;
12418
12431
  const current = pending;
@@ -12516,11 +12529,17 @@ export function _accumulateOllamaStream(lines, onToken) {
12516
12529
  * Parity with Claude-Code 2.1.179 ("preserving partial responses instead of
12517
12530
  * showing raw errors"). Pure + exported for unit tests.
12518
12531
  */
12519
- export function _streamErrorDisposition(err, signal, partialText) {
12532
+ export function _streamErrorDisposition(
12533
+ err,
12534
+ signal,
12535
+ partialText,
12536
+ visible = false,
12537
+ ) {
12520
12538
  if (err?.isOutputBackpressureFailure === true) return "rethrow";
12521
12539
  if (isAbortError(err)) return "rethrow";
12522
12540
  if (signal && signal.aborted) return "rethrow";
12523
- if (typeof partialText === "string" && partialText.trim()) return "preserve";
12541
+ if (visible || (typeof partialText === "string" && partialText.length > 0))
12542
+ return "preserve";
12524
12543
  return "rethrow";
12525
12544
  }
12526
12545
 
@@ -12585,16 +12604,22 @@ export async function _retryStreamingChat(streamFn, opts = {}) {
12585
12604
  const retries = opts.retries ?? resolveStreamRetryMax();
12586
12605
  const base = opts.baseDelayMs ?? STREAM_RETRY_BASE_MS;
12587
12606
  const signal = opts.signal;
12588
- const sleep = opts.sleep || ((ms) => new Promise((r) => setTimeout(r, ms)));
12589
12607
  const now = typeof opts.now === "function" ? opts.now : Date.now;
12590
12608
  let attempt = 0;
12591
12609
  for (;;) {
12610
+ throwIfAborted(signal);
12592
12611
  const attemptStartedAt = now();
12593
12612
  try {
12594
12613
  return await streamFn(attempt);
12595
12614
  } catch (err) {
12596
12615
  if (attempt >= retries || !_isRetryableStreamError(err, signal))
12597
12616
  throw err;
12617
+ const attemptEndedAt = now();
12618
+ const delayMs = resolveStreamRetryDelay(err, attempt + 1, {
12619
+ baseDelayMs: base,
12620
+ now: attemptEndedAt,
12621
+ });
12622
+ if (delayMs === null) throw err;
12598
12623
  attempt++;
12599
12624
  if (
12600
12625
  opts.strictRetryObserver === true &&
@@ -12609,7 +12634,7 @@ export async function _retryStreamingChat(streamFn, opts = {}) {
12609
12634
  if (typeof opts.onRetry === "function") {
12610
12635
  try {
12611
12636
  const observation = opts.onRetry(attempt, err, {
12612
- durationMs: Math.max(0, now() - attemptStartedAt),
12637
+ durationMs: Math.max(0, attemptEndedAt - attemptStartedAt),
12613
12638
  });
12614
12639
  if (observation && typeof observation.then === "function") {
12615
12640
  void Promise.resolve(observation).catch(() => {});
@@ -12638,8 +12663,7 @@ export async function _retryStreamingChat(streamFn, opts = {}) {
12638
12663
  }
12639
12664
  }
12640
12665
  }
12641
- await sleep(base * Math.pow(2, attempt - 1));
12642
- if (signal && signal.aborted) throw err; // user bailed during backoff
12666
+ await waitForStreamRetry(delayMs, signal, { sleep: opts.sleep });
12643
12667
  }
12644
12668
  }
12645
12669
  }
@@ -12762,8 +12786,9 @@ async function _chatOllamaStreaming(
12762
12786
  body: JSON.stringify({ ...body, stream: true }),
12763
12787
  });
12764
12788
  if (!response.ok) {
12765
- throw new Error(await formatProviderResponseError("ollama", response));
12789
+ throw await createProviderResponseError("ollama", response);
12766
12790
  }
12791
+ const retryMetadata = captureStreamRetryMetadata(response);
12767
12792
  const state = _ollamaInitState();
12768
12793
  const ui = _streamUiCallbacks(onToken);
12769
12794
  const reader = response.body.getReader();
@@ -12788,7 +12813,17 @@ async function _chatOllamaStreaming(
12788
12813
  await ui.settle();
12789
12814
  }
12790
12815
  } catch (err) {
12791
- if (_streamErrorDisposition(err, signal, state.content) === "rethrow")
12816
+ attachStreamRetryMetadata(err, retryMetadata);
12817
+ if (!ui.hasVisibleOutput() && !state.content && state.toolCalls?.length)
12818
+ err.noReplay = true;
12819
+ if (
12820
+ _streamErrorDisposition(
12821
+ err,
12822
+ signal,
12823
+ state.content,
12824
+ ui.hasVisibleOutput(),
12825
+ ) === "rethrow"
12826
+ )
12792
12827
  throw err;
12793
12828
  return _finalizeTruncatedStream(_ollamaFinalize, state);
12794
12829
  }
@@ -12813,8 +12848,9 @@ async function _chatAnthropicStreaming(
12813
12848
  body: JSON.stringify(body),
12814
12849
  });
12815
12850
  if (!response.ok) {
12816
- throw new Error(await formatProviderResponseError("anthropic", response));
12851
+ throw await createProviderResponseError("anthropic", response);
12817
12852
  }
12853
+ const retryMetadata = captureStreamRetryMetadata(response);
12818
12854
  const state = _anthropicInitState();
12819
12855
  const ui = _streamUiCallbacks(onToken, onThinking);
12820
12856
  const reader = response.body.getReader();
@@ -12839,7 +12875,21 @@ async function _chatAnthropicStreaming(
12839
12875
  await ui.settle();
12840
12876
  }
12841
12877
  } catch (err) {
12842
- if (_streamErrorDisposition(err, signal, state.text) === "rethrow")
12878
+ attachStreamRetryMetadata(err, retryMetadata);
12879
+ if (
12880
+ !ui.hasVisibleOutput() &&
12881
+ !state.text &&
12882
+ Object.values(state.blocks).some((block) => block.type === "tool_use")
12883
+ )
12884
+ err.noReplay = true;
12885
+ if (
12886
+ _streamErrorDisposition(
12887
+ err,
12888
+ signal,
12889
+ state.text,
12890
+ ui.hasVisibleOutput(),
12891
+ ) === "rethrow"
12892
+ )
12843
12893
  throw err;
12844
12894
  return _finalizeTruncatedStream(_anthropicFinalize, state);
12845
12895
  }
@@ -12871,8 +12921,9 @@ async function _chatOpenAIStreaming(
12871
12921
  body: JSON.stringify(body),
12872
12922
  });
12873
12923
  if (!response.ok) {
12874
- throw new Error(await formatProviderResponseError(provider, response));
12924
+ throw await createProviderResponseError(provider, response);
12875
12925
  }
12926
+ const retryMetadata = captureStreamRetryMetadata(response);
12876
12927
  const state = _openaiInitState();
12877
12928
  const ui = _streamUiCallbacks(onToken);
12878
12929
  const reader = response.body.getReader();
@@ -12897,7 +12948,17 @@ async function _chatOpenAIStreaming(
12897
12948
  await ui.settle();
12898
12949
  }
12899
12950
  } catch (err) {
12900
- if (_streamErrorDisposition(err, signal, state.text) === "rethrow")
12951
+ attachStreamRetryMetadata(err, retryMetadata);
12952
+ if (!ui.hasVisibleOutput() && !state.text && state.tools.length)
12953
+ err.noReplay = true;
12954
+ if (
12955
+ _streamErrorDisposition(
12956
+ err,
12957
+ signal,
12958
+ state.text,
12959
+ ui.hasVisibleOutput(),
12960
+ ) === "rethrow"
12961
+ )
12901
12962
  throw err;
12902
12963
  const out = _finalizeTruncatedStream(_openaiFinalize, state);
12903
12964
  const providerReceipt = _openAIProviderRequestReceipt(
@@ -12943,8 +13004,9 @@ async function _chatOpenAIResponsesStreaming(
12943
13004
  body: JSON.stringify(body),
12944
13005
  });
12945
13006
  if (!response.ok) {
12946
- throw new Error(await formatProviderResponseError("openai", response));
13007
+ throw await createProviderResponseError("openai", response);
12947
13008
  }
13009
+ const retryMetadata = captureStreamRetryMetadata(response);
12948
13010
  const state = createOpenAIResponsesStreamState();
12949
13011
  const ui = _streamUiCallbacks(onToken, onThinking);
12950
13012
  const reader = response.body.getReader();
@@ -12969,10 +13031,31 @@ async function _chatOpenAIResponsesStreaming(
12969
13031
  await ui.settle();
12970
13032
  }
12971
13033
  } catch (error) {
12972
- if (_streamErrorDisposition(error, signal, state.text) === "rethrow") {
13034
+ if (state.terminalError) throw state.terminalError;
13035
+ attachStreamRetryMetadata(error, retryMetadata);
13036
+ if (
13037
+ !ui.hasVisibleOutput() &&
13038
+ !state.text &&
13039
+ state.outputItems.some((item) => item?.type === "function_call")
13040
+ )
13041
+ error.noReplay = true;
13042
+ if (
13043
+ !state.normalized &&
13044
+ _streamErrorDisposition(
13045
+ error,
13046
+ signal,
13047
+ state.text,
13048
+ ui.hasVisibleOutput(),
13049
+ ) === "rethrow"
13050
+ ) {
12973
13051
  throw error;
12974
13052
  }
12975
- const out = _finalizeTruncatedStream(finalizeOpenAIResponsesStream, state);
13053
+ throwIfAborted(signal);
13054
+ if (isAbortError(error) || error?.isOutputBackpressureFailure === true)
13055
+ throw error;
13056
+ const out = state.normalized
13057
+ ? finalizeOpenAIResponsesStream(state)
13058
+ : _finalizeTruncatedStream(finalizeOpenAIResponsesStream, state);
12976
13059
  const responseId = out.responseId || state.responseId;
12977
13060
  delete out.responseId;
12978
13061
  const providerReceipt = _openAIProviderRequestReceipt(
@@ -13394,6 +13477,19 @@ function _workflowNestedToolOutcomeUnknown(binding, toolName, result) {
13394
13477
  return error;
13395
13478
  }
13396
13479
 
13480
+ function _takeCompactionProviderReceipt(call, workflowEffectId) {
13481
+ if (!call?.providerReceipt || call.providerReceiptEmitted) return null;
13482
+ call.providerReceiptEmitted = true;
13483
+ return {
13484
+ type: "provider-request-receipt",
13485
+ callId: call.callId,
13486
+ workflowEffectId,
13487
+ callSequence: call.callSequence,
13488
+ source: "semantic-compaction",
13489
+ ...call.providerReceipt,
13490
+ };
13491
+ }
13492
+
13397
13493
  function _workflowCompactionOutcomeUnknown(
13398
13494
  cause,
13399
13495
  code = "CC_WORKFLOW_COMPACTION_PROVIDER_OUTCOME_UNKNOWN",
@@ -13793,6 +13889,21 @@ function _instrumentAutoCompactorUsage(compactor, options) {
13793
13889
  this,
13794
13890
  requestBinding ? [...args, requestBinding] : args,
13795
13891
  );
13892
+ // Keep validated provider-returned usage private to this actual call.
13893
+ // It is not settled yet: the host consumes token-usage exactly once.
13894
+ try {
13895
+ call.returnedUsage = projectRuntimeTokenUsage({
13896
+ callId: call.callId,
13897
+ provider: result?.provider || call.provider,
13898
+ model: result?.model || call.model,
13899
+ source: call.source,
13900
+ usage: result?.usage,
13901
+ });
13902
+ if (result?.callId && result.callId !== call.callId)
13903
+ call.returnedUsage = null;
13904
+ } catch {
13905
+ call.returnedUsage = null;
13906
+ }
13796
13907
  call.providerReceipt = providerRequestId
13797
13908
  ? _snapshotProviderRequestReceipt(
13798
13909
  result?.providerReceipt,
@@ -13802,6 +13913,7 @@ function _instrumentAutoCompactorUsage(compactor, options) {
13802
13913
  : null;
13803
13914
  return result;
13804
13915
  } catch (error) {
13916
+ call.returnedUsage = null;
13805
13917
  if (workflowEffectId) {
13806
13918
  throw _workflowCompactionOutcomeUnknown(error);
13807
13919
  }
@@ -13949,8 +14061,8 @@ async function _getAutoCompactor(options) {
13949
14061
  compressOptions,
13950
14062
  sessionId: options.sessionId,
13951
14063
  operationId: `auto-${randomUUID()}`,
13952
- provider: options.provider,
13953
- model: options.model,
14064
+ provider: options.provider || "ollama",
14065
+ model: options.model || "unknown",
13954
14066
  env: options.contextMemoryEnv || process.env,
13955
14067
  persist: options.persistCompaction !== false,
13956
14068
  trigger: "auto",
@@ -14985,6 +15097,37 @@ export async function* agentLoop(messages, options) {
14985
15097
  !["committed", "degraded"].includes(stats.canonicalReceipt.status)
14986
15098
  ) {
14987
15099
  automaticCompactionSettlementBlocked = true;
15100
+ const unsettledCall = compactionUsageState.calls.at(-1);
15101
+ if (unsettledCall) {
15102
+ const providerReceipt = _takeCompactionProviderReceipt(
15103
+ unsettledCall,
15104
+ workflowEffectId,
15105
+ );
15106
+ if (providerReceipt) yield providerReceipt;
15107
+ if (
15108
+ unsettledCall.returnedUsage &&
15109
+ stats.summaryUsageUnknown !== true
15110
+ ) {
15111
+ yield {
15112
+ type: "token-usage",
15113
+ ...unsettledCall.returnedUsage,
15114
+ runId,
15115
+ };
15116
+ } else {
15117
+ yield {
15118
+ type: "compaction-usage-unknown",
15119
+ callId: unsettledCall.callId,
15120
+ runId,
15121
+ provider: unsettledCall.provider,
15122
+ model: unsettledCall.model,
15123
+ source: "semantic-compaction",
15124
+ code: "provider_usage_unsettled",
15125
+ reason:
15126
+ stats.summaryUsageUnknownReason ||
15127
+ "provider_transport_outcome_unknown",
15128
+ };
15129
+ }
15130
+ }
14988
15131
  yield {
14989
15132
  type: "compaction-degraded",
14990
15133
  runId,
@@ -15003,6 +15146,20 @@ export async function* agentLoop(messages, options) {
15003
15146
  backgroundSubAgents,
15004
15147
  backgroundUsageFailureState,
15005
15148
  );
15149
+ if (workflowEffectId) {
15150
+ throw _markWorkflowCompactionFailureReported(
15151
+ _workflowCompactionOutcomeUnknown(
15152
+ null,
15153
+ "CC_WORKFLOW_COMPACTION_SETTLEMENT_UNKNOWN",
15154
+ "Workflow-bound semantic compaction requires reconciliation",
15155
+ ),
15156
+ );
15157
+ }
15158
+ yield {
15159
+ type: "run-ended",
15160
+ runId,
15161
+ reason: "compaction-settlement-failed",
15162
+ };
15006
15163
  return;
15007
15164
  }
15008
15165
  const observerFailure = compactionUsageState.calls.find(
@@ -15015,16 +15172,11 @@ export async function* agentLoop(messages, options) {
15015
15172
  }
15016
15173
  compactionUsageCall = compactionUsageState.calls.at(-1) || null;
15017
15174
  const compactionUsage = _compactionTokenUsage(stats);
15018
- if (compactionUsageCall?.providerReceipt) {
15019
- yield {
15020
- type: "provider-request-receipt",
15021
- callId: compactionUsageCall.callId,
15022
- workflowEffectId,
15023
- callSequence: compactionUsageCall.callSequence,
15024
- source: "semantic-compaction",
15025
- ...compactionUsageCall.providerReceipt,
15026
- };
15027
- }
15175
+ const providerReceipt = _takeCompactionProviderReceipt(
15176
+ compactionUsageCall,
15177
+ workflowEffectId,
15178
+ );
15179
+ if (providerReceipt) yield providerReceipt;
15028
15180
  if (stats.degraded === true) {
15029
15181
  const usageOutcomeUnknown = stats.summaryUsageUnknown === true;
15030
15182
  const projectedStats = usageOutcomeUnknown
@@ -15100,6 +15252,11 @@ export async function* agentLoop(messages, options) {
15100
15252
  ),
15101
15253
  );
15102
15254
  }
15255
+ yield {
15256
+ type: "run-ended",
15257
+ runId,
15258
+ reason: "compaction-usage-unknown",
15259
+ };
15103
15260
  return;
15104
15261
  }
15105
15262
  if (
@@ -15162,6 +15319,11 @@ export async function* agentLoop(messages, options) {
15162
15319
  ),
15163
15320
  );
15164
15321
  }
15322
+ yield {
15323
+ type: "run-ended",
15324
+ runId,
15325
+ reason: "compaction-settlement-failed",
15326
+ };
15165
15327
  return;
15166
15328
  }
15167
15329
  if (!hermeticExecution) {
@@ -15226,6 +15388,79 @@ export async function* agentLoop(messages, options) {
15226
15388
  }
15227
15389
  compactionUsageCall =
15228
15390
  compactionUsageCall || compactionUsageState?.calls?.at(-1) || null;
15391
+ const { getRejectedCompactionUsage } =
15392
+ await import("../lib/context-memory-kernel/live-compaction.js");
15393
+ const rejectedUsage = getRejectedCompactionUsage(_e);
15394
+ const returnedUsage = compactionUsageCall?.returnedUsage;
15395
+ const providerReceipt = _takeCompactionProviderReceipt(
15396
+ compactionUsageCall,
15397
+ workflowEffectId,
15398
+ );
15399
+ if (providerReceipt) yield providerReceipt;
15400
+ const knownPlanRejection =
15401
+ rejectedUsage &&
15402
+ returnedUsage &&
15403
+ (!rejectedUsage.callId ||
15404
+ rejectedUsage.callId === returnedUsage.callId) &&
15405
+ (!rejectedUsage.receipt.callId ||
15406
+ rejectedUsage.receipt.callId === returnedUsage.callId) &&
15407
+ rejectedUsage.provider === returnedUsage.provider &&
15408
+ rejectedUsage.model === returnedUsage.model &&
15409
+ [
15410
+ "input_tokens",
15411
+ "output_tokens",
15412
+ "cache_read_input_tokens",
15413
+ "cache_creation_input_tokens",
15414
+ ].every(
15415
+ (field) =>
15416
+ rejectedUsage.usage[field] === returnedUsage.usage[field],
15417
+ );
15418
+ if (knownPlanRejection || (!rejectedUsage && returnedUsage)) {
15419
+ automaticCompactionSettlementBlocked = true;
15420
+ // Yield through the existing host ledger/budget settlement path;
15421
+ // never claim a callback or an error flag already paid this debt.
15422
+ yield { type: "token-usage", ...returnedUsage, runId };
15423
+ yield {
15424
+ type: "compaction-degraded",
15425
+ runId,
15426
+ code: _e.code,
15427
+ reason: knownPlanRejection
15428
+ ? "canonical_compaction_plan_rejected"
15429
+ : "canonical_compaction_settlement_failed",
15430
+ summaryMode: "none",
15431
+ };
15432
+ await _awaitBackgroundUsageSettlement(
15433
+ backgroundSubAgents,
15434
+ backgroundUsageFailureState,
15435
+ );
15436
+ if (workflowEffectId) {
15437
+ if (knownPlanRejection) {
15438
+ const error = new Error(
15439
+ "Workflow-bound compaction plan was rejected; the task is incomplete",
15440
+ { cause: _e },
15441
+ );
15442
+ error.code = "CC_WORKFLOW_COMPACTION_PLAN_REJECTED";
15443
+ error.contextOutcome = "aborted";
15444
+ error.usageOutcome = "known";
15445
+ throw error;
15446
+ }
15447
+ const error = _workflowCompactionOutcomeUnknown(
15448
+ _e,
15449
+ "CC_WORKFLOW_COMPACTION_SETTLEMENT_UNKNOWN",
15450
+ "Workflow-bound semantic compaction settlement is unknown",
15451
+ );
15452
+ error.usageOutcome = "known";
15453
+ throw _markWorkflowCompactionFailureReported(error);
15454
+ }
15455
+ yield {
15456
+ type: "run-ended",
15457
+ runId,
15458
+ reason: knownPlanRejection
15459
+ ? "compaction-plan-rejected"
15460
+ : "compaction-settlement-failed",
15461
+ };
15462
+ return;
15463
+ }
15229
15464
  if (compactionUsageCall) {
15230
15465
  automaticCompactionSettlementBlocked = true;
15231
15466
  yield {
@@ -15249,6 +15484,11 @@ export async function* agentLoop(messages, options) {
15249
15484
  : _workflowCompactionOutcomeUnknown(_e),
15250
15485
  );
15251
15486
  }
15487
+ yield {
15488
+ type: "run-ended",
15489
+ runId,
15490
+ reason: "compaction-usage-unknown",
15491
+ };
15252
15492
  return;
15253
15493
  }
15254
15494
  yield {