chainlesschain 0.166.98 → 0.166.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -23
- package/package.json +1 -1
- package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
- package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-DCIQFtF1.js → AIOps-Cd4iUOPt.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BxhHU3nE.js → ActionButton--ucr-zko.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DdM_307O.js → Analytics-DbejYMWk.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-C43-kSrh.js → AppLayout-CLgKxeGw.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-B2Vp2Am6.js → Artifacts-CTT5BIL5.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-s-lYUfOp.js → Audit-DP-WBWe9.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-DTE7Kzio.js → BackgroundAgents-B6VqheJk.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-9k1q4Mt6.js → Backup-VWJK5zim.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-DlpUtK5R.js → BaseInput-YGFO9RHd.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CR9S8Rmb.js → Chat-CVfydnCd.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-BICpB-qU.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-DpFRu7Df.js → Checkbox-Bd5vKRMk.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-BIl72E4Y.js → Codegen-DHNgPHvg.js} +1 -1
- package/src/assets/web-panel/assets/{Col-91tl_err.js → Col-CA2BYQ8T.js} +1 -1
- package/src/assets/web-panel/assets/{Community-CswahO9-.js → Community-DnKJ-qpI.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-D9pfHmaM.js → Compact-C9BZ8t4r.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CXSZzAO9.js → Compliance-ByyQ2FOl.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CuT9RWTn.js → Cowork-rXTwXE_c.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-B71aJWDV.js → Cron-BuW-HODy.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-CcUuWyx8.js → Crosschain-OudNtbYW.js} +1 -1
- package/src/assets/web-panel/assets/{DID-CtVVGOPL.js → DID-BQ6BxYNN.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-CV7ZCYQq.js → Dashboard-Cz5HG8tz.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DKHxwLgE.js → Dropdown-BzclHOVv.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-Bd03UIvv.js → EmailListRenderer-CbJETFdy.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-CTrG03B_.js → EvolutionSettings-Dx_pJG3d.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-DXS4bS6Q.js → FamilyGuardDashboard-6JCS1MNg.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BODG2Szj.js → Federation-BrPkMYaf.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-D32ccUqD.js → FormItemContext-Bhc9pobs.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-ClsyrKvF.js → GenericCardRenderer-BxOh07uQ.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DcM2yhbL.js → Git-D_idoujr.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BhUzM87n.js → Governance-ZGfIRE-x.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-Dq1n0Ifg.js → Inference-DpAmcwbw.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-dmmPwEks.js → KnowledgeGraph-D1S1UTgP.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-CBSYrPmh.js → Logs-2sc8V5XV.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-575jjYE6.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-Cfw7XLck.js → Marketplace-0xlFUKbe.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CNrZRy4n.js → McpTools-D25eJLGm.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-BESjTxdd.js → Memory-BLRGd9hM.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-Boyjo07i.js → MobileBridge-zpFINGzn.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-BmxmpTWz.js → MobileProjects-Cbyd-8kx.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-CBkrD0Fq.js → Mtc-DgXgUlHc.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-BA7cAK8h.js → MtcAudit-DzcL-dKH.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-m0RGzkKO.js → Multisig-C3OrZ6VN.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-D_TgzifU.js → NLProgramming-Bqp_vWA7.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Dr-Yr9LL.js → Notes-Dyn45-Ht.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-DGanpkqO.js → NotificationSettings-CLjafGZr.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-D1FX50QY.js → OrderTableRenderer-Bx8wMauC.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-DRbPg-gs.js → Organization-5gr9hyLm.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-flEO37z6.js → Overflow-BRdU02hT.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DqfqFbCW.js → P2P-DIi7fzh6.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-Cmi5a5dW.js → PdhVaultBrowser-BCbS1KpA.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-DBVRlvBW.js → Permissions-BjeP9VtA.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-gQqjPr9X.js → PersonalDataHub-y8PXOQUc.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-6HlifUc9.js → Pipeline-B0fL5uxY.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-bm_2-Zwg.js → Privacy-C8jCDn8Z.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BJW3isuq.js → ProjectInit-B_L6Dc6V.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-DD3yolz7.js → ProjectSettings-Bb1CYbZh.js} +2 -2
- package/src/assets/web-panel/assets/Projects-CUSV10Cn.js +1 -0
- package/src/assets/web-panel/assets/{Providers-CQA6WAK7.js → Providers-mBSTDJ0E.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-DOAwp5Xo.js → QrScannerModal-CHxgalvt.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-qeFXsAZT.js → QuickAsk-DI9KIMEV.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-zDWXwZN8.js → Recommend-B5_zW1JH.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-toe6Ip06.js → RemoteSession-BkH4bmM5.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-DRDi_Eqp.js → Reputation-DJrAqwAq.js} +1 -1
- package/src/assets/web-panel/assets/{Row-Do2UbYkf.js → Row-xZ3MAM34.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-B57C6_Sa.js → RssFeed-CCsrLLiu.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DfDyBpe9.js → Search-CTCRKvaP.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CulNxeAM.js → Security-D7joyfp2.js} +4 -4
- package/src/assets/web-panel/assets/{Services-COfAYvs4.js → Services-oqHPmTG4.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-0fn0T146.js → Skeleton-BR_32bTG.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-pPQgAhvJ.js → Skills-BoRz9mln.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-CIsRmePR.js → Sla-UAGUHZ9b.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-Bn01d-8b.js → SpeechSettings-DeP_rMgv.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-Cx_Znk7L.js → SyncSettings-CSzzMmeA.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-DvaskzpG.js → Tasks-CcqOLsLB.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-DmHCEiDO.js → Templates-cDbkGSDG.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CqHyvnbW.js → Tenant-DmOy58cq.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-DTt3yqWL.js → Terminal-CsRZH5vr.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-BhkIxcR3.js → TimelineRenderer-BgJrk6HG.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-mhjYcBBP.js → Tokens-CCQglKDE.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-CdlMQfwX.js → Trigger-t-Gt3oBY.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-Bzovg_Gw.js → Trust-DQgu2kI0.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-ph3EuYi7.js → UkeySign-Cod2WUGj.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-Bo2B4VZE.js → VideoEditing-SGN5zaVK.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BQTKsSUT.js → Wallet-CnLEL-LD.js} +3 -3
- package/src/assets/web-panel/assets/{WebAuthn-nJxsXNHV.js → WebAuthn-C2keUpD6.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-CjH8g2N7.js → WorkflowEditor-B1GvrwWJ.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CkbNmnQD.js → chat-1E9_P_qY.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BY9JcObR.js → colors-DuU6Os4q.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-Dzzq-d8n.js → compact-item-C5NfOAcM.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DiJxxdTx.js → createContext-D4Fxz9qQ.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-zDWbYMr7.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DaXPOw3D.js → hasIn-C6C49iFk.js} +1 -1
- package/src/assets/web-panel/assets/{index-Uh9SjtgW.js → index-AO6iDCSL.js} +1 -1
- package/src/assets/web-panel/assets/{index-B4Sf1AMk.js → index-B-bb-R99.js} +1 -1
- package/src/assets/web-panel/assets/{index-cu1J4avY.js → index-B5lzRoHp.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaylJfw6.js → index-BBVqlelF.js} +1 -1
- package/src/assets/web-panel/assets/index-BPBsZZnT.js +1 -0
- package/src/assets/web-panel/assets/{index-CWLpEg34.js → index-BU5mPkNX.js} +1 -1
- package/src/assets/web-panel/assets/{index-LRZSVBxC.js → index-BULggEX6.js} +1 -1
- package/src/assets/web-panel/assets/{index-Djeh6rAb.js → index-BVE2wCeb.js} +1 -1
- package/src/assets/web-panel/assets/{index-B31oMRmK.js → index-BYg1dtne.js} +1 -1
- package/src/assets/web-panel/assets/{index-DSqQyS9-.js → index-BZKRZYTX.js} +1 -1
- package/src/assets/web-panel/assets/{index-CnLO1_yN.js → index-B_ON9La1.js} +1 -1
- package/src/assets/web-panel/assets/{index-Jmlk_lDX.js → index-Bk-paNL3.js} +1 -1
- package/src/assets/web-panel/assets/{index-BQvtlYUd.js → index-BlHkc48f.js} +1 -1
- package/src/assets/web-panel/assets/{index-BvgMt6Io.js → index-BmvU4Tp_.js} +1 -1
- package/src/assets/web-panel/assets/{index-CbOOm8I8.js → index-BsH8mFp4.js} +1 -1
- package/src/assets/web-panel/assets/{index-C_OMH_FT.js → index-Bu6qMjf4.js} +1 -1
- package/src/assets/web-panel/assets/{index-BycyBM6g.js → index-C2nO02uW.js} +1 -1
- package/src/assets/web-panel/assets/{index-BlWg1bRA.js → index-C7mh6xlu.js} +1 -1
- package/src/assets/web-panel/assets/{index-i9eu2Kir.js → index-CDVwN9Sv.js} +1 -1
- package/src/assets/web-panel/assets/{index-DWT9-E5b.js → index-CJS6GTpv.js} +1 -1
- package/src/assets/web-panel/assets/{index-CqOkm6kW.js → index-CQJoh5rw.js} +1 -1
- package/src/assets/web-panel/assets/{index-7YVCjSqG.js → index-CXb8gEWh.js} +1 -1
- package/src/assets/web-panel/assets/{index-DDnqjZa2.js → index-CXn-e3ki.js} +1 -1
- package/src/assets/web-panel/assets/{index-Igq-72Ep.js → index-CpiOzt7U.js} +1 -1
- package/src/assets/web-panel/assets/index-CtGQDg7m.js +1 -0
- package/src/assets/web-panel/assets/{index-BqCHe05H.js → index-D1TXgNPA.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_Eoh740.js → index-DFK6PTGJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-EiaWq1TH.js → index-DP2DCKD-.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVblRqUN.js → index-DPzunJER.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bhsxh-rH.js → index-DSypQU1h.js} +1 -1
- package/src/assets/web-panel/assets/{index-DbmHmeP-.js → index-DZgT7pH-.js} +1 -1
- package/src/assets/web-panel/assets/{index-dC2JACyJ.js → index-Dh-vezHe.js} +1 -1
- package/src/assets/web-panel/assets/{index-BHeHyLRM.js → index-DpaGe-dr.js} +3 -3
- package/src/assets/web-panel/assets/{index-6Z6Z4UwN.js → index-HQXFl8fh.js} +1 -1
- package/src/assets/web-panel/assets/{index-BGvIb1Sr.js → index-bW6vfpLH.js} +1 -1
- package/src/assets/web-panel/assets/{index-DObXhPhH.js → index-cnDfwWU5.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dl8U-0hn.js → index-gh11zJ9h.js} +1 -1
- package/src/assets/web-panel/assets/{index-CAzfu6k5.js → index-jFg3CPlQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-C6XSCXeb.js → index-lNmDaf3J.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-B0WuG3fa.js → initDefaultProps-3DSfnIpD.js} +1 -1
- package/src/assets/web-panel/assets/{motion-1r5YB22w.js → motion-DxGLmgA0.js} +1 -1
- package/src/assets/web-panel/assets/{move-CvtXWA_V.js → move-DrlLG6m5.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-ChedmEE_.js → mtc-parser-BITbrJSb.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DpEA3MP0.js → omit-D7k5vIbk.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BWgrUZF6.js → pickAttrs-BJSvYFWo.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BWfo_VbI.js → placementArrow-Bf4to1jA.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CRft03Vk.js → responsiveObserve-BXzeyzTa.js} +1 -1
- package/src/assets/web-panel/assets/{slide-l5LeXusH.js → slide-DLzNUNdj.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CCEC0JR-.js → statusUtils-wBBnrRm_.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-Bw5Gw_2w.js → styleChecker-BnmJzXNr.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-BAuxWB7K.js → useFlexGapSupport-DrN8MrJb.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CxUP97Cw.js → useFs-dnkYGkjY.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BJDjT4Sy.js → usePersonalDataHub-k_xkv7-k.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BcCsFzIs.js → vnode-B-v8PXpK.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-MLmG09h6.js → zoom-Coue8wAK.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/data/changelog.json +26 -0
- package/src/harness/worktree-isolator.js +20 -8
- package/src/lib/chat-core.js +57 -25
- package/src/lib/cost-budget.js +8 -0
- package/src/lib/eval/verify01-execution-window.js +70 -0
- package/src/lib/eval/verify01-execution.js +9 -1
- package/src/lib/eval/verify01-host-capture.js +6 -2
- package/src/lib/llm-pricing.js +61 -7
- package/src/lib/model-capabilities.js +10 -2
- package/src/lib/model-catalog-review.js +1 -0
- package/src/lib/model-context-catalog.js +26 -1
- package/src/lib/provider-http-error.js +16 -0
- package/src/lib/provider-options.js +38 -1
- package/src/lib/search-command.js +4 -1
- package/src/lib/stream-retry.js +209 -2
- package/src/lib/usage-pricing-context.js +100 -10
- package/src/runtime/agent-core.js +170 -38
- package/src/runtime/headless-runner.js +17 -0
- package/src/runtime/headless-stream.js +17 -0
- package/src/runtime/provider-stream-state.js +7 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-Xtgfw3-c.js +0 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-CRoDI77y.js +0 -1
- package/src/assets/web-panel/assets/Projects-BF3GtWny.js +0 -1
- package/src/assets/web-panel/assets/devWarning-D502_Z3w.js +0 -1
- package/src/assets/web-panel/assets/index-BrQ4nI4W.js +0 -1
- package/src/assets/web-panel/assets/index-C0_sewGO.js +0 -1
|
@@ -1,11 +1,52 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DOCUMENTED_OPENAI_MODELS,
|
|
3
|
+
DOCUMENTED_ANTHROPIC_MODELS,
|
|
3
4
|
GPT6_PRICING_TERMS,
|
|
4
5
|
} from "./model-context-catalog.js";
|
|
5
6
|
|
|
7
|
+
/** Keep TTL evidence distinct from the aggregate cache-write count. */
|
|
8
|
+
export function projectCacheCreationUsage(usage = {}) {
|
|
9
|
+
if (usage.cacheCreationInvalid === true)
|
|
10
|
+
return { cacheCreationInvalid: true };
|
|
11
|
+
if (
|
|
12
|
+
Object.hasOwn(usage, "cache_creation_input_tokens") &&
|
|
13
|
+
Object.hasOwn(usage, "cacheCreationTokens") &&
|
|
14
|
+
usage.cache_creation_input_tokens !== usage.cacheCreationTokens
|
|
15
|
+
)
|
|
16
|
+
return { cacheCreationInvalid: true };
|
|
17
|
+
const nested = usage.cache_creation;
|
|
18
|
+
const hasFlat =
|
|
19
|
+
Object.hasOwn(usage, "cacheCreation5mTokens") ||
|
|
20
|
+
Object.hasOwn(usage, "cacheCreation1hTokens");
|
|
21
|
+
if (!Object.hasOwn(usage, "cache_creation") && !hasFlat) return {};
|
|
22
|
+
if (
|
|
23
|
+
Object.hasOwn(usage, "cache_creation") &&
|
|
24
|
+
(nested === null || typeof nested !== "object" || Array.isArray(nested))
|
|
25
|
+
)
|
|
26
|
+
return { cacheCreationInvalid: true };
|
|
27
|
+
const five = nested?.ephemeral_5m_input_tokens ?? usage.cacheCreation5mTokens;
|
|
28
|
+
const hour = nested?.ephemeral_1h_input_tokens ?? usage.cacheCreation1hTokens;
|
|
29
|
+
const total = usage.cache_creation_input_tokens ?? usage.cacheCreationTokens;
|
|
30
|
+
if (
|
|
31
|
+
![five, hour, total].every(
|
|
32
|
+
(value) => Number.isSafeInteger(value) && value >= 0,
|
|
33
|
+
) ||
|
|
34
|
+
five + hour !== total ||
|
|
35
|
+
(hasFlat &&
|
|
36
|
+
nested != null &&
|
|
37
|
+
(five !== usage.cacheCreation5mTokens ||
|
|
38
|
+
hour !== usage.cacheCreation1hTokens))
|
|
39
|
+
) {
|
|
40
|
+
return { cacheCreationInvalid: true };
|
|
41
|
+
}
|
|
42
|
+
return { cacheCreation5mTokens: five, cacheCreation1hTokens: hour };
|
|
43
|
+
}
|
|
44
|
+
|
|
6
45
|
/** Only bounded, non-secret pricing labels may enter the durable usage ledger. */
|
|
7
46
|
export function projectUsagePricingContext(usage = {}) {
|
|
8
|
-
const projected =
|
|
47
|
+
const projected = projectCacheCreationUsage(usage);
|
|
48
|
+
if (usage.pricingContextInvalid === true)
|
|
49
|
+
projected.pricingContextInvalid = true;
|
|
9
50
|
for (const [key, alias] of [
|
|
10
51
|
["service_tier", "serviceTier"],
|
|
11
52
|
["regional_processing", "regionalProcessing"],
|
|
@@ -31,23 +72,56 @@ export function projectUsagePricingContext(usage = {}) {
|
|
|
31
72
|
projected[key] = value;
|
|
32
73
|
}
|
|
33
74
|
}
|
|
75
|
+
if (Object.hasOwn(usage, "inference_geo")) {
|
|
76
|
+
const geo = usage.inference_geo;
|
|
77
|
+
if (geo !== "us" && geo !== "global") {
|
|
78
|
+
projected.inference_geo = "unknown";
|
|
79
|
+
projected.pricingContextInvalid = true;
|
|
80
|
+
} else {
|
|
81
|
+
if (
|
|
82
|
+
Object.hasOwn(projected, "regional_processing") &&
|
|
83
|
+
projected.regional_processing !== (geo === "us")
|
|
84
|
+
) {
|
|
85
|
+
throw new TypeError(
|
|
86
|
+
"usage inference_geo conflicts with regional processing",
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
projected.inference_geo = geo;
|
|
90
|
+
projected.regional_processing = geo === "us";
|
|
91
|
+
}
|
|
92
|
+
}
|
|
34
93
|
return projected;
|
|
35
94
|
}
|
|
36
95
|
|
|
37
96
|
/** Preserve per-request thresholds in a bounded set of aggregate price buckets. */
|
|
38
97
|
export function mergeUsagePricingBucket(entry, usage) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
98
|
+
const provider = String(entry.provider).toLowerCase();
|
|
99
|
+
const model = String(entry.model).toLowerCase();
|
|
100
|
+
const terms =
|
|
101
|
+
provider === "openai" && DOCUMENTED_OPENAI_MODELS[model]?.pricing
|
|
102
|
+
? GPT6_PRICING_TERMS
|
|
103
|
+
: provider === "anthropic"
|
|
104
|
+
? DOCUMENTED_ANTHROPIC_MODELS[model]?.pricingTerms
|
|
105
|
+
: null;
|
|
106
|
+
if (!terms?.longContext) return;
|
|
44
107
|
const metadata = projectUsagePricingContext(usage);
|
|
108
|
+
const pricingContextInvalid =
|
|
109
|
+
metadata.pricingContextInvalid === true ||
|
|
110
|
+
(provider === "anthropic" &&
|
|
111
|
+
model === "claude-haiku-5-5" &&
|
|
112
|
+
metadata.regional_processing == null);
|
|
45
113
|
const promptTokens =
|
|
46
114
|
usage.requestInputTokens ??
|
|
47
115
|
usage.inputTokens +
|
|
48
116
|
(usage.cacheReadTokens || 0) +
|
|
49
117
|
(usage.cacheCreationTokens || 0);
|
|
50
|
-
const long = promptTokens >
|
|
118
|
+
const long = promptTokens > terms.longContext.threshold;
|
|
119
|
+
const cache = projectCacheCreationUsage(usage);
|
|
120
|
+
const cacheEvidence = cache.cacheCreationInvalid
|
|
121
|
+
? "invalid"
|
|
122
|
+
: cache.cacheCreation5mTokens != null
|
|
123
|
+
? "split"
|
|
124
|
+
: "missing";
|
|
51
125
|
const serviceTier = metadata.service_tier || "standard";
|
|
52
126
|
const regionalProcessing = metadata.regional_processing === true;
|
|
53
127
|
entry.pricingBuckets ||= [];
|
|
@@ -55,8 +129,9 @@ export function mergeUsagePricingBucket(entry, usage) {
|
|
|
55
129
|
(item) =>
|
|
56
130
|
item.serviceTier === serviceTier &&
|
|
57
131
|
item.regionalProcessing === regionalProcessing &&
|
|
58
|
-
item.
|
|
59
|
-
|
|
132
|
+
(item.pricingContextInvalid === true) === pricingContextInvalid &&
|
|
133
|
+
(item.cacheEvidence || "missing") === cacheEvidence &&
|
|
134
|
+
item.requestInputTokens > terms.longContext.threshold === long,
|
|
60
135
|
);
|
|
61
136
|
if (!bucket) {
|
|
62
137
|
bucket = {
|
|
@@ -69,6 +144,18 @@ export function mergeUsagePricingBucket(entry, usage) {
|
|
|
69
144
|
serviceTier,
|
|
70
145
|
regionalProcessing,
|
|
71
146
|
requestInputTokens: promptTokens,
|
|
147
|
+
...(pricingContextInvalid ? { pricingContextInvalid: true } : {}),
|
|
148
|
+
...(provider === "anthropic"
|
|
149
|
+
? {
|
|
150
|
+
cacheEvidence,
|
|
151
|
+
...(cacheEvidence === "split"
|
|
152
|
+
? { cacheCreation5mTokens: 0, cacheCreation1hTokens: 0 }
|
|
153
|
+
: {}),
|
|
154
|
+
...(cacheEvidence === "invalid"
|
|
155
|
+
? { cacheCreationInvalid: true }
|
|
156
|
+
: {}),
|
|
157
|
+
}
|
|
158
|
+
: {}),
|
|
72
159
|
};
|
|
73
160
|
entry.pricingBuckets.push(bucket);
|
|
74
161
|
}
|
|
@@ -79,8 +166,11 @@ export function mergeUsagePricingBucket(entry, usage) {
|
|
|
79
166
|
"cacheCreationTokens",
|
|
80
167
|
"totalTokens",
|
|
81
168
|
"calls",
|
|
169
|
+
...(cacheEvidence === "split"
|
|
170
|
+
? ["cacheCreation5mTokens", "cacheCreation1hTokens"]
|
|
171
|
+
: []),
|
|
82
172
|
]) {
|
|
83
|
-
const value = usage[key] ?? (key === "calls" ? 1 : 0);
|
|
173
|
+
const value = cache[key] ?? usage[key] ?? (key === "calls" ? 1 : 0);
|
|
84
174
|
if (
|
|
85
175
|
!Number.isSafeInteger(value) ||
|
|
86
176
|
value < 0 ||
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import fs from "fs";
|
|
18
|
+
import { isUtf8 } from "node:buffer";
|
|
18
19
|
import {
|
|
19
20
|
_isNonNegativeSafeInteger,
|
|
20
21
|
_providerUsageCount,
|
|
@@ -59,6 +60,8 @@ import {
|
|
|
59
60
|
TASK_RECOVERY_TOOLS,
|
|
60
61
|
} from "../lib/task-progress-tracker.js";
|
|
61
62
|
import { TOOL_RECOVERY_PAUSED_CODE } from "../lib/tool-recovery-result.js";
|
|
63
|
+
import { haiku55ThinkingParams } from "../lib/provider-options.js";
|
|
64
|
+
import { projectUsagePricingContext } from "../lib/usage-pricing-context.js";
|
|
62
65
|
import broker from "../lib/process-execution-broker/index.js";
|
|
63
66
|
import os from "os";
|
|
64
67
|
import { createHash, randomUUID } from "node:crypto";
|
|
@@ -153,6 +156,10 @@ import {
|
|
|
153
156
|
isRetryableStreamError,
|
|
154
157
|
STREAM_RETRY_BASE_MS,
|
|
155
158
|
resolveStreamRetryMax,
|
|
159
|
+
captureStreamRetryMetadata,
|
|
160
|
+
attachStreamRetryMetadata,
|
|
161
|
+
resolveStreamRetryDelay,
|
|
162
|
+
waitForStreamRetry,
|
|
156
163
|
} from "../lib/stream-retry.js";
|
|
157
164
|
import {
|
|
158
165
|
annotateLines,
|
|
@@ -181,7 +188,7 @@ import {
|
|
|
181
188
|
} from "../lib/unattended-action-policy.js";
|
|
182
189
|
import {
|
|
183
190
|
formatProviderHttpError,
|
|
184
|
-
|
|
191
|
+
createProviderResponseError,
|
|
185
192
|
} from "../lib/provider-http-error.js";
|
|
186
193
|
import { buildPermissionDecision } from "../lib/permission-decision.js";
|
|
187
194
|
import { resolveSandboxPolicyPath } from "../lib/agent-sandbox.js";
|
|
@@ -2024,6 +2031,20 @@ function applyLiteralEdit(content, oldStr, newStr, replaceAll) {
|
|
|
2024
2031
|
return { count, newContent };
|
|
2025
2032
|
}
|
|
2026
2033
|
|
|
2034
|
+
// Edits derive their output from the entire existing file. A replacement
|
|
2035
|
+
// decoder would silently rewrite unrelated legacy or malformed bytes.
|
|
2036
|
+
function readUtf8ForEdit(filePath) {
|
|
2037
|
+
const bytes = fs.readFileSync(filePath);
|
|
2038
|
+
if (!isUtf8(bytes)) {
|
|
2039
|
+
return {
|
|
2040
|
+
error: "File is not valid UTF-8; text edits require valid UTF-8 bytes.",
|
|
2041
|
+
code: "CC_EDIT_INVALID_UTF8",
|
|
2042
|
+
};
|
|
2043
|
+
}
|
|
2044
|
+
// Buffer decoding preserves a valid UTF-8 BOM and literal U+FFFD characters.
|
|
2045
|
+
return { content: bytes.toString("utf8") };
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2027
2048
|
/**
|
|
2028
2049
|
* Compute the content an edit tool WOULD write, without writing it — the
|
|
2029
2050
|
* left/right sides for an IDE diff review. Mirrors the corresponding
|
|
@@ -2085,7 +2106,9 @@ export function computeProposedEdit(name, args = {}, cwd = process.cwd()) {
|
|
|
2085
2106
|
}
|
|
2086
2107
|
if (name === "edit_file") {
|
|
2087
2108
|
if (!fs.existsSync(filePath)) return null;
|
|
2088
|
-
const
|
|
2109
|
+
const decoded = readUtf8ForEdit(filePath);
|
|
2110
|
+
if (decoded.error) return null;
|
|
2111
|
+
const content = decoded.content;
|
|
2089
2112
|
if (
|
|
2090
2113
|
typeof args.old_string !== "string" ||
|
|
2091
2114
|
args.old_string === "" ||
|
|
@@ -2113,7 +2136,9 @@ export function computeProposedEdit(name, args = {}, cwd = process.cwd()) {
|
|
|
2113
2136
|
if (name === "edit_file_hashed") {
|
|
2114
2137
|
if (!fs.existsSync(filePath)) return null;
|
|
2115
2138
|
if (!args.anchor_hash || typeof args.new_line !== "string") return null;
|
|
2116
|
-
const
|
|
2139
|
+
const decoded = readUtf8ForEdit(filePath);
|
|
2140
|
+
if (decoded.error) return null;
|
|
2141
|
+
const original = decoded.content;
|
|
2117
2142
|
const result = replaceByHash(original, {
|
|
2118
2143
|
anchorHash: args.anchor_hash,
|
|
2119
2144
|
expectedLine: args.expected_line,
|
|
@@ -5835,7 +5860,9 @@ async function executeToolInner(
|
|
|
5835
5860
|
if (!fs.existsSync(filePath)) {
|
|
5836
5861
|
return attachDescriptor({ error: `Notebook not found: ${filePath}` });
|
|
5837
5862
|
}
|
|
5838
|
-
const
|
|
5863
|
+
const decoded = readUtf8ForEdit(filePath);
|
|
5864
|
+
if (decoded.error) return attachDescriptor(decoded);
|
|
5865
|
+
const original = decoded.content;
|
|
5839
5866
|
const res = editNotebookCell(original, args);
|
|
5840
5867
|
if (res.error) return attachDescriptor({ error: res.error });
|
|
5841
5868
|
const wrote = writeFileVerified(filePath, res.text);
|
|
@@ -5871,7 +5898,9 @@ async function executeToolInner(
|
|
|
5871
5898
|
}
|
|
5872
5899
|
const staleEdit = _checkFileFreshness(filePath);
|
|
5873
5900
|
if (staleEdit) return attachDescriptor({ error: staleEdit });
|
|
5874
|
-
const
|
|
5901
|
+
const decoded = readUtf8ForEdit(filePath);
|
|
5902
|
+
if (decoded.error) return attachDescriptor(decoded);
|
|
5903
|
+
const content = decoded.content;
|
|
5875
5904
|
const replaceAll = args.replace_all === true;
|
|
5876
5905
|
const { count, newContent } = applyLiteralEdit(
|
|
5877
5906
|
content,
|
|
@@ -5971,7 +6000,9 @@ async function executeToolInner(
|
|
|
5971
6000
|
}
|
|
5972
6001
|
const staleHashed = _checkFileFreshness(filePath);
|
|
5973
6002
|
if (staleHashed) return attachDescriptor({ error: staleHashed });
|
|
5974
|
-
const
|
|
6003
|
+
const decoded = readUtf8ForEdit(filePath);
|
|
6004
|
+
if (decoded.error) return attachDescriptor(decoded);
|
|
6005
|
+
const original = decoded.content;
|
|
5975
6006
|
const result = replaceByHash(original, {
|
|
5976
6007
|
anchorHash: args.anchor_hash,
|
|
5977
6008
|
expectedLine: args.expected_line,
|
|
@@ -11893,7 +11924,7 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
11893
11924
|
}),
|
|
11894
11925
|
});
|
|
11895
11926
|
if (!response.ok) {
|
|
11896
|
-
throw
|
|
11927
|
+
throw await createProviderResponseError("ollama", response);
|
|
11897
11928
|
}
|
|
11898
11929
|
const data = await response.json();
|
|
11899
11930
|
if (
|
|
@@ -11962,10 +11993,16 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
11962
11993
|
messages: _toAnthropicMessages(otherMsgs),
|
|
11963
11994
|
tools: anthropicTools,
|
|
11964
11995
|
};
|
|
11965
|
-
|
|
11966
|
-
|
|
11967
|
-
|
|
11968
|
-
|
|
11996
|
+
if (
|
|
11997
|
+
effModel.toLowerCase() === "claude-haiku-5-5" &&
|
|
11998
|
+
body.messages.at(-1)?.role === "assistant"
|
|
11999
|
+
) {
|
|
12000
|
+
throw new TypeError("Haiku 5.5 does not support assistant prefill.");
|
|
12001
|
+
}
|
|
12002
|
+
// Legacy models retain opt-in thinking. Exact Haiku 5.5 uses its documented
|
|
12003
|
+
// adaptive/medium default and accepts an explicit disabled setting.
|
|
12004
|
+
// Sampling parameters are never sent. RUNTIME-UNVERIFIED: no Anthropic key
|
|
12005
|
+
// here to E2E the
|
|
11969
12006
|
// thinking-block signature replay (see cli_claude_code_parity_landed memory).
|
|
11970
12007
|
const thinkingParams = _anthropicThinkingParams(
|
|
11971
12008
|
effModel,
|
|
@@ -12040,12 +12077,17 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
12040
12077
|
});
|
|
12041
12078
|
|
|
12042
12079
|
if (!response.ok) {
|
|
12043
|
-
throw
|
|
12080
|
+
throw await createProviderResponseError("anthropic", response);
|
|
12044
12081
|
}
|
|
12045
12082
|
|
|
12046
12083
|
const data = await response.json();
|
|
12047
12084
|
const normalized = _normalizeAnthropicResponse(data);
|
|
12048
12085
|
if (_hasCompleteProviderUsage(data.usage)) {
|
|
12086
|
+
const cacheCreationTokens = _optionalProviderUsageCount(
|
|
12087
|
+
data.usage,
|
|
12088
|
+
"cache_creation_input_tokens",
|
|
12089
|
+
"cache_creation_tokens",
|
|
12090
|
+
);
|
|
12049
12091
|
normalized.usage = {
|
|
12050
12092
|
// With prompt caching, Anthropic splits input into uncached
|
|
12051
12093
|
// `input_tokens` + cache read/write — capture all three so cost
|
|
@@ -12066,11 +12108,11 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
12066
12108
|
"cache_read_input_tokens",
|
|
12067
12109
|
"cache_read_tokens",
|
|
12068
12110
|
),
|
|
12069
|
-
cache_creation_input_tokens:
|
|
12070
|
-
|
|
12071
|
-
|
|
12072
|
-
|
|
12073
|
-
),
|
|
12111
|
+
cache_creation_input_tokens: cacheCreationTokens,
|
|
12112
|
+
...projectUsagePricingContext({
|
|
12113
|
+
...data.usage,
|
|
12114
|
+
cache_creation_input_tokens: cacheCreationTokens,
|
|
12115
|
+
}),
|
|
12074
12116
|
};
|
|
12075
12117
|
}
|
|
12076
12118
|
return normalized;
|
|
@@ -12191,7 +12233,7 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
12191
12233
|
body: JSON.stringify(responseBody),
|
|
12192
12234
|
});
|
|
12193
12235
|
if (!response.ok) {
|
|
12194
|
-
throw
|
|
12236
|
+
throw await createProviderResponseError(provider, response);
|
|
12195
12237
|
}
|
|
12196
12238
|
const data = await response.json();
|
|
12197
12239
|
const out = normalizeOpenAIResponsesResponse(data);
|
|
@@ -12272,7 +12314,7 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
12272
12314
|
});
|
|
12273
12315
|
|
|
12274
12316
|
if (!response.ok) {
|
|
12275
|
-
throw
|
|
12317
|
+
throw await createProviderResponseError(provider, response);
|
|
12276
12318
|
}
|
|
12277
12319
|
|
|
12278
12320
|
const data = await response.json();
|
|
@@ -12359,9 +12401,11 @@ function _ollamaInitState() {
|
|
|
12359
12401
|
|
|
12360
12402
|
function _streamUiCallbacks(onToken, onThinking) {
|
|
12361
12403
|
let pending = [];
|
|
12404
|
+
let visible = false;
|
|
12362
12405
|
const capture = (callback) =>
|
|
12363
12406
|
typeof callback === "function"
|
|
12364
12407
|
? (value) => {
|
|
12408
|
+
if (typeof value === "string" && value.length > 0) visible = true;
|
|
12365
12409
|
try {
|
|
12366
12410
|
const result = callback(value);
|
|
12367
12411
|
if (result && typeof result.then === "function") {
|
|
@@ -12375,6 +12419,7 @@ function _streamUiCallbacks(onToken, onThinking) {
|
|
|
12375
12419
|
return {
|
|
12376
12420
|
onToken: capture(onToken),
|
|
12377
12421
|
onThinking: capture(onThinking),
|
|
12422
|
+
hasVisibleOutput: () => visible,
|
|
12378
12423
|
async settle() {
|
|
12379
12424
|
if (pending.length === 0) return;
|
|
12380
12425
|
const current = pending;
|
|
@@ -12478,11 +12523,17 @@ export function _accumulateOllamaStream(lines, onToken) {
|
|
|
12478
12523
|
* Parity with Claude-Code 2.1.179 ("preserving partial responses instead of
|
|
12479
12524
|
* showing raw errors"). Pure + exported for unit tests.
|
|
12480
12525
|
*/
|
|
12481
|
-
export function _streamErrorDisposition(
|
|
12526
|
+
export function _streamErrorDisposition(
|
|
12527
|
+
err,
|
|
12528
|
+
signal,
|
|
12529
|
+
partialText,
|
|
12530
|
+
visible = false,
|
|
12531
|
+
) {
|
|
12482
12532
|
if (err?.isOutputBackpressureFailure === true) return "rethrow";
|
|
12483
12533
|
if (isAbortError(err)) return "rethrow";
|
|
12484
12534
|
if (signal && signal.aborted) return "rethrow";
|
|
12485
|
-
if (typeof partialText === "string" && partialText.
|
|
12535
|
+
if (visible || (typeof partialText === "string" && partialText.length > 0))
|
|
12536
|
+
return "preserve";
|
|
12486
12537
|
return "rethrow";
|
|
12487
12538
|
}
|
|
12488
12539
|
|
|
@@ -12547,16 +12598,22 @@ export async function _retryStreamingChat(streamFn, opts = {}) {
|
|
|
12547
12598
|
const retries = opts.retries ?? resolveStreamRetryMax();
|
|
12548
12599
|
const base = opts.baseDelayMs ?? STREAM_RETRY_BASE_MS;
|
|
12549
12600
|
const signal = opts.signal;
|
|
12550
|
-
const sleep = opts.sleep || ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
12551
12601
|
const now = typeof opts.now === "function" ? opts.now : Date.now;
|
|
12552
12602
|
let attempt = 0;
|
|
12553
12603
|
for (;;) {
|
|
12604
|
+
throwIfAborted(signal);
|
|
12554
12605
|
const attemptStartedAt = now();
|
|
12555
12606
|
try {
|
|
12556
12607
|
return await streamFn(attempt);
|
|
12557
12608
|
} catch (err) {
|
|
12558
12609
|
if (attempt >= retries || !_isRetryableStreamError(err, signal))
|
|
12559
12610
|
throw err;
|
|
12611
|
+
const attemptEndedAt = now();
|
|
12612
|
+
const delayMs = resolveStreamRetryDelay(err, attempt + 1, {
|
|
12613
|
+
baseDelayMs: base,
|
|
12614
|
+
now: attemptEndedAt,
|
|
12615
|
+
});
|
|
12616
|
+
if (delayMs === null) throw err;
|
|
12560
12617
|
attempt++;
|
|
12561
12618
|
if (
|
|
12562
12619
|
opts.strictRetryObserver === true &&
|
|
@@ -12571,7 +12628,7 @@ export async function _retryStreamingChat(streamFn, opts = {}) {
|
|
|
12571
12628
|
if (typeof opts.onRetry === "function") {
|
|
12572
12629
|
try {
|
|
12573
12630
|
const observation = opts.onRetry(attempt, err, {
|
|
12574
|
-
durationMs: Math.max(0,
|
|
12631
|
+
durationMs: Math.max(0, attemptEndedAt - attemptStartedAt),
|
|
12575
12632
|
});
|
|
12576
12633
|
if (observation && typeof observation.then === "function") {
|
|
12577
12634
|
void Promise.resolve(observation).catch(() => {});
|
|
@@ -12600,8 +12657,7 @@ export async function _retryStreamingChat(streamFn, opts = {}) {
|
|
|
12600
12657
|
}
|
|
12601
12658
|
}
|
|
12602
12659
|
}
|
|
12603
|
-
await
|
|
12604
|
-
if (signal && signal.aborted) throw err; // user bailed during backoff
|
|
12660
|
+
await waitForStreamRetry(delayMs, signal, { sleep: opts.sleep });
|
|
12605
12661
|
}
|
|
12606
12662
|
}
|
|
12607
12663
|
}
|
|
@@ -12724,8 +12780,9 @@ async function _chatOllamaStreaming(
|
|
|
12724
12780
|
body: JSON.stringify({ ...body, stream: true }),
|
|
12725
12781
|
});
|
|
12726
12782
|
if (!response.ok) {
|
|
12727
|
-
throw
|
|
12783
|
+
throw await createProviderResponseError("ollama", response);
|
|
12728
12784
|
}
|
|
12785
|
+
const retryMetadata = captureStreamRetryMetadata(response);
|
|
12729
12786
|
const state = _ollamaInitState();
|
|
12730
12787
|
const ui = _streamUiCallbacks(onToken);
|
|
12731
12788
|
const reader = response.body.getReader();
|
|
@@ -12750,7 +12807,17 @@ async function _chatOllamaStreaming(
|
|
|
12750
12807
|
await ui.settle();
|
|
12751
12808
|
}
|
|
12752
12809
|
} catch (err) {
|
|
12753
|
-
|
|
12810
|
+
attachStreamRetryMetadata(err, retryMetadata);
|
|
12811
|
+
if (!ui.hasVisibleOutput() && !state.content && state.toolCalls?.length)
|
|
12812
|
+
err.noReplay = true;
|
|
12813
|
+
if (
|
|
12814
|
+
_streamErrorDisposition(
|
|
12815
|
+
err,
|
|
12816
|
+
signal,
|
|
12817
|
+
state.content,
|
|
12818
|
+
ui.hasVisibleOutput(),
|
|
12819
|
+
) === "rethrow"
|
|
12820
|
+
)
|
|
12754
12821
|
throw err;
|
|
12755
12822
|
return _finalizeTruncatedStream(_ollamaFinalize, state);
|
|
12756
12823
|
}
|
|
@@ -12775,8 +12842,9 @@ async function _chatAnthropicStreaming(
|
|
|
12775
12842
|
body: JSON.stringify(body),
|
|
12776
12843
|
});
|
|
12777
12844
|
if (!response.ok) {
|
|
12778
|
-
throw
|
|
12845
|
+
throw await createProviderResponseError("anthropic", response);
|
|
12779
12846
|
}
|
|
12847
|
+
const retryMetadata = captureStreamRetryMetadata(response);
|
|
12780
12848
|
const state = _anthropicInitState();
|
|
12781
12849
|
const ui = _streamUiCallbacks(onToken, onThinking);
|
|
12782
12850
|
const reader = response.body.getReader();
|
|
@@ -12801,7 +12869,21 @@ async function _chatAnthropicStreaming(
|
|
|
12801
12869
|
await ui.settle();
|
|
12802
12870
|
}
|
|
12803
12871
|
} catch (err) {
|
|
12804
|
-
|
|
12872
|
+
attachStreamRetryMetadata(err, retryMetadata);
|
|
12873
|
+
if (
|
|
12874
|
+
!ui.hasVisibleOutput() &&
|
|
12875
|
+
!state.text &&
|
|
12876
|
+
Object.values(state.blocks).some((block) => block.type === "tool_use")
|
|
12877
|
+
)
|
|
12878
|
+
err.noReplay = true;
|
|
12879
|
+
if (
|
|
12880
|
+
_streamErrorDisposition(
|
|
12881
|
+
err,
|
|
12882
|
+
signal,
|
|
12883
|
+
state.text,
|
|
12884
|
+
ui.hasVisibleOutput(),
|
|
12885
|
+
) === "rethrow"
|
|
12886
|
+
)
|
|
12805
12887
|
throw err;
|
|
12806
12888
|
return _finalizeTruncatedStream(_anthropicFinalize, state);
|
|
12807
12889
|
}
|
|
@@ -12833,8 +12915,9 @@ async function _chatOpenAIStreaming(
|
|
|
12833
12915
|
body: JSON.stringify(body),
|
|
12834
12916
|
});
|
|
12835
12917
|
if (!response.ok) {
|
|
12836
|
-
throw
|
|
12918
|
+
throw await createProviderResponseError(provider, response);
|
|
12837
12919
|
}
|
|
12920
|
+
const retryMetadata = captureStreamRetryMetadata(response);
|
|
12838
12921
|
const state = _openaiInitState();
|
|
12839
12922
|
const ui = _streamUiCallbacks(onToken);
|
|
12840
12923
|
const reader = response.body.getReader();
|
|
@@ -12859,7 +12942,17 @@ async function _chatOpenAIStreaming(
|
|
|
12859
12942
|
await ui.settle();
|
|
12860
12943
|
}
|
|
12861
12944
|
} catch (err) {
|
|
12862
|
-
|
|
12945
|
+
attachStreamRetryMetadata(err, retryMetadata);
|
|
12946
|
+
if (!ui.hasVisibleOutput() && !state.text && state.tools.length)
|
|
12947
|
+
err.noReplay = true;
|
|
12948
|
+
if (
|
|
12949
|
+
_streamErrorDisposition(
|
|
12950
|
+
err,
|
|
12951
|
+
signal,
|
|
12952
|
+
state.text,
|
|
12953
|
+
ui.hasVisibleOutput(),
|
|
12954
|
+
) === "rethrow"
|
|
12955
|
+
)
|
|
12863
12956
|
throw err;
|
|
12864
12957
|
const out = _finalizeTruncatedStream(_openaiFinalize, state);
|
|
12865
12958
|
const providerReceipt = _openAIProviderRequestReceipt(
|
|
@@ -12905,8 +12998,9 @@ async function _chatOpenAIResponsesStreaming(
|
|
|
12905
12998
|
body: JSON.stringify(body),
|
|
12906
12999
|
});
|
|
12907
13000
|
if (!response.ok) {
|
|
12908
|
-
throw
|
|
13001
|
+
throw await createProviderResponseError("openai", response);
|
|
12909
13002
|
}
|
|
13003
|
+
const retryMetadata = captureStreamRetryMetadata(response);
|
|
12910
13004
|
const state = createOpenAIResponsesStreamState();
|
|
12911
13005
|
const ui = _streamUiCallbacks(onToken, onThinking);
|
|
12912
13006
|
const reader = response.body.getReader();
|
|
@@ -12931,10 +13025,31 @@ async function _chatOpenAIResponsesStreaming(
|
|
|
12931
13025
|
await ui.settle();
|
|
12932
13026
|
}
|
|
12933
13027
|
} catch (error) {
|
|
12934
|
-
if (
|
|
13028
|
+
if (state.terminalError) throw state.terminalError;
|
|
13029
|
+
attachStreamRetryMetadata(error, retryMetadata);
|
|
13030
|
+
if (
|
|
13031
|
+
!ui.hasVisibleOutput() &&
|
|
13032
|
+
!state.text &&
|
|
13033
|
+
state.outputItems.some((item) => item?.type === "function_call")
|
|
13034
|
+
)
|
|
13035
|
+
error.noReplay = true;
|
|
13036
|
+
if (
|
|
13037
|
+
!state.normalized &&
|
|
13038
|
+
_streamErrorDisposition(
|
|
13039
|
+
error,
|
|
13040
|
+
signal,
|
|
13041
|
+
state.text,
|
|
13042
|
+
ui.hasVisibleOutput(),
|
|
13043
|
+
) === "rethrow"
|
|
13044
|
+
) {
|
|
12935
13045
|
throw error;
|
|
12936
13046
|
}
|
|
12937
|
-
|
|
13047
|
+
throwIfAborted(signal);
|
|
13048
|
+
if (isAbortError(error) || error?.isOutputBackpressureFailure === true)
|
|
13049
|
+
throw error;
|
|
13050
|
+
const out = state.normalized
|
|
13051
|
+
? finalizeOpenAIResponsesStream(state)
|
|
13052
|
+
: _finalizeTruncatedStream(finalizeOpenAIResponsesStream, state);
|
|
12938
13053
|
const responseId = out.responseId || state.responseId;
|
|
12939
13054
|
delete out.responseId;
|
|
12940
13055
|
const providerReceipt = _openAIProviderRequestReceipt(
|
|
@@ -13067,11 +13182,12 @@ export function _openAIResponsesReasoningParams(
|
|
|
13067
13182
|
|
|
13068
13183
|
/**
|
|
13069
13184
|
* Decide the Anthropic `thinking` request params for a model. Returns null
|
|
13070
|
-
* (off) unless the caller opts in via options.thinking
|
|
13071
|
-
* "hard" | "ultra"). Model-aware per the Claude API:
|
|
13185
|
+
* (off) on legacy models unless the caller opts in via options.thinking
|
|
13186
|
+
* (true | "think" | "hard" | "ultra"). Model-aware per the Claude API:
|
|
13187
|
+
* - exact Haiku 5.5 → adaptive/medium by default, explicitly disableable
|
|
13072
13188
|
* - Opus 4.6/4.7/4.8, Sonnet 4.6 → adaptive thinking + output_config.effort
|
|
13073
13189
|
* - Sonnet 4.5 / Opus 4.0-4.5 / older → legacy enabled+budget (< max_tokens)
|
|
13074
|
-
* -
|
|
13190
|
+
* - other models, including older Haiku → null (no explicit thinking)
|
|
13075
13191
|
* temperature is never added (it 400s on Opus 4.7/4.8). Note: `xhigh`/`max`
|
|
13076
13192
|
* effort are Opus-tier — on Sonnet they may error; left to the caller's intent.
|
|
13077
13193
|
* RUNTIME-UNVERIFIED — no Anthropic key to validate the wire shape live.
|
|
@@ -13082,9 +13198,10 @@ export function _anthropicThinkingParams(
|
|
|
13082
13198
|
options = {},
|
|
13083
13199
|
maxTokens = 8192,
|
|
13084
13200
|
) {
|
|
13201
|
+
const m = String(model || "").toLowerCase();
|
|
13202
|
+
if (m === "claude-haiku-5-5") return haiku55ThinkingParams(m, options);
|
|
13085
13203
|
const want = options?.thinking;
|
|
13086
13204
|
if (!want) return null; // off by default → request unchanged
|
|
13087
|
-
const m = String(model || "").toLowerCase();
|
|
13088
13205
|
const adaptive = /opus-4-(6|7|8)/.test(m) || /sonnet-4-6/.test(m);
|
|
13089
13206
|
const legacy =
|
|
13090
13207
|
/sonnet-4-5/.test(m) ||
|
|
@@ -16320,12 +16437,27 @@ export async function* agentLoop(messages, options) {
|
|
|
16320
16437
|
toolName,
|
|
16321
16438
|
earlyAuthorityDenial,
|
|
16322
16439
|
);
|
|
16440
|
+
const preExecutionDenied =
|
|
16441
|
+
earlyAuthorityDenial.code === TOOL_RECOVERY_PAUSED_CODE;
|
|
16442
|
+
if (preExecutionDenied) {
|
|
16443
|
+
// Declare the rejected request without an execution/ledger boundary
|
|
16444
|
+
// or its arguments. Consumers can pair the refusal by provider ID.
|
|
16445
|
+
yield {
|
|
16446
|
+
type: "tool-pre-execution-denied",
|
|
16447
|
+
tool: toolName,
|
|
16448
|
+
tool_use_id: call.id,
|
|
16449
|
+
turn_id: `${runId}:t${budget.consumed}`,
|
|
16450
|
+
preExecutionDenied: true,
|
|
16451
|
+
execution_started: false,
|
|
16452
|
+
};
|
|
16453
|
+
}
|
|
16323
16454
|
yield {
|
|
16324
16455
|
type: "tool-result",
|
|
16325
16456
|
tool: toolName,
|
|
16326
16457
|
result: earlyAuthorityDenial,
|
|
16327
16458
|
error: earlyAuthorityDenial.error,
|
|
16328
16459
|
execution_started: false,
|
|
16460
|
+
...(preExecutionDenied ? { preExecutionDenied: true } : {}),
|
|
16329
16461
|
tool_use_id: call.id,
|
|
16330
16462
|
turn_id: `${runId}:t${budget.consumed}`,
|
|
16331
16463
|
permission_decision_id: decision?.id || null,
|
|
@@ -3231,6 +3231,19 @@ async function runAgentHeadlessInWorkspace(
|
|
|
3231
3231
|
});
|
|
3232
3232
|
break;
|
|
3233
3233
|
}
|
|
3234
|
+
case "tool-pre-execution-denied": {
|
|
3235
|
+
// A request declaration is not an invocation: do not start a
|
|
3236
|
+
// side effect, telemetry call, or persisted compact tool record.
|
|
3237
|
+
emitStream({
|
|
3238
|
+
type: "tool_use",
|
|
3239
|
+
id: event.tool_use_id,
|
|
3240
|
+
tool: event.tool,
|
|
3241
|
+
args: {},
|
|
3242
|
+
preExecutionDenied: true,
|
|
3243
|
+
execution_started: false,
|
|
3244
|
+
});
|
|
3245
|
+
break;
|
|
3246
|
+
}
|
|
3234
3247
|
case "tool-executing": {
|
|
3235
3248
|
const telemetryToolId = runtimeToolCallId(event.tool_use_id);
|
|
3236
3249
|
const line = ` [${event.tool}] ${formatToolArgs(event.tool, event.args)}`;
|
|
@@ -3352,6 +3365,10 @@ async function runAgentHeadlessInWorkspace(
|
|
|
3352
3365
|
...(event.execution_started === false
|
|
3353
3366
|
? { execution_started: false }
|
|
3354
3367
|
: {}),
|
|
3368
|
+
...(event.preExecutionDenied === true &&
|
|
3369
|
+
event.execution_started === false
|
|
3370
|
+
? { preExecutionDenied: true }
|
|
3371
|
+
: {}),
|
|
3355
3372
|
error: err,
|
|
3356
3373
|
result: event.result,
|
|
3357
3374
|
...(event.permission_decision_id
|
|
@@ -990,6 +990,19 @@ async function runTurn(
|
|
|
990
990
|
}
|
|
991
991
|
turnBindingFeed?.handleEvent(event);
|
|
992
992
|
switch (event.type) {
|
|
993
|
+
case "tool-pre-execution-denied": {
|
|
994
|
+
// Keep the request/result pair visible without plan/ledger execution
|
|
995
|
+
// bookkeeping and without exposing rejected request arguments.
|
|
996
|
+
emit({
|
|
997
|
+
type: "tool_use",
|
|
998
|
+
id: event.tool_use_id,
|
|
999
|
+
tool: event.tool,
|
|
1000
|
+
args: {},
|
|
1001
|
+
preExecutionDenied: true,
|
|
1002
|
+
execution_started: false,
|
|
1003
|
+
});
|
|
1004
|
+
break;
|
|
1005
|
+
}
|
|
993
1006
|
case "tool-executing": {
|
|
994
1007
|
// Additive protocol-v1 correlation id ("tu-<n>", session-scoped —
|
|
995
1008
|
// agent-sdk docs/PROTOCOL.md §1.2.1): the matching tool_result below
|
|
@@ -1129,6 +1142,10 @@ async function runTurn(
|
|
|
1129
1142
|
...(event.execution_started === false
|
|
1130
1143
|
? { execution_started: false }
|
|
1131
1144
|
: {}),
|
|
1145
|
+
...(event.preExecutionDenied === true &&
|
|
1146
|
+
event.execution_started === false
|
|
1147
|
+
? { preExecutionDenied: true }
|
|
1148
|
+
: {}),
|
|
1132
1149
|
error: err,
|
|
1133
1150
|
result: event.result,
|
|
1134
1151
|
...(event.permission_decision_id
|