chainlesschain 0.166.100 → 0.166.102

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 (187) hide show
  1. package/package.json +3 -3
  2. package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
  3. package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
  4. package/src/assets/web-panel/assets/{AIOps-Cd4iUOPt.js → AIOps-CyHIMEd8.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton--ucr-zko.js → ActionButton-vuNxDpHm.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-DbejYMWk.js → Analytics-D0quEM0q.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-CLgKxeGw.js → AppLayout-xRSVpbCs.js} +5 -5
  8. package/src/assets/web-panel/assets/{Artifacts-CTT5BIL5.js → Artifacts-ktfVAZBC.js} +1 -1
  9. package/src/assets/web-panel/assets/{Audit-DP-WBWe9.js → Audit-UJW6maH4.js} +1 -1
  10. package/src/assets/web-panel/assets/{BackgroundAgents-B6VqheJk.js → BackgroundAgents-BYrfdCoT.js} +1 -1
  11. package/src/assets/web-panel/assets/{Backup-VWJK5zim.js → Backup-IBgsJ7BK.js} +1 -1
  12. package/src/assets/web-panel/assets/{BaseInput-YGFO9RHd.js → BaseInput-BmP8_zxy.js} +1 -1
  13. package/src/assets/web-panel/assets/{Chat-CVfydnCd.js → Chat-urkw8_BF.js} +5 -5
  14. package/src/assets/web-panel/assets/{ChatBubbleRenderer-BICpB-qU.js → ChatBubbleRenderer-Cw44zZbh.js} +1 -1
  15. package/src/assets/web-panel/assets/{Checkbox-Bd5vKRMk.js → Checkbox-CYboo-__.js} +1 -1
  16. package/src/assets/web-panel/assets/{Codegen-DHNgPHvg.js → Codegen-DaqR_Ay8.js} +1 -1
  17. package/src/assets/web-panel/assets/{Col-CA2BYQ8T.js → Col-04BSIj_z.js} +1 -1
  18. package/src/assets/web-panel/assets/{Community-DnKJ-qpI.js → Community-DxFk7Trv.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compact-C9BZ8t4r.js → Compact-mjgWlMCB.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compliance-ByyQ2FOl.js → Compliance-CC5ee7QV.js} +1 -1
  21. package/src/assets/web-panel/assets/{Cowork-rXTwXE_c.js → Cowork-BK4BhHZd.js} +2 -2
  22. package/src/assets/web-panel/assets/{Cron-BuW-HODy.js → Cron-CP6jAxq0.js} +2 -2
  23. package/src/assets/web-panel/assets/{Crosschain-OudNtbYW.js → Crosschain-DJPaViZS.js} +1 -1
  24. package/src/assets/web-panel/assets/{DID-BQ6BxYNN.js → DID-BTLxkuOj.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dashboard-Cz5HG8tz.js → Dashboard-Djkiqh3d.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dropdown-BzclHOVv.js → Dropdown-t_eUhqom.js} +1 -1
  27. package/src/assets/web-panel/assets/{EmailListRenderer-CbJETFdy.js → EmailListRenderer-7w6USx_J.js} +1 -1
  28. package/src/assets/web-panel/assets/{EvolutionSettings-Dx_pJG3d.js → EvolutionSettings-mU5IHEk5.js} +1 -1
  29. package/src/assets/web-panel/assets/{FamilyGuardDashboard-6JCS1MNg.js → FamilyGuardDashboard-BCh-VBBC.js} +1 -1
  30. package/src/assets/web-panel/assets/{Federation-BrPkMYaf.js → Federation-Be_VpjI2.js} +1 -1
  31. package/src/assets/web-panel/assets/{FormItemContext-Bhc9pobs.js → FormItemContext-D_lzQ7PI.js} +1 -1
  32. package/src/assets/web-panel/assets/{GenericCardRenderer-BxOh07uQ.js → GenericCardRenderer-LYu3KapV.js} +1 -1
  33. package/src/assets/web-panel/assets/{Git-D_idoujr.js → Git-BBeF-PP4.js} +2 -2
  34. package/src/assets/web-panel/assets/{Governance-ZGfIRE-x.js → Governance-CoF8Kzg7.js} +1 -1
  35. package/src/assets/web-panel/assets/{Inference-DpAmcwbw.js → Inference-C4DLMnXS.js} +1 -1
  36. package/src/assets/web-panel/assets/{KnowledgeGraph-D1S1UTgP.js → KnowledgeGraph-B2mlNewk.js} +1 -1
  37. package/src/assets/web-panel/assets/{Logs-2sc8V5XV.js → Logs-DMZ_44Ya.js} +2 -2
  38. package/src/assets/web-panel/assets/MarkdownRenderer-Ck7Iv_9e.js +1 -0
  39. package/src/assets/web-panel/assets/{Marketplace-0xlFUKbe.js → Marketplace-BqDzTew_.js} +1 -1
  40. package/src/assets/web-panel/assets/{McpTools-D25eJLGm.js → McpTools-BbwSbDN9.js} +3 -3
  41. package/src/assets/web-panel/assets/{Memory-BLRGd9hM.js → Memory-DAaTWgrm.js} +2 -2
  42. package/src/assets/web-panel/assets/{MobileBridge-zpFINGzn.js → MobileBridge-BjbTGxoR.js} +1 -1
  43. package/src/assets/web-panel/assets/{MobileProjects-Cbyd-8kx.js → MobileProjects-DMODOBr-.js} +1 -1
  44. package/src/assets/web-panel/assets/{Mtc-DgXgUlHc.js → Mtc-DT9N2rCs.js} +2 -2
  45. package/src/assets/web-panel/assets/{MtcAudit-DzcL-dKH.js → MtcAudit-DagMfUVv.js} +2 -2
  46. package/src/assets/web-panel/assets/{Multisig-C3OrZ6VN.js → Multisig-C1BKP6nM.js} +3 -3
  47. package/src/assets/web-panel/assets/{NLProgramming-Bqp_vWA7.js → NLProgramming-B5LFh72i.js} +1 -1
  48. package/src/assets/web-panel/assets/{Notes-Dyn45-Ht.js → Notes-Q77V3ltW.js} +3 -3
  49. package/src/assets/web-panel/assets/{NotificationSettings-CLjafGZr.js → NotificationSettings-HxdpNIBs.js} +1 -1
  50. package/src/assets/web-panel/assets/OrderTableRenderer-Dc0DpvBH.js +1 -0
  51. package/src/assets/web-panel/assets/{Organization-5gr9hyLm.js → Organization-QL3NZ7uW.js} +4 -4
  52. package/src/assets/web-panel/assets/{Overflow-BRdU02hT.js → Overflow-B_gqOKho.js} +1 -1
  53. package/src/assets/web-panel/assets/{P2P-DIi7fzh6.js → P2P-BBJubU8Z.js} +2 -2
  54. package/src/assets/web-panel/assets/{PdhVaultBrowser-BCbS1KpA.js → PdhVaultBrowser-CFnGd-2E.js} +3 -3
  55. package/src/assets/web-panel/assets/{Permissions-BjeP9VtA.js → Permissions-BKkznIUM.js} +4 -4
  56. package/src/assets/web-panel/assets/{PersonalDataHub-y8PXOQUc.js → PersonalDataHub-DYK7ZAcd.js} +4 -4
  57. package/src/assets/web-panel/assets/{Pipeline-B0fL5uxY.js → Pipeline-CoeKpjoN.js} +1 -1
  58. package/src/assets/web-panel/assets/{Privacy-C8jCDn8Z.js → Privacy-Diw4G-92.js} +1 -1
  59. package/src/assets/web-panel/assets/{ProjectInit-B_L6Dc6V.js → ProjectInit-CHBOFkma.js} +2 -2
  60. package/src/assets/web-panel/assets/{ProjectSettings-Bb1CYbZh.js → ProjectSettings-BJIsgdOf.js} +2 -2
  61. package/src/assets/web-panel/assets/{Projects-CUSV10Cn.js → Projects-GJjItXIk.js} +1 -1
  62. package/src/assets/web-panel/assets/{Providers-mBSTDJ0E.js → Providers-o8QCimor.js} +1 -1
  63. package/src/assets/web-panel/assets/{QrScannerModal-CHxgalvt.js → QrScannerModal-z2W-zvhW.js} +1 -1
  64. package/src/assets/web-panel/assets/{QuickAsk-DI9KIMEV.js → QuickAsk-_yubhsna.js} +1 -1
  65. package/src/assets/web-panel/assets/{Recommend-B5_zW1JH.js → Recommend-CucgJwih.js} +1 -1
  66. package/src/assets/web-panel/assets/{RemoteSession-BkH4bmM5.js → RemoteSession-EzfIIRg1.js} +2 -2
  67. package/src/assets/web-panel/assets/{Reputation-DJrAqwAq.js → Reputation-_shttE67.js} +1 -1
  68. package/src/assets/web-panel/assets/{Row-xZ3MAM34.js → Row-DQA_S8-9.js} +1 -1
  69. package/src/assets/web-panel/assets/{RssFeed-CCsrLLiu.js → RssFeed-BOqWawXT.js} +3 -3
  70. package/src/assets/web-panel/assets/{Search-CTCRKvaP.js → Search-Dx1v2xOq.js} +1 -1
  71. package/src/assets/web-panel/assets/{Security-D7joyfp2.js → Security-Bt4HHsT4.js} +4 -4
  72. package/src/assets/web-panel/assets/{Services-oqHPmTG4.js → Services-sruHiQ-r.js} +2 -2
  73. package/src/assets/web-panel/assets/{Skeleton-BR_32bTG.js → Skeleton-CiBxvmOJ.js} +1 -1
  74. package/src/assets/web-panel/assets/{Skills-BoRz9mln.js → Skills-De9qKODU.js} +1 -1
  75. package/src/assets/web-panel/assets/{Sla-UAGUHZ9b.js → Sla-B_6yn8Wp.js} +1 -1
  76. package/src/assets/web-panel/assets/{SpeechSettings-DeP_rMgv.js → SpeechSettings-C2CafExS.js} +1 -1
  77. package/src/assets/web-panel/assets/{SyncSettings-CSzzMmeA.js → SyncSettings-Dhh3Qmb0.js} +2 -2
  78. package/src/assets/web-panel/assets/{Tasks-CcqOLsLB.js → Tasks-Mvo5mTWm.js} +1 -1
  79. package/src/assets/web-panel/assets/{Templates-cDbkGSDG.js → Templates-D7WVTQQy.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tenant-DmOy58cq.js → Tenant-7ur9Yfxd.js} +1 -1
  81. package/src/assets/web-panel/assets/{Terminal-CsRZH5vr.js → Terminal-BgzrOA6k.js} +2 -2
  82. package/src/assets/web-panel/assets/{TimelineRenderer-BgJrk6HG.js → TimelineRenderer-Dco20pT1.js} +1 -1
  83. package/src/assets/web-panel/assets/{Tokens-CCQglKDE.js → Tokens-hN6qBPag.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trigger-t-Gt3oBY.js → Trigger-C4f_twAM.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trust-DQgu2kI0.js → Trust-Wf1SMypp.js} +1 -1
  86. package/src/assets/web-panel/assets/{UkeySign-Cod2WUGj.js → UkeySign-DUXSyg3N.js} +1 -1
  87. package/src/assets/web-panel/assets/{VideoEditing-SGN5zaVK.js → VideoEditing-BvqsJaL0.js} +1 -1
  88. package/src/assets/web-panel/assets/{Wallet-CnLEL-LD.js → Wallet-CgAbcjKl.js} +3 -3
  89. package/src/assets/web-panel/assets/{WebAuthn-C2keUpD6.js → WebAuthn-DaLT0W3s.js} +2 -2
  90. package/src/assets/web-panel/assets/{WorkflowEditor-B1GvrwWJ.js → WorkflowEditor-CQqAXoaS.js} +1 -1
  91. package/src/assets/web-panel/assets/{chat-1E9_P_qY.js → chat-BhlohFTB.js} +1 -1
  92. package/src/assets/web-panel/assets/{colors-DuU6Os4q.js → colors-D7HqXIL8.js} +1 -1
  93. package/src/assets/web-panel/assets/{compact-item-C5NfOAcM.js → compact-item-Bqk4FCLY.js} +1 -1
  94. package/src/assets/web-panel/assets/{createContext-D4Fxz9qQ.js → createContext-CEmWrWf0.js} +1 -1
  95. package/src/assets/web-panel/assets/devWarning-YPX_TU7w.js +1 -0
  96. package/src/assets/web-panel/assets/{hasIn-C6C49iFk.js → hasIn-CDY0pFi2.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DP2DCKD-.js → index-1HBam9t1.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-B-bb-R99.js → index-6f6n0KFR.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BmvU4Tp_.js → index-B8L3_-sG.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BsH8mFp4.js → index-BHGOdvOQ.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BVE2wCeb.js → index-BNrvBWDS.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CJS6GTpv.js → index-BPmRkxeX.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-C7mh6xlu.js → index-BXRooi-O.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BZKRZYTX.js → index-BiLu-ImR.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-jFg3CPlQ.js → index-BuKGuH_y.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-BULggEX6.js → index-BxXFRLTZ.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DPzunJER.js → index-BxYO6nde.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-AO6iDCSL.js → index-C02yDu4f.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-BU5mPkNX.js → index-C3opQg47.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DSypQU1h.js → index-C9mvnSii.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DZgT7pH-.js → index-CVrwozwH.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CpiOzt7U.js → index-CYcjOnDX.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BlHkc48f.js → index-Cf1ha8l0.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CXb8gEWh.js → index-Chxt0t-A.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-HQXFl8fh.js → index-CkjgSHVz.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DpaGe-dr.js → index-CkqBoCiu.js} +3 -3
  117. package/src/assets/web-panel/assets/{index-C2nO02uW.js → index-CqK0J4Sj.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-Bu6qMjf4.js → index-CrsM-oiD.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-Bk-paNL3.js → index-Cur88hoN.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CXn-e3ki.js → index-D0nfNmbq.js} +1 -1
  121. package/src/assets/web-panel/assets/index-D53szVZQ.js +1 -0
  122. package/src/assets/web-panel/assets/{index-CDVwN9Sv.js → index-DEzL7s7P.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-B_ON9La1.js → index-DGKRAO61.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CQJoh5rw.js → index-DPBoWNwq.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-cnDfwWU5.js → index-DRcDWMwP.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BBVqlelF.js → index-DmKdCWq1.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BYg1dtne.js → index-DpI1LqJX.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-B5lzRoHp.js → index-DuMt3ewl.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-gh11zJ9h.js → index-Dwob5XoD.js} +1 -1
  130. package/src/assets/web-panel/assets/index-Ub2nJbV2.js +1 -0
  131. package/src/assets/web-panel/assets/{index-D1TXgNPA.js → index-XErJQ1yF.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-DFK6PTGJ.js → index-aBHlgMrq.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-Dh-vezHe.js → index-e9oCy7_4.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-bW6vfpLH.js → index-lBAbMOzg.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-lNmDaf3J.js → index-o_lc3eww.js} +1 -1
  136. package/src/assets/web-panel/assets/{initDefaultProps-3DSfnIpD.js → initDefaultProps-CIeEUxIN.js} +1 -1
  137. package/src/assets/web-panel/assets/{motion-DxGLmgA0.js → motion-IPIj1ZtP.js} +1 -1
  138. package/src/assets/web-panel/assets/{move-DrlLG6m5.js → move-BfSeXZ-f.js} +1 -1
  139. package/src/assets/web-panel/assets/{mtc-parser-BITbrJSb.js → mtc-parser-DX03-Xp4.js} +1 -1
  140. package/src/assets/web-panel/assets/{omit-D7k5vIbk.js → omit-z9EannfX.js} +1 -1
  141. package/src/assets/web-panel/assets/{pickAttrs-BJSvYFWo.js → pickAttrs-DXKmRkqZ.js} +1 -1
  142. package/src/assets/web-panel/assets/{placementArrow-Bf4to1jA.js → placementArrow-k2HV7cIU.js} +1 -1
  143. package/src/assets/web-panel/assets/{responsiveObserve-BXzeyzTa.js → responsiveObserve-bX7CsyWy.js} +1 -1
  144. package/src/assets/web-panel/assets/{slide-DLzNUNdj.js → slide-NskjQLbJ.js} +1 -1
  145. package/src/assets/web-panel/assets/{statusUtils-wBBnrRm_.js → statusUtils-B3IoG-Er.js} +1 -1
  146. package/src/assets/web-panel/assets/{styleChecker-BnmJzXNr.js → styleChecker-DHv_UilX.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFlexGapSupport-DrN8MrJb.js → useFlexGapSupport-DEqGB5Ng.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFs-dnkYGkjY.js → useFs-Bl9CbrqZ.js} +1 -1
  149. package/src/assets/web-panel/assets/{usePersonalDataHub-k_xkv7-k.js → usePersonalDataHub-O-Ukv93M.js} +1 -1
  150. package/src/assets/web-panel/assets/{vnode-B-v8PXpK.js → vnode-hGCHTaZt.js} +1 -1
  151. package/src/assets/web-panel/assets/{zoom-Coue8wAK.js → zoom-BWhIVeKQ.js} +1 -1
  152. package/src/assets/web-panel/index.html +1 -1
  153. package/src/command-help-index.json +1 -1
  154. package/src/commands/agent.js +64 -40
  155. package/src/commands/eval.js +11 -8
  156. package/src/data/changelog.json +26 -0
  157. package/src/harness/provider-backed-compaction.js +13 -5
  158. package/src/lib/config-schema.js +18 -5
  159. package/src/lib/context-memory-kernel/live-compaction.js +142 -61
  160. package/src/lib/context-memory-kernel/memory-query-index.js +5 -2
  161. package/src/lib/context-memory-kernel/runtime.js +4 -0
  162. package/src/lib/context-memory-kernel/segmented-memory-port.js +28 -3
  163. package/src/lib/context-source-ledger.js +52 -9
  164. package/src/lib/formal-budget-authority.js +533 -0
  165. package/src/lib/formal-budget-contract.js +609 -0
  166. package/src/lib/formal-budget-transport.js +345 -0
  167. package/src/lib/goal-condition-engine.js +25 -2
  168. package/src/lib/llm-config-defaults.js +10 -4
  169. package/src/lib/llm-pricing.js +16 -4
  170. package/src/lib/model-capabilities.js +26 -0
  171. package/src/lib/model-catalog-review.js +18 -1
  172. package/src/lib/model-context-catalog.js +41 -1
  173. package/src/lib/openai-responses.js +8 -0
  174. package/src/lib/skill-retrieval-router.js +1 -0
  175. package/src/lib/usage-pricing-context.js +33 -2
  176. package/src/repl/agent-repl.js +247 -153
  177. package/src/runtime/agent-core.js +371 -97
  178. package/src/runtime/coding-agent-contract-shared.cjs +14 -1
  179. package/src/runtime/headless-runner.js +1 -0
  180. package/src/runtime/headless-stream.js +137 -4
  181. package/src/runtime/mcp-tool-search.js +0 -0
  182. package/src/runtime/provider-stream-state.js +14 -1
  183. package/src/assets/web-panel/assets/MarkdownRenderer-575jjYE6.js +0 -1
  184. package/src/assets/web-panel/assets/OrderTableRenderer-Bx8wMauC.js +0 -1
  185. package/src/assets/web-panel/assets/devWarning-zDWbYMr7.js +0 -1
  186. package/src/assets/web-panel/assets/index-BPBsZZnT.js +0 -1
  187. package/src/assets/web-panel/assets/index-CtGQDg7m.js +0 -1
@@ -61,7 +61,11 @@ import {
61
61
  } from "../lib/task-progress-tracker.js";
62
62
  import { TOOL_RECOVERY_PAUSED_CODE } from "../lib/tool-recovery-result.js";
63
63
  import { haiku55ThinkingParams } from "../lib/provider-options.js";
64
- import { projectUsagePricingContext } from "../lib/usage-pricing-context.js";
64
+ import {
65
+ projectUsagePricingContext,
66
+ projectEnvelopePricingContext,
67
+ preserveRequestedServiceTierEvidence,
68
+ } from "../lib/usage-pricing-context.js";
65
69
  import broker from "../lib/process-execution-broker/index.js";
66
70
  import os from "os";
67
71
  import { createHash, randomUUID } from "node:crypto";
@@ -88,6 +92,7 @@ import sharedHookEvents from "../lib/settings-hook-events.js";
88
92
  import {
89
93
  resolveAgentOutputBudget,
90
94
  resolveModelCapabilityProfile,
95
+ resolveModelServiceTier,
91
96
  } from "../lib/model-capabilities.js";
92
97
  import {
93
98
  createOpenAIResponsesBody,
@@ -198,6 +203,7 @@ import {
198
203
  settleManagedToolCheckpoint,
199
204
  } from "../lib/managed-tool-checkpoint.js";
200
205
  import { sessionBudgetAdmissionError } from "../lib/session-budget-production-root.js";
206
+ import { projectRuntimeTokenUsage } from "../lib/runtime-usage-ledger.js";
201
207
  import {
202
208
  createMcpCallLedger,
203
209
  McpEffect,
@@ -1538,18 +1544,19 @@ function filesystemIdentity(stats) {
1538
1544
  function sameFilesystemObjectIdentity(left, right) {
1539
1545
  return Boolean(
1540
1546
  left &&
1541
- right &&
1542
- left.dev === right.dev &&
1543
- left.ino === right.ino &&
1544
- left.type === right.type,
1547
+ right &&
1548
+ left.dev === right.dev &&
1549
+ left.ino === right.ino &&
1550
+ left.type === right.type,
1545
1551
  );
1546
1552
  }
1547
1553
 
1548
1554
  function sameFilesystemIdentity(left, right, { content = false } = {}) {
1549
1555
  return Boolean(
1550
1556
  sameFilesystemObjectIdentity(left, right) &&
1551
- left.nlink === right.nlink &&
1552
- (!content || (left.size === right.size && left.mtimeNs === right.mtimeNs)),
1557
+ left.nlink === right.nlink &&
1558
+ (!content ||
1559
+ (left.size === right.size && left.mtimeNs === right.mtimeNs)),
1553
1560
  );
1554
1561
  }
1555
1562
 
@@ -3440,8 +3447,9 @@ export async function executeTool(name, args, context = {}) {
3440
3447
  GUARDED_FILE_MUTATION_TOOLS.has(name) &&
3441
3448
  settingsVerdict.decision !== "allow"
3442
3449
  ) {
3443
- const { sensitiveFileReason, autoExecConfigReason } =
3444
- await import("../lib/sensitive-file-guard.js");
3450
+ const { sensitiveFileReason, autoExecConfigReason } = await import(
3451
+ "../lib/sensitive-file-guard.js"
3452
+ );
3445
3453
  const guarded = fileMutationPaths(name, args)
3446
3454
  .map((candidatePath) => ({
3447
3455
  path: candidatePath,
@@ -3476,8 +3484,9 @@ export async function executeTool(name, args, context = {}) {
3476
3484
  GUARDED_FILE_MUTATION_TOOLS.has(name) &&
3477
3485
  settingsVerdict.decision !== "allow"
3478
3486
  ) {
3479
- const { sessionStorePathReason } =
3480
- await import("../lib/session-store-guard.js");
3487
+ const { sessionStorePathReason } = await import(
3488
+ "../lib/session-store-guard.js"
3489
+ );
3481
3490
  const guarded = fileMutationPaths(name, args)
3482
3491
  .map((candidatePath) => ({
3483
3492
  path: candidatePath,
@@ -4222,8 +4231,9 @@ export async function executeTool(name, args, context = {}) {
4222
4231
  context.externalToolExecutors
4223
4232
  ) {
4224
4233
  try {
4225
- const { collectIdeDiagnostics, formatIdeDiagnostics } =
4226
- await import("../lib/ide-context.js");
4234
+ const { collectIdeDiagnostics, formatIdeDiagnostics } = await import(
4235
+ "../lib/ide-context.js"
4236
+ );
4227
4237
  const diags = await collectIdeDiagnostics(
4228
4238
  {
4229
4239
  mcpClient: context.mcpHostClient || context.mcpClient,
@@ -4765,8 +4775,9 @@ export async function _getSharedCodeIntel(cwd) {
4765
4775
  const root = path.resolve(cwd || process.cwd());
4766
4776
  let entry = _codeIntelPool.get(root);
4767
4777
  if (!entry) {
4768
- const { CodeIntelligence } =
4769
- await import("../lib/lsp/code-intelligence.js");
4778
+ const { CodeIntelligence } = await import(
4779
+ "../lib/lsp/code-intelligence.js"
4780
+ );
4770
4781
  // Re-check AFTER the await: two concurrent callers (the parallel read-only
4771
4782
  // batch runs several `code_intelligence` calls at once) both observed an
4772
4783
  // empty pool before this `await import`, so without this guard both would
@@ -4855,8 +4866,9 @@ async function _postEditDiagnostics(filePath, cwd, additionalDirectories) {
4855
4866
  }
4856
4867
  let hasServer = false;
4857
4868
  try {
4858
- const { languageIdForFile, resolveServer } =
4859
- await import("../lib/lsp/lsp-server-registry.js");
4869
+ const { languageIdForFile, resolveServer } = await import(
4870
+ "../lib/lsp/lsp-server-registry.js"
4871
+ );
4860
4872
  const languageId = languageIdForFile(filePath);
4861
4873
  if (!languageId) return null; // unsupported file type — no LSP, no cost
4862
4874
  hasServer = Boolean(resolveServer(languageId, root));
@@ -4879,8 +4891,9 @@ async function _postEditDiagnostics(filePath, cwd, additionalDirectories) {
4879
4891
  // the model sees the most severe diagnostics first and can't be flooded by
4880
4892
  // a pathological diagnostics dump. Budget is overridable via
4881
4893
  // CC_EDIT_DIAGNOSTICS_TOKENS (default 2000).
4882
- const { capDiagnostics } =
4883
- await import("../lib/lsp/diagnostics-scheduler.js");
4894
+ const { capDiagnostics } = await import(
4895
+ "../lib/lsp/diagnostics-scheduler.js"
4896
+ );
4884
4897
  const budget = Number(process.env.CC_EDIT_DIAGNOSTICS_TOKENS) || 2000;
4885
4898
  const { kept } = capDiagnostics(diags, { maxTokens: budget });
4886
4899
  return kept.length ? kept : null;
@@ -4944,12 +4957,14 @@ async function _getSubtreeLoader(cwd, sessionScope = "__legacy__") {
4944
4957
  }
4945
4958
  let loader = scopedLoaders.get(sessionScope);
4946
4959
  if (!loader) {
4947
- const { SubtreeInstructionLoader } =
4948
- await import("../lib/project-instructions.js");
4960
+ const { SubtreeInstructionLoader } = await import(
4961
+ "../lib/project-instructions.js"
4962
+ );
4949
4963
  let instructionExcludes;
4950
4964
  try {
4951
- const { readStringArraySetting } =
4952
- await import("../lib/settings-loader.cjs");
4965
+ const { readStringArraySetting } = await import(
4966
+ "../lib/settings-loader.cjs"
4967
+ );
4953
4968
  instructionExcludes = readStringArraySetting("instructionExcludes", {
4954
4969
  cwd: root,
4955
4970
  });
@@ -4994,8 +5009,9 @@ async function _prepareSubtreeInstructions(
4994
5009
  }
4995
5010
  const fresh = [...discovered.values()];
4996
5011
  if (!fresh || !fresh.length) return null;
4997
- const { DEFAULT_MAX_FILE_BYTES } =
4998
- await import("../lib/project-instructions.js");
5012
+ const { DEFAULT_MAX_FILE_BYTES } = await import(
5013
+ "../lib/project-instructions.js"
5014
+ );
4999
5015
  const out = [];
5000
5016
  const errors = [];
5001
5017
  for (const f of fresh) {
@@ -5102,8 +5118,9 @@ async function _withSubtreeInstructions(
5102
5118
  async function filterSkillsByCwd(skills, cwd) {
5103
5119
  try {
5104
5120
  if (!Array.isArray(skills) || skills.every((s) => !s?.paths)) return skills;
5105
- const { filterSkillsByRelCwd, relCwdForCwd } =
5106
- await import("../lib/skill-path-scope.js");
5121
+ const { filterSkillsByRelCwd, relCwdForCwd } = await import(
5122
+ "../lib/skill-path-scope.js"
5123
+ );
5107
5124
  const { findProjectRoot } = await import("../lib/project-detector.js");
5108
5125
  const root = (cwd && findProjectRoot(cwd)) || cwd || "";
5109
5126
  return filterSkillsByRelCwd(skills, relCwdForCwd(cwd, root));
@@ -5118,8 +5135,9 @@ async function promoteBrowserGeneratedArtifact(
5118
5135
  ) {
5119
5136
  if (!filePath) return { artifact: null, error: null };
5120
5137
  try {
5121
- const { ArtifactStore, publicArtifactMetadata } =
5122
- await import("../lib/artifact-store.js");
5138
+ const { ArtifactStore, publicArtifactMetadata } = await import(
5139
+ "../lib/artifact-store.js"
5140
+ );
5123
5141
  const entry = new ArtifactStore().publish({
5124
5142
  filePath,
5125
5143
  title,
@@ -5172,8 +5190,9 @@ async function promoteBrowserDownload(
5172
5190
  async function publishBrowserEvidence(envelope, sessionId) {
5173
5191
  if (!envelope?.envelopeDigest) return { artifact: null, error: null };
5174
5192
  try {
5175
- const { ArtifactStore, publicArtifactMetadata } =
5176
- await import("../lib/artifact-store.js");
5193
+ const { ArtifactStore, publicArtifactMetadata } = await import(
5194
+ "../lib/artifact-store.js"
5195
+ );
5177
5196
  const {
5178
5197
  browserEvidenceDigest,
5179
5198
  canonicalBrowserEvidenceJson,
@@ -5236,8 +5255,9 @@ async function publishBrowserEvidence(envelope, sessionId) {
5236
5255
  }
5237
5256
 
5238
5257
  async function resolveBrowserUploadArtifact(artifactId, sessionId) {
5239
- const { ArtifactStore, publicArtifactMetadata } =
5240
- await import("../lib/artifact-store.js");
5258
+ const { ArtifactStore, publicArtifactMetadata } = await import(
5259
+ "../lib/artifact-store.js"
5260
+ );
5241
5261
  const store = new ArtifactStore();
5242
5262
  return store.withIndexSnapshot((entries) => {
5243
5263
  const matches = entries.filter((entry) => entry.id === artifactId);
@@ -6218,8 +6238,9 @@ async function executeToolInner(
6218
6238
  // through PowerShell via explicit argv (`powershell.exe -NoProfile
6219
6239
  // [-ExecutionPolicy <p>] -Command <cmd>`). The unconfigured path keeps
6220
6240
  // the historical default shell byte-identical (useDefaultShell=true).
6221
- const { resolveShellInvocation } =
6222
- await import("../lib/shell-selector.cjs");
6241
+ const { resolveShellInvocation } = await import(
6242
+ "../lib/shell-selector.cjs"
6243
+ );
6223
6244
  let shellInv = resolveShellInvocation({
6224
6245
  command: args.command,
6225
6246
  requested: args.shell,
@@ -6992,8 +7013,9 @@ async function executeToolInner(
6992
7013
  let removeSettingsAuthorityListener = null;
6993
7014
  if (needsEgress) {
6994
7015
  try {
6995
- const { startEgressProxyWorker } =
6996
- await import("../lib/sandbox-egress-worker.js");
7016
+ const { startEgressProxyWorker } = await import(
7017
+ "../lib/sandbox-egress-worker.js"
7018
+ );
6997
7019
  if (dockerEgress) {
6998
7020
  privateSocketDir = fs.mkdtempSync(
6999
7021
  path.join(os.tmpdir(), "cc-egress-"),
@@ -7034,8 +7056,9 @@ async function executeToolInner(
7034
7056
  // Proxy startup and dynamic imports are asynchronous. Re-read the
7035
7057
  // live authority after they settle and before sandbox dispatch.
7036
7058
  if (dockerEgress && proxyHandle?.socketPath) {
7037
- const { createDockerEgressAuthorityMonitor } =
7038
- await import("../lib/sandbox-egress-authority-monitor.js");
7059
+ const { createDockerEgressAuthorityMonitor } = await import(
7060
+ "../lib/sandbox-egress-authority-monitor.js"
7061
+ );
7039
7062
  authorityMonitor = createDockerEgressAuthorityMonitor({
7040
7063
  sessionId: sessionId || null,
7041
7064
  policyVersion:
@@ -7655,8 +7678,9 @@ async function executeToolInner(
7655
7678
  !ruleAllowed &&
7656
7679
  typeof approvalGate.decide === "function"
7657
7680
  ) {
7658
- const { APPROVAL_RISK, APPROVAL_DECISION } =
7659
- await import("@chainlesschain/session-core");
7681
+ const { APPROVAL_RISK, APPROVAL_DECISION } = await import(
7682
+ "@chainlesschain/session-core"
7683
+ );
7660
7684
  const gate = await approvalGate.decide({
7661
7685
  sessionId,
7662
7686
  riskLevel: APPROVAL_RISK.HIGH,
@@ -7867,8 +7891,9 @@ async function executeToolInner(
7867
7891
 
7868
7892
  case "slash_command": {
7869
7893
  try {
7870
- const { getCommand, expandCommand, discoverCommands } =
7871
- await import("../lib/slash-commands.js");
7894
+ const { getCommand, expandCommand, discoverCommands } = await import(
7895
+ "../lib/slash-commands.js"
7896
+ );
7872
7897
  const raw = String(args.command || "").trim();
7873
7898
  if (!raw) {
7874
7899
  return attachDescriptor({
@@ -8079,8 +8104,9 @@ async function executeToolInner(
8079
8104
 
8080
8105
  case "notify": {
8081
8106
  try {
8082
- const { sendAgentNotification } =
8083
- await import("../lib/agent-notify.js");
8107
+ const { sendAgentNotification } = await import(
8108
+ "../lib/agent-notify.js"
8109
+ );
8084
8110
  const outcome = await sendAgentNotification({
8085
8111
  title: args.title,
8086
8112
  body: args.body,
@@ -8094,8 +8120,9 @@ async function executeToolInner(
8094
8120
 
8095
8121
  case "schedule": {
8096
8122
  try {
8097
- const { AgentScheduleStore } =
8098
- await import("../lib/agent-schedule-store.js");
8123
+ const { AgentScheduleStore } = await import(
8124
+ "../lib/agent-schedule-store.js"
8125
+ );
8099
8126
  const { parseDuration } = await import("../lib/loop.js");
8100
8127
  const store = new AgentScheduleStore();
8101
8128
  const action = String(args.action || "").toLowerCase();
@@ -8218,8 +8245,9 @@ async function executeToolInner(
8218
8245
  // Only METADATA returns to the conversation (the transcript never
8219
8246
  // carries the file body); `cc artifacts` lists/inspects/cleans.
8220
8247
  try {
8221
- const { ArtifactStore, publicArtifactMetadata } =
8222
- await import("../lib/artifact-store.js");
8248
+ const { ArtifactStore, publicArtifactMetadata } = await import(
8249
+ "../lib/artifact-store.js"
8250
+ );
8223
8251
  const store = new ArtifactStore();
8224
8252
  const entry = store.publish({
8225
8253
  filePath: path.resolve(cwd, String(args.path || "")),
@@ -8309,8 +8337,9 @@ async function executeToolInner(
8309
8337
  !ruleAllowed &&
8310
8338
  typeof approvalGate.decide === "function"
8311
8339
  ) {
8312
- const { APPROVAL_RISK, APPROVAL_DECISION } =
8313
- await import("@chainlesschain/session-core");
8340
+ const { APPROVAL_RISK, APPROVAL_DECISION } = await import(
8341
+ "@chainlesschain/session-core"
8342
+ );
8314
8343
  const summary = Array.isArray(args.actions)
8315
8344
  ? args.actions
8316
8345
  .map((a) => a?.type)
@@ -8435,8 +8464,9 @@ async function executeToolInner(
8435
8464
  case "search_files": {
8436
8465
  if (typeof args.path === "string" && args.path.length > 0) {
8437
8466
  const file = path.resolve(cwd, args.path);
8438
- const { credentialFileReason } =
8439
- await import("../lib/credential-guard.js");
8467
+ const { credentialFileReason } = await import(
8468
+ "../lib/credential-guard.js"
8469
+ );
8440
8470
  const reason =
8441
8471
  credentialFileReason(file) ||
8442
8472
  (fs.existsSync(file)
@@ -9181,6 +9211,22 @@ async function executeToolInner(
9181
9211
  }
9182
9212
 
9183
9213
  case "list_skills": {
9214
+ const limit = args.limit ?? 20;
9215
+ const offset = args.offset ?? 0;
9216
+ if (
9217
+ !Number.isSafeInteger(limit) ||
9218
+ limit < 1 ||
9219
+ limit > 64 ||
9220
+ !Number.isSafeInteger(offset) ||
9221
+ offset < 0 ||
9222
+ offset > 10_000
9223
+ ) {
9224
+ return attachDescriptor({
9225
+ error:
9226
+ "Skill directory limit must be 1–64 and offset must be 0–10000.",
9227
+ code: "CC_SKILL_DIRECTORY_PAGE_INVALID",
9228
+ });
9229
+ }
9184
9230
  let skills = await filterSkillsByCwd(
9185
9231
  skillLoader.getResolvedSkills().filter(skillAllowed),
9186
9232
  cwd,
@@ -9270,6 +9316,19 @@ async function executeToolInner(
9270
9316
  }
9271
9317
  }
9272
9318
  }
9319
+ if (!routing) {
9320
+ const key = (skill) =>
9321
+ `${skill.id}\u0000${skill.source || ""}\u0000${skill.executionIdentity?.contentDigest || ""}`;
9322
+ skills = [...skills].sort((left, right) =>
9323
+ key(left) < key(right) ? -1 : key(left) > key(right) ? 1 : 0,
9324
+ );
9325
+ }
9326
+ const totalCount = routing?.matchedCount ?? skills.length;
9327
+ const candidateCount = skills.length;
9328
+ skills = skills.slice(offset, offset + limit);
9329
+ const nextOffset =
9330
+ offset + skills.length < candidateCount ? offset + skills.length : null;
9331
+ const hasMore = offset + skills.length < totalCount;
9273
9332
  skillLoader.recordDescriptorUse?.(skills, {
9274
9333
  sessionId,
9275
9334
  turnId,
@@ -9277,6 +9336,19 @@ async function executeToolInner(
9277
9336
  });
9278
9337
  return attachDescriptor({
9279
9338
  count: skills.length,
9339
+ totalCount,
9340
+ offset,
9341
+ limit,
9342
+ hasMore,
9343
+ nextOffset,
9344
+ ...(hasMore
9345
+ ? {
9346
+ hint:
9347
+ nextOffset == null
9348
+ ? "Refine query or category to search beyond the top 64 matches."
9349
+ : "Use nextOffset for the next page, or query/category to narrow the directory.",
9350
+ }
9351
+ : {}),
9280
9352
  ...(routing
9281
9353
  ? {
9282
9354
  routing: {
@@ -10700,8 +10772,9 @@ async function _executeSpawnSubAgent(args, ctx) {
10700
10772
  // the breadth counter increments so spawnedCount is this-spawn-exclusive.
10701
10773
  if (ctx.subAgentContract) {
10702
10774
  try {
10703
- const { enforceRecursionLimits } =
10704
- await import("../lib/subagent-contract.js");
10775
+ const { enforceRecursionLimits } = await import(
10776
+ "../lib/subagent-contract.js"
10777
+ );
10705
10778
  const recur = enforceRecursionLimits({
10706
10779
  depth: currentDepth,
10707
10780
  spawnedCount: ctx.subAgentBudget?.spawned || 0,
@@ -10887,8 +10960,9 @@ async function _executeSpawnSubAgent(args, ctx) {
10887
10960
  let inheritedMcp = null;
10888
10961
  let inheritedHooks = null;
10889
10962
  try {
10890
- const { filterInheritedMcp, filterInheritedHooks } =
10891
- await import("../lib/subagent-inheritance.js");
10963
+ const { filterInheritedMcp, filterInheritedHooks } = await import(
10964
+ "../lib/subagent-inheritance.js"
10965
+ );
10892
10966
  inheritedMcp = filterInheritedMcp(
10893
10967
  {
10894
10968
  extraToolDefinitions: ctx.extraToolDefinitions,
@@ -10921,8 +10995,9 @@ async function _executeSpawnSubAgent(args, ctx) {
10921
10995
  // repo, refuse the spawn instead of silently running in the parent checkout.
10922
10996
  if (subIsolation === "worktree") {
10923
10997
  try {
10924
- const { resolveIsolationFailClosed } =
10925
- await import("../lib/subagent-contract.js");
10998
+ const { resolveIsolationFailClosed } = await import(
10999
+ "../lib/subagent-contract.js"
11000
+ );
10926
11001
  const { isGitRepo } = await import("../lib/git-integration.js");
10927
11002
  const iso = resolveIsolationFailClosed({
10928
11003
  requested: "worktree",
@@ -10941,8 +11016,9 @@ async function _executeSpawnSubAgent(args, ctx) {
10941
11016
  let profile = null;
10942
11017
  if (profileName) {
10943
11018
  try {
10944
- const { getSubAgentProfile } =
10945
- await import("../lib/sub-agent-profiles.js");
11019
+ const { getSubAgentProfile } = await import(
11020
+ "../lib/sub-agent-profiles.js"
11021
+ );
10946
11022
  profile = getSubAgentProfile(profileName);
10947
11023
  if (!profile) {
10948
11024
  return {
@@ -11010,8 +11086,9 @@ async function _executeSpawnSubAgent(args, ctx) {
11010
11086
  let childApprovalGate = null;
11011
11087
  if (effectiveContract?.permissionMode) {
11012
11088
  try {
11013
- const { resolvePermissionMode, resolveEnabledTools } =
11014
- await import("./headless-runner.js");
11089
+ const { resolvePermissionMode, resolveEnabledTools } = await import(
11090
+ "./headless-runner.js"
11091
+ );
11015
11092
  const perm = resolvePermissionMode(effectiveContract.permissionMode);
11016
11093
  if (perm.readOnly) {
11017
11094
  allowedTools = resolveEnabledTools({ allowedTools, readOnly: true });
@@ -11271,8 +11348,9 @@ async function _executeSpawnSubAgent(args, ctx) {
11271
11348
  let subWorktreeOptions = null;
11272
11349
  if (subIsolation === "worktree") {
11273
11350
  try {
11274
- const { normalizeSparsePaths } =
11275
- await import("../lib/worktree-sparse.js");
11351
+ const { normalizeSparsePaths } = await import(
11352
+ "../lib/worktree-sparse.js"
11353
+ );
11276
11354
  const sparse = normalizeSparsePaths(
11277
11355
  args.sparsePaths ?? mdSparsePaths ?? null,
11278
11356
  );
@@ -11474,10 +11552,11 @@ async function _executeSpawnSubAgent(args, ctx) {
11474
11552
 
11475
11553
  // Resolve the registry ONCE before the try so the failure path can also move
11476
11554
  // the sub-agent out of `_active` (the success path does this via complete()).
11477
- const { SubAgentRegistry } =
11478
- await import("../lib/sub-agent-registry.js").catch(() => ({
11479
- SubAgentRegistry: null,
11480
- }));
11555
+ const { SubAgentRegistry } = await import(
11556
+ "../lib/sub-agent-registry.js"
11557
+ ).catch(() => ({
11558
+ SubAgentRegistry: null,
11559
+ }));
11481
11560
  let registry = null;
11482
11561
  if (SubAgentRegistry) {
11483
11562
  try {
@@ -11797,6 +11876,12 @@ function _openAIProviderRequestReceipt(response, data, clientRequestId) {
11797
11876
  * @returns {Promise<object>} response with .message
11798
11877
  */
11799
11878
  export async function chatWithTools(rawMessages, options) {
11879
+ if (options.serviceTier != null) {
11880
+ resolveModelServiceTier(
11881
+ resolveModelCapabilityProfile(options),
11882
+ options.serviceTier,
11883
+ );
11884
+ }
11800
11885
  const evolutionIngress =
11801
11886
  options.evolutionIngress == null
11802
11887
  ? null
@@ -11826,8 +11911,9 @@ export async function chatWithTools(rawMessages, options) {
11826
11911
  options.contextMemoryPreplanned !== true &&
11827
11912
  options.contextMemorySkipPlanning !== true
11828
11913
  ) {
11829
- const { prepareCanonicalProviderContext } =
11830
- await import("../lib/context-memory-kernel/provider-context.js");
11914
+ const { prepareCanonicalProviderContext } = await import(
11915
+ "../lib/context-memory-kernel/provider-context.js"
11916
+ );
11831
11917
  const prepared = await prepareCanonicalProviderContext(rawMessages, {
11832
11918
  ...options,
11833
11919
  contextMemoryToolDefinitions: tools,
@@ -11860,6 +11946,11 @@ export async function chatWithTools(rawMessages, options) {
11860
11946
 
11861
11947
  throwIfAborted(signal);
11862
11948
 
11949
+ // Host accounting starts only after request admission. A rejected model
11950
+ // projection never reaches the provider; failures after this boundary must
11951
+ // still retain conservative usage accounting regardless of error metadata.
11952
+ await options.onProviderCallStart?.();
11953
+
11863
11954
  if (provider === "ollama") {
11864
11955
  const apiUrl = `${baseUrl}/api/chat`;
11865
11956
  // Multimodal (`cc agent --image`): ollama wants `{content, images:[base64]}`
@@ -12184,6 +12275,7 @@ export async function chatWithTools(rawMessages, options) {
12184
12275
  reasoning: _openAIResponsesReasoningParams(options, modelProfile),
12185
12276
  stream: typeof options.onToken === "function",
12186
12277
  modelProfile,
12278
+ serviceTier: options.serviceTier,
12187
12279
  });
12188
12280
  if (typeof options.onToken === "function") {
12189
12281
  return await _retryStreamingChat(
@@ -12237,6 +12329,11 @@ export async function chatWithTools(rawMessages, options) {
12237
12329
  }
12238
12330
  const data = await response.json();
12239
12331
  const out = normalizeOpenAIResponsesResponse(data);
12332
+ if (out.usage)
12333
+ out.usage = preserveRequestedServiceTierEvidence(
12334
+ out.usage,
12335
+ options.serviceTier,
12336
+ );
12240
12337
  delete out.responseId;
12241
12338
  const providerReceipt = supportsOpenAIRequestIdentity
12242
12339
  ? _openAIProviderRequestReceipt(response, data, providerRequestId)
@@ -12373,6 +12470,7 @@ export async function chatWithTools(rawMessages, options) {
12373
12470
  input_tokens: promptTokens - cached,
12374
12471
  output_tokens: completionTokens,
12375
12472
  cache_read_input_tokens: cached,
12473
+ ...projectEnvelopePricingContext(data.usage, data),
12376
12474
  };
12377
12475
  }
12378
12476
  }
@@ -13061,6 +13159,11 @@ async function _chatOpenAIResponsesStreaming(
13061
13159
  return out;
13062
13160
  }
13063
13161
  const out = finalizeOpenAIResponsesStream(state);
13162
+ if (out.usage)
13163
+ out.usage = preserveRequestedServiceTierEvidence(
13164
+ out.usage,
13165
+ body.service_tier,
13166
+ );
13064
13167
  const responseId = out.responseId || state.responseId;
13065
13168
  delete out.responseId;
13066
13169
  const providerReceipt = _openAIProviderRequestReceipt(
@@ -13471,6 +13574,19 @@ function _workflowNestedToolOutcomeUnknown(binding, toolName, result) {
13471
13574
  return error;
13472
13575
  }
13473
13576
 
13577
+ function _takeCompactionProviderReceipt(call, workflowEffectId) {
13578
+ if (!call?.providerReceipt || call.providerReceiptEmitted) return null;
13579
+ call.providerReceiptEmitted = true;
13580
+ return {
13581
+ type: "provider-request-receipt",
13582
+ callId: call.callId,
13583
+ workflowEffectId,
13584
+ callSequence: call.callSequence,
13585
+ source: "semantic-compaction",
13586
+ ...call.providerReceipt,
13587
+ };
13588
+ }
13589
+
13474
13590
  function _workflowCompactionOutcomeUnknown(
13475
13591
  cause,
13476
13592
  code = "CC_WORKFLOW_COMPACTION_PROVIDER_OUTCOME_UNKNOWN",
@@ -13870,6 +13986,21 @@ function _instrumentAutoCompactorUsage(compactor, options) {
13870
13986
  this,
13871
13987
  requestBinding ? [...args, requestBinding] : args,
13872
13988
  );
13989
+ // Keep validated provider-returned usage private to this actual call.
13990
+ // It is not settled yet: the host consumes token-usage exactly once.
13991
+ try {
13992
+ call.returnedUsage = projectRuntimeTokenUsage({
13993
+ callId: call.callId,
13994
+ provider: result?.provider || call.provider,
13995
+ model: result?.model || call.model,
13996
+ source: call.source,
13997
+ usage: result?.usage,
13998
+ });
13999
+ if (result?.callId && result.callId !== call.callId)
14000
+ call.returnedUsage = null;
14001
+ } catch {
14002
+ call.returnedUsage = null;
14003
+ }
13873
14004
  call.providerReceipt = providerRequestId
13874
14005
  ? _snapshotProviderRequestReceipt(
13875
14006
  result?.providerReceipt,
@@ -13879,6 +14010,7 @@ function _instrumentAutoCompactorUsage(compactor, options) {
13879
14010
  : null;
13880
14011
  return result;
13881
14012
  } catch (error) {
14013
+ call.returnedUsage = null;
13882
14014
  if (workflowEffectId) {
13883
14015
  throw _workflowCompactionOutcomeUnknown(error);
13884
14016
  }
@@ -13953,8 +14085,9 @@ async function _getAutoCompactor(options) {
13953
14085
  let canonicalRequired = false;
13954
14086
  try {
13955
14087
  const { feature } = await import("../lib/feature-flags.js");
13956
- const { resolveCliContextMemoryCutover } =
13957
- await import("../lib/context-memory-kernel/authority.js");
14088
+ const { resolveCliContextMemoryCutover } = await import(
14089
+ "../lib/context-memory-kernel/authority.js"
14090
+ );
13958
14091
  const cutover = resolveCliContextMemoryCutover({
13959
14092
  env: options.contextMemoryEnv || process.env,
13960
14093
  scopeKey: options.sessionId
@@ -13963,8 +14096,9 @@ async function _getAutoCompactor(options) {
13963
14096
  });
13964
14097
  canonicalRequired = cutover.canonical;
13965
14098
  if (feature("PROMPT_COMPRESSOR") || cutover.canonical) {
13966
- const { PromptCompressor } =
13967
- await import("../harness/prompt-compressor.js");
14099
+ const { PromptCompressor } = await import(
14100
+ "../harness/prompt-compressor.js"
14101
+ );
13968
14102
  const llmQuery =
13969
14103
  typeof options.compactionLlmQuery === "function"
13970
14104
  ? options.compactionLlmQuery
@@ -14014,8 +14148,9 @@ async function _getAutoCompactor(options) {
14014
14148
  compressor = _instrumentAutoCompactorUsage(compressor, options);
14015
14149
  if (cutover.canonical) {
14016
14150
  const compatibilitySummarizer = compressor;
14017
- const { compactLiveMessagesCanonical } =
14018
- await import("../lib/context-memory-kernel/live-compaction.js");
14151
+ const { compactLiveMessagesCanonical } = await import(
14152
+ "../lib/context-memory-kernel/live-compaction.js"
14153
+ );
14019
14154
  compressor = {
14020
14155
  canonicalKernel: true,
14021
14156
  shouldAutoCompact: (messages) =>
@@ -14026,8 +14161,8 @@ async function _getAutoCompactor(options) {
14026
14161
  compressOptions,
14027
14162
  sessionId: options.sessionId,
14028
14163
  operationId: `auto-${randomUUID()}`,
14029
- provider: options.provider,
14030
- model: options.model,
14164
+ provider: options.provider || "ollama",
14165
+ model: options.model || "unknown",
14031
14166
  env: options.contextMemoryEnv || process.env,
14032
14167
  persist: options.persistCompaction !== false,
14033
14168
  trigger: "auto",
@@ -14337,6 +14472,12 @@ function permissionDecision(callId, tool, result) {
14337
14472
  }
14338
14473
 
14339
14474
  export async function* agentLoop(messages, options) {
14475
+ if (options.serviceTier != null) {
14476
+ resolveModelServiceTier(
14477
+ resolveModelCapabilityProfile(options),
14478
+ options.serviceTier,
14479
+ );
14480
+ }
14340
14481
  const executionPolicy = captureAgentExecutionPolicy(options, {
14341
14482
  hermetic: true,
14342
14483
  });
@@ -14351,8 +14492,9 @@ export async function* agentLoop(messages, options) {
14351
14492
  : captureAgentEvolutionIngress(options.evolutionIngress);
14352
14493
  let llmCall = configuredChatFn || chatWithTools;
14353
14494
  if (evolutionIngress !== null && configuredChatFn) {
14354
- const { captureCanonicalFallbackChatFn } =
14355
- await import("./fallback-model.js");
14495
+ const { captureCanonicalFallbackChatFn } = await import(
14496
+ "./fallback-model.js"
14497
+ );
14356
14498
  llmCall = captureCanonicalFallbackChatFn(
14357
14499
  configuredChatFn,
14358
14500
  evolutionIngress,
@@ -14361,8 +14503,9 @@ export async function* agentLoop(messages, options) {
14361
14503
  // Shared iteration budget — replaces hardcoded MAX_ITERATIONS.
14362
14504
  // When options.iterationBudget is provided (e.g. from parent agent),
14363
14505
  // the same budget instance is shared, so parent+child consume from one pool.
14364
- const { IterationBudget, WarningLevel } =
14365
- await import("../lib/iteration-budget.js");
14506
+ const { IterationBudget, WarningLevel } = await import(
14507
+ "../lib/iteration-budget.js"
14508
+ );
14366
14509
  const budget = options.iterationBudget || new IterationBudget();
14367
14510
  const { HostResourceBudget } = await import("../lib/host-resource-budget.js");
14368
14511
  const hostResourceBudget =
@@ -14712,8 +14855,9 @@ export async function* agentLoop(messages, options) {
14712
14855
  options.strictUsageTelemetry !== true &&
14713
14856
  workflowEffectId == null
14714
14857
  ) {
14715
- const { makeRunnableProviderFallback } =
14716
- await import("../lib/runnable-provider.js");
14858
+ const { makeRunnableProviderFallback } = await import(
14859
+ "../lib/runnable-provider.js"
14860
+ );
14717
14861
  llmCall = makeRunnableProviderFallback(llmCall, {
14718
14862
  onFallback: ({ from, to, reason, fromModel, toModel }) => {
14719
14863
  // Telemetry: a provider/model fallback is a reliability signal — count
@@ -15062,6 +15206,37 @@ export async function* agentLoop(messages, options) {
15062
15206
  !["committed", "degraded"].includes(stats.canonicalReceipt.status)
15063
15207
  ) {
15064
15208
  automaticCompactionSettlementBlocked = true;
15209
+ const unsettledCall = compactionUsageState.calls.at(-1);
15210
+ if (unsettledCall) {
15211
+ const providerReceipt = _takeCompactionProviderReceipt(
15212
+ unsettledCall,
15213
+ workflowEffectId,
15214
+ );
15215
+ if (providerReceipt) yield providerReceipt;
15216
+ if (
15217
+ unsettledCall.returnedUsage &&
15218
+ stats.summaryUsageUnknown !== true
15219
+ ) {
15220
+ yield {
15221
+ type: "token-usage",
15222
+ ...unsettledCall.returnedUsage,
15223
+ runId,
15224
+ };
15225
+ } else {
15226
+ yield {
15227
+ type: "compaction-usage-unknown",
15228
+ callId: unsettledCall.callId,
15229
+ runId,
15230
+ provider: unsettledCall.provider,
15231
+ model: unsettledCall.model,
15232
+ source: "semantic-compaction",
15233
+ code: "provider_usage_unsettled",
15234
+ reason:
15235
+ stats.summaryUsageUnknownReason ||
15236
+ "provider_transport_outcome_unknown",
15237
+ };
15238
+ }
15239
+ }
15065
15240
  yield {
15066
15241
  type: "compaction-degraded",
15067
15242
  runId,
@@ -15080,6 +15255,20 @@ export async function* agentLoop(messages, options) {
15080
15255
  backgroundSubAgents,
15081
15256
  backgroundUsageFailureState,
15082
15257
  );
15258
+ if (workflowEffectId) {
15259
+ throw _markWorkflowCompactionFailureReported(
15260
+ _workflowCompactionOutcomeUnknown(
15261
+ null,
15262
+ "CC_WORKFLOW_COMPACTION_SETTLEMENT_UNKNOWN",
15263
+ "Workflow-bound semantic compaction requires reconciliation",
15264
+ ),
15265
+ );
15266
+ }
15267
+ yield {
15268
+ type: "run-ended",
15269
+ runId,
15270
+ reason: "compaction-settlement-failed",
15271
+ };
15083
15272
  return;
15084
15273
  }
15085
15274
  const observerFailure = compactionUsageState.calls.find(
@@ -15092,16 +15281,11 @@ export async function* agentLoop(messages, options) {
15092
15281
  }
15093
15282
  compactionUsageCall = compactionUsageState.calls.at(-1) || null;
15094
15283
  const compactionUsage = _compactionTokenUsage(stats);
15095
- if (compactionUsageCall?.providerReceipt) {
15096
- yield {
15097
- type: "provider-request-receipt",
15098
- callId: compactionUsageCall.callId,
15099
- workflowEffectId,
15100
- callSequence: compactionUsageCall.callSequence,
15101
- source: "semantic-compaction",
15102
- ...compactionUsageCall.providerReceipt,
15103
- };
15104
- }
15284
+ const providerReceipt = _takeCompactionProviderReceipt(
15285
+ compactionUsageCall,
15286
+ workflowEffectId,
15287
+ );
15288
+ if (providerReceipt) yield providerReceipt;
15105
15289
  if (stats.degraded === true) {
15106
15290
  const usageOutcomeUnknown = stats.summaryUsageUnknown === true;
15107
15291
  const projectedStats = usageOutcomeUnknown
@@ -15177,6 +15361,11 @@ export async function* agentLoop(messages, options) {
15177
15361
  ),
15178
15362
  );
15179
15363
  }
15364
+ yield {
15365
+ type: "run-ended",
15366
+ runId,
15367
+ reason: "compaction-usage-unknown",
15368
+ };
15180
15369
  return;
15181
15370
  }
15182
15371
  if (
@@ -15239,6 +15428,11 @@ export async function* agentLoop(messages, options) {
15239
15428
  ),
15240
15429
  );
15241
15430
  }
15431
+ yield {
15432
+ type: "run-ended",
15433
+ runId,
15434
+ reason: "compaction-settlement-failed",
15435
+ };
15242
15436
  return;
15243
15437
  }
15244
15438
  if (!hermeticExecution) {
@@ -15303,6 +15497,80 @@ export async function* agentLoop(messages, options) {
15303
15497
  }
15304
15498
  compactionUsageCall =
15305
15499
  compactionUsageCall || compactionUsageState?.calls?.at(-1) || null;
15500
+ const { getRejectedCompactionUsage } = await import(
15501
+ "../lib/context-memory-kernel/live-compaction.js"
15502
+ );
15503
+ const rejectedUsage = getRejectedCompactionUsage(_e);
15504
+ const returnedUsage = compactionUsageCall?.returnedUsage;
15505
+ const providerReceipt = _takeCompactionProviderReceipt(
15506
+ compactionUsageCall,
15507
+ workflowEffectId,
15508
+ );
15509
+ if (providerReceipt) yield providerReceipt;
15510
+ const knownPlanRejection =
15511
+ rejectedUsage &&
15512
+ returnedUsage &&
15513
+ (!rejectedUsage.callId ||
15514
+ rejectedUsage.callId === returnedUsage.callId) &&
15515
+ (!rejectedUsage.receipt.callId ||
15516
+ rejectedUsage.receipt.callId === returnedUsage.callId) &&
15517
+ rejectedUsage.provider === returnedUsage.provider &&
15518
+ rejectedUsage.model === returnedUsage.model &&
15519
+ [
15520
+ "input_tokens",
15521
+ "output_tokens",
15522
+ "cache_read_input_tokens",
15523
+ "cache_creation_input_tokens",
15524
+ ].every(
15525
+ (field) =>
15526
+ rejectedUsage.usage[field] === returnedUsage.usage[field],
15527
+ );
15528
+ if (knownPlanRejection || (!rejectedUsage && returnedUsage)) {
15529
+ automaticCompactionSettlementBlocked = true;
15530
+ // Yield through the existing host ledger/budget settlement path;
15531
+ // never claim a callback or an error flag already paid this debt.
15532
+ yield { type: "token-usage", ...returnedUsage, runId };
15533
+ yield {
15534
+ type: "compaction-degraded",
15535
+ runId,
15536
+ code: _e.code,
15537
+ reason: knownPlanRejection
15538
+ ? "canonical_compaction_plan_rejected"
15539
+ : "canonical_compaction_settlement_failed",
15540
+ summaryMode: "none",
15541
+ };
15542
+ await _awaitBackgroundUsageSettlement(
15543
+ backgroundSubAgents,
15544
+ backgroundUsageFailureState,
15545
+ );
15546
+ if (workflowEffectId) {
15547
+ if (knownPlanRejection) {
15548
+ const error = new Error(
15549
+ "Workflow-bound compaction plan was rejected; the task is incomplete",
15550
+ { cause: _e },
15551
+ );
15552
+ error.code = "CC_WORKFLOW_COMPACTION_PLAN_REJECTED";
15553
+ error.contextOutcome = "aborted";
15554
+ error.usageOutcome = "known";
15555
+ throw error;
15556
+ }
15557
+ const error = _workflowCompactionOutcomeUnknown(
15558
+ _e,
15559
+ "CC_WORKFLOW_COMPACTION_SETTLEMENT_UNKNOWN",
15560
+ "Workflow-bound semantic compaction settlement is unknown",
15561
+ );
15562
+ error.usageOutcome = "known";
15563
+ throw _markWorkflowCompactionFailureReported(error);
15564
+ }
15565
+ yield {
15566
+ type: "run-ended",
15567
+ runId,
15568
+ reason: knownPlanRejection
15569
+ ? "compaction-plan-rejected"
15570
+ : "compaction-settlement-failed",
15571
+ };
15572
+ return;
15573
+ }
15306
15574
  if (compactionUsageCall) {
15307
15575
  automaticCompactionSettlementBlocked = true;
15308
15576
  yield {
@@ -15326,6 +15594,11 @@ export async function* agentLoop(messages, options) {
15326
15594
  : _workflowCompactionOutcomeUnknown(_e),
15327
15595
  );
15328
15596
  }
15597
+ yield {
15598
+ type: "run-ended",
15599
+ runId,
15600
+ reason: "compaction-usage-unknown",
15601
+ };
15329
15602
  return;
15330
15603
  }
15331
15604
  yield {
@@ -15667,8 +15940,9 @@ export async function* agentLoop(messages, options) {
15667
15940
  // the run-level ids (turn.id correlates with the agent.iteration counter).
15668
15941
  let canonicalProviderContext = null;
15669
15942
  if (options.contextMemorySkipPlanning !== true) {
15670
- const { prepareCanonicalProviderContext } =
15671
- await import("../lib/context-memory-kernel/provider-context.js");
15943
+ const { prepareCanonicalProviderContext } = await import(
15944
+ "../lib/context-memory-kernel/provider-context.js"
15945
+ );
15672
15946
  canonicalProviderContext = await prepareCanonicalProviderContext(
15673
15947
  callMessages,
15674
15948
  {