chainlesschain 0.166.101 → 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 (182) hide show
  1. package/package.json +2 -2
  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-BjBS_29I.js → AIOps-CyHIMEd8.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-CUnnQUaj.js → ActionButton-vuNxDpHm.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-BqYZxgnY.js → Analytics-D0quEM0q.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-m8B886ka.js → AppLayout-xRSVpbCs.js} +3 -3
  8. package/src/assets/web-panel/assets/{Artifacts-JEOxU3Ug.js → Artifacts-ktfVAZBC.js} +1 -1
  9. package/src/assets/web-panel/assets/{Audit-DAXS5c9J.js → Audit-UJW6maH4.js} +1 -1
  10. package/src/assets/web-panel/assets/{BackgroundAgents-e3a9XHw3.js → BackgroundAgents-BYrfdCoT.js} +1 -1
  11. package/src/assets/web-panel/assets/{Backup-D3Qmp68h.js → Backup-IBgsJ7BK.js} +1 -1
  12. package/src/assets/web-panel/assets/{BaseInput-C7CXyiUl.js → BaseInput-BmP8_zxy.js} +1 -1
  13. package/src/assets/web-panel/assets/{Chat-2AHlAGi8.js → Chat-urkw8_BF.js} +6 -6
  14. package/src/assets/web-panel/assets/{ChatBubbleRenderer-D3KsyCUV.js → ChatBubbleRenderer-Cw44zZbh.js} +1 -1
  15. package/src/assets/web-panel/assets/{Checkbox-YfBuQlBH.js → Checkbox-CYboo-__.js} +1 -1
  16. package/src/assets/web-panel/assets/{Codegen-DCCQDfTL.js → Codegen-DaqR_Ay8.js} +1 -1
  17. package/src/assets/web-panel/assets/{Col-03i2WfrV.js → Col-04BSIj_z.js} +1 -1
  18. package/src/assets/web-panel/assets/{Community-CJQIpng6.js → Community-DxFk7Trv.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compact-CCtcQ2pq.js → Compact-mjgWlMCB.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compliance-Vxl7ZszJ.js → Compliance-CC5ee7QV.js} +1 -1
  21. package/src/assets/web-panel/assets/{Cowork-DN-BwA8I.js → Cowork-BK4BhHZd.js} +2 -2
  22. package/src/assets/web-panel/assets/{Cron-Dc2Q46X7.js → Cron-CP6jAxq0.js} +2 -2
  23. package/src/assets/web-panel/assets/{Crosschain-CQCblsl-.js → Crosschain-DJPaViZS.js} +1 -1
  24. package/src/assets/web-panel/assets/{DID-YYvqUR8C.js → DID-BTLxkuOj.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dashboard-Cafy3DZT.js → Dashboard-Djkiqh3d.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dropdown-BOyYpIpv.js → Dropdown-t_eUhqom.js} +1 -1
  27. package/src/assets/web-panel/assets/{EmailListRenderer-B7NYjc1j.js → EmailListRenderer-7w6USx_J.js} +1 -1
  28. package/src/assets/web-panel/assets/{EvolutionSettings-C5wfxztf.js → EvolutionSettings-mU5IHEk5.js} +1 -1
  29. package/src/assets/web-panel/assets/{FamilyGuardDashboard-aA7KnDGK.js → FamilyGuardDashboard-BCh-VBBC.js} +1 -1
  30. package/src/assets/web-panel/assets/{Federation-DlgXUu1L.js → Federation-Be_VpjI2.js} +1 -1
  31. package/src/assets/web-panel/assets/{FormItemContext-B5YsrLDg.js → FormItemContext-D_lzQ7PI.js} +1 -1
  32. package/src/assets/web-panel/assets/{GenericCardRenderer-DaWojPFw.js → GenericCardRenderer-LYu3KapV.js} +1 -1
  33. package/src/assets/web-panel/assets/{Git-dkhh6Fx2.js → Git-BBeF-PP4.js} +2 -2
  34. package/src/assets/web-panel/assets/{Governance-Cz6vmkjc.js → Governance-CoF8Kzg7.js} +1 -1
  35. package/src/assets/web-panel/assets/{Inference-DWt0hbh8.js → Inference-C4DLMnXS.js} +1 -1
  36. package/src/assets/web-panel/assets/{KnowledgeGraph-BZJ0Z-nL.js → KnowledgeGraph-B2mlNewk.js} +1 -1
  37. package/src/assets/web-panel/assets/{Logs-BaBBmL1A.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-ct8sgQ0s.js → Marketplace-BqDzTew_.js} +1 -1
  40. package/src/assets/web-panel/assets/{McpTools-CXKCRGYQ.js → McpTools-BbwSbDN9.js} +3 -3
  41. package/src/assets/web-panel/assets/{Memory-O7ZwlS6a.js → Memory-DAaTWgrm.js} +2 -2
  42. package/src/assets/web-panel/assets/{MobileBridge-By12C-eC.js → MobileBridge-BjbTGxoR.js} +1 -1
  43. package/src/assets/web-panel/assets/{MobileProjects-Ba-EVdex.js → MobileProjects-DMODOBr-.js} +1 -1
  44. package/src/assets/web-panel/assets/{Mtc-g-932zV2.js → Mtc-DT9N2rCs.js} +2 -2
  45. package/src/assets/web-panel/assets/{MtcAudit-BW8hB0ly.js → MtcAudit-DagMfUVv.js} +4 -4
  46. package/src/assets/web-panel/assets/{Multisig-zspLaMbT.js → Multisig-C1BKP6nM.js} +3 -3
  47. package/src/assets/web-panel/assets/{NLProgramming-dJeUPDoq.js → NLProgramming-B5LFh72i.js} +1 -1
  48. package/src/assets/web-panel/assets/{Notes-C4msiRQL.js → Notes-Q77V3ltW.js} +3 -3
  49. package/src/assets/web-panel/assets/{NotificationSettings-MOCHM-qg.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-DOZurBfk.js → Organization-QL3NZ7uW.js} +4 -4
  52. package/src/assets/web-panel/assets/{Overflow-qOT9BhUp.js → Overflow-B_gqOKho.js} +1 -1
  53. package/src/assets/web-panel/assets/{P2P-BMoy7Eo4.js → P2P-BBJubU8Z.js} +2 -2
  54. package/src/assets/web-panel/assets/{PdhVaultBrowser-ByyV1q-D.js → PdhVaultBrowser-CFnGd-2E.js} +3 -3
  55. package/src/assets/web-panel/assets/{Permissions-6Qyro4ye.js → Permissions-BKkznIUM.js} +4 -4
  56. package/src/assets/web-panel/assets/{PersonalDataHub-DR3DRNSX.js → PersonalDataHub-DYK7ZAcd.js} +4 -4
  57. package/src/assets/web-panel/assets/{Pipeline-Cr6TTdud.js → Pipeline-CoeKpjoN.js} +1 -1
  58. package/src/assets/web-panel/assets/{Privacy-B70otG0l.js → Privacy-Diw4G-92.js} +1 -1
  59. package/src/assets/web-panel/assets/{ProjectInit-BHCqxoSk.js → ProjectInit-CHBOFkma.js} +2 -2
  60. package/src/assets/web-panel/assets/{ProjectSettings-B80GZpZk.js → ProjectSettings-BJIsgdOf.js} +2 -2
  61. package/src/assets/web-panel/assets/Projects-GJjItXIk.js +1 -0
  62. package/src/assets/web-panel/assets/{Providers-dsVTimHa.js → Providers-o8QCimor.js} +1 -1
  63. package/src/assets/web-panel/assets/{QrScannerModal-DRJ8YepZ.js → QrScannerModal-z2W-zvhW.js} +1 -1
  64. package/src/assets/web-panel/assets/{QuickAsk-BSXdEjIB.js → QuickAsk-_yubhsna.js} +1 -1
  65. package/src/assets/web-panel/assets/{Recommend-CQLJGyKC.js → Recommend-CucgJwih.js} +1 -1
  66. package/src/assets/web-panel/assets/{RemoteSession-BF9WUFVZ.js → RemoteSession-EzfIIRg1.js} +2 -2
  67. package/src/assets/web-panel/assets/{Reputation-Cy9o5tvW.js → Reputation-_shttE67.js} +1 -1
  68. package/src/assets/web-panel/assets/{Row-BP346_3b.js → Row-DQA_S8-9.js} +1 -1
  69. package/src/assets/web-panel/assets/{RssFeed-BKulxXf3.js → RssFeed-BOqWawXT.js} +3 -3
  70. package/src/assets/web-panel/assets/{Search-EemQj2Dv.js → Search-Dx1v2xOq.js} +1 -1
  71. package/src/assets/web-panel/assets/{Security-DcWPAwwk.js → Security-Bt4HHsT4.js} +3 -3
  72. package/src/assets/web-panel/assets/{Services-Bltqciay.js → Services-sruHiQ-r.js} +2 -2
  73. package/src/assets/web-panel/assets/{Skeleton-BwRyOGY8.js → Skeleton-CiBxvmOJ.js} +1 -1
  74. package/src/assets/web-panel/assets/{Skills-D98qlvpJ.js → Skills-De9qKODU.js} +1 -1
  75. package/src/assets/web-panel/assets/{Sla-BUTtBMY0.js → Sla-B_6yn8Wp.js} +1 -1
  76. package/src/assets/web-panel/assets/{SpeechSettings-C7kcY_98.js → SpeechSettings-C2CafExS.js} +1 -1
  77. package/src/assets/web-panel/assets/{SyncSettings-Bsk6lKvT.js → SyncSettings-Dhh3Qmb0.js} +2 -2
  78. package/src/assets/web-panel/assets/{Tasks-DvSrtz0P.js → Tasks-Mvo5mTWm.js} +1 -1
  79. package/src/assets/web-panel/assets/{Templates-BUM6LwPs.js → Templates-D7WVTQQy.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tenant-D9TkOm7z.js → Tenant-7ur9Yfxd.js} +1 -1
  81. package/src/assets/web-panel/assets/{Terminal-CP8ZVErN.js → Terminal-BgzrOA6k.js} +2 -2
  82. package/src/assets/web-panel/assets/{TimelineRenderer-V3SoKZ1T.js → TimelineRenderer-Dco20pT1.js} +1 -1
  83. package/src/assets/web-panel/assets/{Tokens-CCRlUTOA.js → Tokens-hN6qBPag.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trigger-CznUcPme.js → Trigger-C4f_twAM.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trust-D1GIk_NF.js → Trust-Wf1SMypp.js} +1 -1
  86. package/src/assets/web-panel/assets/{UkeySign-DHtvtyC-.js → UkeySign-DUXSyg3N.js} +1 -1
  87. package/src/assets/web-panel/assets/{VideoEditing-CVxdaJIq.js → VideoEditing-BvqsJaL0.js} +1 -1
  88. package/src/assets/web-panel/assets/{Wallet-D221OjyE.js → Wallet-CgAbcjKl.js} +4 -4
  89. package/src/assets/web-panel/assets/{WebAuthn-Cw0-ESsq.js → WebAuthn-DaLT0W3s.js} +2 -2
  90. package/src/assets/web-panel/assets/{WorkflowEditor-ZYScrBx3.js → WorkflowEditor-CQqAXoaS.js} +1 -1
  91. package/src/assets/web-panel/assets/{chat-BU0e1obR.js → chat-BhlohFTB.js} +1 -1
  92. package/src/assets/web-panel/assets/{colors-gzYweuha.js → colors-D7HqXIL8.js} +1 -1
  93. package/src/assets/web-panel/assets/{compact-item-ChAXal_k.js → compact-item-Bqk4FCLY.js} +1 -1
  94. package/src/assets/web-panel/assets/{createContext-of3FolD7.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-4PsK_Kx8.js → hasIn-CDY0pFi2.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-1dzYRBbg.js → index-1HBam9t1.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CHv_63Cp.js → index-6f6n0KFR.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-DjRAIRX7.js → index-B8L3_-sG.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-Cn1clrxx.js → index-BHGOdvOQ.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-cFkMIx1x.js → index-BNrvBWDS.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-BfI4dXbi.js → index-BPmRkxeX.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-CO2owKe0.js → index-BXRooi-O.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-DEzjUgkl.js → index-BiLu-ImR.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DZ0oKtBg.js → index-BuKGuH_y.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-D1PGrfHE.js → index-BxXFRLTZ.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-B5L7zddz.js → index-BxYO6nde.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CyDQNprx.js → index-C02yDu4f.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Ef5YkVAn.js → index-C3opQg47.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CGFL59q4.js → index-C9mvnSii.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-D_5LTPMH.js → index-CVrwozwH.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DJVrzXtk.js → index-CYcjOnDX.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-Bftq5rJR.js → index-Cf1ha8l0.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-DEXBckNR.js → index-Chxt0t-A.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-By-pper5.js → index-CkjgSHVz.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-Dy0ojH6G.js → index-CkqBoCiu.js} +3 -3
  117. package/src/assets/web-panel/assets/{index-Cx4Z6nUl.js → index-CqK0J4Sj.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-Djfgsjfy.js → index-CrsM-oiD.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BdxRVNPY.js → index-Cur88hoN.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-D_9k680X.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-DsoV9rzn.js → index-DEzL7s7P.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-wo0De0iG.js → index-DGKRAO61.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-E8oDMSAo.js → index-DPBoWNwq.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-CCLsbul3.js → index-DRcDWMwP.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BOeX7BzS.js → index-DmKdCWq1.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CxzBcXOa.js → index-DpI1LqJX.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DEB5fQqG.js → index-DuMt3ewl.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CeEE_SGZ.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-Wr91cnWr.js → index-XErJQ1yF.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-D_ialOHx.js → index-aBHlgMrq.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-D-Zss5KL.js → index-e9oCy7_4.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-DDYj14Q4.js → index-lBAbMOzg.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-yMf7zmWv.js → index-o_lc3eww.js} +1 -1
  136. package/src/assets/web-panel/assets/{initDefaultProps-D0Bx6pgr.js → initDefaultProps-CIeEUxIN.js} +1 -1
  137. package/src/assets/web-panel/assets/{motion-BnLuJqJ5.js → motion-IPIj1ZtP.js} +1 -1
  138. package/src/assets/web-panel/assets/{move-Bxpq9xgR.js → move-BfSeXZ-f.js} +1 -1
  139. package/src/assets/web-panel/assets/{mtc-parser-BdmrNhOs.js → mtc-parser-DX03-Xp4.js} +1 -1
  140. package/src/assets/web-panel/assets/{omit-tjJD34BZ.js → omit-z9EannfX.js} +1 -1
  141. package/src/assets/web-panel/assets/{pickAttrs-CMFzLt7b.js → pickAttrs-DXKmRkqZ.js} +1 -1
  142. package/src/assets/web-panel/assets/{placementArrow-BZf6O3cd.js → placementArrow-k2HV7cIU.js} +1 -1
  143. package/src/assets/web-panel/assets/{responsiveObserve-DFDLazsV.js → responsiveObserve-bX7CsyWy.js} +1 -1
  144. package/src/assets/web-panel/assets/{slide-CMbTvp4Y.js → slide-NskjQLbJ.js} +1 -1
  145. package/src/assets/web-panel/assets/{statusUtils-FOan8MI7.js → statusUtils-B3IoG-Er.js} +1 -1
  146. package/src/assets/web-panel/assets/{styleChecker-DTABspd4.js → styleChecker-DHv_UilX.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFlexGapSupport-CNHXWBpY.js → useFlexGapSupport-DEqGB5Ng.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFs-5K-c_RoL.js → useFs-Bl9CbrqZ.js} +1 -1
  149. package/src/assets/web-panel/assets/{usePersonalDataHub-Di0hL4G-.js → usePersonalDataHub-O-Ukv93M.js} +1 -1
  150. package/src/assets/web-panel/assets/{vnode-DTyDv4ja.js → vnode-hGCHTaZt.js} +1 -1
  151. package/src/assets/web-panel/assets/{zoom-ontRt8ft.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/data/changelog.json +13 -0
  156. package/src/lib/config-schema.js +18 -5
  157. package/src/lib/context-memory-kernel/memory-query-index.js +5 -2
  158. package/src/lib/context-memory-kernel/runtime.js +4 -0
  159. package/src/lib/context-memory-kernel/segmented-memory-port.js +28 -3
  160. package/src/lib/context-source-ledger.js +52 -9
  161. package/src/lib/goal-condition-engine.js +25 -2
  162. package/src/lib/llm-config-defaults.js +10 -4
  163. package/src/lib/llm-pricing.js +16 -4
  164. package/src/lib/model-capabilities.js +26 -0
  165. package/src/lib/model-catalog-review.js +18 -1
  166. package/src/lib/model-context-catalog.js +41 -1
  167. package/src/lib/openai-responses.js +8 -0
  168. package/src/lib/skill-retrieval-router.js +1 -0
  169. package/src/lib/usage-pricing-context.js +33 -2
  170. package/src/repl/agent-repl.js +247 -153
  171. package/src/runtime/agent-core.js +198 -87
  172. package/src/runtime/coding-agent-contract-shared.cjs +14 -1
  173. package/src/runtime/headless-runner.js +1 -0
  174. package/src/runtime/headless-stream.js +1 -0
  175. package/src/runtime/mcp-tool-search.js +0 -0
  176. package/src/runtime/provider-stream-state.js +14 -1
  177. package/src/assets/web-panel/assets/MarkdownRenderer-C1yByobo.js +0 -1
  178. package/src/assets/web-panel/assets/OrderTableRenderer-CX0T66NM.js +0 -1
  179. package/src/assets/web-panel/assets/Projects-cq-b9-fQ.js +0 -1
  180. package/src/assets/web-panel/assets/devWarning-Pa13TVrO.js +0 -1
  181. package/src/assets/web-panel/assets/index-BhQg-v6V.js +0 -1
  182. package/src/assets/web-panel/assets/index-DUD5o-vW.js +0 -1
@@ -308,6 +308,10 @@ export function registerAgentCommand(program, dependencies = {}) {
308
308
  "LLM provider (ollama, openai, volcengine, deepseek, ...)",
309
309
  )
310
310
  .option("--base-url <url>", "API base URL")
311
+ .option(
312
+ "--service-tier <tier>",
313
+ "Reviewed provider service tier (standard, fast, flex, ultrafast)",
314
+ )
311
315
  .option("--api-key <key>", "API key")
312
316
  .option(
313
317
  "--think [level]",
@@ -769,8 +773,9 @@ export function registerAgentCommand(program, dependencies = {}) {
769
773
  // --capabilities: print the machine-readable manifest and exit — no
770
774
  // config, no bootstrap, no network (gap-analysis 2026-07-11 快速收益 #6).
771
775
  if (options.capabilities) {
772
- const { buildAgentCapabilities } =
773
- await import("../lib/headless-manifest.js");
776
+ const { buildAgentCapabilities } = await import(
777
+ "../lib/headless-manifest.js"
778
+ );
774
779
  console.log(JSON.stringify(buildAgentCapabilities(), null, 2));
775
780
  return;
776
781
  }
@@ -789,8 +794,9 @@ export function registerAgentCommand(program, dependencies = {}) {
789
794
  let toolAdmission = null;
790
795
  if (process.env.CC_TOOL_ADMISSION) {
791
796
  try {
792
- const { parseToolAdmissionConfig } =
793
- await import("../lib/agent-tool-admission.js");
797
+ const { parseToolAdmissionConfig } = await import(
798
+ "../lib/agent-tool-admission.js"
799
+ );
794
800
  toolAdmission = parseToolAdmissionConfig(
795
801
  process.env.CC_TOOL_ADMISSION,
796
802
  );
@@ -878,8 +884,9 @@ export function registerAgentCommand(program, dependencies = {}) {
878
884
  // screen readers (mono theme + no repainting status line). Applied
879
885
  // before anything renders.
880
886
  {
881
- const { screenReaderRequested, applyScreenReaderMode } =
882
- await import("../lib/accessibility.js");
887
+ const { screenReaderRequested, applyScreenReaderMode } = await import(
888
+ "../lib/accessibility.js"
889
+ );
883
890
  if (screenReaderRequested(options)) {
884
891
  applyScreenReaderMode();
885
892
  }
@@ -912,8 +919,9 @@ export function registerAgentCommand(program, dependencies = {}) {
912
919
  };
913
920
  if (options.worktree !== undefined || backgroundRequested) {
914
921
  try {
915
- const { resolveBackgroundWorktreePolicy } =
916
- await import("../lib/background-worktree-policy.js");
922
+ const { resolveBackgroundWorktreePolicy } = await import(
923
+ "../lib/background-worktree-policy.js"
924
+ );
917
925
  worktreeDecision = resolveBackgroundWorktreePolicy({
918
926
  background: backgroundRequested,
919
927
  worktree: options.worktree,
@@ -965,8 +973,9 @@ export function registerAgentCommand(program, dependencies = {}) {
965
973
  };
966
974
  if (worktreeDecision.enabled) {
967
975
  try {
968
- const { setupAgentWorktree, finishAgentWorktree } =
969
- await import("../lib/agent-worktree.js");
976
+ const { setupAgentWorktree, finishAgentWorktree } = await import(
977
+ "../lib/agent-worktree.js"
978
+ );
970
979
  _finishAgentWorktreeFn = finishAgentWorktree;
971
980
  const detectedRepoRoot = worktreeDecision.repoRoot || invocationCwd;
972
981
  const worktreeCwd =
@@ -994,8 +1003,9 @@ export function registerAgentCommand(program, dependencies = {}) {
994
1003
  const { loadHooks } = await import("../lib/settings-hooks.cjs");
995
1004
  _worktreeSettingsHooks =
996
1005
  loadHooks({ cwd: _worktree.repoRoot }).hooks || null;
997
- const { runWorktreeCreateHooks, dispatchAsyncHooks } =
998
- await import("../lib/settings-hook-events.js");
1006
+ const { runWorktreeCreateHooks, dispatchAsyncHooks } = await import(
1007
+ "../lib/settings-hook-events.js"
1008
+ );
999
1009
  await runWorktreeCreateHooks(_worktreeSettingsHooks, {
1000
1010
  worktreePath: _worktree.path,
1001
1011
  branch: _worktree.branch,
@@ -1003,8 +1013,9 @@ export function registerAgentCommand(program, dependencies = {}) {
1003
1013
  cwd: _worktree.path,
1004
1014
  });
1005
1015
  if (!_worktreeAsyncSupervisor) {
1006
- const { AsyncHookSupervisor } =
1007
- await import("../lib/async-hook-supervisor.js");
1016
+ const { AsyncHookSupervisor } = await import(
1017
+ "../lib/async-hook-supervisor.js"
1018
+ );
1008
1019
  _worktreeAsyncSupervisor = new AsyncHookSupervisor({
1009
1020
  persistStats: true,
1010
1021
  });
@@ -1089,8 +1100,9 @@ export function registerAgentCommand(program, dependencies = {}) {
1089
1100
  // Claude-Code parity: auto-checkpoint defaults ON inside a git repo
1090
1101
  // (shadow-commit engine, zero working-tree touch); explicit
1091
1102
  // --checkpoint / --no-checkpoint always wins.
1092
- const { resolveAutoCheckpoint } =
1093
- await import("../lib/auto-checkpoint-default.js");
1103
+ const { resolveAutoCheckpoint } = await import(
1104
+ "../lib/auto-checkpoint-default.js"
1105
+ );
1094
1106
  const autoCheckpoint = resolveAutoCheckpoint({
1095
1107
  flagValue: options.checkpoint,
1096
1108
  flagSource: command?.getOptionValueSource?.("checkpoint"),
@@ -1118,8 +1130,9 @@ export function registerAgentCommand(program, dependencies = {}) {
1118
1130
  options.outputFormat !== "text" ||
1119
1131
  !process.stdin.isTTY;
1120
1132
  if (headlessIntent) {
1121
- const { getLastLogicalSessionId } =
1122
- await import("../lib/session-transcript-migration.js");
1133
+ const { getLastLogicalSessionId } = await import(
1134
+ "../lib/session-transcript-migration.js"
1135
+ );
1123
1136
  const database =
1124
1137
  sessionBootstrapContext.db?.getDatabase?.() ||
1125
1138
  sessionBootstrapContext.db?.getDb?.() ||
@@ -1127,8 +1140,9 @@ export function registerAgentCommand(program, dependencies = {}) {
1127
1140
  options.session = getLastLogicalSessionId(database);
1128
1141
  } else {
1129
1142
  // Interactive: picker across both stores (agent REPL rebuilds either).
1130
- const { pickRecentSession } =
1131
- await import("../lib/session-picker.js");
1143
+ const { pickRecentSession } = await import(
1144
+ "../lib/session-picker.js"
1145
+ );
1132
1146
  const picked = await pickRecentSession(sessionBootstrapContext, {
1133
1147
  message: "Resume which agent session?",
1134
1148
  });
@@ -1154,8 +1168,9 @@ export function registerAgentCommand(program, dependencies = {}) {
1154
1168
  // diagnostics belong on stderr; stdout may already be reserved for a
1155
1169
  // JSON/NDJSON protocol selected by this command.
1156
1170
  await withQuietStdout(async () => {
1157
- const { sessionHasPersistedEvidence } =
1158
- await import("../harness/jsonl-session-store.js");
1171
+ const { sessionHasPersistedEvidence } = await import(
1172
+ "../harness/jsonl-session-store.js"
1173
+ );
1159
1174
  if (!sessionHasPersistedEvidence(options.session)) {
1160
1175
  const [{ bootstrap }, { ensureCanonicalSessionFromDatabase }] =
1161
1176
  await Promise.all([
@@ -1185,8 +1200,9 @@ export function registerAgentCommand(program, dependencies = {}) {
1185
1200
  // a no-op (silent) for a fresh run.
1186
1201
  if (options.forkSession && options.session) {
1187
1202
  const store = await import("../harness/jsonl-session-store.js");
1188
- const { applyForkSession } =
1189
- await import("../runtime/headless-runner.js");
1203
+ const { applyForkSession } = await import(
1204
+ "../runtime/headless-runner.js"
1205
+ );
1190
1206
  const fork = applyForkSession(
1191
1207
  {
1192
1208
  forkSession: true,
@@ -1259,8 +1275,9 @@ export function registerAgentCommand(program, dependencies = {}) {
1259
1275
  let settingsSandbox = null;
1260
1276
  let managedSettingsSandbox = null;
1261
1277
  try {
1262
- const { loadSettingsConfig } =
1263
- await import("../lib/settings-loader.cjs");
1278
+ const { loadSettingsConfig } = await import(
1279
+ "../lib/settings-loader.cjs"
1280
+ );
1264
1281
  const sc = loadSettingsConfig({
1265
1282
  cwd: process.cwd(),
1266
1283
  settingsFile: options.settings || null,
@@ -1451,8 +1468,9 @@ export function registerAgentCommand(program, dependencies = {}) {
1451
1468
  // never pollutes spawned-bin test stderr.
1452
1469
  if (!process.env.VITEST && !process.env.VITEST_WORKER_ID) {
1453
1470
  try {
1454
- const { maybeWarnDeprecatedModel } =
1455
- await import("../lib/model-deprecation.js");
1471
+ const { maybeWarnDeprecatedModel } = await import(
1472
+ "../lib/model-deprecation.js"
1473
+ );
1456
1474
  maybeWarnDeprecatedModel({ model: options.model });
1457
1475
  } catch {
1458
1476
  /* fail-open: a deprecation notice must never affect the run */
@@ -1536,8 +1554,9 @@ export function registerAgentCommand(program, dependencies = {}) {
1536
1554
  ) {
1537
1555
  decisionConfig = Object.freeze({ mode: "off" });
1538
1556
  } else {
1539
- const { resolveHeadlessSkillDecisionOptions } =
1540
- await import("../runtime/headless-runner.js");
1557
+ const { resolveHeadlessSkillDecisionOptions } = await import(
1558
+ "../runtime/headless-runner.js"
1559
+ );
1541
1560
  decisionConfig = resolveHeadlessSkillDecisionOptions(options);
1542
1561
  }
1543
1562
  } catch (error) {
@@ -1599,8 +1618,9 @@ export function registerAgentCommand(program, dependencies = {}) {
1599
1618
  process.exit(1);
1600
1619
  return;
1601
1620
  }
1602
- const { runAgentHeadlessStream } =
1603
- await import("../runtime/headless-stream.js");
1621
+ const { runAgentHeadlessStream } = await import(
1622
+ "../runtime/headless-stream.js"
1623
+ );
1604
1624
  const { parseToolList, validateHeadlessInvocationOptions } =
1605
1625
  await import("../runtime/headless-runner.js");
1606
1626
  const cwd = process.cwd();
@@ -1859,8 +1879,9 @@ export function registerAgentCommand(program, dependencies = {}) {
1859
1879
  // presenting a fresh conversation as a successful resume.
1860
1880
  if (resumeRequested && options.session) {
1861
1881
  const hasPersistedEvidence = await withQuietStdout(async () => {
1862
- const { sessionHasPersistedEvidence } =
1863
- await import("../harness/jsonl-session-store.js");
1882
+ const { sessionHasPersistedEvidence } = await import(
1883
+ "../harness/jsonl-session-store.js"
1884
+ );
1864
1885
  return sessionHasPersistedEvidence(options.session);
1865
1886
  });
1866
1887
  if (!hasPersistedEvidence) {
@@ -1870,14 +1891,16 @@ export function registerAgentCommand(program, dependencies = {}) {
1870
1891
  );
1871
1892
  }
1872
1893
  }
1873
- const { runAgentHeadless, parseToolList } =
1874
- await import("../runtime/headless-runner.js");
1894
+ const { runAgentHeadless, parseToolList } = await import(
1895
+ "../runtime/headless-runner.js"
1896
+ );
1875
1897
  // --goal-condition: validate the spec up front so a bad prefix fails
1876
1898
  // fast (before any model call) with a clear message.
1877
1899
  if (options.goalCondition) {
1878
1900
  try {
1879
- const { parseGoalCondition } =
1880
- await import("../lib/goal-condition-engine.js");
1901
+ const { parseGoalCondition } = await import(
1902
+ "../lib/goal-condition-engine.js"
1903
+ );
1881
1904
  parseGoalCondition(options.goalCondition);
1882
1905
  } catch (e) {
1883
1906
  process.stderr.write(`--goal-condition: ${e.message}\n`);
@@ -1896,8 +1919,9 @@ export function registerAgentCommand(program, dependencies = {}) {
1896
1919
  : null;
1897
1920
  let evolutionComposition;
1898
1921
  try {
1899
- const { validateHeadlessInvocationOptions } =
1900
- await import("../runtime/headless-runner.js");
1922
+ const { validateHeadlessInvocationOptions } = await import(
1923
+ "../runtime/headless-runner.js"
1924
+ );
1901
1925
  validateHeadlessInvocationOptions({
1902
1926
  outputFormat: options.outputFormat,
1903
1927
  permissionMode: options.permissionMode,
@@ -1,6 +1,19 @@
1
1
  {
2
2
  "source": "CHANGELOG.md",
3
3
  "releases": [
4
+ {
5
+ "productVersion": null,
6
+ "cliVersion": "0.166.102",
7
+ "cliVersions": ["0.166.102"],
8
+ "date": null,
9
+ "title": "",
10
+ "sections": [
11
+ {
12
+ "heading": "Fixed - cc CLI 0.166.102: restore session pricing validation",
13
+ "body": "- Accept the reviewed Priority and Ultrafast pricing terms when validating the\n built-in model catalog, restoring session observability, budget and Eval\n projections while continuing to reject unknown tiers and invalid multipliers.\n- Make the model-switch warning regression insensitive to source formatting.\n- Publish Personal Data Hub 0.4.65 with source snapshots in answer citations\n before CLI 0.166.102, then pair VS Code 0.37.146 and JetBrains 0.4.164 after\n the exact release commit passes its complete Actions gates."
14
+ }
15
+ ]
16
+ },
4
17
  {
5
18
  "productVersion": null,
6
19
  "cliVersion": "0.166.101",
@@ -69,6 +69,19 @@ const DESCRIPTORS = [
69
69
  default: DEFAULT_CONFIG.llm.model,
70
70
  description: "Default model id",
71
71
  }),
72
+ descriptor("llm.serviceTier", "string", {
73
+ enum: [
74
+ "standard",
75
+ "default",
76
+ "auto",
77
+ "fast",
78
+ "priority",
79
+ "flex",
80
+ "ultrafast",
81
+ ],
82
+ description:
83
+ "Requested live service tier; model and endpoint support are checked before dispatch",
84
+ }),
72
85
  descriptor("llm.visionModel", ["string", "null"], {
73
86
  description: "Model used for image turns",
74
87
  }),
@@ -502,11 +515,11 @@ function valueIssue(key, code, message) {
502
515
  function isPersistedSecretRef(value) {
503
516
  return Boolean(
504
517
  value &&
505
- typeof value === "object" &&
506
- !Array.isArray(value) &&
507
- Object.keys(value).length === 1 &&
508
- typeof value.__cc_secret_ref === "string" &&
509
- value.__cc_secret_ref.length > 0,
518
+ typeof value === "object" &&
519
+ !Array.isArray(value) &&
520
+ Object.keys(value).length === 1 &&
521
+ typeof value.__cc_secret_ref === "string" &&
522
+ value.__cc_secret_ref.length > 0,
510
523
  );
511
524
  }
512
525
 
@@ -2,6 +2,9 @@ import { createHash } from "node:crypto";
2
2
 
3
3
  export const MEMORY_QUERY_INDEX_SCHEMA = "chainlesschain.memory-query-index/v1";
4
4
  const CURSOR_SCHEMA = "chainlesschain.memory-list-cursor/v1";
5
+ // Preserve the existing English collation while avoiding constructing locale
6
+ // options for every comparison during shard sorts, cursor search and merging.
7
+ const memoryRowCollator = new Intl.Collator("en");
5
8
 
6
9
  export function queryDigest(bytes) {
7
10
  return `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
@@ -10,8 +13,8 @@ export function queryDigest(bytes) {
10
13
  export function compareMemoryRows(left, right) {
11
14
  return (
12
15
  right.importance - left.importance ||
13
- right.updatedAt.localeCompare(left.updatedAt, "en") ||
14
- left.memoryId.localeCompare(right.memoryId, "en")
16
+ memoryRowCollator.compare(right.updatedAt, left.updatedAt) ||
17
+ memoryRowCollator.compare(left.memoryId, right.memoryId)
15
18
  );
16
19
  }
17
20
 
@@ -22,6 +22,10 @@ export function createCliContextMemoryRuntime(options = {}) {
22
22
  const memoryPort =
23
23
  options.memoryPort ||
24
24
  new SegmentedMemoryPort({
25
+ queryIndexCacheMode:
26
+ options.memoryQueryIndexCacheMode ||
27
+ (options.env || process.env).CC_CONTEXT_MEMORY_QUERY_CACHE ||
28
+ "validate-disk",
25
29
  readOnly: !decision.canonical,
26
30
  ...(options.memoryFilePath ? { filePath: options.memoryFilePath } : {}),
27
31
  });
@@ -170,6 +170,7 @@ export class SegmentedMemoryPort extends DurableJsonMemoryPort {
170
170
  maxTotalBytes = DEFAULT_MAX_TOTAL_BYTES,
171
171
  maxEvents = DEFAULT_SEGMENTED_MAX_EVENTS,
172
172
  readOnly = false,
173
+ queryIndexCacheMode = "validate-disk",
173
174
  ...options
174
175
  } = {}) {
175
176
  super({ ...options, maxEvents });
@@ -177,6 +178,9 @@ export class SegmentedMemoryPort extends DurableJsonMemoryPort {
177
178
  throw new TypeError("maxTotalBytes must be a positive safe integer");
178
179
  this.maxTotalBytes = maxTotalBytes;
179
180
  this.readOnly = Boolean(readOnly);
181
+ if (!["validate-disk", "verified-memory"].includes(queryIndexCacheMode))
182
+ throw new TypeError("Unknown query index cache mode");
183
+ this.queryIndexCacheMode = queryIndexCacheMode;
180
184
  this.filePath = resolve(this.filePath);
181
185
  this.shardDirectory = `${this.filePath}.shards`;
182
186
  this._queryIndexes = new Map();
@@ -656,6 +660,27 @@ export class SegmentedMemoryPort extends DurableJsonMemoryPort {
656
660
 
657
661
  _readQueryIndex(manifest, bucket) {
658
662
  const descriptor = manifest.shards[bucket];
663
+ const binding = JSON.stringify([
664
+ manifest.digest,
665
+ manifest.storeRevision,
666
+ descriptor.digest,
667
+ descriptor.queryDigest,
668
+ descriptor.queryBytes,
669
+ descriptor.recordCount,
670
+ ]);
671
+ const cached = this._queryIndexes.get(bucket);
672
+ // This is an already verified, host-owned decoded snapshot, never a trust
673
+ // decision based on filesystem timestamps. Re-read and verify the current
674
+ // manifest on every operation; any generation/authority change invalidates
675
+ // this binding. Selected authority shards are still read and verified.
676
+ // Disk repair remains eager in validate-disk mode; verified-memory repairs
677
+ // a derived index on the next cache miss, rather than every warm query.
678
+ if (
679
+ this.queryIndexCacheMode === "verified-memory" &&
680
+ descriptor.queryDigest &&
681
+ cached?.binding === binding
682
+ )
683
+ return cached.index;
659
684
  let bytes;
660
685
  if (descriptor.queryDigest) {
661
686
  const file = this._queryIndexPath(bucket, descriptor);
@@ -705,8 +730,8 @@ export class SegmentedMemoryPort extends DurableJsonMemoryPort {
705
730
  bytes = encodeQueryIndex(this._readShard(manifest, bucket));
706
731
  }
707
732
  const digest = descriptor.queryDigest || queryDigest(bytes);
708
- const cached = this._queryIndexes.get(bucket);
709
- if (cached?.digest === digest) return cached.index;
733
+ if (cached?.digest === digest && cached.binding === binding)
734
+ return cached.index;
710
735
  let index;
711
736
  try {
712
737
  index = compileQueryIndex(bytes, descriptor);
@@ -717,7 +742,7 @@ export class SegmentedMemoryPort extends DurableJsonMemoryPort {
717
742
  cause,
718
743
  );
719
744
  }
720
- this._queryIndexes.set(bucket, { digest, index });
745
+ this._queryIndexes.set(bucket, { digest, binding, index });
721
746
  return index;
722
747
  }
723
748
 
@@ -40,7 +40,28 @@ class ContextSourceLedger {
40
40
  * @returns {string} entryId
41
41
  */
42
42
  record(entry) {
43
+ if (
44
+ entry.tokenCount != null &&
45
+ (!Number.isSafeInteger(entry.tokenCount) || entry.tokenCount < 0)
46
+ ) {
47
+ throw new TypeError(
48
+ "Context tokenCount must be a non-negative safe integer",
49
+ );
50
+ }
43
51
  const entryId = entry.entryId || crypto.randomUUID();
52
+ const previous = this._entries.get(entryId);
53
+ if (previous) {
54
+ for (const [index, key] of [
55
+ [this._byTurn, previous.turnId],
56
+ [this._bySession, previous.sessionId],
57
+ ]) {
58
+ const remaining = (index.get(key) || []).filter(
59
+ (item) => item.entryId !== entryId,
60
+ );
61
+ if (remaining.length) index.set(key, remaining);
62
+ else index.delete(key);
63
+ }
64
+ }
44
65
  const full = {
45
66
  entryId,
46
67
  traceId: entry.traceId || null,
@@ -53,6 +74,7 @@ class ContextSourceLedger {
53
74
  summary: entry.summary,
54
75
  metadata: entry.metadata,
55
76
  tokenCount: entry.tokenCount || 0,
77
+ tokenBasis: entry.tokenBasis === "observed" ? "observed" : "estimated",
56
78
  insertedAt: new Date(),
57
79
  tags: entry.tags || [],
58
80
  };
@@ -64,7 +86,8 @@ class ContextSourceLedger {
64
86
  this._byTurn.get(full.turnId).push(full);
65
87
 
66
88
  // Index by session
67
- if (!this._bySession.has(full.sessionId)) this._bySession.set(full.sessionId, []);
89
+ if (!this._bySession.has(full.sessionId))
90
+ this._bySession.set(full.sessionId, []);
68
91
  this._bySession.get(full.sessionId).push(full);
69
92
 
70
93
  return entryId;
@@ -82,6 +105,7 @@ class ContextSourceLedger {
82
105
  summary: entry.summary || entry.content,
83
106
  metadata: entry.metadata,
84
107
  tokenCount: entry.tokenCount ?? entry.tokens ?? 0,
108
+ tokenBasis: entry.tokenBasis,
85
109
  traceId: entry.traceId,
86
110
  });
87
111
  }
@@ -95,14 +119,31 @@ class ContextSourceLedger {
95
119
  }
96
120
 
97
121
  /** Aggregate token usage by source type. */
98
- getTokenBreakdown() {
99
- const bySource = {};
122
+ getTokenBreakdown(options = {}) {
123
+ const sources = new Map();
100
124
  let total = 0;
101
- for (const entry of this._entries.values()) {
125
+ for (const entry of this.getProvenance(options)) {
102
126
  total += entry.tokenCount;
103
- bySource[entry.sourceType] = (bySource[entry.sourceType] || 0) + entry.tokenCount;
127
+ sources.set(
128
+ entry.sourceType,
129
+ (sources.get(entry.sourceType) || 0) + entry.tokenCount,
130
+ );
104
131
  }
105
- return { total, bySource };
132
+ return { total, bySource: Object.fromEntries(sources) };
133
+ }
134
+
135
+ /** Source attribution is separate from provider request usage and billing. */
136
+ getTokenReport(options = {}) {
137
+ const entries = this.getProvenance(options);
138
+ const byBasis = { estimated: 0, observed: 0 };
139
+ for (const entry of entries) byBasis[entry.tokenBasis] += entry.tokenCount;
140
+ return {
141
+ ...this.getTokenBreakdown(options),
142
+ byBasis,
143
+ entries: entries.length,
144
+ currentRequestVerified: false,
145
+ billingVerified: false,
146
+ };
106
147
  }
107
148
 
108
149
  /** Clear the in-memory ledger (test/runtime lifecycle boundary). */
@@ -146,7 +187,8 @@ class ContextSourceLedger {
146
187
 
147
188
  for (const e of entries) {
148
189
  byType[e.sourceType] = (byType[e.sourceType] || 0) + 1;
149
- byPermission[e.permissionMode] = (byPermission[e.permissionMode] || 0) + 1;
190
+ byPermission[e.permissionMode] =
191
+ (byPermission[e.permissionMode] || 0) + 1;
150
192
  bySource[e.sourceId] = (bySource[e.sourceId] || 0) + 1;
151
193
  totalTokens += e.tokenCount;
152
194
  avgConfidence += e.confidence;
@@ -162,7 +204,7 @@ class ContextSourceLedger {
162
204
  byType,
163
205
  byPermission,
164
206
  bySource,
165
- entries: entries.map(e => ({
207
+ entries: entries.map((e) => ({
166
208
  sourceType: e.sourceType,
167
209
  sourceId: e.sourceId,
168
210
  permissionMode: e.permissionMode,
@@ -184,8 +226,9 @@ class ContextSourceLedger {
184
226
  this._entries.delete(e.entryId);
185
227
  const turnEntries = this._byTurn.get(e.turnId);
186
228
  if (turnEntries) {
187
- const idx = turnEntries.findIndex(x => x.entryId === e.entryId);
229
+ const idx = turnEntries.findIndex((x) => x.entryId === e.entryId);
188
230
  if (idx >= 0) turnEntries.splice(idx, 1);
231
+ if (!turnEntries.length) this._byTurn.delete(e.turnId);
189
232
  }
190
233
  }
191
234
  this._bySession.delete(sessionId);
@@ -246,6 +246,16 @@ function whichLimitHit(state, budget, nowMs) {
246
246
  * the loop stops. Does NOT mutate `state` — returns the next one.
247
247
  */
248
248
  export function evaluateGoalStep(state, evaluation, budget, opts = {}) {
249
+ if (state.done === true) {
250
+ return {
251
+ state: { ...state },
252
+ decision:
253
+ state.outcome === "completed"
254
+ ? GOAL_DECISION.COMPLETE
255
+ : GOAL_DECISION.EXHAUSTED,
256
+ events: [],
257
+ };
258
+ }
249
259
  const nowMs = Number(opts.now ?? state.startedAtMs);
250
260
  const next = {
251
261
  ...state,
@@ -326,10 +336,23 @@ export class GoalConditionEngine {
326
336
 
327
337
  /** Accumulate a turn's usage before evaluating it. */
328
338
  recordTurnUsage({ tokens = 0, costUsd = 0 } = {}) {
339
+ if (
340
+ !Number.isSafeInteger(tokens) ||
341
+ tokens < 0 ||
342
+ typeof costUsd !== "number" ||
343
+ !Number.isFinite(costUsd) ||
344
+ costUsd < 0 ||
345
+ !Number.isSafeInteger(this.state.tokens + tokens) ||
346
+ !Number.isFinite(this.state.costUsd + costUsd)
347
+ ) {
348
+ throw new RangeError(
349
+ "Goal usage requires finite non-negative cost and safe token counts",
350
+ );
351
+ }
329
352
  this.state = {
330
353
  ...this.state,
331
- tokens: this.state.tokens + (Number(tokens) || 0),
332
- costUsd: this.state.costUsd + (Number(costUsd) || 0),
354
+ tokens: this.state.tokens + tokens,
355
+ costUsd: this.state.costUsd + costUsd,
333
356
  };
334
357
  return this.state;
335
358
  }
@@ -38,16 +38,18 @@ export async function reconcileConfigLlmProvider(cfgLlm = {}) {
38
38
  if (!cfgLlm || !cfgLlm.provider || !cfgLlm.baseUrl) {
39
39
  return { llm: cfgLlm, changed: false };
40
40
  }
41
- const { inferProviderFromBaseUrl, modelForeignToProvider } =
42
- await import("./runnable-provider.js");
41
+ const { inferProviderFromBaseUrl, modelForeignToProvider } = await import(
42
+ "./runnable-provider.js"
43
+ );
43
44
  const inferred = inferProviderFromBaseUrl(cfgLlm.baseUrl);
44
45
  if (!inferred || inferred === cfgLlm.provider) {
45
46
  return { llm: cfgLlm, changed: false };
46
47
  }
47
48
  const corrected = { ...cfgLlm, provider: inferred };
48
49
  if (modelForeignToProvider(inferred, cfgLlm.model)) {
49
- const { selectModelForTask, TaskType } =
50
- await import("./task-model-selector.js");
50
+ const { selectModelForTask, TaskType } = await import(
51
+ "./task-model-selector.js"
52
+ );
51
53
  const def = selectModelForTask(inferred, TaskType.CHAT);
52
54
  if (def) corrected.model = def;
53
55
  }
@@ -88,6 +90,8 @@ export function applyConfigLlmDefaults(options = {}, cfgLlm = {}, opts = {}) {
88
90
  options.provider === cfgLlm.provider
89
91
  ) {
90
92
  if (!options.baseUrl && cfgLlm.baseUrl) options.baseUrl = cfgLlm.baseUrl;
93
+ if (options.serviceTier == null && cfgLlm.serviceTier != null)
94
+ options.serviceTier = cfgLlm.serviceTier;
91
95
  backfillApiKey(options, cfgLlm);
92
96
  if (!options.model && !opts.explicitModel && cfgLlm.model) {
93
97
  options.model = cfgLlm.model;
@@ -96,6 +100,8 @@ export function applyConfigLlmDefaults(options = {}, cfgLlm = {}, opts = {}) {
96
100
  }
97
101
  if (options.provider || !cfgLlm.provider) return options;
98
102
  options.provider = cfgLlm.provider;
103
+ if (options.serviceTier == null && cfgLlm.serviceTier != null)
104
+ options.serviceTier = cfgLlm.serviceTier;
99
105
  if (opts.explicitModel) {
100
106
  options.model = opts.explicitModel;
101
107
  } else if (cfgLlm.model) {
@@ -67,6 +67,9 @@ export const PRICE_TABLE = Object.freeze({
67
67
  exact: true,
68
68
  terms: Object.freeze({
69
69
  ...GPT6_PRICING_TERMS,
70
+ ...(model.serviceMultipliers
71
+ ? { serviceMultipliers: model.serviceMultipliers }
72
+ : {}),
70
73
  ...(model.cacheReadMultiplier == null
71
74
  ? {}
72
75
  : { cacheReadMultiplier: model.cacheReadMultiplier }),
@@ -259,9 +262,16 @@ export function normalizePricingTerms(value) {
259
262
  Reflect.ownKeys(tiers).length === 0 ||
260
263
  Reflect.ownKeys(tiers).some(
261
264
  (key) =>
262
- !["standard", "default", "auto", "batch", "flex", "fast"].includes(
263
- key,
264
- ) || !finite(tiers[key]),
265
+ ![
266
+ "standard",
267
+ "default",
268
+ "auto",
269
+ "batch",
270
+ "flex",
271
+ "fast",
272
+ "priority",
273
+ "ultrafast",
274
+ ].includes(key) || !finite(tiers[key]),
265
275
  )
266
276
  )
267
277
  fail();
@@ -378,7 +388,9 @@ export function estimateCost({
378
388
  ? Object.hasOwn(rate.terms.serviceMultipliers, serviceTier)
379
389
  ? rate.terms.serviceMultipliers[serviceTier]
380
390
  : null
381
- : 1;
391
+ : ["standard", "default"].includes(serviceTier)
392
+ ? 1
393
+ : null;
382
394
  if (
383
395
  !rate ||
384
396
  tierMultiplier == null ||