zidane 7.2.5 → 8.0.4
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/LICENSE +21 -0
- package/README.md +34 -6
- package/dist/{acp-D-tVyUjw.js → acp-DQDhi2dj.js} +230 -77
- package/dist/acp-DQDhi2dj.js.map +1 -0
- package/dist/acp-cli.d.ts +1 -1
- package/dist/acp-cli.js +9 -66
- package/dist/acp-cli.js.map +1 -1
- package/dist/acp.d.ts +10 -590
- package/dist/acp.d.ts.map +1 -1
- package/dist/acp.js +3 -3
- package/dist/{agent-D0zZnGbt.js → agent-DSLNmBp0.js} +14401 -13214
- package/dist/agent-DSLNmBp0.js.map +1 -0
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +3 -2
- package/dist/aliasing-lVFbm81n.js +217 -0
- package/dist/aliasing-lVFbm81n.js.map +1 -0
- package/dist/{anthropic-C2aole0G.js → anthropic-CD00LhUP.js} +1442 -1264
- package/dist/anthropic-CD00LhUP.js.map +1 -0
- package/dist/artifacts-CV2hUKnL.js.map +1 -1
- package/dist/{atomic-write-B7zr1ddF.js → atomic-write-Ijgf2Mhc.js} +13 -3
- package/dist/atomic-write-Ijgf2Mhc.js.map +1 -0
- package/dist/call-tool-dHlbGOIY.js +70 -0
- package/dist/call-tool-dHlbGOIY.js.map +1 -0
- package/dist/chat/pure.d.ts +372 -6
- package/dist/chat/pure.d.ts.map +1 -1
- package/dist/chat/pure.js +35 -244
- package/dist/chat/pure.js.map +1 -1
- package/dist/{approvals-DKaJZYlm.js → chat-JPJJ8uu5.js} +15879 -14631
- package/dist/chat-JPJJ8uu5.js.map +1 -0
- package/dist/chat.d.ts +4 -6
- package/dist/chat.js +23 -12
- package/dist/cli-shared-C-YCaglL.js +159 -0
- package/dist/cli-shared-C-YCaglL.js.map +1 -0
- package/dist/client-core-BQSyDALT.d.ts +2115 -0
- package/dist/client-core-BQSyDALT.d.ts.map +1 -0
- package/dist/codemode-worker.d.ts +1 -0
- package/dist/codemode-worker.js +155 -0
- package/dist/codemode-worker.js.map +1 -0
- package/dist/codemode.d.ts +352 -0
- package/dist/codemode.d.ts.map +1 -0
- package/dist/codemode.js +5 -0
- package/dist/connection-Dr-Js4yZ.d.ts +28 -0
- package/dist/connection-Dr-Js4yZ.d.ts.map +1 -0
- package/dist/connection-loop-gdh22LTI.js +112 -0
- package/dist/connection-loop-gdh22LTI.js.map +1 -0
- package/dist/context-segments-BHKlagL6.js +1016 -0
- package/dist/context-segments-BHKlagL6.js.map +1 -0
- package/dist/{context-transport-T_6AYIvy.js → context-transport-DSMTUsK1.js} +3 -3
- package/dist/{context-transport-T_6AYIvy.js.map → context-transport-DSMTUsK1.js.map} +1 -1
- package/dist/contexts/daytona.d.ts +19 -8
- package/dist/contexts/daytona.d.ts.map +1 -1
- package/dist/contexts/daytona.js +1 -440
- package/dist/contexts/docker.d.ts +36 -7
- package/dist/contexts/docker.d.ts.map +1 -1
- package/dist/contexts/docker.js +1 -456
- package/dist/contexts/e2b.d.ts +68 -13
- package/dist/contexts/e2b.d.ts.map +1 -1
- package/dist/contexts/e2b.js +1 -382
- package/dist/contexts/sandbox.d.ts +1 -1
- package/dist/contexts/sandbox.js +5 -0
- package/dist/contexts/sandbox.js.map +1 -1
- package/dist/{contexts-CRE9pw07.js → contexts-d7UolYot.js} +1059 -524
- package/dist/contexts-d7UolYot.js.map +1 -0
- package/dist/contexts.d.ts +3 -3
- package/dist/contexts.js +1 -1
- package/dist/cred-keys-GpBg71cP.js +105 -0
- package/dist/cred-keys-GpBg71cP.js.map +1 -0
- package/dist/{auth-BG2rVKSt.js → credentials-JttEuRON.js} +55 -206
- package/dist/credentials-JttEuRON.js.map +1 -0
- package/dist/{cursor-iojRXHF9.js → cursor-CdjaQTBW.js} +3 -3
- package/dist/{cursor-iojRXHF9.js.map → cursor-CdjaQTBW.js.map} +1 -1
- package/dist/daemon-cli.d.ts +1 -1
- package/dist/daemon-cli.js +3 -2
- package/dist/daemon-cli.js.map +1 -1
- package/dist/daytona-DG3omipZ.js +513 -0
- package/dist/daytona-DG3omipZ.js.map +1 -0
- package/dist/defaults-Cx3zvDOV.js +23 -0
- package/dist/defaults-Cx3zvDOV.js.map +1 -0
- package/dist/dispatcher-BMlu2BmZ.js +4941 -0
- package/dist/dispatcher-BMlu2BmZ.js.map +1 -0
- package/dist/docker-BZhMMJUp.js +727 -0
- package/dist/docker-BZhMMJUp.js.map +1 -0
- package/dist/e2b-CEVOdRib.js +480 -0
- package/dist/e2b-CEVOdRib.js.map +1 -0
- package/dist/edit-utils-EGosADZq.js +234 -0
- package/dist/edit-utils-EGosADZq.js.map +1 -0
- package/dist/environment-8wsKE2Ln.js +214 -0
- package/dist/environment-8wsKE2Ln.js.map +1 -0
- package/dist/eval-BNcvle_J.js +1595 -0
- package/dist/eval-BNcvle_J.js.map +1 -0
- package/dist/eval.d.ts +2 -2
- package/dist/eval.js +1 -1489
- package/dist/executor-Cx5-8yqi.js +621 -0
- package/dist/executor-Cx5-8yqi.js.map +1 -0
- package/dist/extension-authoring-DyGGmq9V.js +385 -0
- package/dist/extension-authoring-DyGGmq9V.js.map +1 -0
- package/dist/extensions.d.ts +2 -2
- package/dist/extensions.js +3 -3
- package/dist/{fetch-url-DX75gpL0.js → fetch-url-Ct2TjDWt.js} +4 -4
- package/dist/{fetch-url-DX75gpL0.js.map → fetch-url-Ct2TjDWt.js.map} +1 -1
- package/dist/{format-BF745pLL.js → format-C2NQEVUH.js} +39 -2
- package/dist/format-C2NQEVUH.js.map +1 -0
- package/dist/format-bytes-C7tfc3Zm.js +55 -0
- package/dist/format-bytes-C7tfc3Zm.js.map +1 -0
- package/dist/headless-C_rNUuYC.js +960 -0
- package/dist/headless-C_rNUuYC.js.map +1 -0
- package/dist/headless.d.ts +1 -1
- package/dist/headless.js +1 -413
- package/dist/{history-search-C4bk1Wz_.js → history-search-CcYzF8-0.js} +7 -3
- package/dist/history-search-CcYzF8-0.js.map +1 -0
- package/dist/history-search-worker.d.ts +1 -1
- package/dist/history-search-worker.js +1 -1
- package/dist/host-D7NrI03V.js +378 -0
- package/dist/host-D7NrI03V.js.map +1 -0
- package/dist/host-signals-BcP5QKUD.js +118 -0
- package/dist/host-signals-BcP5QKUD.js.map +1 -0
- package/dist/identity-CwfO8K-t.js +26 -0
- package/dist/identity-CwfO8K-t.js.map +1 -0
- package/dist/{index-BgN1T3lk.d.ts → index-BGe1fQT7.d.ts} +10987 -9320
- package/dist/index-BGe1fQT7.d.ts.map +1 -0
- package/dist/index-BVQsIKGn.d.ts +448 -0
- package/dist/index-BVQsIKGn.d.ts.map +1 -0
- package/dist/{index-C6NEd5y_.d.ts → index-CHABJd-L.d.ts} +3386 -502
- package/dist/index-CHABJd-L.d.ts.map +1 -0
- package/dist/{index-C37_ppWv.d.ts → index-D6a7qXpg.d.ts} +2 -3
- package/dist/index-D6a7qXpg.d.ts.map +1 -0
- package/dist/index.d.ts +6 -6
- package/dist/index.js +27 -23
- package/dist/{completion-core-BRo86R_L.js → inline-ghost-BVRQeGoL.js} +50 -2
- package/dist/inline-ghost-BVRQeGoL.js.map +1 -0
- package/dist/ipc/remote.d.ts +313 -0
- package/dist/ipc/remote.d.ts.map +1 -0
- package/dist/ipc/remote.js +4 -0
- package/dist/ipc.d.ts +6 -964
- package/dist/ipc.js +403 -4
- package/dist/ipc.js.map +1 -0
- package/dist/{isolation-Kfoof0MM.d.ts → isolation-D9L650W5.d.ts} +100 -15
- package/dist/isolation-D9L650W5.d.ts.map +1 -0
- package/dist/json-rpc--HXQti1E.js +350 -0
- package/dist/json-rpc--HXQti1E.js.map +1 -0
- package/dist/links-j8rED1sR.js +603 -0
- package/dist/links-j8rED1sR.js.map +1 -0
- package/dist/local-terminal-D8QThwo_.js +252 -0
- package/dist/local-terminal-D8QThwo_.js.map +1 -0
- package/dist/{logger--C1VQjwJ.js → logger-Gtqlayx8.js} +199 -173
- package/dist/logger-Gtqlayx8.js.map +1 -0
- package/dist/logs-view-CWG8aUAG.js.map +1 -1
- package/dist/{mcp-CgNd-f3F.js → mcp-_wecH9Qe.js} +608 -562
- package/dist/mcp-_wecH9Qe.js.map +1 -0
- package/dist/mcp.d.ts +2 -2
- package/dist/mcp.js +2 -2
- package/dist/media-sniff-UKijEaiQ.js.map +1 -1
- package/dist/{messages-2jcOA_5R.js → messages-BqiwcD2Q.js} +1017 -1014
- package/dist/messages-BqiwcD2Q.js.map +1 -0
- package/dist/{oauth-DxHO17JE.js → oauth-Px_pBB9W.js} +5 -5
- package/dist/{oauth-DxHO17JE.js.map → oauth-Px_pBB9W.js.map} +1 -1
- package/dist/{openai-compat-Dy56weK8.js → openai-compat-CFrpH7uq.js} +432 -589
- package/dist/openai-compat-CFrpH7uq.js.map +1 -0
- package/dist/orchestration-BCGmB8Ps.js +511 -0
- package/dist/orchestration-BCGmB8Ps.js.map +1 -0
- package/dist/output/stream-json.d.ts +1 -2
- package/dist/output/stream-json.d.ts.map +1 -1
- package/dist/output/stream-json.js +1 -1
- package/dist/output/terminal.d.ts +1 -2
- package/dist/output/terminal.d.ts.map +1 -1
- package/dist/output/terminal.js +13 -7
- package/dist/output/terminal.js.map +1 -1
- package/dist/{plugins-gbI7SBA6.js → plugins-DS7mahzZ.js} +20 -101
- package/dist/plugins-DS7mahzZ.js.map +1 -0
- package/dist/plugins.d.ts +1 -1
- package/dist/plugins.js +1 -2
- package/dist/prelude-Cxo4t74B.js +517 -0
- package/dist/prelude-Cxo4t74B.js.map +1 -0
- package/dist/presets.d.ts +1 -1
- package/dist/presets.js +1 -2
- package/dist/project-root-B8zADr4o.js +167 -0
- package/dist/project-root-B8zADr4o.js.map +1 -0
- package/dist/project-user-paths-BSgtrRxl.js +58 -0
- package/dist/project-user-paths-BSgtrRxl.js.map +1 -0
- package/dist/{prompts-Pqc3JdW_.d.ts → prompts-DYcvqShf.d.ts} +14 -11
- package/dist/prompts-DYcvqShf.d.ts.map +1 -0
- package/dist/protocol-DnhqqSmE.js +13 -0
- package/dist/protocol-DnhqqSmE.js.map +1 -0
- package/dist/providers/anthropic.d.ts +2 -2
- package/dist/providers/anthropic.js +1 -2
- package/dist/providers/arcee.d.ts +1 -1
- package/dist/providers/arcee.js +1 -1
- package/dist/providers/baseten.d.ts +1 -1
- package/dist/providers/baseten.js +1 -1
- package/dist/providers/cerebras.d.ts +1 -1
- package/dist/providers/cerebras.js +3 -2
- package/dist/providers/cerebras.js.map +1 -1
- package/dist/providers/local.d.ts +1 -1
- package/dist/providers/local.js +1 -1
- package/dist/providers/openai-compat.d.ts +1 -1
- package/dist/providers/openai-compat.js +1 -2
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openai.js +15 -12
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openrouter.d.ts +1 -1
- package/dist/providers/openrouter.js +3 -2
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/xai.d.ts +1 -1
- package/dist/providers/xai.js +3 -3
- package/dist/{providers-BVhnFyiY.js → providers-XUR7F4Hi.js} +4 -4
- package/dist/{providers-BVhnFyiY.js.map → providers-XUR7F4Hi.js.map} +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +4 -4
- package/dist/registry-D6ShBWJU.js +5234 -0
- package/dist/registry-D6ShBWJU.js.map +1 -0
- package/dist/remote-hosts-BtA_9ZGp.js +97 -0
- package/dist/remote-hosts-BtA_9ZGp.js.map +1 -0
- package/dist/restate.d.ts +2 -3
- package/dist/restate.d.ts.map +1 -1
- package/dist/restate.js +631 -572
- package/dist/restate.js.map +1 -1
- package/dist/run-summary-CklLiZ4y.js +288 -0
- package/dist/run-summary-CklLiZ4y.js.map +1 -0
- package/dist/{sandbox-BH0WQkXn.d.ts → sandbox-C5dR5DwQ.d.ts} +6 -3
- package/dist/sandbox-C5dR5DwQ.d.ts.map +1 -0
- package/dist/session/sqlite.d.ts +1 -2
- package/dist/session/sqlite.d.ts.map +1 -1
- package/dist/session/sqlite.js +1 -616
- package/dist/session-factory-BUGY5P40.js +1576 -0
- package/dist/session-factory-BUGY5P40.js.map +1 -0
- package/dist/{session-BqRP1hS7.js → session-xh9JXu6i.js} +94 -52
- package/dist/session-xh9JXu6i.js.map +1 -0
- package/dist/session.d.ts +1 -1
- package/dist/session.js +2 -2
- package/dist/settings-keys-Ckf29NeM.js +677 -0
- package/dist/settings-keys-Ckf29NeM.js.map +1 -0
- package/dist/shell-path-Dqaoow2J.js +412 -0
- package/dist/shell-path-Dqaoow2J.js.map +1 -0
- package/dist/{skills-BC3dodWp.js → skills-DKqZJm4X.js} +430 -470
- package/dist/skills-DKqZJm4X.js.map +1 -0
- package/dist/skills.d.ts +2 -2
- package/dist/skills.js +1 -2
- package/dist/source-mPExaUm8.js +381 -0
- package/dist/source-mPExaUm8.js.map +1 -0
- package/dist/sqlite-DV1DQzN2.js +698 -0
- package/dist/sqlite-DV1DQzN2.js.map +1 -0
- package/dist/{src-CkNQKFKr.js → src-BRMYRJib.js} +903 -1121
- package/dist/src-BRMYRJib.js.map +1 -0
- package/dist/{stdio-DPpBDPx5.js → stdio-C6YyoW3I.js} +4 -4
- package/dist/{stdio-DPpBDPx5.js.map → stdio-C6YyoW3I.js.map} +1 -1
- package/dist/{stdio-loader-Bbx19dMZ.js → stdio-loader-C830Vg-Z.js} +4 -4
- package/dist/{stdio-loader-Bbx19dMZ.js.map → stdio-loader-C830Vg-Z.js.map} +1 -1
- package/dist/system-prompt-MNVHatSD.d.ts.map +1 -1
- package/dist/timeout-DEaqslLO.d.ts.map +1 -1
- package/dist/todo-edits-Dn251YUP.js +1790 -0
- package/dist/todo-edits-Dn251YUP.js.map +1 -0
- package/dist/{turn-operations-DrbJlpq9.js → tool-formatters-IQFDrdrs.js} +1456 -2120
- package/dist/tool-formatters-IQFDrdrs.js.map +1 -0
- package/dist/tool-state-Dku6YqAB.js +989 -0
- package/dist/tool-state-Dku6YqAB.js.map +1 -0
- package/dist/tools/fetch-url.d.ts +1 -2
- package/dist/tools/fetch-url.d.ts.map +1 -1
- package/dist/tools/fetch-url.js +1 -2
- package/dist/tools/prompts.d.ts +1 -1
- package/dist/tools/prompts.js +7 -7
- package/dist/tools/prompts.js.map +1 -1
- package/dist/tools/web-search.d.ts +1 -2
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +2 -2
- package/dist/tools/web-search.js.map +1 -1
- package/dist/tools-_DnT3AGM.js +578 -0
- package/dist/tools-_DnT3AGM.js.map +1 -0
- package/dist/tools.d.ts +3 -3
- package/dist/tools.js +4 -2
- package/dist/tui.d.ts +534 -517
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +34933 -27243
- package/dist/tui.js.map +1 -1
- package/dist/turn-operations-B8sokwi5.js +333 -0
- package/dist/turn-operations-B8sokwi5.js.map +1 -0
- package/dist/turn-operations-DQX5ZZni.d.ts +3089 -0
- package/dist/turn-operations-DQX5ZZni.d.ts.map +1 -0
- package/dist/types-C7ZFOztE.d.ts +132 -0
- package/dist/types-C7ZFOztE.d.ts.map +1 -0
- package/dist/types-CH5XpIHw.js +114 -0
- package/dist/types-CH5XpIHw.js.map +1 -0
- package/dist/{types-CWgENVLY.js → types-Cu0ZGDu9.js} +10 -6
- package/dist/types-Cu0ZGDu9.js.map +1 -0
- package/dist/types-IqegbJEE.d.ts +624 -0
- package/dist/types-IqegbJEE.d.ts.map +1 -0
- package/dist/types.d.ts +4 -4
- package/dist/types.js +1 -1
- package/dist/url-D8HCl65b.js +1259 -0
- package/dist/url-D8HCl65b.js.map +1 -0
- package/dist/wasm-BVT-j5cl.js +33 -0
- package/dist/wasm-BVT-j5cl.js.map +1 -0
- package/dist/workspace-exec-stream-SV2R9d5S.js +355 -0
- package/dist/workspace-exec-stream-SV2R9d5S.js.map +1 -0
- package/dist/ws-CIHMvlSh.js +952 -0
- package/dist/ws-CIHMvlSh.js.map +1 -0
- package/dist/ws-client-N7NxzvQp.js +230 -0
- package/dist/ws-client-N7NxzvQp.js.map +1 -0
- package/dist/{xai-CazjStOK.js → xai-CvJTeLrI.js} +165 -5
- package/dist/xai-CvJTeLrI.js.map +1 -0
- package/dist/xdg-zweed0-t.js +117 -0
- package/dist/xdg-zweed0-t.js.map +1 -0
- package/docs/ACP.md +52 -0
- package/docs/ARCHITECTURE.md +103 -6
- package/docs/ARTIFACTS.md +8 -4
- package/docs/CHAT.md +165 -14
- package/docs/EXECUTION_CONTEXT.md +8 -0
- package/docs/EXTENSIONS.md +123 -2
- package/docs/HEADLESS.md +2 -0
- package/docs/IPC.md +775 -64
- package/docs/MACHINES.md +456 -0
- package/docs/PANELS.md +3 -0
- package/docs/README.md +4 -0
- package/docs/RESTATE.md +3 -2
- package/docs/RUN_IN_BACKGROUND.md +10 -2
- package/docs/SERVER.md +1085 -0
- package/docs/SKILL.md +6 -1
- package/docs/TERMINAL.md +75 -0
- package/docs/TUI.md +65 -14
- package/package.json +58 -26
- package/scripts/eval.ts +4 -0
- package/dist/acp-D-tVyUjw.js.map +0 -1
- package/dist/agent-D0zZnGbt.js.map +0 -1
- package/dist/anthropic-C2aole0G.js.map +0 -1
- package/dist/approvals-DKaJZYlm.js.map +0 -1
- package/dist/atomic-write-B7zr1ddF.js.map +0 -1
- package/dist/auth-BG2rVKSt.js.map +0 -1
- package/dist/completion-core-BRo86R_L.js.map +0 -1
- package/dist/contexts/daytona.js.map +0 -1
- package/dist/contexts/docker.js.map +0 -1
- package/dist/contexts/e2b.js.map +0 -1
- package/dist/contexts-CRE9pw07.js.map +0 -1
- package/dist/eval.js.map +0 -1
- package/dist/format-BF745pLL.js.map +0 -1
- package/dist/glob-DluQFSw1.js +0 -270
- package/dist/glob-DluQFSw1.js.map +0 -1
- package/dist/headless.js.map +0 -1
- package/dist/history-search-C4bk1Wz_.js.map +0 -1
- package/dist/index-BgN1T3lk.d.ts.map +0 -1
- package/dist/index-C37_ppWv.d.ts.map +0 -1
- package/dist/index-C6NEd5y_.d.ts.map +0 -1
- package/dist/ipc-BKVIIOqH.js +0 -331
- package/dist/ipc-BKVIIOqH.js.map +0 -1
- package/dist/ipc.d.ts.map +0 -1
- package/dist/isolation-Kfoof0MM.d.ts.map +0 -1
- package/dist/json-rpc-rSWMUh9b.js +0 -192
- package/dist/json-rpc-rSWMUh9b.js.map +0 -1
- package/dist/logger--C1VQjwJ.js.map +0 -1
- package/dist/mcp-CgNd-f3F.js.map +0 -1
- package/dist/messages-2jcOA_5R.js.map +0 -1
- package/dist/openai-compat-Dy56weK8.js.map +0 -1
- package/dist/output-cap-C9zukcCj.js +0 -100
- package/dist/output-cap-C9zukcCj.js.map +0 -1
- package/dist/panels-B6gRk4bf.js +0 -789
- package/dist/panels-B6gRk4bf.js.map +0 -1
- package/dist/plugins-gbI7SBA6.js.map +0 -1
- package/dist/prompts-Pqc3JdW_.d.ts.map +0 -1
- package/dist/run-summary-BU_NgwUT.js +0 -269
- package/dist/run-summary-BU_NgwUT.js.map +0 -1
- package/dist/sandbox-BH0WQkXn.d.ts.map +0 -1
- package/dist/session/sqlite.js.map +0 -1
- package/dist/session-BqRP1hS7.js.map +0 -1
- package/dist/shell-path-DfdXrGg9.js +0 -1549
- package/dist/shell-path-DfdXrGg9.js.map +0 -1
- package/dist/skills-BC3dodWp.js.map +0 -1
- package/dist/src-CkNQKFKr.js.map +0 -1
- package/dist/todo-edits-UOwgxGKu.js +0 -528
- package/dist/todo-edits-UOwgxGKu.js.map +0 -1
- package/dist/tool-formatters-DoRLnfuD.d.ts +0 -759
- package/dist/tool-formatters-DoRLnfuD.d.ts.map +0 -1
- package/dist/transcript-anchors-BeudMbXx.d.ts +0 -1762
- package/dist/transcript-anchors-BeudMbXx.d.ts.map +0 -1
- package/dist/turn-operations-C8bMBDl_.d.ts +0 -1258
- package/dist/turn-operations-C8bMBDl_.d.ts.map +0 -1
- package/dist/turn-operations-DrbJlpq9.js.map +0 -1
- package/dist/types-CWgENVLY.js.map +0 -1
- package/dist/xai-CazjStOK.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic-CD00LhUP.js","names":["osArch","osPlatform"],"sources":["../src/providers/anthropic-claude-code.ts","../src/providers/anthropic-oauth-error.ts","../src/providers/anthropic-rate-limit.ts","../src/providers/anthropic-client.ts","../src/providers/anthropic-errors.ts","../src/providers/anthropic-cache.ts","../src/providers/anthropic-thinking.ts","../src/providers/anthropic-request.ts","../src/providers/anthropic-retry.ts","../src/providers/anthropic-tool-json.ts","../src/chat/anthropic-models.ts","../src/providers/anthropic-usage.ts","../src/providers/diagnostic.ts","../src/providers/anthropic-stream.ts","../src/providers/anthropic.ts"],"sourcesContent":["/**\n * Claude Code client alignment for Anthropic subscription OAuth.\n *\n * Anthropic's subscription endpoint serves the Claude Code CLI. Requests that\n * do not look like that client are, at best, treated as a different product; at\n * worst they miss features the CLI relies on. This module holds every surface\n * that has to match, in one file, so a client bump is one edit rather than a\n * scavenger hunt through the provider.\n *\n * Modelled on `@pi-plugins/claude-oauth`, which maintains the same alignment\n * for pi and verifies its pins against a live client trace. Everything here is\n * scoped to the OAuth path — API-key, gateway-bearer and Bedrock requests never\n * reach it.\n */\n\nimport type { SessionMessage } from '../types'\nimport { Buffer } from 'node:buffer'\nimport { createHash, randomUUID } from 'node:crypto'\nimport { homedir, hostname, arch as osArch, platform as osPlatform, userInfo } from 'node:os'\nimport { renderSystemForWire } from '../system-prompt'\n\n/**\n * Pinned Claude Code client versions.\n *\n * These travel together: the billing fingerprint below hashes\n * {@link CLAUDE_CODE_VERSION}, so bumping one without the others produces a\n * value that does not correspond to any real client.\n *\n * The backend enforces a MINIMUM client version per model (\"Claude Code 2.1.165\n * does not support this model; version 2.1.251 or newer is required\"), so a\n * stale pin turns into a hard 400 on every request the day a model raises the\n * floor. Bump procedure (all from the published `@anthropic-ai/claude-code-\n * darwin-arm64` tarball of the target version — the binary is the source of\n * truth, not a changelog):\n * - `CLAUDE_CODE_VERSION` / `CLAUDE_AGENT_SDK_VERSION`: the npm versions\n * (they share a tail: 2.1.N ↔ 0.3.N);\n * - `..._STAINLESS_PACKAGE_VERSION`: the `@anthropic-ai/sdk` bundled in the\n * binary (`var xx=\"0.112.1\"` next to the Stainless client code);\n * - `..._STAINLESS_RUNTIME_VERSION`: `process.version` of the Bun the binary\n * was compiled with (Bun 1.4 reports `v26.3.0`);\n * - `CLAUDE_CLIENT_VERSION`: the desktop-app client version header; keep\n * unless a trace shows otherwise.\n * Verified against 2.1.280 (2026-09-23).\n */\nexport const CLAUDE_CODE_VERSION = '2.1.280'\nexport const CLAUDE_AGENT_SDK_VERSION = '0.3.280'\nexport const CLAUDE_CLIENT_VERSION = '1.11187.4'\nconst CLAUDE_CODE_STAINLESS_PACKAGE_VERSION = '0.112.1'\nconst CLAUDE_CODE_STAINLESS_RUNTIME_VERSION = 'v26.3.0'\n\n/**\n * Claude Code caps requested output at 64k even where the model ceiling is\n * higher (Opus allows 128k). Requests above the cap are clamped to match.\n */\nexport const CLAUDE_CODE_MAX_OUTPUT_TOKENS = 64_000\n\n/**\n * Tool names the Claude subscription backend reserves.\n *\n * A tool named exactly `todowrite` is classified as a paid Claude product\n * surface: the otherwise-valid OAuth request is refused with \"You're out of\n * extra usage\" when the account has no purchased usage credits. The same body\n * succeeds when only that wire name changes.\n */\nexport const CLAUDE_CODE_RESERVED_TOOL_NAMES: readonly string[] = ['todowrite']\n\nconst RESERVED_TOOL_ALIAS_PREFIX = 'zidane_'\n\n/**\n * Request-local wire aliases that move reserved names out of the way, for\n * Claude subscription OAuth only.\n *\n * Resolved against the request's FULL name set (history + current specs) rather\n * than hardcoded, because the obvious alias is itself a legal tool name: an\n * extension shipping `zidane_todowrite` alongside `todowrite` would otherwise\n * make the boundary throw on a collision it can trivially avoid. Suffixing is\n * deterministic, so the wire bytes — and the provider prompt cache — stay\n * stable across turns with the same tool set.\n *\n * Canonical names are restored at the provider boundary, so dispatch, hooks,\n * persistence, and other auth modes never see the alias.\n */\nexport function claudeCodeToolAliases(names: ReadonlySet<string>): Record<string, string> | undefined {\n let aliases: Record<string, string> | undefined\n const taken = new Set(names)\n for (const reserved of CLAUDE_CODE_RESERVED_TOOL_NAMES) {\n if (!names.has(reserved))\n continue\n let candidate = `${RESERVED_TOOL_ALIAS_PREFIX}${reserved}`\n for (let n = 2; taken.has(candidate); n++)\n candidate = `${RESERVED_TOOL_ALIAS_PREFIX}${reserved}_${n}`\n taken.add(candidate)\n aliases ??= {}\n aliases[reserved] = candidate\n }\n return aliases\n}\n\n/**\n * The wire `system` block and `messages` for one request.\n *\n * Claude Code OAuth requires the system block to be the canonical Claude Code\n * prompt, so the real system prompt is folded into a leading user/assistant\n * pair ahead of the conversation. Every other auth shape sends the rendered\n * system prompt as the system block. Shared by `stream()` and `countTokens()`\n * so the count measures what is actually sent.\n */\nexport function foldSystemForWire(\n system: string,\n messages: readonly SessionMessage[],\n claudeCode: boolean,\n): { system: string, messages: SessionMessage[] } {\n const wireSystem = renderSystemForWire(system)\n if (!claudeCode)\n return { system: wireSystem, messages: [...messages] }\n return {\n system: `You are Claude Code, Anthropic's official CLI for Claude.`,\n messages: system\n ? [\n { role: 'user', content: [{ type: 'text' as const, text: wireSystem }] },\n { role: 'assistant', content: [{ type: 'text' as const, text: 'Understood. I will proceed with these instructions above the rest of my system prompt.' }] },\n ...messages,\n ]\n : [...messages],\n }\n}\n\n/**\n * Beta set the Claude Code agent sends, in client order.\n *\n * Sent as one unit: the endpoint is configured for this combination, and\n * trimming it to \"the ones we think we use\" is how a client stops looking like\n * the client. Betas without matching request fields are inert.\n */\nexport const CLAUDE_CODE_BETAS = [\n 'claude-code-20250219',\n 'oauth-2025-04-20',\n 'interleaved-thinking-2025-05-14',\n 'fine-grained-tool-streaming-2025-05-14',\n 'context-management-2025-06-27',\n 'prompt-caching-scope-2026-01-05',\n 'mid-conversation-system-2026-04-07',\n 'advanced-tool-use-2025-11-20',\n 'effort-2025-11-24',\n 'extended-cache-ttl-2025-04-11',\n] as const\n\n/** Billing-header pins. See {@link claudeCodeBillingText}. */\nconst BILLING_FINGERPRINT_SALT = '59cf53e54c78'\nconst BILLING_FINGERPRINT_INDICES = [4, 7, 20] as const\nexport const BILLING_HEADER_PREFIX = 'x-anthropic-billing-header:'\nexport const CCH_PLACEHOLDER = 'cch=00000'\nconst CCH_SEED = 0x4D659218E32A3268n\n\n// ---------------------------------------------------------------------------\n// Headers\n// ---------------------------------------------------------------------------\n\n/** `os.arch()` values mapped to the labels Stainless emits. */\nfunction stainlessArch(value: string): string {\n switch (value.toLowerCase()) {\n case 'amd64': case 'x64': return 'x64'\n case 'arm64': case 'aarch64': return 'arm64'\n case '386': case 'x86': case 'ia32': return 'x86'\n default: return `other::${value.toLowerCase()}`\n }\n}\n\n/** `os.platform()` values mapped to the labels Stainless emits. */\nfunction stainlessOs(value: string): string {\n switch (value.toLowerCase()) {\n case 'darwin': return 'MacOS'\n case 'win32': case 'windows': return 'Windows'\n case 'linux': return 'Linux'\n case 'freebsd': return 'FreeBSD'\n default: return `Other::${value.toLowerCase()}`\n }\n}\n\n/**\n * Headers a Claude Code OAuth request carries.\n *\n * The `x-stainless-*` entries deliberately OVERRIDE the ones the Anthropic SDK\n * generates about itself: left alone they advertise `Anthropic/JS <sdk version>`\n * on a request claiming to be the CLI, which is a contradiction no real client\n * produces.\n */\nexport function buildClaudeCodeHeaders(): Record<string, string> {\n return {\n 'user-agent': `claude-cli/${CLAUDE_CODE_VERSION} (external, local-agent, agent-sdk/${CLAUDE_AGENT_SDK_VERSION})`,\n 'x-app': 'cli',\n 'anthropic-dangerous-direct-browser-access': 'true',\n 'x-stainless-retry-count': '0',\n 'x-stainless-runtime-version': CLAUDE_CODE_STAINLESS_RUNTIME_VERSION,\n 'x-stainless-package-version': CLAUDE_CODE_STAINLESS_PACKAGE_VERSION,\n 'x-stainless-runtime': 'node',\n 'x-stainless-lang': 'js',\n 'x-stainless-arch': stainlessArch(osArch()),\n 'x-stainless-os': stainlessOs(osPlatform()),\n 'x-stainless-timeout': '900',\n 'anthropic-client-platform': 'desktop_app',\n 'anthropic-client-version': CLAUDE_CLIENT_VERSION,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Billing header block\n// ---------------------------------------------------------------------------\n\n/**\n * Text of the `system[0]` billing block.\n *\n * The version suffix is `sha256(salt + msg[4] + msg[7] + msg[20] + version)`\n * truncated to 3 hex chars, where the indices sample the first user message.\n * Missing characters (a first message shorter than 21 chars) contribute `'0'`,\n * matching the client rather than throwing.\n *\n * The `cch` field ships as {@link CCH_PLACEHOLDER} and is overwritten by\n * {@link patchCch} once the body is serialized — it hashes those very bytes, so\n * it cannot be computed here.\n */\nexport function claudeCodeBillingText(firstUserMessage: string): string {\n const seed = BILLING_FINGERPRINT_INDICES.map(i => firstUserMessage[i] ?? '0').join('')\n const suffix = createHash('sha256')\n .update(`${BILLING_FINGERPRINT_SALT}${seed}${CLAUDE_CODE_VERSION}`)\n .digest('hex')\n .slice(0, 3)\n return `${BILLING_HEADER_PREFIX} cc_version=${CLAUDE_CODE_VERSION}.${suffix}; cc_entrypoint=local-agent; ${CCH_PLACEHOLDER};`\n}\n\n/** Concatenated text of the first user message — the fingerprint's sample source. */\nexport function firstUserMessageText(\n messages: readonly { role?: string, content?: unknown }[],\n): string {\n const first = messages.find(m => m.role === 'user')\n const content = first?.content\n if (typeof content === 'string')\n return content\n if (!Array.isArray(content))\n return ''\n return content\n .filter((b): b is { type: 'text', text: string } =>\n !!b && typeof b === 'object' && (b as { type?: unknown }).type === 'text'\n && typeof (b as { text?: unknown }).text === 'string')\n .map(b => b.text)\n .join('')\n}\n\n/**\n * Machine-stable device id + per-process session id, sent as\n * `metadata.user_id`'s JSON envelope.\n *\n * `userInfo()` throws in locked-down sandboxes, so the seed degrades to the\n * hostname rather than taking the process down.\n */\nfunction machineSeed(): string {\n try {\n return `${hostname()}:${userInfo().username}:${homedir()}`\n }\n catch {\n return `${hostname()}:zidane-claude-code-fallback`\n }\n}\n\nconst DEVICE_ID = createHash('sha256').update(`zidane-claude-code-device-v1:${machineSeed()}`).digest('hex')\nconst SESSION_ID = randomUUID()\n\n/** The `metadata.user_id` envelope Claude Code sends. */\nexport function claudeCodeUserId(): string {\n return JSON.stringify({ device_id: DEVICE_ID, session_id: SESSION_ID })\n}\n\n// ---------------------------------------------------------------------------\n// cch attestation\n// ---------------------------------------------------------------------------\n\nconst MASK = (1n << 64n) - 1n\nconst PRIME64_1 = 11400714785074694791n\nconst PRIME64_2 = 14029467366897019727n\nconst PRIME64_3 = 1609587929392839161n\nconst PRIME64_4 = 9650029242287828579n\nconst PRIME64_5 = 2870177450012600261n\n\nconst rotl = (x: bigint, r: bigint): bigint => ((x << r) | (x >> (64n - r))) & MASK\n\nfunction round(acc: bigint, input: bigint): bigint {\n const next = (acc + input * PRIME64_2) & MASK\n return (rotl(next, 31n) * PRIME64_1) & MASK\n}\n\nfunction mergeRound(acc: bigint, val: bigint): bigint {\n const merged = acc ^ round(0n, val)\n return (((merged * PRIME64_1) & MASK) + PRIME64_4) & MASK\n}\n\n/**\n * XXH64, reproducing Claude Code's `cch` request-integrity value.\n *\n * Ported rather than delegated to `Bun.hash.xxHash64` so the result cannot\n * drift with a runtime's hash implementation or seed handling, and so the\n * provider still works off-Bun. Verified against published XXH64 vectors.\n */\nexport function xxHash64(input: Uint8Array, seed: bigint): bigint {\n const len = input.length\n const dv = new DataView(input.buffer, input.byteOffset, input.byteLength)\n let h64: bigint\n let p = 0\n\n if (len >= 32) {\n let v1 = (seed + PRIME64_1 + PRIME64_2) & MASK\n let v2 = (seed + PRIME64_2) & MASK\n let v3 = seed & MASK\n let v4 = (seed - PRIME64_1) & MASK\n const limit = len - 32\n while (p <= limit) {\n v1 = round(v1, dv.getBigUint64(p, true))\n p += 8\n v2 = round(v2, dv.getBigUint64(p, true))\n p += 8\n v3 = round(v3, dv.getBigUint64(p, true))\n p += 8\n v4 = round(v4, dv.getBigUint64(p, true))\n p += 8\n }\n h64 = (rotl(v1, 1n) + rotl(v2, 7n) + rotl(v3, 12n) + rotl(v4, 18n)) & MASK\n h64 = mergeRound(h64, v1)\n h64 = mergeRound(h64, v2)\n h64 = mergeRound(h64, v3)\n h64 = mergeRound(h64, v4)\n }\n else {\n h64 = (seed + PRIME64_5) & MASK\n }\n\n h64 = (h64 + BigInt(len)) & MASK\n\n while (p + 8 <= len) {\n h64 ^= round(0n, dv.getBigUint64(p, true))\n h64 = (rotl(h64, 27n) * PRIME64_1) & MASK\n h64 = (h64 + PRIME64_4) & MASK\n p += 8\n }\n if (p + 4 <= len) {\n h64 ^= (BigInt(dv.getUint32(p, true)) * PRIME64_1) & MASK\n h64 = (rotl(h64, 23n) * PRIME64_2) & MASK\n h64 = (h64 + PRIME64_3) & MASK\n p += 4\n }\n while (p < len) {\n h64 ^= (BigInt(input[p] ?? 0) * PRIME64_5) & MASK\n h64 = (rotl(h64, 11n) * PRIME64_1) & MASK\n p += 1\n }\n\n h64 ^= h64 >> 33n\n h64 = (h64 * PRIME64_2) & MASK\n h64 ^= h64 >> 29n\n h64 = (h64 * PRIME64_3) & MASK\n h64 ^= h64 >> 32n\n return h64 & MASK\n}\n\nconst encoder = new TextEncoder()\n/**\n * Anchor for the placeholder search. The SDK serializes `messages` before\n * `system`, so these bytes can only belong to the block we injected — user\n * content that happens to contain `cch=00000` can never match.\n */\nconst BILLING_SYSTEM_MARKER = encoder.encode(`\"system\":[{\"type\":\"text\",\"text\":\"${BILLING_HEADER_PREFIX}`)\nconst CCH_PLACEHOLDER_BYTES = encoder.encode(CCH_PLACEHOLDER)\n/** The placeholder must sit this close to the marker, else system[0] was reshaped. */\nconst CCH_SEARCH_WINDOW = 150\n\n/**\n * Overwrite the `cch` placeholder with `XXH64(body) & 0xfffff`, in place.\n *\n * Returns the original bytes untouched when the placeholder is absent or not\n * anchored to `system[0]` — a request that goes out with the placeholder intact\n * is far better than one whose user content was corrupted by a stray patch.\n */\nexport function patchCch(encoded: Uint8Array): Uint8Array {\n const view = Buffer.from(encoded.buffer, encoded.byteOffset, encoded.byteLength)\n const markerIdx = view.indexOf(BILLING_SYSTEM_MARKER)\n if (markerIdx === -1)\n return encoded\n const searchFrom = markerIdx + BILLING_SYSTEM_MARKER.length\n const placeholderIdx = view.indexOf(CCH_PLACEHOLDER_BYTES, searchFrom)\n if (placeholderIdx === -1 || placeholderIdx - searchFrom > CCH_SEARCH_WINDOW)\n return encoded\n\n const cch = (xxHash64(encoded, CCH_SEED) & 0xFFFFFn).toString(16).padStart(5, '0')\n // Skip `cch=` and overwrite the five placeholder digits.\n for (let i = 0; i < 5; i++)\n encoded[placeholderIdx + 4 + i] = cch.charCodeAt(i)\n return encoded\n}\n\n/**\n * Wrap a `fetch` so bodies carrying the placeholder get their attestation\n * patched after serialization.\n *\n * Handed to the Anthropic SDK per client rather than installed on\n * `globalThis` — every other request in the process stays untouched, and two\n * providers cannot fight over the global.\n */\nexport function wrapFetchForCch(base: typeof fetch): typeof fetch {\n const wrapped = (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n const body = init?.body\n let finalBody: BodyInit | null | undefined = body\n if (typeof body === 'string' && body.includes(CCH_PLACEHOLDER)) {\n // `BodyInit` accepts a BufferSource; the Uint8Array is narrowed for the DOM\n // lib's overloads, which do not model the ArrayBufferLike generic.\n finalBody = patchCch(encoder.encode(body)) as unknown as BodyInit\n }\n\n return base(input, finalBody === body ? init : { ...init, body: finalBody })\n }\n // `preconnect` is part of the runtime's `fetch` surface but never used here;\n // carry the original's so the wrapper stays a drop-in.\n wrapped.preconnect = base.preconnect?.bind(base) ?? (() => {})\n return wrapped as typeof fetch\n}\n","type RefreshFailure = 'sign-in' | 'retry' | 'account' | 'upgrade' | 'unknown'\n\nfunction classifyRefreshFailure(reason: string): RefreshFailure {\n // Classify evidence, not a bare 401/403 or the generic refresh wrapper.\n if (/\\bclaude(?: code)?\\b.+(?:outdated|unsupported version|version .*?(?:required|newer)|upgrade|update your)/i.test(reason)\n || /\\b(?:outdated|unsupported) claude(?: code)?\\b/i.test(reason)) {\n return 'upgrade'\n }\n if (/\\b(?:invalid_scope|insufficient_scope|permission_denied|access_denied|permission denied|insufficient scope|insufficient permissions?)\\b|\\b(?:organization|organisation|org|enterprise)\\b.{1,80}\\b(?:policy|disabled|restricted|denied|not allowed)\\b/i.test(reason))\n return 'account'\n if (/\\binvalid_grant\\b|\\b(?:token|grant|credentials?)\\b.{1,40}\\b(?:has been |was |is )?revoked\\b|\\brevoked (?:token|grant|credentials?)\\b/i.test(reason))\n return 'sign-in'\n if (/\\b(?:fetch failed|failed to fetch|network|ECONNRESET|ECONNREFUSED|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|timeout|timed out|temporarily_unavailable|server_error|rate_limit(?:_exceeded)?|too many requests|service unavailable)\\b|\\b(?:HTTP|status|failed:)(?:\\s*[:=])?\\s*(?:5\\d\\d|429|408)\\b/i.test(reason))\n return 'retry'\n return 'unknown'\n}\n\n/** Keep the resolver's preserved reason; only explicit grant rejection warrants login. */\nexport function anthropicOAuthRefreshError(reason: string, providerId?: string): string {\n const prefix = providerId\n ? `OAuth token refresh failed for \"${providerId}\".`\n : 'Anthropic OAuth token refresh failed.'\n let guidance: string\n switch (classifyRefreshFailure(reason)) {\n case 'sign-in':\n guidance = providerId ? 'Sign in again.' : 'Sign in again with `bun run auth --anthropic`.'\n break\n case 'retry':\n guidance = 'Check connectivity or service availability, then retry.'\n break\n case 'account':\n guidance = 'Check account access and organization policy with your administrator; repeated login may not help.'\n break\n case 'upgrade':\n guidance = 'Upgrade and restart the running app or daemon to update its Claude client compatibility.'\n break\n default:\n guidance = 'Inspect the underlying error before changing credentials.'\n }\n return `${prefix} ${guidance} ${reason}`\n}\n","export function longAnthropicRetryDelay(headers?: Headers): number | undefined {\n const value = headers?.get('retry-after')\n if (!value)\n return undefined\n const seconds = Number(value)\n const delay = Number.isFinite(seconds) ? seconds * 1000 : Date.parse(value) - Date.now()\n return Number.isFinite(delay) && delay > 60_000 ? delay : undefined\n}\n\nexport function anthropicRateLimitMessage(delayMs: number): string {\n let seconds = Math.ceil(delayMs / 1000)\n const parts: string[] = []\n for (const [unit, size] of [['day', 86400], ['hour', 3600], ['minute', 60], ['second', 1]] as const) {\n const count = Math.floor(seconds / size)\n if (count > 0) {\n parts.push(`${count} ${unit}${count === 1 ? '' : 's'}`)\n seconds %= size\n }\n if (parts.length === 2)\n break\n }\n return `Claude has limited this account. Try again in ${parts.join(', ')}. Check your usage in Claude or contact Anthropic support.`\n}\n\nexport function wrapFetchForAnthropicRateLimit(fetch: typeof globalThis.fetch): typeof globalThis.fetch {\n return Object.assign(async (...args: Parameters<typeof fetch>) => {\n const response = await fetch(...args)\n if (response.status !== 429 || longAnthropicRetryDelay(response.headers) === undefined)\n return response\n const headers = new Headers(response.headers)\n // The SDK honors this header before applying its automatic retry policy.\n headers.set('x-should-retry', 'false')\n return new Response(response.body, { status: response.status, statusText: response.statusText, headers })\n }, fetch)\n}\n","import type Anthropic from '@anthropic-ai/sdk'\nimport type { AnthropicBedrockConfig, AnthropicParams } from './anthropic-params'\nimport { lazyAsync } from '../lazy'\nimport { buildClaudeCodeHeaders, CLAUDE_CODE_BETAS, wrapFetchForCch } from './anthropic-claude-code'\nimport { anthropicOAuthRefreshError } from './anthropic-oauth-error'\nimport { wrapFetchForAnthropicRateLimit } from './anthropic-rate-limit'\nimport { readOAuthCredentials } from './oauth'\n\ntype AnthropicCtor = typeof Anthropic\nexport type AnthropicInstance = InstanceType<AnthropicCtor>\n\n// Lazy-loaded SDK class. `@anthropic-ai/sdk` is an OPTIONAL peer dependency: the\n// module is imported only when the anthropic provider opens a connection.\nexport const loadAnthropicSdk = lazyAsync(async (): Promise<AnthropicCtor> => {\n try {\n const mod = await import('@anthropic-ai/sdk')\n return mod.default as unknown as AnthropicCtor\n }\n catch (err) {\n throw new Error(\n 'The `anthropic` provider requires the `@anthropic-ai/sdk` package, which is an optional peer dependency. '\n + 'Install it with your package manager (e.g. `bun add @anthropic-ai/sdk`).',\n err instanceof Error ? { cause: err } : undefined,\n )\n }\n})\n\n// Same optional-peer treatment for the Bedrock flavor. `AnthropicBedrock`\n// subclasses the same client core (`BaseAnthropic`) and exposes the identical\n// `messages` surface (minus `countTokens` / `batches`), so downstream stream\n// handling is byte-identical — only construction and auth differ (SigV4).\nconst loadBedrockSdk = lazyAsync(async (): Promise<AnthropicCtor> => {\n try {\n const mod = await import('@anthropic-ai/bedrock-sdk')\n return mod.AnthropicBedrock as unknown as AnthropicCtor\n }\n catch (err) {\n throw new Error(\n 'The `anthropic` provider in Bedrock mode requires the `@anthropic-ai/bedrock-sdk` package, which is an optional peer dependency. '\n + 'Install it with your package manager (e.g. `bun add @anthropic-ai/bedrock-sdk`).',\n err instanceof Error ? { cause: err } : undefined,\n )\n }\n})\n\n/**\n * Build the Bedrock client for one call. Auth is SigV4 via the AWS credential\n * chain — the Anthropic key/OAuth machinery is intentionally bypassed. Betas\n * are NOT forwarded: Bedrock's translation layer rejects unknown beta flags,\n * and the persona/fast-mode features they gate don't exist there.\n */\nexport async function createBedrockClient(\n config: AnthropicBedrockConfig,\n anthropicParams: AnthropicParams | undefined,\n extraHeaders: Record<string, string> | undefined,\n): Promise<AnthropicInstance> {\n const Ctor = (config.sdk ?? await loadBedrockSdk()) as AnthropicCtor\n const options: Record<string, unknown> = {\n awsRegion: config.region ?? process.env.AWS_REGION ?? 'us-west-2',\n ...(anthropicParams?.baseURL ? { baseURL: anthropicParams.baseURL } : {}),\n ...(extraHeaders && Object.keys(extraHeaders).length > 0 ? { defaultHeaders: extraHeaders } : {}),\n }\n return new (Ctor as unknown as new (o: Record<string, unknown>) => AnthropicInstance)(options)\n}\n\n/** Normalize the `bedrock` param: `true` → empty config, absent → undefined. */\nexport function normalizeBedrock(value: AnthropicParams['bedrock']): AnthropicBedrockConfig | undefined {\n if (!value)\n return undefined\n return value === true ? {} : value\n}\n\n/**\n * Beta flags sent unconditionally on the OAuth path (Claude Code parity).\n *\n * The full client set, sent as one unit — see `CLAUDE_CODE_BETAS`. Betas whose\n * request fields we never populate are inert, so the cost of matching the\n * client exactly is nil while the cost of guessing a subset is looking like a\n * different client.\n */\nconst OAUTH_DEFAULT_BETAS = CLAUDE_CODE_BETAS\n\n/**\n * Beta flag that enables the `speed: \"fast\"` request field (fast mode — up to\n * 2.5× output tokens/sec at premium pricing; supported models are enumerated\n * in `FAST_MODE_OPTIONS` in chat/anthropic-models.ts). Sent as an\n * `anthropic-beta` header only on requests that opt into fast mode; absent\n * otherwise so standard requests keep a byte-stable header for prompt caching.\n *\n * See: https://platform.claude.com/docs/en/build-with-claude/fast-mode\n */\nexport const FAST_MODE_BETA = 'fast-mode-2026-02-01'\n\nconst API_KEY_RESERVED_EXTRA_HEADER_NAMES = new Set(['anthropic-beta'])\nconst OAUTH_RESERVED_EXTRA_HEADER_NAMES = new Set([\n 'accept',\n 'anthropic-beta',\n 'anthropic-client-platform',\n 'anthropic-client-version',\n 'x-stainless-arch',\n 'x-stainless-lang',\n 'x-stainless-os',\n 'x-stainless-package-version',\n 'x-stainless-retry-count',\n 'x-stainless-runtime',\n 'x-stainless-runtime-version',\n 'x-stainless-timeout',\n 'anthropic-dangerous-direct-browser-access',\n 'user-agent',\n 'x-app',\n])\n\nfunction filterReservedExtraHeaders(\n extraHeaders: Record<string, string> | undefined,\n reservedNames: ReadonlySet<string>,\n): Record<string, string> {\n const out: Record<string, string> = {}\n for (const [name, value] of Object.entries(extraHeaders ?? {})) {\n if (!reservedNames.has(name.toLowerCase()))\n out[name] = value\n }\n return out\n}\n\n/**\n * Build the `anthropic-beta` header value — OAuth defaults plus caller-supplied\n * extras, de-duped while preserving order. Returns `undefined` when no betas\n * apply (non-OAuth, no extras).\n */\nexport function resolveAnthropicBetas(\n isOAuth: boolean,\n extraBetas?: readonly string[],\n): string | undefined {\n const seen = new Set<string>()\n const out: string[] = []\n if (isOAuth) {\n for (const b of OAUTH_DEFAULT_BETAS) {\n if (!seen.has(b)) { seen.add(b); out.push(b) }\n }\n }\n if (extraBetas) {\n for (const b of extraBetas) {\n if (typeof b === 'string' && b.length > 0 && !seen.has(b)) {\n seen.add(b)\n out.push(b)\n }\n }\n }\n return out.length > 0 ? out.join(',') : undefined\n}\n\n/**\n * Credential-resolution identity for {@link resolveOAuthApiKey}. Anthropic's\n * own unless the caller pointed the provider at a gateway with its own\n * credentials via {@link AnthropicParams.credentialSource}.\n */\nexport function credentialIdentity(anthropicParams?: AnthropicParams): {\n providerId: string\n envKey?: string\n missingError: string\n refreshError: (reason: string) => string\n} {\n const source = anthropicParams?.credentialSource\n if (!source) {\n return {\n providerId: 'anthropic',\n envKey: 'ANTHROPIC_API_KEY',\n missingError: 'No API key found. Run `bun run auth` first.',\n refreshError: reason => anthropicOAuthRefreshError(reason),\n }\n }\n return {\n providerId: source.providerId,\n envKey: source.envKey,\n missingError: source.missingError ?? `No credentials found for \"${source.providerId}\". Sign in first.`,\n refreshError: source.refreshError ?? (reason => anthropicOAuthRefreshError(reason, source.providerId)),\n }\n}\n\n/**\n * Whether the wire auth is a bearer token, and whether the Claude Code\n * persona (betas + `x-app` headers + system-prompt folding) applies. Only the\n * default `'auto'` mode infers both from the token shape — see\n * {@link AnthropicParams.authMode}.\n */\nexport function resolveAnthropicAuthShape(\n apiKey: string,\n authMode: AnthropicParams['authMode'],\n): { bearer: boolean, claudeCode: boolean } {\n if (authMode === 'bearer')\n return { bearer: true, claudeCode: false }\n if (authMode === 'api-key')\n return { bearer: false, claudeCode: false }\n const isOAuth = apiKey.includes('sk-ant-oat')\n return { bearer: isOAuth, claudeCode: isOAuth }\n}\n\nexport function getConfiguredApiKey(anthropicParams?: AnthropicParams): string {\n if (anthropicParams?.apiKey)\n return anthropicParams.apiKey\n\n if (anthropicParams?.access)\n return anthropicParams.access\n\n // Gateway credentials live under their own key — resolve the factory-time\n // snapshot from there and never fall back to Anthropic's own key/creds\n // (a `bex_` gateway must not silently stream on the user's Anthropic key).\n // An empty snapshot is fine: the real error surfaces per call from\n // `resolveOAuthApiKey` with this source's `missingError`.\n const source = anthropicParams?.credentialSource\n if (source) {\n const fromEnv = source.envKey ? process.env[source.envKey] : undefined\n if (fromEnv)\n return fromEnv\n return readOAuthCredentials()[source.providerId]?.access ?? ''\n }\n\n if (process.env.ANTHROPIC_API_KEY)\n return process.env.ANTHROPIC_API_KEY\n\n // `readOAuthCredentials` tolerates a missing or corrupted file and returns `{}`\n // in both cases, so stale/half-written creds never crash agent construction.\n const access = readOAuthCredentials().anthropic?.access\n if (typeof access === 'string' && access.length > 0)\n return access\n\n throw new Error('No API key found. Run `bun run auth` first.')\n}\n\n/**\n * Resolve {@link AnthropicParams.extraHeaders} to a concrete map. A function\n * form is invoked (and awaited) per call so gateway auth tokens can refresh\n * each turn; a static map passes through.\n */\nexport async function resolveExtraHeaders(\n value: AnthropicParams['extraHeaders'],\n): Promise<Record<string, string> | undefined> {\n return typeof value === 'function' ? value() : value\n}\n\n/**\n * SDK constructor options for a resolved credential — the single place that\n * decides which auth header goes on the wire.\n *\n * Exported (and pure) so the header shape is test-pinned without a network\n * round-trip: `authToken` → `Authorization: Bearer …`, `apiKey` → `x-api-key`,\n * and `apiKey: null` alongside `authToken` is what suppresses `x-api-key` so a\n * gateway sees exactly one credential.\n */\nexport function buildAnthropicClientOptions(\n apiKey: string,\n auth: { bearer: boolean, claudeCode: boolean },\n baseURL?: string,\n extraBetas?: readonly string[],\n extraHeaders?: Record<string, string>,\n): Record<string, unknown> {\n const base = baseURL ? { baseURL } : {}\n const betaHeader = resolveAnthropicBetas(auth.claudeCode, extraBetas)\n if (auth.claudeCode) {\n const callerHeaders = filterReservedExtraHeaders(extraHeaders, OAUTH_RESERVED_EXTRA_HEADER_NAMES)\n const defaultHeaders: Record<string, string> = {\n ...callerHeaders,\n accept: 'application/json',\n ...buildClaudeCodeHeaders(),\n }\n if (betaHeader)\n defaultHeaders['anthropic-beta'] = betaHeader\n return {\n apiKey: null,\n authToken: apiKey,\n dangerouslyAllowBrowser: true,\n defaultHeaders,\n // Patches the `cch` attestation into the serialized body. Per-client\n // rather than on `globalThis` so nothing else in the process is touched.\n fetch: wrapFetchForAnthropicRateLimit(wrapFetchForCch(globalThis.fetch)),\n ...base,\n }\n }\n // Non-persona paths — only emit the beta header when the caller opted in,\n // and let caller headers through except `anthropic-beta` (reserved so the\n // fast-mode / opt-in beta computation stays authoritative).\n const defaultHeaders = filterReservedExtraHeaders(extraHeaders, API_KEY_RESERVED_EXTRA_HEADER_NAMES)\n if (betaHeader)\n defaultHeaders['anthropic-beta'] = betaHeader\n const headers = Object.keys(defaultHeaders).length > 0 ? { defaultHeaders } : {}\n // Bearer without the persona: a gateway token (`bex_…`, an internal router\n // key) in front of `baseURL`.\n if (auth.bearer)\n return { apiKey: null, authToken: apiKey, ...headers, ...base }\n return { apiKey, ...headers, ...base }\n}\n\nexport function createClient(\n SDK: AnthropicCtor,\n apiKey: string,\n auth: { bearer: boolean, claudeCode: boolean },\n baseURL?: string,\n extraBetas?: readonly string[],\n extraHeaders?: Record<string, string>,\n wrapFetch?: (fetch: typeof globalThis.fetch) => typeof globalThis.fetch,\n): AnthropicInstance {\n const options = buildAnthropicClientOptions(apiKey, auth, baseURL, extraBetas, extraHeaders)\n if (wrapFetch)\n options.fetch = wrapFetch((options.fetch ?? globalThis.fetch) as typeof globalThis.fetch)\n return new SDK(options as ConstructorParameters<AnthropicCtor>[0])\n}\n","import type Anthropic from '@anthropic-ai/sdk'\nimport type { ClassifiedError } from '../errors'\nimport { classifyErrorPrelude, isRetryableHttpStatus, matchesContextExceeded, matchesToolPairingError } from '../errors'\nimport { anthropicRateLimitMessage, longAnthropicRetryDelay } from './anthropic-rate-limit'\n\n/**\n * Duck-type check for an Anthropic SDK `APIError` — avoids a runtime dependency\n * on `@anthropic-ai/sdk` so `classifyError` stays usable even when the optional\n * peer dep isn't loaded (e.g. host code calling it on an unrelated provider's\n * error).\n *\n * Anthropic's APIError shape: `.status: number` + `.error` (parsed body, object\n * or null). Plain `Error`s don't have `.status` + `.error`.\n */\nfunction looksLikeAnthropicApiError(err: unknown): boolean {\n if (!err || typeof err !== 'object')\n return false\n const e = err as { status?: unknown, error?: unknown }\n return typeof e.status === 'number' && 'error' in e\n}\n\n/**\n * Anthropic SSE `error` event types that warrant a retry. `overloaded_error`\n * is the headline case (capacity event mid-stream); `api_error` and\n * `timeout_error` are both server-side transient failures. `invalid_request_error`,\n * `authentication_error`, `permission_error`, `not_found_error`, `billing_error`\n * are terminal — retrying them would just hammer a bad request.\n *\n * `rate_limit_error` here would be redundant: the SDK's pre-stream retry\n * handles 429, and a mid-stream `rate_limit_error` is exceedingly rare. We\n * include it anyway for symmetry with the HTTP-level retry policy.\n */\nconst SSE_RETRYABLE_ERROR_TYPES = new Set<string>([\n 'overloaded_error',\n 'api_error',\n 'timeout_error',\n 'rate_limit_error',\n])\n\n/**\n * Try to parse an Anthropic SSE `error` event payload out of a thrown error's\n * message. The SDK's `MessageStream` surfaces mid-stream error events by\n * throwing an `AnthropicError` whose `.message` contains the raw JSON shape:\n *\n * {\"type\":\"error\",\"error\":{\"type\":\"overloaded_error\",\"message\":\"Overloaded\"},\"request_id\":\"req_...\"}\n *\n * Returns the inner `{ type, message }` or `null` when the message isn't\n * the canonical SSE error shape. Tolerant: silently returns `null` for\n * non-string input, non-JSON content, or any shape mismatch.\n */\nfunction matchSseErrorEvent(message: unknown): { type: string, message: string } | null {\n if (typeof message !== 'string' || message.length === 0)\n return null\n // Cheap pre-check to avoid JSON.parse on every error message.\n if (!message.includes('\"type\":\"error\"') && !message.includes('\"type\": \"error\"'))\n return null\n // The message may be the JSON itself or have it embedded (some SDK paths\n // prefix a human prelude). Scan for the first `{` and try from there.\n const start = message.indexOf('{')\n if (start < 0)\n return null\n try {\n const parsed = JSON.parse(message.slice(start)) as unknown\n if (!parsed || typeof parsed !== 'object')\n return null\n const outer = parsed as { type?: unknown, error?: unknown }\n if (outer.type !== 'error' || !outer.error || typeof outer.error !== 'object')\n return null\n const inner = outer.error as { type?: unknown, message?: unknown }\n if (typeof inner.type !== 'string')\n return null\n return {\n type: inner.type,\n message: typeof inner.message === 'string' ? inner.message : inner.type,\n }\n }\n catch {\n return null\n }\n}\n\n/**\n * Classify an Anthropic SDK / HTTP error for typed-error wrapping.\n *\n * - `prompt is too long` (400 invalid_request_error) → `context_exceeded`.\n * - `'tool_use' ids were found without 'tool_result' blocks` /\n * `'tool_result must be preceded by a tool_call'` (400) →\n * `tool_pairing_corruption`. The local repair pass should have caught\n * this — the typed error tells consumers their pre-send pipeline is\n * shipping orphaned blocks somehow (custom `context:transform` hook,\n * bypassed loop, mid-stream session edit) so they can patch the root\n * cause instead of chasing 400s.\n * - Any other Anthropic `APIError`-shaped value → `provider_error` with the\n * native status/type code.\n * - Unknown errors → `null` (loop wraps in `AgentProviderError` generically).\n *\n * Anthropic's wire error shape is `{ type: 'error', error: { type, message } }` — the\n * SDK stores the parsed body on `err.error`. We walk both levels so callers see the\n * most specific `providerCode` we can find.\n */\nexport function classifyAnthropicError(err: unknown): ClassifiedError | null {\n const prelude = classifyErrorPrelude(err)\n if (prelude === 'not-object')\n return null\n if (prelude === 'aborted')\n return { kind: 'aborted' }\n\n interface InnerError { type?: string, message?: string }\n interface AnthError {\n name?: string\n message?: string\n status?: number\n headers?: Headers\n error?: InnerError & { error?: InnerError }\n }\n const anyErr = err as AnthError\n const delay = anyErr.status === 429 && anyErr.headers instanceof Headers\n ? longAnthropicRetryDelay(anyErr.headers)\n : undefined\n if (delay !== undefined) {\n return {\n kind: 'provider_error',\n providerCode: 'rate_limit_error',\n message: anthropicRateLimitMessage(delay),\n retryable: false,\n }\n }\n\n // Mid-stream SSE error event — the SDK's `MessageStream` surfaces these by\n // throwing an `AnthropicError` (plain Error subclass, no `.status`) whose\n // `.message` carries the raw SSE error JSON, e.g.\n // `{\"type\":\"error\",\"error\":{\"type\":\"overloaded_error\",\"message\":\"Overloaded\"},\"request_id\":\"...\"}`.\n // The pre-stream HTTP retry inside the SDK can't help here — the response\n // already opened with a 200, then the server emitted `event: error`\n // mid-stream. Classify these so the loop-level retry kicks in.\n //\n // Guarded on `!looksLikeAnthropicApiError(err)` so we don't shadow the\n // structured `APIError` branch below (which also stringifies its body into\n // `.message` and would otherwise match this same pattern).\n if (!looksLikeAnthropicApiError(err)) {\n const sseError = matchSseErrorEvent(anyErr.message)\n if (sseError) {\n return {\n kind: 'provider_error',\n providerCode: sseError.type,\n message: sseError.message,\n retryable: SSE_RETRYABLE_ERROR_TYPES.has(sseError.type),\n }\n }\n return null\n }\n\n // Prefer the inner error when present (Anthropic's nested shape).\n const innerType = anyErr.error?.error?.type\n const outerType = anyErr.error?.type\n const nativeType = innerType && innerType !== 'error' ? innerType : outerType\n const message = anyErr.error?.error?.message\n ?? anyErr.error?.message\n ?? anyErr.message\n ?? ''\n\n if (matchesContextExceeded(message)) {\n return {\n kind: 'context_exceeded',\n providerCode: nativeType ?? 'invalid_request_error',\n message,\n }\n }\n\n if (matchesToolPairingError(message)) {\n return {\n kind: 'tool_pairing_corruption',\n providerCode: nativeType ?? 'invalid_request_error',\n message,\n }\n }\n\n const status = anyErr.status\n const retryable = typeof status === 'number'\n ? isRetryableHttpStatus(status)\n : undefined\n\n return {\n kind: 'provider_error',\n providerCode: nativeType ?? (status ? String(status) : undefined),\n message,\n ...(retryable !== undefined ? { retryable } : {}),\n }\n}\n\n/** True only for a provider authentication rejection eligible for one OAuth refresh retry. */\nexport function isAnthropicAuthenticationError(err: unknown): boolean {\n if (!err || typeof err !== 'object')\n return false\n const candidate = err as { status?: number, error?: { type?: string, error?: { type?: string } } }\n return candidate.status === 401\n || candidate.error?.type === 'authentication_error'\n || candidate.error?.error?.type === 'authentication_error'\n}\n\nexport function shouldFallbackFromFastMode(err: unknown): boolean {\n const classified = classifyAnthropicError(err)\n if (classified?.kind === 'provider_error' && classified.retryable === true)\n return true\n\n const message = err instanceof Error ? err.message : String(err)\n return /\\b(?:fast|speed)\\b/i.test(message)\n && /capacity|overload|rate|unavailable|unsupported|not supported|not permitted|extra inputs|invalid/i.test(message)\n}\n\n/**\n * The 400 the API returns under `prefix_mismatch_behavior: \"error\"` for a\n * replayed block whose prefix changed. Distinct from a corrupt/tampered\n * signature: this one names the binding and the remedy.\n */\nexport function isPrefixMismatchError(err: unknown): boolean {\n return /bound to a different conversation|prefix_mismatch_behavior/i.test(errorText(err))\n}\n\n/**\n * Anthropic signs thinking blocks so they can be echoed through tool-use\n * chains without exposing raw reasoning. A signature can become\n * unverifiable after a model/route/account switch, a legacy session edit,\n * or a provider-side signing-key rotation. We cannot validate the opaque\n * signature locally; Anthropic reports this as a request-validation 400\n * (`invalid_request_error`) with no machine-readable subcode — the message\n * string is the only signal.\n *\n * Detection is layered, most-stable signal first:\n *\n * 1. Structural: the validation 400 pinpoints a wire location\n * (`messages.N.content.M: …`) and OUR OWN request payload has a\n * thinking/redacted_thinking block at that exact position. The locator\n * format is API-stable; the prose around it is not (Anthropic has\n * already reworded it once, from \"Invalid signature in thinking block\"\n * to \"Invalid `signature` in `thinking` block\", which silently\n * disabled a wording-only matcher). This deliberately classifies ANY\n * validation complaint targeting one of our opaque thinking blocks as\n * recoverable — dropping the block is the correct remedy for the whole\n * class (bad signature, corrupt data, ordering), and if the scrubbed\n * retry still 400s the error propagates unchanged.\n * 2. Wording fallback: some error shapes omit the locator; match the\n * known prose variants, tolerating backticks and minor rewording.\n *\n * Match narrowly: retrying any broader 400 could hide a real bad request.\n */\nexport function isRecoverableThinkingBlockError(err: unknown, messages?: Anthropic.MessageParam[]): boolean {\n if (!isRequestValidationError(err))\n return false\n\n if (messages !== undefined) {\n const path = parseFailingBlockPath(err)\n if (path !== undefined) {\n const content = messages[path.message]?.content\n const block = Array.isArray(content) ? content[path.content] : undefined\n if (block !== undefined && (block.type === 'thinking' || block.type === 'redacted_thinking'))\n return true\n }\n }\n\n return /invalid\\s+`?signature`?\\s+in\\s+(?:the\\s+)?`?thinking`?\\s+block/i.test(errorText(err))\n}\n\n/**\n * True when the error looks like an Anthropic request-validation failure:\n * status 400 and, when the nested API body carries a type, that type is\n * `invalid_request_error`. Both fields are optional on SDK-wrapped or\n * gateway shapes, so each is enforced only when present — but a present,\n * different value (e.g. 429, `authentication_error`) disqualifies: the\n * recovery permanently scrubs session history, so it must never fire on a\n * non-validation failure that coincidentally mentions a locator.\n */\nfunction isRequestValidationError(err: unknown): boolean {\n // Field probes only — a non-object error (string throw from a custom\n // stream factory) has neither status nor type and falls through to the\n // caller's prose match, same as the pre-structural matcher.\n const status = typeof err === 'object' && err !== null && 'status' in err\n ? (err as { status?: unknown }).status\n : undefined\n if (status !== undefined && status !== 400)\n return false\n const nestedType = typeof err === 'object' && err !== null ? nestedErrorType(err) : undefined\n return nestedType === undefined || nestedType === 'invalid_request_error'\n}\n\n/** The `error.error.type` of a nested Anthropic API error body, when present. */\nfunction nestedErrorType(err: object): string | undefined {\n const outer = 'error' in err ? (err as { error?: unknown }).error : undefined\n if (typeof outer !== 'object' || outer === null)\n return undefined\n const inner = 'error' in outer ? (outer as { error?: unknown }).error : outer\n if (typeof inner !== 'object' || inner === null)\n return undefined\n const type = 'type' in inner ? (inner as { type?: unknown }).type : undefined\n return typeof type === 'string' ? type : undefined\n}\n\n/** Error message + nested API error body, flattened for pattern matching. */\nfunction errorText(err: unknown): string {\n const nested = typeof err === 'object' && err !== null && 'error' in err\n ? JSON.stringify((err as { error?: unknown }).error)\n : ''\n return `${err instanceof Error ? err.message : String(err)} ${nested}`\n}\n\n/**\n * Full wire locator of the block the 400 pinpointed (`messages.5.content.0:\n * …`), or `undefined` when the shape doesn't carry one. Unlike the prose,\n * this locator prefix is a stable part of Anthropic's validation-error\n * format — it lets {@link isRecoverableThinkingBlockError} verify against\n * the actual request payload instead of trusting wording.\n */\nfunction parseFailingBlockPath(err: unknown): { message: number, content: number } | undefined {\n const match = /\\bmessages\\.(\\d+)\\.content\\.(\\d+)\\b/.exec(errorText(err))\n if (!match)\n return undefined\n const message = Number(match[1])\n const content = Number(match[2])\n return Number.isSafeInteger(message) && Number.isSafeInteger(content)\n ? { message, content }\n : undefined\n}\n\n/**\n * Wire index of the message the 400 pinpointed (`messages.5.content.0:\n * Invalid signature…`), or `undefined` when the shape doesn't carry one.\n * Lets the retry scrub only blocks at/before the failing message — later\n * messages can hold STILL-VALID thinking (e.g. minted this run after a\n * mid-session account switch) that the active tool-use chain requires.\n */\nexport function parseFailingMessageIndex(err: unknown): number | undefined {\n const match = /\\bmessages\\.(\\d+)\\./.exec(errorText(err))\n if (!match)\n return undefined\n const index = Number(match[1])\n return Number.isSafeInteger(index) ? index : undefined\n}\n\n/**\n * True for the 400 Anthropic returns when a model does not support forcing a\n * tool: `tool_choice: type \"tool\" and \"any\" are not supported for this model.`\n * Anchored on the status/type gate plus the field name and the \"not supported\n * for this model\" tail, so a reworded middle still matches while an unrelated\n * `tool_choice` validation error (bad name, wrong shape) does not.\n */\nexport function isForcedToolChoiceUnsupportedError(err: unknown): boolean {\n return isRequestValidationError(err)\n && /\\btool_choice\\b[^.]+not supported for this model\\b/i.test(errorText(err))\n}\n\n/**\n * True for the 400 an endpoint returns when it does not know the\n * preserved-thinking binding surface: either the `anthropic-beta` value\n * (`Unexpected value(s) \\`thinking-binding-controls-2026-08-01\\` for the\n * \\`anthropic-beta\\` header`) or the body field (`thinking.block_binding:\n * Extra inputs are not permitted`). Anchored on the validation-400 gate plus\n * one of the two names so an unrelated `thinking` validation error (bad\n * budget, wrong type) does not match. Gateways and the subscription backend\n * are the expected sources — the same places fast mode had to be dropped.\n *\n * NOT the prefix-mismatch 400 itself. Under `'error'` mode that error reads\n * `Invalid \\`signature\\` in \\`thinking\\` block. The block is bound to a\n * different conversation. Remove the block, or set\n * \\`thinking.block_binding.prefix_mismatch_behavior\\` to \"drop_block\".` — it\n * names the field while proving the endpoint understood it. Matching it here\n * would mis-diagnose a user-requested failure as an unsupported endpoint and\n * disable the binding for the instance's lifetime, so the signature shape is\n * excluded explicitly.\n */\nexport function isThinkingBindingRejectedError(err: unknown): boolean {\n if (!isRequestValidationError(err))\n return false\n const text = errorText(err)\n return /block_binding|prefix_mismatch_behavior|thinking-binding-controls/i.test(text)\n && !/invalid\\s+`?signature`?|bound to a different conversation/i.test(text)\n}\n\n/**\n * True for the 400 Anthropic returns when a model does not support the manual\n * extended-thinking shape: `\"thinking.type.enabled\" is not supported for this\n * model. Use \"thinking.type.adaptive\" and \"output_config.effort\" ...`. Anchored\n * on the validation-400 gate plus the dotted field name and the \"not supported\n * for this model\" tail, so a reworded middle still matches while an unrelated\n * `thinking` validation error (bad budget, wrong type) does not. Only the\n * `enabled` variant is matched: zidane omits the field for the `'off'` level\n * (adaptive on these models) and never emits `thinking.type.disabled`.\n */\nexport function isEnabledThinkingUnsupportedError(err: unknown): boolean {\n return isRequestValidationError(err)\n && /\\bthinking\\.type\\.enabled\\b[^.]+not supported for this model\\b/i.test(errorText(err))\n}\n","import type Anthropic from '@anthropic-ai/sdk'\nimport type { CacheTtl } from '../types'\nimport { splitSystemPrompt } from '../system-prompt'\n\nconst EPHEMERAL: Anthropic.CacheControlEphemeral = { type: 'ephemeral' }\n\n/**\n * `cache_control` for the requested TTL. `'5m'` stays the bare ephemeral shape\n * (no `ttl` field) so default-TTL requests are byte-identical to what every\n * zidane version has ever sent — adding `ttl: '5m'` would be semantically\n * equal but is gratuitous churn against proxies that pattern-match the body.\n * `'1h'` also requires the `extended-cache-ttl-2025-04-11` beta header, which\n * the request path adds — see {@link EXTENDED_CACHE_TTL_BETA}.\n */\nfunction cacheControlFor(ttl: CacheTtl | undefined): Anthropic.CacheControlEphemeral {\n return ttl === '1h' ? { type: 'ephemeral', ttl: '1h' } : EPHEMERAL\n}\n\n/** Beta flag Anthropic requires before it honors `ttl: '1h'` on `cache_control`. */\nexport const EXTENDED_CACHE_TTL_BETA = 'extended-cache-ttl-2025-04-11'\n\n/** Anthropic's per-request limit on `cache_control` markers. */\nconst MAX_CACHE_BREAKPOINTS = 4\n\n/**\n * Mutate an Anthropic request in place to add cache breakpoints on the three\n * stable prefixes:\n * 1. System prompt — `cache_control` on the static prefix only (see below).\n * 2. Tool definitions — last tool.\n * 3. Conversation — last content block of the last message.\n *\n * Each breakpoint tells Anthropic to cache the prefix ending at that block;\n * subsequent turns reuse the cached prefix and pay only for the delta. Safe\n * no-op when any prefix is empty (no tools, empty system, etc.).\n *\n * System-prompt boundary handling (`SYSTEM_PROMPT_BOUNDARY`):\n *\n * - When `originalSystem` is provided AND carries the marker, the system\n * block is rewritten as a 2-block array: static (cached) then dynamic\n * (uncached). The caller is expected to have already stripped the marker\n * from `params.system` via {@link renderSystemForWire} — this helper\n * only re-splits to apply `cache_control` cleanly.\n * - When `originalSystem` is omitted or marker-free, the existing single-\n * block treatment applies: `cache_control` on the whole system string.\n * - Array system prompts: existing semantics — `cache_control` lands on the\n * last block. Callers building their own multi-block layout own the\n * breakpoint placement.\n */\nexport function applyAnthropicCacheBreakpoints(\n params: Anthropic.MessageCreateParamsStreaming,\n originalSystem?: string,\n ttl?: CacheTtl,\n): void {\n const cacheControl = cacheControlFor(ttl)\n if (typeof params.system === 'string') {\n if (params.system.length > 0) {\n // `originalSystem` is the authoritative source for the boundary split\n // — `params.system` may have been pre-rendered by `renderSystemForWire`.\n // Fall back to `params.system` itself when no original was supplied\n // (or an empty original) so an external caller that embedded a marker\n // directly doesn't leak it into the cached block on the wire.\n const splitSource = originalSystem && originalSystem.length > 0\n ? originalSystem\n : params.system\n const parts = splitSystemPrompt(splitSource)\n if (parts.dynamic.length > 0) {\n const blocks: Anthropic.TextBlockParam[] = []\n if (parts.static.length > 0)\n blocks.push({ type: 'text', text: parts.static, cache_control: cacheControl })\n blocks.push({ type: 'text', text: parts.dynamic })\n params.system = blocks\n }\n else {\n // No marker — wrap the (already marker-free) string in a single\n // cached block. `parts.static` equals `splitSource` in this branch.\n params.system = [{ type: 'text', text: parts.static, cache_control: cacheControl }]\n }\n }\n }\n else if (Array.isArray(params.system) && params.system.length > 0) {\n const lastIdx = params.system.length - 1\n params.system = params.system.map((block, i) =>\n i === lastIdx ? { ...block, cache_control: cacheControl } : block,\n )\n }\n\n if (params.tools && params.tools.length > 0) {\n const lastIdx = params.tools.length - 1\n params.tools = params.tools.map((tool, i) =>\n i === lastIdx ? { ...tool, cache_control: cacheControl } : tool,\n ) as Anthropic.ToolUnion[]\n }\n\n if (params.messages.length === 0)\n return\n const lastMsgIdx = params.messages.length - 1\n markMessageBreakpoint(params.messages, lastMsgIdx, cacheControl)\n\n // Lookback breakpoint on the previous request's tail (the user message before\n // the latest assistant turn). Anthropic searches only ~20 blocks back from a\n // breakpoint for an earlier cache entry, so a turn with ~10+ parallel tool\n // calls pushes the moving breakpoint past the last write and the whole\n // conversation is re-written instead of read (Bedrock does not collapse\n // tool_use runs, so it misses sooner). Re-marking the old tail turns that\n // into a guaranteed read. Uses the spare slot of the 4-breakpoint limit, so\n // it is skipped when the request already carries 4 markers.\n if (countCacheBreakpoints(params) >= MAX_CACHE_BREAKPOINTS)\n return\n for (let i = lastMsgIdx - 1; i >= 0; i--) {\n if (params.messages[i].role !== 'user')\n continue\n if (i < lastMsgIdx - 1)\n markMessageBreakpoint(params.messages, i, cacheControl)\n break\n }\n}\n\n/** Put `cache_control` on the last cache-eligible block of `messages[idx]`. */\nfunction markMessageBreakpoint(\n messages: Anthropic.MessageParam[],\n idx: number,\n cacheControl: ReturnType<typeof cacheControlFor>,\n): void {\n const msg = messages[idx]\n if (typeof msg.content === 'string') {\n if (msg.content.length === 0)\n return\n messages[idx] = {\n ...msg,\n content: [{ type: 'text', text: msg.content, cache_control: cacheControl }],\n }\n return\n }\n if (!Array.isArray(msg.content) || msg.content.length === 0)\n return\n const blocks = msg.content\n // `ThinkingBlockParam` and `RedactedThinkingBlockParam` do not accept `cache_control`\n // in the SDK types — walk backward past any trailing thinking blocks to find the\n // nearest cache-eligible block. Returns -1 when every block is a thinking variant,\n // which skips this breakpoint; system + tools still carry the cache prefix.\n let targetIdx = blocks.length - 1\n while (targetIdx >= 0 && isThinkingBlock(blocks[targetIdx]))\n targetIdx -= 1\n if (targetIdx < 0)\n return\n const nextBlocks = blocks.slice()\n nextBlocks[targetIdx] = { ...nextBlocks[targetIdx], cache_control: cacheControl } as typeof nextBlocks[number]\n messages[idx] = { ...msg, content: nextBlocks }\n}\n\nfunction hasCacheControl(value: unknown): boolean {\n return typeof value === 'object' && value !== null && (value as { cache_control?: unknown }).cache_control != null\n}\n\nfunction countCacheBreakpoints(params: Anthropic.MessageCreateParamsStreaming): number {\n let count = 0\n if (Array.isArray(params.system)) {\n for (const block of params.system) {\n if (hasCacheControl(block))\n count++\n }\n }\n for (const tool of params.tools ?? []) {\n if (hasCacheControl(tool))\n count++\n }\n for (const msg of params.messages) {\n if (!Array.isArray(msg.content))\n continue\n for (const block of msg.content) {\n if (hasCacheControl(block)) {\n count++\n }\n // tool_result blocks can nest cache-marked content parts.\n else if (block.type === 'tool_result' && Array.isArray(block.content)) {\n for (const part of block.content) {\n if (hasCacheControl(part))\n count++\n }\n }\n }\n }\n return count\n}\n\nfunction isThinkingBlock(block: { type: string }): boolean {\n return block.type === 'thinking' || block.type === 'redacted_thinking'\n}\n","import type { ThinkingLevel } from '../types'\n\n/** Gates `thinking.block_binding` and the `input_transformations` response field. */\nexport const THINKING_BINDING_BETA = 'thinking-binding-controls-2026-08-01'\n\nexport type ThinkingBindingBehavior = 'drop_block' | 'error' | 'off'\n\nconst THINKING_BINDING_BEHAVIORS: ReadonlySet<string> = new Set<ThinkingBindingBehavior>(['drop_block', 'error', 'off'])\n\n/**\n * Env channel the chat host writes the user's `thinkingBinding` SETTING to.\n * Distinct from `ZIDANE_THINKING_BINDING` (the shell override) so the two\n * never read each other back: a host recreated in-process must not mistake\n * an earlier host's setting write for a shell value.\n */\nexport const THINKING_BINDING_SETTING_ENV = 'ZIDANE_THINKING_BINDING_SETTING'\n\n/**\n * Effective {@link AnthropicParams.thinkingBinding}: the explicit param wins,\n * then the shell's `ZIDANE_THINKING_BINDING`, then the chat host's setting\n * channel ({@link THINKING_BINDING_SETTING_ENV}), then `'drop_block'`. Read\n * per request so a flip lands on the next call without rebuilding the\n * provider (the factory is no-arg in the chat host). Unrecognized values are\n * ignored at each level.\n */\nexport function resolveThinkingBinding(\n param: ThinkingBindingBehavior | undefined,\n env: NodeJS.ProcessEnv = process.env,\n): ThinkingBindingBehavior {\n if (param !== undefined)\n return param\n for (const key of ['ZIDANE_THINKING_BINDING', THINKING_BINDING_SETTING_ENV]) {\n const value = env[key]?.trim()\n if (value && THINKING_BINDING_BEHAVIORS.has(value))\n return value as ThinkingBindingBehavior\n }\n return 'drop_block'\n}\n\ntype BudgetedThinkingLevel = Exclude<ThinkingLevel, 'off' | 'adaptive'>\n\n/**\n * Output tokens reserved for the visible response when an explicit thinking\n * budget must be shrunk to fit under the model's `max_tokens` ceiling — see\n * the budget clamp in `buildAnthropicStreamRequest` (`./anthropic-request`).\n */\nexport const THINKING_RESPONSE_RESERVE_TOKENS = 1024\n\n/**\n * Explicit thinking budgets for Bedrock, per effort tier. Bedrock's\n * anthropic-native path only accepts the legacy\n * `thinking: { type: 'enabled', budget_tokens }` shape (the 4.6 surface —\n * `output_config.effort`, adaptive, `display` — is rejected by its\n * translation layer), so effort tiers degrade to token budgets. Floor is\n * Anthropic's 1024 minimum; ceilings stay well under haiku/sonnet output\n * caps — the request builder clamps against the model ceiling regardless.\n */\nexport const BEDROCK_THINKING_BUDGETS: Record<'low' | 'medium' | 'high' | 'xhigh' | 'max', number> = {\n low: 4096,\n medium: 12288,\n high: 24576,\n xhigh: 32768,\n max: 32768,\n}\n\n/**\n * Map `ThinkingLevel` budgeted tiers to Anthropic's `output_config.effort`\n * enum. `minimal` collapses to `low` (the closest equivalent — Anthropic does\n * not have a sub-`low` tier).\n */\nconst EFFORT_FOR_LEVEL: Record<BudgetedThinkingLevel, 'low' | 'medium' | 'high' | 'xhigh' | 'max'> = {\n minimal: 'low',\n low: 'low',\n medium: 'medium',\n high: 'high',\n xhigh: 'xhigh',\n max: 'max',\n}\n\n/**\n * Description of the Anthropic-side thinking configuration derived from a\n * ThinkingLevel. `null` means no thinking-related field should be set on the\n * request.\n *\n * Two shapes:\n * - `adaptive` — `thinking.type='adaptive'`. The model self-budgets per turn.\n * When `effort` is set, also emits `output_config.effort` to hint at the\n * level of reasoning the caller wants. This is the post-Claude-4.6 default\n * for level-based control and avoids the `thinking.type='enabled'`\n * deprecation warning. When `maxTokensCap` is set, the request builder\n * reduces `max_tokens` to `min(max_tokens, maxTokensCap)` — adaptive thinks\n * and replies inside one envelope, so capping the envelope soft-bounds the\n * thinking too.\n * - `enabled` — explicit-budget path: `thinking.type='enabled'` with an\n * explicit `budget_tokens`. `maxTokensBump` is added to the request's\n * `max_tokens` so the budget sits on top of the response cap. When the\n * caller's level maps to an effort tier, `effort` is carried too and\n * emitted as `output_config.effort` alongside the explicit budget —\n * both fields are valid together on 4.6+ models. The only way to pin a\n * precise token budget; Anthropic emits a deprecation warning for this\n * shape on opus 4.6+, so we only route here when the caller explicitly\n * sets `behavior.thinkingBudget`.\n *\n * In both shapes Anthropic requires `temperature` to be `1`.\n */\nexport type AnthropicThinkingPlan\n = | { kind: 'enabled', budgetTokens: number, maxTokensBump: number, effort?: 'low' | 'medium' | 'high' | 'xhigh' | 'max' }\n | { kind: 'adaptive', effort?: 'low' | 'medium' | 'high' | 'xhigh' | 'max', maxTokensCap?: number, taskBudgetTokens?: number }\n\n/**\n * Decide how to translate a `ThinkingLevel` into Anthropic's request shape.\n * Pure / synchronous — exported so tests can assert routing without standing\n * up the SDK.\n *\n * Routing rules:\n * - `'off'` → `null` (no thinking field, no effort hint).\n * - `'adaptive'` → adaptive thinking with no effort hint (model decides\n * everything). When `taskBudget` is set, it is carried as\n * `taskBudgetTokens` and emitted as `output_config.task_budget` — the\n * native whole-task thinking cap. LEGACY: when `customBudget` is set, it\n * is carried as `maxTokensCap` so the request builder caps `max_tokens`\n * accordingly — this clamps the whole response envelope (text and\n * tool-call JSON included), which is the wrong knob for bounding thinking\n * now that `taskBudget` exists; kept only for callers who already depend\n * on it. Prefer `taskBudget`.\n * - Budgeted levels → adaptive thinking with an `effort` hint (plus\n * `taskBudgetTokens` when `taskBudget` is set), unless `customBudget` is\n * provided.\n * - Any level + `customBudget` → explicit-budget `enabled` path, carrying\n * the level's `effort` hint alongside the budget. The caller has opted\n * into precise budget control and accepts the Anthropic deprecation\n * warning that comes with it on opus 4.6+. `'adaptive'` is the sole\n * exception: it never falls back to enabled, since adaptive is the\n * current Anthropic API surface for self-budgeted thinking. `taskBudget`\n * is adaptive-only and ignored on this path.\n * - `effortHint: false` (default `true`) strips the `effort` hint from\n * every shape — budgeted levels plan plain adaptive and the\n * `customBudget` path plans `enabled` with no `output_config.effort` —\n * for Anthropic models that reject the effort field.\n */\nexport function planAnthropicThinking(\n level: ThinkingLevel,\n customBudget?: number,\n taskBudget?: number,\n effortHint = true,\n): AnthropicThinkingPlan | null {\n if (level === 'off')\n return null\n const taskBudgetTokens = typeof taskBudget === 'number' && taskBudget > 0 ? taskBudget : undefined\n if (level === 'adaptive') {\n return {\n kind: 'adaptive',\n ...(typeof customBudget === 'number' && customBudget > 0 ? { maxTokensCap: customBudget } : {}),\n ...(taskBudgetTokens !== undefined ? { taskBudgetTokens } : {}),\n }\n }\n if (customBudget !== undefined) {\n return {\n kind: 'enabled',\n budgetTokens: customBudget,\n maxTokensBump: customBudget,\n ...(effortHint ? { effort: EFFORT_FOR_LEVEL[level] } : {}),\n }\n }\n return {\n kind: 'adaptive',\n ...(effortHint ? { effort: EFFORT_FOR_LEVEL[level] } : {}),\n ...(taskBudgetTokens !== undefined ? { taskBudgetTokens } : {}),\n }\n}\n","import type Anthropic from '@anthropic-ai/sdk'\nimport type { Model } from '@anthropic-ai/sdk/resources'\nimport type { StreamOptions } from '.'\nimport type { CacheTtl } from '../types'\nimport type { AnthropicBedrockConfig, AnthropicContextManagement, AnthropicParams } from './anthropic-params'\nimport type { AnthropicThinkingPlan, ThinkingBindingBehavior } from './anthropic-thinking'\nimport type { ModelCatalog } from './model-catalog'\nimport type { ToolNameBoundary } from './tool-name-boundary'\nimport { lazyAsync } from '../lazy'\nimport { toAnthropic } from '../session/messages'\nimport { applyAnthropicCacheBreakpoints } from './anthropic-cache'\nimport {\n CLAUDE_CODE_MAX_OUTPUT_TOKENS,\n claudeCodeBillingText,\n claudeCodeToolAliases,\n claudeCodeUserId,\n firstUserMessageText,\n foldSystemForWire,\n} from './anthropic-claude-code'\nimport { BEDROCK_THINKING_BUDGETS, THINKING_RESPONSE_RESERVE_TOKENS } from './anthropic-thinking'\nimport { lookupModel } from './model-catalog'\nimport { resolvePromptCacheKey } from './prompt-cache-key'\nimport { createToolNameBoundary } from './tool-name-boundary'\n\n/**\n * Conservative per-family output ceiling, used ONLY as a fallback when pi-ai's\n * model registry doesn't know the model (or pi-ai is externalized) — see\n * {@link resolveAnthropicMaxOutput}, which is the primary path. These are\n * non-beta floors we can always send without a 400; the registry reports the\n * real (often much higher, e.g. Opus 4.x = 128K native) max when available.\n */\nexport function defaultAnthropicMaxTokens(modelId: string): number {\n const id = modelId.toLowerCase()\n if (id.includes('haiku'))\n return 8192\n if (id.includes('sonnet'))\n return 64000\n // opus + anything unrecognized → 32000: a safe floor when the registry is\n // unavailable. The registry lifts this to the model's true max when present.\n return 32000\n}\n\n/**\n * Lazily-loaded pi-ai model-registry getter (cached; keeps the multi-MB\n * registry out of the static bundle, mirroring `cost.ts`). Returns `null` when\n * pi-ai is externalized, in which case callers fall back to the family map.\n */\nconst loadPiModelGetter = lazyAsync(\n async (): Promise<((provider: string, model: string) => { maxTokens?: number } | undefined) | null> => {\n try {\n const mod = await import('@earendil-works/pi-ai/providers/all')\n return mod.getBuiltinModel as unknown as (provider: string, model: string) => { maxTokens?: number } | undefined\n }\n catch {\n return null\n }\n },\n)\n\n/**\n * Resolve a model's max output tokens. Prefers pi-ai's bundled registry — the\n * authoritative source the SDK itself uses to build requests, so e.g. Opus 4.x\n * reports its full native 128K (no extended-output beta required) — and falls\n * back to {@link defaultAnthropicMaxTokens} only when the registry lacks the\n * model. Used as BOTH the default (when the caller leaves `maxTokens` unset)\n * and a hard clamp, since a `max_tokens` above the model's max would 400.\n *\n * The clamp is only as good as the ceiling's provenance, so an explicit caller\n * `maxTokens` can RAISE the fallback: models the registry doesn't know are\n * mostly ids that never appear in pi-ai's anthropic registry — Bedrock ids\n * (`global.anthropic.claude-*`) and non-Anthropic models served over the\n * Anthropic wire (`openai.gpt-*` on Bedrock, gateway aliases). For the\n * latter the fallback degrades to the 32000 catch-all; for the former the\n * family match yields a deliberately conservative non-beta floor. Clamping a\n * caller who knows the real ceiling down to either silently truncates long\n * generations mid-write (observed as turns pinned at exactly 32000 tokens).\n *\n * It can only raise, never lower: the caller's `maxTokens` is a cap on the\n * VISIBLE response, already enforced as `max_tokens` itself, whereas this\n * value is the model's physical ceiling. Letting it lower the ceiling would\n * break the `enabled` thinking path's invariant that the budget sits ON TOP\n * of the response cap — the budget would be shrunk to share the caller's cap,\n * or dropped entirely once no satisfiable budget fits.\n *\n * A registry-backed max always wins over the caller — above it the provider\n * 400s. A CATALOG entry (`behavior.modelCatalog` / `setModelCatalog`) outranks\n * even that: it's an explicit claim about a model whose registry entry may be\n * absent, stale, or an alias for something else entirely.\n */\nexport async function resolveAnthropicMaxOutput(\n modelId: string,\n explicitMaxTokens?: number,\n catalog?: ModelCatalog,\n): Promise<number> {\n const override = lookupModel('anthropic', modelId, catalog)?.maxTokens\n if (typeof override === 'number' && override > 0)\n return override\n const getModel = await loadPiModelGetter()\n const registryMax = getModel?.('anthropic', modelId)?.maxTokens\n if (typeof registryMax === 'number' && registryMax > 0)\n return registryMax\n const fallback = defaultAnthropicMaxTokens(modelId)\n return typeof explicitMaxTokens === 'number' && explicitMaxTokens > 0\n ? Math.max(fallback, explicitMaxTokens)\n : fallback\n}\n\n/** The streaming request body — see the widening note where it is built. */\nexport type AnthropicStreamParams = Anthropic.MessageCreateParamsStreaming & {\n context_management?: AnthropicContextManagement\n speed?: 'fast' | 'standard'\n // `task_budget` shipped after the pinned SDK's `OutputConfig` type;\n // widen until the SDK catches up.\n output_config?: { task_budget?: { type: 'tokens', total: number } }\n}\n\n/** Per-call decisions the request body is shaped by (resolved before the client is built). */\nexport interface AnthropicRequestInput {\n anthropicParams: AnthropicParams | undefined\n bedrockConfig: AnthropicBedrockConfig | undefined\n options: StreamOptions\n callIsOAuth: boolean\n effectiveCacheTtl: CacheTtl | undefined\n extendedTtl: boolean\n plan: AnthropicThinkingPlan | null\n thinkingBinding: ThinkingBindingBehavior\n bindingActive: boolean\n resolvedExtraHeaders: Record<string, string> | undefined\n}\n\n/** The built request plus the request-local state the response path needs. */\nexport interface AnthropicStreamRequest {\n params: AnthropicStreamParams\n nameBoundary: ToolNameBoundary\n modelId: Model\n affinityHeader: Record<string, string> | undefined\n}\n\n/**\n * Build the Messages request body for one `stream()` call: system block (and\n * the OAuth persona fold), tool-name boundary, max-output resolution, cache\n * breakpoints, thinking shape, Claude Code alignment, fast mode, tool choice,\n * and the prompt-cache affinity key/header.\n */\nexport async function buildAnthropicStreamRequest(input: AnthropicRequestInput): Promise<AnthropicStreamRequest> {\n const { anthropicParams, bedrockConfig, options, callIsOAuth, effectiveCacheTtl, extendedTtl, plan, thinkingBinding, bindingActive, resolvedExtraHeaders } = input\n // System prompt injection is handled by agent.ts — we just pass it through.\n // For OAuth, the Claude Code API requires the system block to start with\n // the canonical Claude Code prompt — we prepend it to the real system prompt.\n // For OAuth, the CC API requires the system block to start with the canonical\n // Claude Code prompt. The real system prompt is injected as user+assistant messages.\n //\n // The boundary marker (`SYSTEM_PROMPT_BOUNDARY`) is structural metadata\n // for `applyAnthropicCacheBreakpoints`; strip it before the bytes hit\n // the wire so it never reaches the model. The original (un-rendered)\n // string is preserved as `options.system` and forwarded to the cache\n // helper below for an accurate static/dynamic split.\n const { system, messages } = foldSystemForWire(options.system, options.messages, callIsOAuth)\n\n // Request-local tool-name boundary. The tools array is normally clean\n // (agent aliasing + `sanitizeToolSpecs` ran upstream), but REPLAYED\n // HISTORY can carry names the current alias maps never saw — sessions\n // imported from other clients, renamed MCP servers, removed tools. The\n // Anthropic-family endpoints (direct API, Bedrock Converse, compatible\n // gateways) validate historical `toolUse.name` against\n // `[a-zA-Z0-9_-]{1,64}` as strictly as the tools array, so one stale\n // name 400s the whole request. Offender-only: clean requests are\n // byte-identical and the prompt cache is unaffected.\n const inputTools = (options.tools ?? []) as Anthropic.ToolUnion[]\n const nameBoundary = createToolNameBoundary(\n messages,\n inputTools.map(t => t.name),\n callIsOAuth ? claudeCodeToolAliases : undefined,\n )\n // Renaming only touches genuine offenders — always plain custom tools\n // (server-tool names like `web_search` are wire-legal by construction),\n // so widening the spread back to the union member is safe.\n const wireTools = nameBoundary.changed\n ? inputTools.map(t => (t.name === nameBoundary.toWire(t.name) ? t : { ...t, name: nameBoundary.toWire(t.name) } as Anthropic.ToolUnion))\n : inputTools\n\n const modelId = options.model as Model\n // The model's max output, sourced from pi-ai's registry (Opus 4.x = 128K\n // native; conservative family fallback when the registry misses). Used as\n // BOTH the default (when `maxTokens` is unset — the field is required) AND\n // a hard clamp, since a value above the model's max would 400. An explicit\n // caller maxTokens RAISES the fallback for registry-unknown models (never\n // lowers it — see the resolver's docblock: the thinking budget sits on top\n // of the caller's cap, so the cap can't double as the ceiling).\n const modelMaxOutput = await resolveAnthropicMaxOutput(modelId, options.maxTokens, options.modelCatalog)\n\n // `context_management` is an untyped beta in SDK v0.90; widen `params` with\n // an optional field so we don't have to double-cast through `unknown` to\n // attach it below.\n const params: AnthropicStreamParams = {\n // Forward-compat escape hatch for un-typed beta fields. Spread first so\n // the typed core (model / max_tokens / system / tools / messages /\n // stream) and the explicit `context_management` below override on\n // collision — explicit always wins.\n ...((anthropicParams?.extraBodyParams ?? {}) as Record<string, unknown>),\n model: modelId,\n // Required field — default to the model's full max output when unset.\n // The ceiling (incl. a caller cap above the model max) is enforced once,\n // after the thinking plan, since the `enabled` path adds budget on top.\n max_tokens: options.maxTokens ?? modelMaxOutput,\n system,\n tools: wireTools,\n messages: nameBoundary.messages.map(m => toAnthropic(m)) as Anthropic.MessageParam[],\n stream: true,\n }\n\n // Server-side context management (beta `context-management-2025-06-27`).\n // Skipped when the caller didn't pass a config — leaving the field off\n // the wire keeps requests valid on accounts that don't have the beta enabled.\n //\n // Also skipped on Bedrock: its translation layer rejects the field (same\n // API generation as `output_config`, which it 400s with \"Extra inputs are\n // not permitted\"). Dropping a request-shaping option we know will fail is\n // what this file does elsewhere for locally-predictable 400s (the thinking\n // budget clamp, the effort-surface swap); shipping it instead would\n // guarantee the failure.\n if (anthropicParams?.contextManagement && !bedrockConfig)\n params.context_management = anthropicParams.contextManagement\n\n // Prompt caching — inject `cache_control: { type: 'ephemeral' }` breakpoints\n // on the three largest stable prefixes: system prompt, tool definitions, and\n // the last message's final content block. Three of Anthropic's four allowed\n // breakpoints; leaves headroom for a future thinking-block breakpoint.\n //\n // On the API-key path, `params.system` was derived from\n // `renderSystemForWire(options.system)` so the cache helper can split\n // the original on the `SYSTEM_PROMPT_BOUNDARY` marker and apply\n // `cache_control` to the static prefix only — per-turn churn in the\n // dynamic suffix no longer invalidates the cached doctrine above.\n //\n // On the OAuth path, `params.system` is the canonical Claude Code\n // prompt (`\"You are Claude Code...\"`) — `options.system` lives in the\n // injected user message instead, so we do NOT forward it here. Passing\n // it would replace the CC prompt with the user's doctrine. The user\n // message is still naturally cached via the last-message breakpoint\n // applied below; per-turn churn there bypasses the boundary feature on\n // OAuth, but parity with the pre-feature behavior is preserved.\n //\n // Skipped when `options.cache === false` (opt-out) or on any shape that would\n // produce an invalid request (empty system string, zero tools, empty message list).\n if (options.cache !== false)\n applyAnthropicCacheBreakpoints(params, callIsOAuth ? undefined : options.system, extendedTtl ? effectiveCacheTtl : undefined)\n\n // Enable thinking / extended thinking when requested. The default path\n // for level-based control is `thinking.type='adaptive'` plus an\n // `output_config.effort` hint — Anthropic deprecated the explicit\n // `thinking.type='enabled' + budget_tokens` shape on opus 4.6+ and\n // recommends adaptive instead. Callers who need a precise token budget\n // can opt into the explicit-budget path by setting\n // `behavior.thinkingBudget`, accepting Anthropic's deprecation\n // warning in exchange. Either shape requires `temperature=1`.\n //\n // `display: 'summarized'` is set explicitly on both shapes — Opus 4.7\n // and Claude Mythos Preview silently flipped the default to\n // `'omitted'` (signature-only, no text), which makes the SDK fire\n // `thinking` deltas with empty `thinking` content and breaks every\n // host that surfaces traces live. Older models still default to\n // `'summarized'` so this is a no-op there.\n applyAnthropicThinkingPlan(params, plan, bedrockConfig, bindingActive, thinkingBinding)\n\n // The `enabled` thinking path adds the budget ON TOP of `max_tokens`,\n // which — now that the base defaults to the model's full max — can push\n // the envelope past the model's hard ceiling → 400. Clamp the final value\n // so the budget shares the envelope rather than overflowing it.\n params.max_tokens = Math.min(params.max_tokens, modelMaxOutput)\n\n // Claude Code payload alignment. Applied after every other mutation so\n // nothing downstream reshapes what the attestation will be hashed over.\n if (callIsOAuth)\n alignClaudeCodePayload(params)\n\n fitThinkingBudgetUnderEnvelope(params)\n\n // Fast mode (`speed: \"fast\"`) — ~2.5× output throughput at premium\n // pricing. Supported only on the models in `FAST_MODE_OPTIONS`\n // (chat/anthropic-models.ts); the model-options surface only offers it\n // on those, and Anthropic 400s a request with\n // `speed` on an unsupported model. `speed` is an untyped beta field in\n // SDK v0.90 (widened on `params` above).\n //\n // NOT sent on subscription OAuth: fast mode bills against PURCHASED usage\n // credits, not the plan's included allowance, so Anthropic refuses it with\n // `Usage credits are required for fast mode` (429) — surfaced in the TUI as\n // \"You're out of extra usage\" — for every subscription user who has not\n // topped up, no matter how much included allowance remains. Live-verified:\n // the identical request returns 200 without `speed` and is refused with\n // it. Dropping the field degrades to standard throughput, which is the\n // only thing that can actually run on that credential.\n if (options.modelOptions?.fast && !callIsOAuth)\n params.speed = 'fast'\n\n // Tool choice forcing. The forced name must match the (possibly\n // boundary-renamed) name in the tools array, mirroring openai-compat.\n if (options.toolChoice) {\n if (options.toolChoice.type === 'tool' && options.toolChoice.name)\n params.tool_choice = { type: 'tool', name: nameBoundary.toWire(options.toolChoice.name) }\n else if (options.toolChoice.type === 'required')\n params.tool_choice = { type: 'any' }\n else\n params.tool_choice = { type: 'auto' }\n }\n\n // Prompt-cache affinity key, carried as `metadata.user_id`. Derived from\n // the session's stable prefix, so it is byte-identical across a session's\n // turns and cannot itself break a cache. Merged onto any `metadata` the\n // caller passed via `extraBodyParams` (spread first above) rather than\n // clobbering it, and a caller- or gateway-supplied `user_id` always wins:\n // an intermediary that sets this itself must not be second-guessed.\n //\n // `options.system` is used for the derivation on BOTH auth paths, not\n // `params.system` — on OAuth the latter is the canonical Claude Code\n // prompt, identical across every session, which would collapse all\n // sessions onto one key.\n const promptCacheKey = resolvePromptCacheKey(anthropicParams?.promptCacheKey, {\n model: modelId,\n system: options.system,\n messages: options.messages,\n })\n if (promptCacheKey !== undefined && params.metadata?.user_id === undefined)\n params.metadata = { ...params.metadata, user_id: promptCacheKey }\n\n // HTTP header names are case-insensitive (and the SDK merges per-request\n // headers over `defaultHeaders` case-insensitively), so the no-clobber\n // probe must be too — an exact-key check would let the affinity header\n // silently beat a differently-cased caller header from `extraHeaders`.\n const affinityHeaderName = anthropicParams?.promptCacheKeyHeader?.toLowerCase()\n const affinityHeader = anthropicParams?.promptCacheKeyHeader !== undefined && promptCacheKey !== undefined\n && !Object.keys(resolvedExtraHeaders ?? {}).some(k => k.toLowerCase() === affinityHeaderName)\n ? { [anthropicParams.promptCacheKeyHeader]: promptCacheKey }\n : undefined\n\n return { params, nameBoundary, modelId, affinityHeader }\n}\n\n/** Set the thinking fields (and the max-tokens/temperature they imply) from the plan. */\nfunction applyAnthropicThinkingPlan(\n params: AnthropicStreamParams,\n plan: AnthropicThinkingPlan | null,\n bedrockConfig: AnthropicBedrockConfig | undefined,\n bindingActive: boolean,\n thinkingBinding: ThinkingBindingBehavior,\n): void {\n if (plan && bedrockConfig) {\n // Bedrock's translation layer predates the 4.6 thinking surface:\n // `output_config.effort` is rejected with \"Extra inputs are not\n // permitted\" (live-verified), and `thinking.type='adaptive'` /\n // `display` are the same API generation — so every level routes\n // through the legacy explicit-budget shape Bedrock documents. The\n // effort tier picks the budget; an explicit `thinkingBudget` wins.\n const budget = plan.kind === 'enabled'\n ? plan.budgetTokens\n : BEDROCK_THINKING_BUDGETS[plan.effort ?? 'medium']\n params.thinking = { type: 'enabled', budget_tokens: budget }\n // Budget rides on top of the response cap, clamped to the model\n // ceiling below like the standard `enabled` path.\n params.max_tokens = budget + params.max_tokens\n params.temperature = 1\n }\n else if (plan) {\n if (plan.kind === 'enabled') {\n params.thinking = { type: 'enabled', budget_tokens: plan.budgetTokens, display: 'summarized' }\n params.max_tokens = plan.maxTokensBump + params.max_tokens\n // The explicit budget pins tokens; the effort hint still shapes HOW\n // the model spends them. Both fields are valid together on 4.6+.\n // Merge onto any `output_config` the caller passed via\n // `extraBodyParams` (spread first above) rather than clobbering it.\n if (plan.effort)\n params.output_config = { ...params.output_config, effort: plan.effort }\n }\n else {\n params.thinking = { type: 'adaptive', display: 'summarized' }\n const outputConfig: NonNullable<typeof params.output_config> = {}\n if (plan.effort)\n outputConfig.effort = plan.effort\n // Native whole-task thinking cap — adaptive-only. Coexists with the\n // effort hint.\n if (typeof plan.taskBudgetTokens === 'number' && plan.taskBudgetTokens > 0)\n outputConfig.task_budget = { type: 'tokens', total: plan.taskBudgetTokens }\n // Merge onto any caller-supplied `output_config` from\n // `extraBodyParams`; don't drop their fields.\n if (Object.keys(outputConfig).length > 0)\n params.output_config = { ...params.output_config, ...outputConfig }\n // LEGACY (`thinkingBudget` on adaptive): soft-cap the response\n // envelope (`max_tokens`). This clamps text and tool-call JSON too —\n // prefer `taskBudget` above. Reduce only; never raise above the\n // caller's request.\n if (typeof plan.maxTokensCap === 'number' && plan.maxTokensCap > 0)\n params.max_tokens = Math.min(params.max_tokens, plan.maxTokensCap)\n }\n params.temperature = 1\n // Preserved-thinking prefix binding — see `AnthropicParams.thinkingBinding`.\n // The SDK's `ThinkingConfigParam` predates the field; widen locally.\n if (bindingActive) {\n (params.thinking as unknown as Record<string, unknown>).block_binding = {\n prefix_mismatch_behavior: thinkingBinding,\n }\n }\n }\n}\n\n/** Claude Code payload alignment for the OAuth persona (output cap, billing block, `user_id`). */\nfunction alignClaudeCodePayload(params: AnthropicStreamParams): void {\n // The client caps requested output at 64k even where the model allows\n // more (Opus permits 128k), so a larger ceiling is a shape no real\n // client sends.\n params.max_tokens = Math.min(params.max_tokens, CLAUDE_CODE_MAX_OUTPUT_TOKENS)\n // Billing block goes at system[0], ahead of the persona marker. Its\n // `cch` placeholder is filled in by the wrapped fetch once the body is\n // serialized — the hash covers those bytes, so it cannot be computed\n // here.\n if (Array.isArray(params.system)) {\n params.system = [\n { type: 'text', text: claudeCodeBillingText(firstUserMessageText(params.messages)) },\n ...params.system,\n ]\n }\n // Never clobber a caller-set `user_id`: `promptCacheKey` writes the same\n // field and its routing intent outranks fingerprint parity.\n const metadata = params.metadata as { user_id?: unknown } | undefined\n if (typeof metadata?.user_id !== 'string')\n params.metadata = { ...params.metadata, user_id: claudeCodeUserId() }\n}\n\n// Anthropic requires `thinking.budget_tokens` STRICTLY below\n// `max_tokens` (400 otherwise — live-verified on Bedrock, where every\n// level routes through the explicit-budget shape and a mid-tier budget\n// already exceeds a haiku-class 8K ceiling; the direct API has the\n// same failure with a caller `thinkingBudget` above the ceiling).\n// After the envelope clamp above, shrink the budget to fit, reserving\n// room for the visible response. When even Anthropic's documented\n// 1024-token budget minimum can't fit under the envelope, no\n// satisfiable budget exists — degrade to a non-thinking request\n// (dropping the temperature pin the thinking branch set; nothing else\n// sets it) rather than shipping a 400 we can predict locally.\nfunction fitThinkingBudgetUnderEnvelope(params: AnthropicStreamParams): void {\n if (params.thinking?.type === 'enabled' && params.thinking.budget_tokens >= params.max_tokens) {\n const fitted = params.max_tokens - THINKING_RESPONSE_RESERVE_TOKENS\n if (fitted >= 1024) {\n params.thinking.budget_tokens = fitted\n }\n else {\n delete params.thinking\n delete params.temperature\n }\n }\n}\n","import type Anthropic from '@anthropic-ai/sdk'\n\n/**\n * Hard cap on signature-400 scrub retries within one `stream()` call. Two\n * passes resolve every real-world shape (bounded pass, then the\n * everything-but-active-chain pass); the third is margin. Beyond that the\n * error is not signature poisoning and must surface.\n */\nexport const MAX_THINKING_SCRUB_PASSES = 3\n\n/**\n * Models observed rejecting forced tool use, so later calls skip straight to\n * the downgraded shape instead of paying the failing round-trip every time.\n *\n * Learned, not declared: Claude Fable 5.1 is the first model where\n * `tool_choice` of `tool` / `any` returns 400, and a catalog flag would need\n * upkeep for every successor that follows suit. Process-wide and keyed by\n * model id only — whether a model accepts forcing is a property of the model,\n * not of the endpoint or credential serving it.\n */\nexport const MODELS_REJECTING_FORCED_TOOL_CHOICE = new Set<string>()\n\n/** The same request with `thinking.block_binding` removed. */\nexport function withoutThinkingBinding<P extends Anthropic.MessageCreateParams>(params: P): P {\n if (!params.thinking)\n return params\n const { block_binding: _dropped, ...thinking } = params.thinking as unknown as Record<string, unknown>\n return { ...params, thinking: thinking as unknown as Anthropic.ThinkingConfigParam }\n}\n\nexport function isForcedToolChoice(choice: Anthropic.MessageCreateParams['tool_choice']): boolean {\n return choice?.type === 'tool' || choice?.type === 'any'\n}\n\n/**\n * Models observed rejecting the explicit-budget thinking shape\n * (`thinking: { type: 'enabled', budget_tokens }`), so later calls skip the\n * failing round-trip and downgrade to adaptive up front.\n *\n * Learned, not declared — same rationale as\n * {@link MODELS_REJECTING_FORCED_TOOL_CHOICE}. Claude Opus 5.5 is the first\n * model where the `enabled` shape 400s (adaptive-only, thinking always on);\n * successors that follow suit are caught without a catalog edit.\n */\nexport const MODELS_REJECTING_ENABLED_THINKING = new Set<string>()\n\nexport function isEnabledThinking(thinking: Anthropic.MessageCreateParams['thinking']): boolean {\n return thinking?.type === 'enabled'\n}\n\n/**\n * The same request with the explicit budget dropped: `thinking.type` flipped to\n * `adaptive`, `budget_tokens` removed, every other thinking field\n * (`display`, `block_binding`) kept. `temperature` stays pinned to 1 (adaptive\n * requires it, same as the enabled shape) and the budget-inflated `max_tokens`\n * is left as-is — it is already clamped to the model ceiling and an oversized\n * envelope is harmless for adaptive, which thinks and replies inside it. Any\n * `output_config.effort` the enabled path set survives on `params.output_config`.\n */\nexport function withoutEnabledThinking<P extends Anthropic.MessageCreateParams>(params: P): P {\n const thinking = params.thinking as unknown as Record<string, unknown> | undefined\n if (!thinking || thinking.type !== 'enabled')\n return params\n const { budget_tokens: _dropped, type: _type, ...rest } = thinking\n return {\n ...params,\n thinking: { ...rest, type: 'adaptive' } as unknown as Anthropic.ThinkingConfigParam,\n }\n}\n\n/**\n * The same request with forcing removed: `tool_choice: auto` plus one trailing\n * system sentence naming what the model was being forced into.\n *\n * The sentence is load-bearing, not decoration. `enforceSchemaOutput` sends the\n * agent's own system prompt, which says nothing about `__output__` — forcing\n * was the whole instruction — so without it a model on `auto` can legitimately\n * answer in prose and the caller's \"no structured payload\" guard fires. It is\n * appended as a final uncached block: everything before it keeps its cache\n * prefix, and the downgrade adds no new breakpoint.\n */\nexport function withoutForcedToolChoice<P extends Anthropic.MessageCreateParams>(params: P): P {\n const choice = params.tool_choice\n const nudge = choice?.type === 'tool'\n ? `Respond only by calling the \\`${choice.name}\\` tool. Do not reply with prose.`\n : 'Respond only by calling one of the provided tools. Do not reply with prose.'\n const system: Anthropic.MessageCreateParams['system'] = typeof params.system === 'string'\n ? (params.system.length > 0 ? `${params.system}\\n\\n${nudge}` : nudge)\n : [...(params.system ?? []), { type: 'text', text: nudge }]\n return { ...params, system, tool_choice: { type: 'auto' } }\n}\n\n/**\n * Wire index where the ACTIVE chain begins: the last user message that\n * carries real user content (string content, or any non-tool_result\n * block). Everything from there onward is the current prompt plus the\n * in-flight assistant/tool exchange — its thinking blocks were minted by\n * this very call chain and Anthropic requires them to be echoed back, so\n * escalated scrubs must never cross this boundary. `undefined` when no\n * such message exists (degenerate resume shapes) — callers treat that as\n * \"no protected region\".\n */\nfunction activeChainScrubBoundary(messages: Anthropic.MessageParam[]): number | undefined {\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i]\n if (message?.role !== 'user')\n continue\n if (typeof message.content === 'string')\n return i\n if (message.content.some(block => block.type !== 'tool_result'))\n return i\n }\n return undefined\n}\n\n/**\n * Decide what a scrub pass may touch. The bound NEVER crosses into the\n * active chain wholesale — not even on pass 0 with no parseable locator\n * (an unbounded first pass would strip the in-flight chain's thinking and\n * trade a recoverable 400 for an \"expected thinking block\" one). When the\n * API-reported failing index lies INSIDE the chain, only that single\n * message is scrubbed on top of the pre-chain region: the block the API\n * itself rejected fails whether or not it is echoed, but sibling chain\n * messages below it may hold still-valid thinking the exchange requires.\n *\n * - pass 0 with a pre-chain locator → bounded at the locator (preserves\n * later, still-valid historical thinking).\n * - pass 0 without a locator, and every escalated pass → the full\n * pre-chain history.\n * - no active chain at all (degenerate resume shapes) → locator bound on\n * pass 0, full history afterwards.\n */\nexport function planThinkingScrub(\n scrubPass: number,\n failingIndex: number | undefined,\n messages: Anthropic.MessageParam[],\n): { upToIndex?: number, alsoMessageIndex?: number } {\n const chainStart = activeChainScrubBoundary(messages)\n if (chainStart === undefined) {\n return scrubPass === 0 && failingIndex !== undefined\n ? { upToIndex: failingIndex }\n : {} // no protected region — scrub the full history\n }\n const beforeChain = chainStart - 1\n const inChain = failingIndex !== undefined && failingIndex >= chainStart\n const upToIndex = scrubPass === 0 && failingIndex !== undefined && !inChain\n ? failingIndex\n : beforeChain\n return inChain ? { upToIndex, alsoMessageIndex: failingIndex } : { upToIndex }\n}\n\n/**\n * Remove opaque historical Anthropic reasoning from a retry payload. Text,\n * tool calls/results, images, and every other block are preserved exactly.\n * If a message consisted only of reasoning, leave a neutral text marker so\n * the wire never receives an empty content array and conversation role\n * boundaries stay intact.\n *\n * `upToIndex` bounds the scrub to messages at/before the API-reported\n * failing index (see {@link parseFailingMessageIndex}); `undefined` strips\n * everywhere. `alsoMessageIndex` additionally scrubs that single message\n * beyond the bound (see {@link planThinkingScrub}). A later stale block\n * simply triggers the same recovery again — each pass removes at least\n * one block, so the recursion is bounded.\n */\nexport function withoutHistoricalThinking(\n messages: Anthropic.MessageParam[],\n upToIndex?: number,\n alsoMessageIndex?: number,\n): {\n messages: Anthropic.MessageParam[]\n removed: number\n} {\n let removed = 0\n const scrubbed = messages.map((message, index) => {\n if (upToIndex !== undefined && index > upToIndex && index !== alsoMessageIndex)\n return message\n if (!Array.isArray(message.content))\n return message\n const content = message.content.filter((block) => {\n if (block.type === 'thinking' || block.type === 'redacted_thinking') {\n removed += 1\n return false\n }\n return true\n })\n return {\n ...message,\n content: content.length > 0\n ? content\n : [{ type: 'text' as const, text: '[historical reasoning omitted]' }],\n }\n })\n return { messages: scrubbed, removed }\n}\n","/**\n * Raw control characters in streamed tool input.\n *\n * With fine-grained tool streaming (one of the Claude Code subscription\n * betas) the API streams a tool call's input JSON without validating it, so a\n * string value can carry a literal newline or tab. The SDK re-parses the\n * accumulated input on every `input_json_delta` with a strict `JSON.parse`,\n * which throws \"Bad control character in string literal\" and fails the whole\n * turn. Escaping those characters inside strings before the SDK sees the delta\n * yields the value the model meant.\n */\n\nimport { createToolJsonEscaper } from './tool-args'\n\ninterface StreamEventLike {\n type: string\n index?: number\n delta?: { type?: string, partial_json?: string }\n}\n\n/** The stream with every `input_json_delta` escaped; same object, so the SDK keeps its controller. */\nfunction escapingStream<T extends AsyncIterable<unknown>>(stream: T): T {\n const escape = createToolJsonEscaper()\n const events = stream[Symbol.asyncIterator].bind(stream)\n Object.defineProperty(stream, Symbol.asyncIterator, {\n configurable: true,\n async* value() {\n for await (const event of { [Symbol.asyncIterator]: events }) {\n const e = event as StreamEventLike\n if (e.type === 'content_block_delta' && e.delta?.type === 'input_json_delta' && typeof e.delta.partial_json === 'string')\n yield { ...e, delta: { ...e.delta, partial_json: escape(e.index ?? 0, e.delta.partial_json) } }\n else\n yield event\n }\n },\n })\n return stream\n}\n\ninterface MessagesLike {\n create: (...args: never[]) => unknown\n stream: (...args: never[]) => unknown\n}\n\n/**\n * `messages` whose `stream()` escapes tool-input control characters. The\n * SDK's `stream()` builds its `MessageStream` from `this.create(...)\n * .withResponse()`, so only `create` is replaced; everything else (client,\n * logger, headers, abort, `connect`) is the real one, through the prototype.\n * Pinned by a test against the real SDK, which fails if that changes.\n */\nexport function withToolJsonEscaping<M extends MessagesLike>(messages: M): M {\n const create = (...args: unknown[]): unknown => {\n const pending = (messages.create as (...a: unknown[]) => { withResponse: () => Promise<{ data: unknown }> })(...args)\n if (!(args[0] as { stream?: boolean } | undefined)?.stream)\n return pending\n return {\n ...pending,\n withResponse: async () => {\n const result = await pending.withResponse()\n return { ...result, data: escapingStream(result.data as AsyncIterable<unknown>) }\n },\n }\n }\n return Object.create(messages, { create: { value: create } }) as M\n}\n","/**\n * Anthropic models not (yet) bundled in `@earendil-works/pi-ai`'s registry.\n *\n * pi-ai ships a static price/metadata registry that lags new Anthropic\n * releases by a dep bump. Until the bump lands, list freshly-shipped models\n * here so they show in the picker, expose the reasoning knob, and get an\n * accurate cost estimate. Entries are merged ahead of pi-ai's list in\n * {@link modelsForDescriptor} and de-duped by id, so once pi-ai catches up\n * the bundled entry simply wins — and the entry here should be deleted.\n *\n * Fast-mode eligibility ({@link FAST_MODE_OPTIONS}) is NOT covered by the\n * registry and stays here permanently: pi-ai carries no `speed` metadata, so\n * every new Opus release needs its id added there by hand.\n */\n\nimport type { ModelInfo, ModelOption } from './providers'\n\n/**\n * Anthropic \"fast mode\" — `speed: \"fast\"` on the Messages API. ~2.5× output\n * tokens/sec at a per-model price multiplier. Supported on Opus 4.6 / 4.7 /\n * 4.8 / 5 / 5.5 only; the API errors if sent on any other model, so it's\n * attached just to those entries (see {@link FAST_MODE_OPTIONS}).\n *\n * The multiplier scales ALL rate components (input, output, and both cache\n * rates) uniformly: per Anthropic, \"prompt caching multipliers apply on top of\n * fast mode pricing\" across the full context window. Opus 5.5 ($4/$20 →\n * $8/$40), 5 and 4.8 ($5/$25 → $10/$50) are 2×; Opus 4.6 / 4.7 are a steeper\n * 6× ($5/$25 → $30/$150).\n * See https://platform.claude.com/docs/en/build-with-claude/fast-mode.\n */\nexport const FAST_MODE_OPTION: ModelOption = {\n id: 'fast',\n label: 'Fast mode',\n description: '~2.5× faster output at premium pricing',\n costMultiplier: { input: 2, output: 2, cacheRead: 2, cacheWrite: 2 },\n}\n\nconst FAST_MODE_OPTION_LEGACY: ModelOption = {\n ...FAST_MODE_OPTION,\n description: '~2.5× faster output at 6× pricing',\n costMultiplier: { input: 6, output: 6, cacheRead: 6, cacheWrite: 6 },\n}\n\n/** Model ids that accept `speed: \"fast\"`, mapped to their fast-mode option. */\nexport const FAST_MODE_OPTIONS: Readonly<Record<string, ModelOption>> = {\n 'claude-opus-5-5': FAST_MODE_OPTION,\n 'claude-opus-5': FAST_MODE_OPTION,\n 'claude-opus-4-8': FAST_MODE_OPTION,\n 'claude-opus-4-7': FAST_MODE_OPTION_LEGACY,\n 'claude-opus-4-6': FAST_MODE_OPTION_LEGACY,\n}\n\n/**\n * The price multiplier to apply to a model's base rates when fast mode is\n * active, or `undefined` when the model has no fast-mode pricing (i.e. doesn't\n * support it). Mirrors {@link FAST_MODE_OPTIONS} — kept as a separate accessor\n * so the cost layer can stay decoupled from the picker-facing option objects.\n */\nexport function fastModeCostMultiplier(modelId: string): ModelOption['costMultiplier'] {\n return FAST_MODE_OPTIONS[modelId]?.costMultiplier\n}\n\n/**\n * Currently empty: pi-ai 1.0.4 bundles every GA Anthropic model up to and\n * including Claude Sonnet 5.5 — Opus 4.8 / 5 / 5.5, Fable 5 / 5.1,\n * Sonnet 4.6 / 5 / 5.5, Haiku 4.5 — with published rates, 1M context and 128k output.\n *\n * When adding a stopgap entry, mirror pi-ai's `ModelInfo` shape and set\n * `provider: 'anthropic'`. Known caveats worth carrying over in the comment:\n * Fable 5 / 5.1 REJECT forced tool use (`tool_choice` of `any` or `tool`\n * returns 400), which breaks zidane's structured-output paths (`loop.ts`,\n * `generate-data.ts`, the eval judge) — Opus 5.5 rejects it too, handled\n * generically by the learned `MODELS_REJECTING_FORCED_TOOL_CHOICE` retry in\n * providers/anthropic.ts. Opus 5.5 also REJECTS non-adaptive thinking:\n * `thinking: {type:'enabled', budget_tokens}` and `{type:'disabled'}` both 400\n * with `\"thinking.type.enabled/disabled\" is not supported for this model`;\n * zidane's explicit-budget path (`behavior.thinkingBudget`, the Bedrock-only\n * shape) emits `enabled`, so the provider catches that 400 and retries as\n * adaptive (`MODELS_REJECTING_ENABLED_THINKING`). Claude Mythos 5 / 5.1 are\n * deliberately absent: invitation-only (Project Glasswing), so they would be\n * dead picker entries for virtually all users.\n *\n * See https://platform.claude.com/docs/en/about-claude/models/overview.\n */\nexport const ANTHROPIC_EXTRA_MODELS: readonly ModelInfo[] = []\n","import type Anthropic from '@anthropic-ai/sdk'\nimport type { TurnFinishReason, TurnUsage } from '../types'\nimport type { CostMultiplier } from './cost'\nimport type { ModelCatalog } from './model-catalog'\nimport { fastModeCostMultiplier } from '../chat/anthropic-models'\nimport { fillEstimatedCost } from './cost'\n\n/**\n * Map Anthropic's native `stop_reason` to the zidane `TurnFinishReason` union.\n *\n * `pause_turn` and `model_context_window_exceeded` are 4.6+ stop reasons that\n * pre-Z21 collapsed to `'other'` and silently terminated the run. They now\n * map to `'pause'` and `'length'` respectively, and the surrounding caller\n * adjusts the `done` flag so the loop can recover.\n */\nexport function mapStopReason(stopReason: string | null | undefined): TurnFinishReason | undefined {\n if (!stopReason)\n return undefined\n switch (stopReason) {\n case 'end_turn':\n case 'stop_sequence':\n return 'stop'\n case 'tool_use':\n return 'tool-calls'\n case 'max_tokens':\n case 'model_context_window_exceeded':\n // 4.6+: response bumped against the model's context window mid-stream.\n // Treat as a length-class stop so consumers can prune + retry; the\n // partial assistant response is preserved.\n return 'length'\n case 'refusal':\n return 'content-filter'\n // 4.6+: server-side mid-turn pause for long thinking. The loop\n // continues with a synthetic continue message rather than terminating.\n case 'pause_turn':\n return 'pause'\n default:\n return 'other'\n }\n}\n\n/**\n * Anthropic bills a 1h-TTL cache write at 2× base input against 1.25× for the\n * default 5m TTL, but `cache_creation_input_tokens` (what `TurnUsage.\n * cacheCreation` carries) is the SUM of both buckets. Registry `cacheWrite`\n * rates are the 5m rate, so a turn that wrote under `ttl: '1h'` needs its\n * write component scaled by `(5m·1.25 + 1h·2) / (total·1.25)`. `1` when the\n * response carries no split (Bedrock, older API versions) or no 1h writes.\n */\nconst CACHE_WRITE_1H_OVER_5M = 2 / 1.25\n\nexport function cacheWriteTtlMultiplier(usage: {\n cache_creation_input_tokens?: number | null\n cache_creation?: { ephemeral_5m_input_tokens?: number, ephemeral_1h_input_tokens?: number } | null\n}): number {\n const split = usage.cache_creation\n const oneHour = split?.ephemeral_1h_input_tokens ?? 0\n if (oneHour <= 0)\n return 1\n const fiveMin = split?.ephemeral_5m_input_tokens ?? 0\n const total = usage.cache_creation_input_tokens ?? (fiveMin + oneHour)\n if (total <= 0)\n return 1\n return (fiveMin + oneHour * CACHE_WRITE_1H_OVER_5M) / total\n}\n\n/** Per-rate product of two multipliers; a missing key on either side is `1`. */\nfunction composeCostMultipliers(a: CostMultiplier | undefined, b: CostMultiplier | undefined): CostMultiplier | undefined {\n if (!a)\n return b\n if (!b)\n return a\n return {\n input: (a.input ?? 1) * (b.input ?? 1),\n output: (a.output ?? 1) * (b.output ?? 1),\n cacheRead: (a.cacheRead ?? 1) * (b.cacheRead ?? 1),\n cacheWrite: (a.cacheWrite ?? 1) * (b.cacheWrite ?? 1),\n }\n}\n\n/**\n * Price an API-key (non-OAuth) turn.\n *\n * - Bedrock traffic is looked up under pi-ai's `amazon-bedrock` registry: the\n * echoed ids (`global.anthropic.claude-…`, `eu.anthropic.…`) never appear\n * under `anthropic`, and Bedrock's regional uplifts only exist there.\n * - The API may echo a dated snapshot for an alias request (`claude-haiku-4-5`\n * → `claude-haiku-4-5-20251001`). Rates and the fast-mode multiplier are\n * resolved by the echoed id first, then by the REQUESTED id, so a snapshot\n * the registry doesn't list yet is still priced (and a fast-mode Opus turn\n * keeps its 2× instead of silently billing at base). The echoed id stays on\n * the record — only the price falls back.\n * - 1h cache writes are scaled to their real rate (see\n * {@link cacheWriteTtlMultiplier}); fast mode composes on top.\n */\nexport async function priceAnthropicUsage(\n raw: TurnUsage,\n response: Pick<Anthropic.Message, 'usage'>,\n requestedModelId: string,\n fastRequested: boolean,\n bedrock: boolean,\n catalog: ModelCatalog | undefined,\n): Promise<TurnUsage> {\n const providerKey = bedrock ? 'amazon-bedrock' : 'anthropic'\n const echoedModelId = raw.modelId ?? requestedModelId\n const fast = fastRequested\n ? (fastModeCostMultiplier(echoedModelId) ?? fastModeCostMultiplier(requestedModelId))\n : undefined\n const ttl = cacheWriteTtlMultiplier(response.usage)\n const multiplier = composeCostMultipliers(fast, ttl === 1 ? undefined : { cacheWrite: ttl })\n\n const priced = await fillEstimatedCost(raw, providerKey, multiplier, catalog)\n if (priced.cost !== undefined || echoedModelId === requestedModelId)\n return priced\n const byRequested = await fillEstimatedCost({ ...raw, modelId: requestedModelId }, providerKey, multiplier, catalog)\n return byRequested.cost !== undefined ? { ...raw, cost: byRequested.cost } : raw\n}\n","export type ProviderDiagnosticStage = 'credentials' | 'refresh' | 'shared-refresh' | 'prepare' | 'dispatch' | 'response-headers' | 'first-activity' | 'stream' | 'transport'\nexport type ProviderDiagnosticEvent = 'start' | 'end' | 'waiting' | 'success' | 'abort' | 'failure'\n\ninterface DiagnosticMetadata {\n httpStatus?: unknown\n upstreamRequestId?: unknown\n transportAttempt?: unknown\n networkCode?: unknown\n retryAfter?: unknown\n}\n\nconst NETWORK_CODES = new Set(['ECONNREFUSED', 'ECONNRESET', 'ETIMEDOUT', 'ENOTFOUND', 'EAI_AGAIN', 'ENETUNREACH', 'EHOSTUNREACH', 'EPIPE', 'UND_ERR_CONNECT_TIMEOUT', 'UND_ERR_HEADERS_TIMEOUT', 'UND_ERR_SOCKET', 'CERT_HAS_EXPIRED', 'DEPTH_ZERO_SELF_SIGNED_CERT', 'UNABLE_TO_VERIFY_LEAF_SIGNATURE', 'ERR_TLS_CERT_ALTNAME_INVALID', 'AbortError', 'TimeoutError'])\n\nexport function sanitizeProviderDiagnosticMetadata(metadata: DiagnosticMetadata) {\n const safe: { httpStatus?: number, upstreamRequestId?: string, transportAttempt?: number, networkCode?: string, retryAfter?: string } = {}\n if (typeof metadata.transportAttempt === 'number' && Number.isSafeInteger(metadata.transportAttempt) && metadata.transportAttempt > 0)\n safe.transportAttempt = metadata.transportAttempt\n if (typeof metadata.networkCode === 'string' && NETWORK_CODES.has(metadata.networkCode))\n safe.networkCode = metadata.networkCode\n if (typeof metadata.httpStatus === 'number' && Number.isInteger(metadata.httpStatus) && metadata.httpStatus >= 100 && metadata.httpStatus <= 599)\n safe.httpStatus = metadata.httpStatus\n if (typeof metadata.upstreamRequestId === 'string' && metadata.upstreamRequestId.length <= 128 && /^req_[\\w-]+$/.test(metadata.upstreamRequestId))\n safe.upstreamRequestId = metadata.upstreamRequestId\n const retryAfter = metadata.retryAfter\n if (typeof retryAfter === 'string' && retryAfter.length <= 32\n && (/^\\d+(?:\\.\\d+)?$/.test(retryAfter)\n || (retryAfter.length === 29 && new Date(retryAfter).toUTCString() === retryAfter))) {\n safe.retryAfter = retryAfter\n }\n return safe\n}\n\nexport interface ProviderDiagnostic {\n requestId: string\n stage: ProviderDiagnosticStage\n event: ProviderDiagnosticEvent\n elapsedMs: number\n stageElapsedMs: number\n attempt: number\n httpStatus?: number\n upstreamRequestId?: string\n transportAttempt?: number\n networkCode?: string\n retryAfter?: string\n}\n\n/** No request or error objects cross this boundary. Diagnostics cannot fail a request. */\nexport function createProviderDiagnosticTracker(emit?: (event: ProviderDiagnostic) => void, signal?: AbortSignal) {\n const requestId = crypto.randomUUID()\n const started = performance.now()\n let stageStarted = started\n let current: ProviderDiagnosticStage | undefined\n let attempt = 0\n let transportAttempt = 0\n let finished = false\n let timer: ReturnType<typeof setInterval> | undefined\n let abort = () => {}\n function send(event: ProviderDiagnosticEvent, metadata: { httpStatus?: unknown, upstreamRequestId?: unknown } = {}) {\n if (!current)\n return\n const now = performance.now()\n try {\n emit?.({ requestId, stage: current, event, elapsedMs: Math.round(now - started), stageElapsedMs: Math.round(now - stageStarted), attempt, ...sanitizeProviderDiagnosticMetadata(metadata) })\n }\n catch {}\n }\n const tracker = {\n wrapFetch(fetch: typeof globalThis.fetch): typeof globalThis.fetch {\n if (!emit)\n return fetch\n return Object.assign(async (...args: Parameters<typeof fetch>) => {\n const number = ++transportAttempt\n const began = performance.now()\n const report = (event: ProviderDiagnosticEvent, metadata: DiagnosticMetadata = {}) => {\n try {\n emit({ requestId, stage: 'transport', event, elapsedMs: Math.round(performance.now() - started), stageElapsedMs: Math.round(performance.now() - began), attempt, ...sanitizeProviderDiagnosticMetadata({ ...metadata, transportAttempt: number }) })\n }\n catch {}\n }\n report('start')\n try {\n const response = await fetch(...args)\n report('end', { httpStatus: response.status, upstreamRequestId: response.headers.get('request-id'), retryAfter: response.headers.get('retry-after') })\n return response\n }\n catch (error) {\n const err = error as { code?: unknown, name?: unknown, cause?: { code?: unknown } } | null\n const code = [err?.cause?.code, err?.code, err?.name].find(value => typeof value === 'string' && NETWORK_CODES.has(value))\n report('failure', { networkCode: code })\n throw error\n }\n }, fetch)\n },\n stage(stage: ProviderDiagnosticStage, metadata: { httpStatus?: unknown, upstreamRequestId?: unknown } = {}) {\n if (!emit || finished)\n return\n if (current)\n send('end')\n current = stage\n stageStarted = performance.now()\n if (stage === 'dispatch')\n attempt++\n send('start', metadata)\n if (timer)\n clearInterval(timer)\n timer = setInterval(send, 30_000, 'waiting')\n timer.unref?.()\n if (signal?.aborted)\n abort()\n },\n finish(event: 'success' | 'abort' | 'failure', metadata: { httpStatus?: unknown, upstreamRequestId?: unknown } = {}) {\n if (!emit || finished)\n return\n finished = true\n clearInterval(timer)\n signal?.removeEventListener('abort', abort)\n if (current) {\n send('end')\n send(event, metadata)\n }\n },\n }\n abort = () => tracker.finish('abort')\n if (emit)\n signal?.addEventListener('abort', abort, { once: true })\n return tracker\n}\n","import type Anthropic from '@anthropic-ai/sdk'\nimport type { MessageStream } from '@anthropic-ai/sdk/lib/MessageStream'\nimport type { InputTransformation, StreamCallbacks, StreamOptions, TurnResult } from '.'\nimport type { StreamUsageSnapshot, TurnUsage } from '../types'\nimport type { AnthropicInstance } from './anthropic-client'\nimport type { AnthropicBedrockConfig, AnthropicParams } from './anthropic-params'\nimport type { AnthropicRequestInput, AnthropicStreamParams, AnthropicStreamRequest } from './anthropic-request'\nimport type { extractRuntimeCredentials } from './oauth'\nimport { errorMessage } from '../errors'\nimport { fromAnthropic } from '../session/messages'\nimport { EXTENDED_CACHE_TTL_BETA } from './anthropic-cache'\nimport { createBedrockClient, createClient, credentialIdentity, FAST_MODE_BETA, loadAnthropicSdk, resolveAnthropicAuthShape, resolveExtraHeaders } from './anthropic-client'\nimport {\n isAnthropicAuthenticationError,\n isEnabledThinkingUnsupportedError,\n isForcedToolChoiceUnsupportedError,\n isPrefixMismatchError,\n isRecoverableThinkingBlockError,\n isThinkingBindingRejectedError,\n parseFailingMessageIndex,\n shouldFallbackFromFastMode,\n} from './anthropic-errors'\nimport { buildAnthropicStreamRequest } from './anthropic-request'\nimport {\n isEnabledThinking,\n isForcedToolChoice,\n MAX_THINKING_SCRUB_PASSES,\n MODELS_REJECTING_ENABLED_THINKING,\n MODELS_REJECTING_FORCED_TOOL_CHOICE,\n planThinkingScrub,\n withoutEnabledThinking,\n withoutForcedToolChoice,\n withoutHistoricalThinking,\n withoutThinkingBinding,\n} from './anthropic-retry'\nimport { planAnthropicThinking, resolveThinkingBinding, THINKING_BINDING_BETA } from './anthropic-thinking'\nimport { withToolJsonEscaping } from './anthropic-tool-json'\nimport { mapStopReason, priceAnthropicUsage } from './anthropic-usage'\nimport { createProviderDiagnosticTracker } from './diagnostic'\nimport { resolveOAuthApiKey } from './oauth'\n\n/** State one `anthropic()` provider instance shares across all of its calls. */\nexport interface AnthropicProviderState {\n anthropicParams: AnthropicParams | undefined\n bedrockConfig: AnthropicBedrockConfig | undefined\n runtimeCredentials: ReturnType<typeof extractRuntimeCredentials>\n /**\n * Set once this provider instance sees the endpoint reject the\n * preserved-thinking binding beta or field; every later request on the\n * instance skips both up front instead of paying the failing round-trip.\n * Per instance, not process-wide: acceptance is a property of the\n * endpoint + credential, and one process may hold several.\n */\n thinkingBindingRejected: boolean\n}\n\ntype ProviderDiagnosticTracker = ReturnType<typeof createProviderDiagnosticTracker>\n\n/** Per-call values that change while the call runs (OAuth stage callbacks, auth rotation). */\ninterface AnthropicCallLive {\n diagnosticActive: boolean\n apiKey: string\n}\n\ninterface AnthropicCallAuthContext {\n provider: AnthropicProviderState\n callbacks: StreamCallbacks\n diagnostic: ProviderDiagnosticTracker\n live: AnthropicCallLive\n}\n\n/** Everything resolved before the request body is built. `client` is replaced by auth/binding retries. */\ninterface AnthropicPreparedCall extends AnthropicCallAuthContext, AnthropicRequestInput {\n client: AnthropicInstance\n callAuth: { bearer: boolean, claudeCode: boolean }\n callCanRotateAuth: boolean\n baseConditionalBetas: string[]\n requestBetas: readonly string[] | undefined\n}\n\ntype AnthropicCall = AnthropicPreparedCall & Omit<AnthropicStreamRequest, 'params'>\n\n/** Stream-listener accumulators for one dispatched request. */\ninterface AnthropicTurnState {\n text: string\n observedOutput: boolean\n inputTransformations: InputTransformation[] | undefined\n}\n\nfunction isInputTransformation(value: unknown): value is InputTransformation {\n if (typeof value !== 'object' || value === null)\n return false\n const v = value as Record<string, unknown>\n return typeof v.type === 'string' && typeof v.path === 'string' && typeof v.reason === 'string'\n}\n\nfunction betasFor(anthropicParams: AnthropicParams | undefined, conditional: string[]): readonly string[] | undefined {\n return conditional.length > 0\n ? [...(anthropicParams?.extraBetas ?? []), ...conditional]\n : anthropicParams?.extraBetas\n}\n\n/** The `anthropic()` provider's `stream()`: prepare auth + client, build the request, run it. */\nexport async function streamAnthropic(\n provider: AnthropicProviderState,\n options: StreamOptions,\n callbacks: StreamCallbacks,\n): Promise<TurnResult> {\n const diagnostic = createProviderDiagnosticTracker(callbacks.onDiagnostic, options.signal)\n const live: AnthropicCallLive = { diagnosticActive: false, apiKey: '' }\n try {\n const prepared = await prepareAnthropicCall(provider, options, callbacks, diagnostic, live)\n const { params, nameBoundary, modelId, affinityHeader } = await buildAnthropicStreamRequest(prepared)\n const call: AnthropicCall = { ...prepared, nameBoundary, modelId, affinityHeader }\n const { callIsOAuth } = call\n\n // `fastRequested` drives the fast→standard downgrade retry, so it must\n // track whether `speed` actually reached the payload — on OAuth it never\n // does, and claiming otherwise would arm a fallback for a field we did\n // not send.\n let initialParams = isForcedToolChoice(params.tool_choice) && MODELS_REJECTING_FORCED_TOOL_CHOICE.has(modelId)\n ? withoutForcedToolChoice(params)\n : params\n if (isEnabledThinking(initialParams.thinking) && MODELS_REJECTING_ENABLED_THINKING.has(modelId))\n initialParams = withoutEnabledThinking(initialParams)\n const result = await runAnthropicStream(call, initialParams, options.modelOptions?.fast === true && !callIsOAuth)\n diagnostic.finish('success')\n return result\n }\n catch (err) {\n diagnostic.finish(options.signal?.aborted ? 'abort' : 'failure', {\n httpStatus: err && typeof err === 'object' && 'status' in err ? err.status : undefined,\n })\n throw err\n }\n finally {\n diagnostic.finish('failure')\n }\n}\n\n/** Resolve (or force-refresh) this call's credential through the shared OAuth machinery. */\nasync function resolveAnthropicCallApiKey(\n call: AnthropicCallAuthContext,\n forceRefresh = false,\n rejectedAccess?: string,\n): Promise<string> {\n const identity = credentialIdentity(call.provider.anthropicParams)\n return await resolveOAuthApiKey(\n {\n provider: identity.providerId,\n providerId: identity.providerId,\n params: call.provider.runtimeCredentials ? { ...call.provider.anthropicParams, ...call.provider.runtimeCredentials } : call.provider.anthropicParams,\n envKey: identity.envKey,\n missingError: identity.missingError,\n refreshError: identity.refreshError,\n forceRefresh,\n rejectedAccess,\n },\n {\n ...call.callbacks,\n onOAuthStage(stage) {\n if (!call.callbacks.onDiagnostic || call.provider.anthropicParams?.authMode === 'api-key' || call.provider.anthropicParams?.authMode === 'bearer')\n return\n call.live.diagnosticActive = true\n call.diagnostic.stage(stage)\n },\n async onOAuthRefresh(ctx) {\n if (ctx.source === 'params') {\n call.provider.runtimeCredentials = {\n access: ctx.credentials.access,\n refresh: ctx.credentials.refresh,\n expires: ctx.credentials.expires,\n }\n }\n await call.callbacks.onOAuthRefresh?.(ctx)\n },\n },\n )\n}\n\n/**\n * Auth, betas, extra headers, and client for one call — everything decided\n * before the request body.\n */\nasync function prepareAnthropicCall(\n provider: AnthropicProviderState,\n options: StreamOptions,\n callbacks: StreamCallbacks,\n diagnostic: ProviderDiagnosticTracker,\n live: AnthropicCallLive,\n): Promise<AnthropicPreparedCall> {\n const { anthropicParams, bedrockConfig } = provider\n // Bedrock mode: SigV4 auth via the AWS credential chain — the Anthropic\n // key/OAuth resolution below must not run (it throws for users who,\n // correctly, have no Anthropic key). No persona, no betas: the wire\n // shape past client construction is identical, so everything from the\n // system block on flows through the same code.\n if (!bedrockConfig)\n live.apiKey = await resolveAnthropicCallApiKey({ provider, callbacks, diagnostic, live })\n // Per-call OAuth detection — see the matching note in `countTokens`.\n // Resolved before the conditional betas: the extended-TTL gate below\n // branches on it. Bedrock is never OAuth (empty key → bearer: false).\n const callAuth = resolveAnthropicAuthShape(live.apiKey, bedrockConfig ? 'api-key' : anthropicParams?.authMode)\n const callIsOAuth = callAuth.claudeCode\n if (callIsOAuth && callbacks.onDiagnostic) {\n live.diagnosticActive = true\n diagnostic.stage('prepare')\n }\n /**\n * Whether a provider auth rejection on this call is worth ATTEMPTING one\n * forced credential rotation. A bearer-authenticated call MAY resolve its\n * token through the refreshable OAuth store — subscription OAuth and\n * `authMode: 'bearer'` gateways (`extensions/bolt`) both do — so a 401\n * arriving before the local expiry is recoverable for them. Deliberately\n * WIDER than {@link callIsOAuth}, which additionally means \"wear the\n * Claude Code persona\"; a gateway is not Claude Code but its token still\n * rotates.\n *\n * The ones that cannot rotate stop at the identical-credential guard in\n * the recovery below rather than being excluded here: a static bearer\n * token supplied as `apiKey` short-circuits `resolveOAuthApiKey` and never\n * reaches the store, so the re-resolve returns the same value and costs\n * nothing but a function call. API-key and Bedrock calls never get that\n * far — `callAuth.bearer` is false for both.\n */\n const callCanRotateAuth = callAuth.bearer\n // Fast mode (`speed: \"fast\"`) is gated behind the `fast-mode-2026-02-01`\n // beta — without the header Anthropic rejects the body field with\n // `speed: Extra inputs are not permitted`. Inject it here (not in the\n // static default betas) so the header is present exactly when the request\n // will carry `speed: \"fast\"`, keeping non-fast requests byte-stable for\n // the prompt cache.\n //\n // Same conditional-injection contract for the extended cache TTL: the\n // `ttl: '1h'` field on `cache_control` is rejected without its beta, so\n // the header rides exactly the requests whose breakpoints carry the ttl\n // (cache on + cacheTtl '1h') and every other request stays byte-stable.\n //\n // OAuth DEFAULTS TO 1h, matching the Claude Code client: the CLI runs\n // extended retention on subscription auth, and the whole point of this\n // path is to behave like it. A 5-minute TTL re-writes the entire prefix\n // at cache-write pricing after any pause longer than five minutes, and\n // on a subscription those writes come out of a fixed allowance rather\n // than a bill — so the default that is merely expensive on API-key auth\n // is the one that exhausts a plan here.\n //\n // An explicit `cacheTtl` from the caller still wins in both directions,\n // which is the opt-out (`cacheTtl: '5m'`) equivalent to the reference\n // plugin's `PI_CACHE_RETENTION=short`.\n //\n // API-key auth keeps the 5m default: there the tradeoff is real money\n // per token (1h writes bill ~2x base input against 1.25x for 5m), so it\n // stays opt-in.\n //\n // Bedrock stays excluded: beta headers are not sent there (the SigV4\n // client drops them), so a `ttl` field would arrive without its gating\n // beta and 400. `cacheTtl` degrades to the default TTL on Bedrock.\n const effectiveCacheTtl = options.cacheTtl ?? (callIsOAuth ? '1h' : undefined)\n const extendedTtl = options.cache !== false && effectiveCacheTtl === '1h' && !bedrockConfig\n // Resolved here (ahead of the request body) because the binding beta\n // below is gated on it. Consumed by the `params.thinking` block further\n // down. See the comment there for the shape rationale.\n const thinking = options.thinking ?? 'off'\n const plan = planAnthropicThinking(thinking, options.thinkingBudget, options.taskBudget, options.effortHint !== false)\n // Same conditional-injection contract: `thinking.block_binding` is\n // rejected without its beta, so the header rides exactly the requests\n // whose `thinking` object carries the field.\n const thinkingBinding = resolveThinkingBinding(anthropicParams?.thinkingBinding)\n const bindingActive = plan !== null && !bedrockConfig && thinkingBinding !== 'off' && !provider.thinkingBindingRejected\n const baseConditionalBetas = [\n // Gated with the field below — the beta rides exactly the requests that\n // carry `speed`, so an OAuth request stays byte-stable for the cache.\n ...(options.modelOptions?.fast && !callIsOAuth ? [FAST_MODE_BETA] : []),\n ...(extendedTtl ? [EXTENDED_CACHE_TTL_BETA] : []),\n ]\n const conditionalBetas = [\n ...baseConditionalBetas,\n ...(bindingActive ? [THINKING_BINDING_BETA] : []),\n ]\n const requestBetas = betasFor(anthropicParams, conditionalBetas)\n // Bound rather than inlined into `createClient`: the affinity-header\n // no-clobber check below needs the resolved map, and a function resolver\n // must not be called twice per request (it may mint a token).\n const resolvedExtraHeaders = await resolveExtraHeaders(anthropicParams?.extraHeaders)\n const client = bedrockConfig\n ? await createBedrockClient(bedrockConfig, anthropicParams, resolvedExtraHeaders)\n : createClient(\n await loadAnthropicSdk(),\n live.apiKey,\n callAuth,\n anthropicParams?.baseURL,\n requestBetas,\n resolvedExtraHeaders,\n callIsOAuth ? diagnostic.wrapFetch : undefined,\n )\n\n return {\n provider,\n callbacks,\n diagnostic,\n live,\n anthropicParams,\n bedrockConfig,\n options,\n callIsOAuth,\n effectiveCacheTtl,\n extendedTtl,\n plan,\n thinkingBinding,\n bindingActive,\n resolvedExtraHeaders,\n client,\n callAuth,\n callCanRotateAuth,\n baseConditionalBetas,\n requestBetas,\n }\n}\n\n/** Dispatch one request and settle it, recovering through the retry ladder on failure. */\nasync function runAnthropicStream(\n call: AnthropicCall,\n requestParams: AnthropicStreamParams,\n fastRequested: boolean,\n scrubPass = 0,\n authPass = 0,\n): Promise<TurnResult> {\n if (call.live.diagnosticActive)\n call.diagnostic.stage('dispatch')\n // Tool input can stream with raw control characters (fine-grained tool streaming): see anthropic-tool-json.\n const s = withToolJsonEscaping(call.client.messages).stream(requestParams, {\n signal: call.options.signal,\n ...(call.affinityHeader ? { headers: call.affinityHeader } : {}),\n })\n\n const turn = attachAnthropicStreamListeners(call, s)\n\n let response: Anthropic.Message\n try {\n response = await s.finalMessage()\n }\n catch (err) {\n return recoverAnthropicStreamFailure(call, turn, err, requestParams, fastRequested, scrubPass, authPass)\n }\n\n return settleAnthropicStream(call, turn, response, fastRequested)\n}\n\n/** Wire diagnostics, output deltas, live usage, input transformations, and server-tool callbacks. */\nfunction attachAnthropicStreamListeners(call: AnthropicCall, s: MessageStream): AnthropicTurnState {\n if (call.live.diagnosticActive) {\n s.on('connect', () => call.diagnostic.stage('response-headers', {\n httpStatus: s.response?.status,\n upstreamRequestId: s.request_id,\n }))\n let firstActivity = true\n s.on('streamEvent', () => {\n if (!firstActivity)\n return\n firstActivity = false\n call.diagnostic.stage('first-activity')\n call.diagnostic.stage('stream')\n })\n }\n\n const turn: AnthropicTurnState = { text: '', observedOutput: false, inputTransformations: undefined }\n\n s.on('text', (delta) => {\n turn.observedOutput = true\n turn.text += delta\n call.callbacks.onText(delta)\n })\n\n if (call.callbacks.onThinking) {\n s.on('thinking', (delta) => {\n turn.observedOutput = true\n call.callbacks.onThinking!(delta)\n })\n }\n\n // Mid-stream usage: `message_start` carries the prompt-side split (the\n // API has already tokenized the request); the running `output_tokens`\n // arrives in `message_delta`, which the API emits ONCE, right before\n // `message_stop`. `message_start.usage.output_tokens` is a `1`\n // placeholder, so it is deliberately NOT forwarded — the loop keeps\n // its character estimate moving until the real count lands. Cumulative\n // snapshots, so re-emitting the whole object on each event is the\n // contract. OAuth traffic is flagged non-billable so hosts show tokens\n // without a price, mirroring the absent `usage.cost` on the settled\n // turn.\n if (call.callbacks.onUsage) {\n let live: StreamUsageSnapshot | undefined\n s.on('streamEvent', (event) => {\n if (event.type === 'message_start') {\n const u = event.message.usage\n live = {\n inputTokens: u.input_tokens ?? 0,\n ...(u.cache_read_input_tokens != null ? { cacheRead: u.cache_read_input_tokens } : {}),\n ...(u.cache_creation_input_tokens != null ? { cacheCreation: u.cache_creation_input_tokens } : {}),\n ...(call.callIsOAuth ? { billable: false } : {}),\n }\n }\n else if (event.type === 'message_delta') {\n live = { ...(live ?? { inputTokens: 0, ...(call.callIsOAuth ? { billable: false } : {}) }), outputTokens: event.usage.output_tokens }\n }\n else {\n return\n }\n call.callbacks.onUsage!(live)\n })\n }\n\n // Preserved-thinking drops: with the binding beta the API lists every\n // replayed `thinking` block it discarded (prefix edited, or produced\n // by a model the serving one can't read) in `input_transformations`.\n // It rides the `message` object of `message_start`; after a\n // mid-stream server-side fallback the final `message_delta` carries\n // the serving model's entries again, superseding the first list.\n // Buffer the latest non-empty list and forward it ONCE after the\n // stream settles, so a fallback turn does not fire the loop's\n // `provider:input-transformations` hook twice and double-count.\n if (call.callbacks.onInputTransformations) {\n s.on('streamEvent', (event) => {\n const carrier = event.type === 'message_start'\n ? event.message\n : event.type === 'message_delta' ? event : undefined\n const list = (carrier as { input_transformations?: unknown } | undefined)?.input_transformations\n if (Array.isArray(list) && list.length > 0)\n turn.inputTransformations = list.filter(isInputTransformation)\n })\n }\n\n // Liveness signal for tool-only turns: `inputJson` fires as a\n // `tool_use` block's arguments stream in. Without it, a turn that\n // emits only tool calls (no text/thinking) never trips the loop's\n // \"first response observed\" gate and the first-response watchdog can\n // abort an actively-progressing stream. (B2)\n if (call.callbacks.onToolCallDelta) {\n s.on('inputJson', () => {\n turn.observedOutput = true\n call.callbacks.onToolCallDelta!()\n })\n }\n\n // Server-tool blocks (e.g. `web_search_20250305`) execute on Anthropic's\n // side and arrive in the assistant content stream — not via our tool\n // loop. The SDK fires `contentBlock` once per block as it closes, so\n // listen for the two we care about and dispatch generic callbacks.\n // Other block types (text, thinking, tool_use, …) have their own paths\n // above / in `finalMessage()` — ignored here to avoid double-emission.\n if (call.callbacks.onServerToolUse || call.callbacks.onServerToolResult) {\n s.on('contentBlock', (block) => {\n turn.observedOutput = true\n if (block.type === 'server_tool_use') {\n call.callbacks.onServerToolUse?.({\n id: block.id,\n name: block.name,\n input: (block.input as Record<string, unknown> | undefined) ?? {},\n })\n }\n else if (block.type === 'web_search_tool_result') {\n call.callbacks.onServerToolResult?.({\n toolUseId: block.tool_use_id,\n toolName: 'web_search',\n content: block.content,\n })\n }\n })\n }\n\n return turn\n}\n\n/**\n * The retry ladder for a failed dispatch: thinking-signature scrub, forced\n * OAuth rotation, fast-mode fallback, binding downgrade, forced-tool-choice\n * and enabled-thinking downgrades. Rethrows when nothing applies.\n */\nasync function recoverAnthropicStreamFailure(\n call: AnthropicCall,\n turn: AnthropicTurnState,\n err: unknown,\n requestParams: AnthropicStreamParams,\n fastRequested: boolean,\n scrubPass: number,\n authPass: number,\n): Promise<TurnResult> {\n // Under `thinkingBinding: 'error'` the caller asked to SEE a prefix\n // mismatch: let that 400 propagate instead of scrubbing history\n // around it. Other thinking-block 400s (corrupt signature) still\n // take the ladder.\n const requestedFailure = call.bindingActive && call.thinkingBinding === 'error' && isPrefixMismatchError(err)\n if (!requestedFailure && !turn.observedOutput && scrubPass < MAX_THINKING_SCRUB_PASSES && isRecoverableThinkingBlockError(err, requestParams.messages)) {\n const failingIndex = parseFailingMessageIndex(err)\n // Escalation ladder: the first pass scrubs only at/before the\n // API-reported failing index (preserving still-valid thinking\n // later in the wire). If the retry hits ANOTHER signature 400 —\n // the API reports one bad locator at a time, so scattered stale\n // blocks surface index-by-index — stop chasing locators and\n // scrub the full history EXCEPT the active chain. See\n // {@link planThinkingScrub} for the chain-protection rules\n // (never strip the in-flight exchange's thinking wholesale;\n // Anthropic requires it echoed back).\n const plan = planThinkingScrub(scrubPass, failingIndex, requestParams.messages)\n const scrubbed = withoutHistoricalThinking(requestParams.messages, plan.upToIndex, plan.alsoMessageIndex)\n // Guard against an infinite retry if Anthropic reports the same\n // error despite there being nothing left to strip (or if this is\n // already the scrubbed retry).\n if (scrubbed.removed > 0) {\n // Ask the loop to repair + persist its canonical history before\n // retrying. Direct provider consumers may omit the callback;\n // the scrubbed wire retry still succeeds for this turn.\n try {\n await call.callbacks.onHistoryRepair?.({\n type: 'invalid-anthropic-thinking-signature',\n ...(failingIndex !== undefined ? { wireMessageIndex: failingIndex } : {}),\n })\n }\n catch (repairErr) {\n // Canonical persistence is best-effort; never let a host\n // callback block the safe wire-level recovery for this turn.\n if (process.env.ZIDANE_DEBUG)\n process.stderr.write(`[zidane/anthropic] history repair callback failed: ${errorMessage(repairErr)}\\n`)\n }\n return await runAnthropicStream(call, { ...requestParams, messages: scrubbed.messages }, fastRequested, scrubPass + 1, authPass)\n }\n }\n // OAuth access can be revoked server-side before its local expiry.\n // Re-read/refresh once, rebuild the client with the rotated access\n // token, and retry only when no output was observed (avoids replaying\n // a partially delivered assistant turn). API-key and Bedrock runs\n // never enter this path — `callAuth.bearer` is false for both. Bearer\n // gateways DO enter it, and stop at the identical-credential guard\n // below when their token turns out not to rotate. Zidane still\n // persists only through the existing onOAuthRefresh callback for\n // parameter-owned credentials.\n if (call.callCanRotateAuth && authPass === 0 && !turn.observedOutput && isAnthropicAuthenticationError(err)) {\n const rejectedAccess = call.live.apiKey\n let refreshedApiKey: string\n try {\n refreshedApiKey = await resolveAnthropicCallApiKey(call, true, rejectedAccess)\n }\n catch (refreshErr) {\n // The forced refresh is additive recovery, so its failure must not\n // replace the provider's own rejection: a revoked grant fails BOTH\n // (and the 401 is what carries the status / `authentication_error`\n // that `classifyAnthropicError` keys on), while a transient\n // network failure here would otherwise surface as \"re-login\" to a\n // user whose credential was fine.\n //\n // The reason still has to survive, though — a revoked grant is the\n // likeliest way into this branch, and \"why\" should not be reachable\n // only through an env var nobody has set. `cause` keeps it in the\n // chain and in printed stack traces while leaving the message and\n // the classification untouched. Never clobber a cause the SDK set.\n //\n // Best-effort by construction: `err` belongs to the provider SDK,\n // and assigning to a frozen or sealed object throws a TypeError\n // under ESM's strict mode. Letting that escape would replace the\n // 401 with a TypeError — precisely the masking this whole branch\n // exists to prevent — so a failure to annotate is swallowed and\n // the rejection propagates unchanged.\n if (err !== null && typeof err === 'object' && (err as { cause?: unknown }).cause === undefined) {\n try {\n (err as { cause?: unknown }).cause = refreshErr\n }\n catch {}\n }\n if (process.env.ZIDANE_DEBUG)\n process.stderr.write(`[zidane/anthropic] forced OAuth refresh after 401 failed: ${errorMessage(refreshErr)}\\n`)\n throw err\n }\n // Access-only OAuth inputs cannot rotate. Retrying the identical\n // rejected credential would only duplicate the request and can be\n // dangerous if the provider emitted an empty/ambiguous stream.\n if (refreshedApiKey === rejectedAccess)\n throw err\n call.live.apiKey = refreshedApiKey\n call.client = createClient(\n await loadAnthropicSdk(),\n call.live.apiKey,\n // `callAuth`, not a re-sniff of the rotated token: the persona\n // decision is already baked into this call's system block and\n // message shape (see the `callIsOAuth` branches above). A rotated\n // token that happens not to look like `sk-ant-oat` — every\n // `authMode: 'bearer'` gateway token, plus anything from a\n // `credentialSource` custom flow — would otherwise flip the wire\n // auth to `x-api-key` and drop the Claude Code betas mid-call.\n call.callAuth,\n call.anthropicParams?.baseURL,\n call.requestBetas,\n call.resolvedExtraHeaders,\n call.callIsOAuth ? call.diagnostic.wrapFetch : undefined,\n )\n return await runAnthropicStream(call, requestParams, fastRequested, scrubPass, authPass + 1)\n }\n if (fastRequested && !turn.observedOutput && shouldFallbackFromFastMode(err)) {\n const standardParams = { ...requestParams }\n delete standardParams.speed\n return await runAnthropicStream(call, standardParams, false, scrubPass, authPass)\n }\n // Preserved-thinking binding not understood by this endpoint (older\n // gateway, subscription backend). Retry once without the beta and\n // the field — the request is otherwise identical — and remember\n // the downgrade for the instance. Clean-slate only, like fast mode.\n if (call.bindingActive && !call.provider.thinkingBindingRejected && !turn.observedOutput && isThinkingBindingRejectedError(err)) {\n call.provider.thinkingBindingRejected = true\n if (process.env.ZIDANE_DEBUG)\n process.stderr.write(`[zidane/anthropic] endpoint rejected thinking.block_binding; retrying without it: ${errorMessage(err)}\\n`)\n call.client = createClient(\n await loadAnthropicSdk(),\n call.live.apiKey,\n call.callAuth,\n call.anthropicParams?.baseURL,\n betasFor(call.anthropicParams, call.baseConditionalBetas),\n call.resolvedExtraHeaders,\n call.callIsOAuth ? call.diagnostic.wrapFetch : undefined,\n )\n return await runAnthropicStream(call, withoutThinkingBinding(requestParams), fastRequested, scrubPass, authPass)\n }\n // Forced tool use rejected by the model (Fable 5.1 onward). A pure\n // request-shape problem, so retry once with `auto` and a system-level\n // instruction standing in for the forcing. Clean-slate only, and\n // self-terminating: the retry no longer carries a forced choice, so\n // it cannot re-enter this branch. Remembered so the next call on\n // this model downgrades up front.\n if (!turn.observedOutput && isForcedToolChoice(requestParams.tool_choice) && isForcedToolChoiceUnsupportedError(err)) {\n MODELS_REJECTING_FORCED_TOOL_CHOICE.add(call.modelId)\n return await runAnthropicStream(call, withoutForcedToolChoice(requestParams), fastRequested, scrubPass, authPass)\n }\n // Explicit-budget thinking rejected by the model (Opus 5.5 onward,\n // adaptive-only). Retry once as adaptive — a pure request-shape\n // downgrade, clean-slate only, and self-terminating: the retry\n // carries `thinking.type='adaptive'`, so it cannot re-enter this\n // branch. Remembered so the next call downgrades up front.\n if (!turn.observedOutput && isEnabledThinking(requestParams.thinking) && isEnabledThinkingUnsupportedError(err)) {\n MODELS_REJECTING_ENABLED_THINKING.add(call.modelId)\n return await runAnthropicStream(call, withoutEnabledThinking(requestParams), fastRequested, scrubPass, authPass)\n }\n throw err\n}\n\n/** Fire the settled-stream hooks and map the final message to a `TurnResult`. */\nasync function settleAnthropicStream(\n call: AnthropicCall,\n turn: AnthropicTurnState,\n response: Anthropic.Message,\n fastRequested: boolean,\n): Promise<TurnResult> {\n // Settled stream only: a retried request re-reports its own drops.\n // Observational — a throwing host callback must not fail the turn.\n if (turn.inputTransformations && turn.inputTransformations.length > 0) {\n try {\n call.callbacks.onInputTransformations?.(turn.inputTransformations)\n }\n catch (hookErr) {\n if (process.env.ZIDANE_DEBUG)\n process.stderr.write(`[zidane/anthropic] onInputTransformations threw: ${errorMessage(hookErr)}\\n`)\n }\n }\n\n const toolCalls = response.content\n .filter((b): b is Anthropic.ToolUseBlock => b.type === 'tool_use')\n .map(b => ({ id: b.id, name: call.nameBoundary.fromWire(b.name), input: b.input as Record<string, unknown> }))\n\n const finishReason = mapStopReason(response.stop_reason)\n\n // `pause_turn` is *not* terminal — the loop has to inject a continue\n // message and run another turn. Without this branch, the previous\n // `toolCalls.length === 0` shortcut would mark the run done at the\n // pause and silently drop the work in flight.\n const isPause = response.stop_reason === 'pause_turn'\n\n const rawUsage: TurnUsage = {\n input: response.usage.input_tokens,\n output: response.usage.output_tokens,\n cacheCreation: response.usage.cache_creation_input_tokens ?? undefined,\n cacheRead: response.usage.cache_read_input_tokens ?? undefined,\n ...(finishReason ? { finishReason } : {}),\n modelId: response.model ?? (call.options.model as string),\n }\n // OAuth = subscription traffic (Claude Pro/Max via a Claude Code\n // account): usage is included in the flat plan, not billed per\n // token. Estimating API-list prices for it produces large dollar\n // figures the user never pays — so `cost` stays absent and cost\n // surfaces (footer counter, usage-by-model rows) show tokens\n // without a price, matching Claude Code's own /cost behavior.\n // API-key turns estimate as before; a mixed session (OAuth primary\n // with an API-key fallback, or vice versa) prices each turn by how\n // it was actually served.\n const usage = call.callIsOAuth\n ? rawUsage\n : await priceAnthropicUsage(rawUsage, response, call.modelId, fastRequested, Boolean(call.bedrockConfig), call.options.modelCatalog)\n const assistantMessage = fromAnthropic({ role: 'assistant', content: response.content })\n // Restore caller-side names on persisted content so the outer loop's\n // own wire→canonical aliasing applies normally (mirrors openai.ts).\n if (call.nameBoundary.changed) {\n assistantMessage.content = assistantMessage.content.map(block =>\n block.type === 'tool_call' ? { ...block, name: call.nameBoundary.fromWire(block.name) } : block,\n )\n }\n return {\n assistantMessage,\n text: turn.text,\n toolCalls,\n done: !isPause && (response.stop_reason === 'end_turn' || toolCalls.length === 0),\n usage,\n }\n}\n","// Type-only imports — erased at build time. Safe when the peer dep is not installed\n// at consume time; the types only need to resolve during Zidane's own build\n// (where `@anthropic-ai/sdk` is present as a devDependency).\nimport type Anthropic from '@anthropic-ai/sdk'\nimport type { Model } from '@anthropic-ai/sdk/resources'\nimport type { Provider, StreamCallbacks, ToolResult, ToolSpec, TurnResult } from '.'\nimport type { PromptPart, SessionContentBlock, SessionMessage } from '../types'\nimport type { AnthropicParams } from './anthropic-params'\nimport type { AnthropicProviderState } from './anthropic-stream'\nimport { unsupportedMediaError } from '../prompt'\nimport { toAnthropic } from '../session/messages'\nimport { claudeCodeToolAliases, foldSystemForWire } from './anthropic-claude-code'\nimport {\n createClient,\n credentialIdentity,\n getConfiguredApiKey,\n loadAnthropicSdk,\n normalizeBedrock,\n resolveAnthropicAuthShape,\n resolveExtraHeaders,\n} from './anthropic-client'\nimport { classifyAnthropicError } from './anthropic-errors'\nimport { streamAnthropic } from './anthropic-stream'\nimport { extractRuntimeCredentials, resolveOAuthApiKey } from './oauth'\nimport { sanitizeToolSpecs } from './schema-sanitize'\nimport { createToolNameBoundary } from './tool-name-boundary'\n\nexport { applyAnthropicCacheBreakpoints, EXTENDED_CACHE_TTL_BETA } from './anthropic-cache'\nexport { buildAnthropicClientOptions, credentialIdentity, resolveAnthropicAuthShape, resolveAnthropicBetas } from './anthropic-client'\nexport { classifyAnthropicError } from './anthropic-errors'\nexport type { AnthropicBedrockConfig, AnthropicContextManagement, AnthropicParams } from './anthropic-params'\nexport { defaultAnthropicMaxTokens, resolveAnthropicMaxOutput } from './anthropic-request'\nexport { planAnthropicThinking, resolveThinkingBinding, THINKING_BINDING_SETTING_ENV } from './anthropic-thinking'\nexport type { AnthropicThinkingPlan, ThinkingBindingBehavior } from './anthropic-thinking'\nexport { cacheWriteTtlMultiplier } from './anthropic-usage'\n\n/**\n * Build a user `SessionMessage` from multimodal prompt parts.\n *\n * - Text parts → text blocks.\n * - Image parts → base64 image blocks.\n * - Document parts → canonical document blocks. `toAnthropic` emits native\n * document blocks only for base64 PDFs; text/non-PDF documents fall back to\n * attachment-tagged text to avoid invalid Anthropic source media types.\n *\n * The format mirrors `defaultPromptMessage`'s output on shape — Anthropic-specific\n * handling differs only in that `promptMessage` being present tells the agent loop\n * to route PromptPart[] through this function rather than throwing on base64 docs.\n */\nfunction anthropicPromptMessage(parts: PromptPart[]): SessionMessage {\n const content: SessionContentBlock[] = []\n\n for (const part of parts) {\n if (part.type === 'text') {\n if (part.text.length > 0)\n content.push({ type: 'text', text: part.text })\n continue\n }\n\n if (part.type === 'image') {\n content.push({ type: 'image', mediaType: part.mediaType, data: part.data })\n continue\n }\n\n if (part.type === 'audio')\n throw unsupportedMediaError('audio', 'anthropic')\n if (part.type === 'video')\n throw unsupportedMediaError('video', 'anthropic')\n\n // document\n content.push({\n type: 'document',\n mediaType: part.mediaType,\n data: part.data,\n encoding: part.encoding,\n ...(part.name ? { name: part.name } : {}),\n })\n }\n\n return { role: 'user', content }\n}\n\nexport function anthropic(\n anthropicParams?: AnthropicParams,\n): Provider {\n const bedrockConfig = normalizeBedrock(anthropicParams?.bedrock)\n // Bedrock mode authenticates through the AWS credential chain — resolving\n // an Anthropic key here would throw for users who (correctly) have none.\n const configuredApiKey = bedrockConfig ? '' : getConfiguredApiKey(anthropicParams)\n // Factory-time snapshot — used only for the static `meta.isOAuth` flag.\n // Keys resolve per call (env / file creds can change between construction\n // and a turn), so `countTokens` / `stream` re-derive the auth shape from the\n // freshly resolved key instead of trusting this.\n const isOAuth = resolveAnthropicAuthShape(configuredApiKey, anthropicParams?.authMode).bearer\n const defaultModel = anthropicParams?.defaultModel || 'claude-fable-5-1'\n const state: AnthropicProviderState = {\n anthropicParams,\n bedrockConfig,\n runtimeCredentials: extractRuntimeCredentials(anthropicParams),\n thinkingBindingRejected: false,\n }\n\n return {\n name: 'anthropic',\n meta: {\n defaultModel,\n isOAuth,\n // True when server-side context management is configured: the API may\n // clear old tool results mid-conversation without the client knowing.\n // The loop reads this to disable the read_file dedup, whose client-side\n // hash can't tell that a server-cleared body left the wire — otherwise\n // the \"unchanged\" replay stub would strand the model on missing content.\n clearsContextServerSide: Boolean(anthropicParams?.contextManagement),\n capabilities: {\n vision: true,\n imageInToolResult: true,\n documents: true,\n // Anthropic Messages API has no audio/video input content block.\n audio: false,\n video: false,\n // Anthropic Messages API supports `web_search_20250305` as a\n // server-side tool — the model issues searches and consumes\n // results without a client-visible tool_use round-trip. The\n // canonical `web_search` `ToolDef` ships as a cross-provider\n // fallback; when this capability is set, `formatTools` rewrites\n // it to the server-tool wire shape and drops the function-tool\n // version so the model uses the native path.\n //\n // NOT on Bedrock: AWS doesn't host Anthropic's server-side search\n // (live-verified 400, \"The provided request is not valid\"), and\n // because `formatTools` rewrites the TOOLS ARRAY, advertising it\n // would fail every request from any agent whose toolset merely\n // CONTAINS a `web_search` tool — zidane's default set does. With\n // the capability absent, that ToolDef passes through as a regular\n // function tool and executes client-side like on every other\n // non-Anthropic route. Callers can re-enable via `capabilities`\n // below if AWS ever ships it.\n ...(bedrockConfig ? {} : { nativeWebSearch: { maxUses: 5 } }),\n // Bedrock caps a Messages request at 20 images (the first-party API\n // allows 100–600); inline media must age out before that.\n ...(bedrockConfig ? { maxMediaPerRequest: 20 } : {}),\n // Anthropic adaptive has no native per-turn thinking budget knob, so\n // `thinkingBudget` caps the whole response envelope (`max_tokens`).\n // The loop skips `thinkingDecay` for adaptive here — see the flag docs.\n adaptiveBudgetIsEnvelope: true,\n // Caller overrides last — a gateway in front of `baseURL` may not\n // implement every native affordance (server-side web search is the\n // usual casualty), and advertising one it lacks 400s every turn.\n ...anthropicParams?.capabilities,\n },\n },\n\n formatTools(tools: ToolSpec[]): Anthropic.ToolUnion[] {\n // Sanitize before forwarding — Anthropic 400s on the strict shapes\n // (root `$ref`, root `oneOf|anyOf|allOf`, `type: ['object', 'null']`,\n // missing `properties`, `nullable: true`) that show up in MCP-server\n // schemas. The strict `anthropic` profile coerces those without\n // changing semantics for valid schemas. Warnings are de-duped to\n // `console.warn` so the same bad schema doesn't spam the log every\n // turn.\n //\n // `web_search` is special-cased: when present, it's emitted as the\n // server-tool `web_search_20250305` block and removed from the\n // function-tools list. The model invokes it without a client-side\n // round-trip; Anthropic injects the search results into the\n // assistant message directly. See the `nativeWebSearch` capability\n // declared above.\n const nativeWebSearch = this.meta.capabilities?.nativeWebSearch\n // `hasWebSearch` is the existence check; `fnTools` is the filtered\n // list. Computing existence via `tools.some` (rather than comparing\n // pre/post-filter lengths) makes the rewrite intent obvious at a\n // glance.\n const hasWebSearch = !!nativeWebSearch && tools.some(t => t.name === 'web_search')\n const fnTools = hasWebSearch ? tools.filter(t => t.name !== 'web_search') : tools\n const sanitized = sanitizeToolSpecs(fnTools, { profile: 'anthropic' })\n // `?? ''`: MCP servers routinely omit descriptions, and while the\n // Anthropic API tolerates the field's absence, anthropic-format\n // GATEWAYS in front of it often validate `description` as a required\n // string — one description-less tool then 400s the whole request\n // before any model sees it. An empty string is valid everywhere.\n const out: Anthropic.ToolUnion[] = sanitized.map(t => ({\n name: t.name,\n description: t.description ?? '',\n input_schema: t.inputSchema as Anthropic.Tool['input_schema'],\n }))\n if (hasWebSearch && nativeWebSearch) {\n // `max_uses` is optional — omit when the capability doesn't pin a value\n // so Anthropic's server-side default applies.\n const block: Anthropic.WebSearchTool20250305 = {\n type: 'web_search_20250305',\n name: 'web_search',\n }\n if (typeof nativeWebSearch.maxUses === 'number')\n block.max_uses = nativeWebSearch.maxUses\n out.push(block)\n }\n return out\n },\n\n userMessage(content: string): SessionMessage {\n return { role: 'user', content: [{ type: 'text', text: content }] }\n },\n\n assistantMessage(content: string): SessionMessage {\n return { role: 'assistant', content: [{ type: 'text', text: content }] }\n },\n\n toolResultsMessage(results: ToolResult[]): SessionMessage {\n return {\n role: 'user',\n content: results.map(r => ({\n type: 'tool_result' as const,\n callId: r.id,\n output: r.content,\n ...(r.isError ? { isError: true as const } : {}),\n ...(r.metadata ? { metadata: r.metadata } : {}),\n })),\n }\n },\n\n promptMessage: anthropicPromptMessage,\n\n classifyError: classifyAnthropicError,\n\n async countTokens(payload, signal): Promise<number | null> {\n // Bedrock has no `count_tokens` endpoint (the SDK omits the method) —\n // return null immediately so the caller's heuristic takes over without\n // paying a doomed request or logging an error every turn.\n if (bedrockConfig)\n return null\n try {\n const SDK = await loadAnthropicSdk()\n const identity = credentialIdentity(anthropicParams)\n const apiKey = await resolveOAuthApiKey(\n {\n provider: identity.providerId,\n providerId: identity.providerId,\n params: state.runtimeCredentials ? { ...anthropicParams, ...state.runtimeCredentials } : anthropicParams,\n envKey: identity.envKey,\n missingError: identity.missingError,\n refreshError: identity.refreshError,\n },\n )\n // Derive OAuth-ness from the freshly resolved key — auth mode can\n // change between factory construction and this call (env var set,\n // creds file rotated), and a stale flag would skew the count's\n // system-prompt folding relative to what `stream()` actually sends.\n const callAuth = resolveAnthropicAuthShape(apiKey, anthropicParams?.authMode)\n const callIsOAuth = callAuth.claudeCode\n const client = createClient(\n SDK,\n apiKey,\n callAuth,\n anthropicParams?.baseURL,\n anthropicParams?.extraBetas,\n await resolveExtraHeaders(anthropicParams?.extraHeaders),\n )\n\n // Mirror `stream()`'s wire-payload build so the count matches what is\n // actually sent: OAuth folds the real system prompt into a synthetic\n // user/assistant pair and sends the canonical Claude Code prompt as\n // the system block.\n const { system, messages } = foldSystemForWire(payload.system, payload.messages, callIsOAuth)\n\n // Same request-local name boundary as `stream()` — a foreign/legacy\n // tool name in replayed history would 400 the count exactly like the\n // real request.\n const countTools = payload.tools as Anthropic.Tool[]\n const countBoundary = createToolNameBoundary(\n messages,\n countTools.map(t => t.name),\n callIsOAuth ? claudeCodeToolAliases : undefined,\n )\n const res = await client.messages.countTokens(\n {\n model: payload.model as Model,\n system,\n tools: countBoundary.changed\n ? countTools.map(t => ({ ...t, name: countBoundary.toWire(t.name) }))\n : countTools,\n messages: countBoundary.messages.map(m => toAnthropic(m)) as Anthropic.MessageParam[],\n },\n signal ? { signal } : undefined,\n )\n return res.input_tokens\n }\n catch (err) {\n // Unreachable under the active auth / network — caller falls back to\n // the heuristic. Surface the cause when debugging so a silent auth /\n // scope rejection (e.g. OAuth lacking the count endpoint) is visible.\n if (process.env.ZIDANE_DEBUG_COUNT)\n console.error('[anthropic.countTokens] failed:', err)\n return null\n }\n },\n\n stream(options, callbacks: StreamCallbacks): Promise<TurnResult> {\n return streamAnthropic(state, options, callbacks)\n },\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifacts-CV2hUKnL.js","names":[],"sources":["../src/session/artifacts.ts"],"sourcesContent":["/**\n * Session artifacts — durable, typed pointers to things a session produced\n * OUTSIDE its transcript: a pull request, a branch, a commit, a file, a\n * deployment, an issue. The artifact stores the locator plus enough\n * metadata to display and re-resolve it; the content stays where it lives.\n *\n * Design constraints (see the store contracts in `./index.ts`):\n *\n * - Artifacts are NOT part of `SessionData`. They live in their own\n * table / map so `load()` / `save()` / export / compaction never see\n * them, and stores that don't implement the optional artifact methods\n * keep working unchanged.\n * - `kind` is an open string. Core knows nothing about what a\n * `pull_request` is; extensions register kinds (detection, rendering,\n * refresh) and unknown kinds always fall back to `label` + `uri`.\n * - `(sessionId, kind, uri)` is the identity: re-emitting the same\n * artifact upserts (refreshes `label` / `meta` / `updatedAt`) instead\n * of duplicating, and keeps the ORIGINAL `id` / `runId` / `turnId` /\n * `createdAt` so the transcript anchor points at the producing turn.\n * - Bounded: `meta` ≤ 16 KB, ≤ 200 artifacts per session. A `find` over\n * 50k files must not become 50k rows.\n */\n\nimport type { JsonValue } from '../types'\nimport { Buffer } from 'node:buffer'\n\n/** Built-in kinds. Open set — extensions add their own. */\nexport const ARTIFACT_KINDS = {\n pullRequest: 'pull_request',\n branch: 'branch',\n commit: 'commit',\n file: 'file',\n} as const\n\n/**\n * Reserved tool-result metadata namespace. Tools (and extension\n * `detect` hooks) emit `metadata.artifacts = ArtifactInput[]` and the\n * loop lifts each entry into the session's artifact store.\n */\nexport const ARTIFACTS_METADATA_KEY = 'artifacts'\n\nexport const ARTIFACT_META_MAX_BYTES = 16_384\nexport const ARTIFACT_LABEL_MAX_CHARS = 512\nexport const ARTIFACT_URI_MAX_CHARS = 2_048\nexport const ARTIFACT_KIND_MAX_CHARS = 64\nexport const ARTIFACTS_PER_SESSION_CAP = 200\n/** Allowed `kind` shape: word chars plus `.`, `:` and `-` for namespacing. */\nexport const ARTIFACT_KIND_PATTERN = /^[\\w.:-]+$/\n\nexport interface SessionArtifact {\n /** Stable id (uuid). Preserved across upserts of the same `(kind, uri)`. */\n id: string\n sessionId: string\n /**\n * Run that produced it. A `persist`-spawned subagent shares the parent\n * session and records under its OWN run id (detection reaches it via the\n * `child:tool:transform` bubble; see `presets/artifacts.ts`).\n */\n runId?: string\n /** Tool-result turn that produced it — the transcript anchor. */\n turnId?: string\n /** Open kind string. Built-ins in {@link ARTIFACT_KINDS}. */\n kind: string\n /** Canonical locator: PR URL, `git:<repo>#<branch>`, `file://<abs path>`, … */\n uri: string\n /** Human line. Always present — the rendering fallback for unknown kinds. */\n label: string\n /**\n * Project the artifact landed in, resolved at emission time from where\n * the thing actually is (a worktree, a sibling repo), defaulting to the\n * session's own `projectRoot`. Drives \"everything produced from this\n * repo\" queries.\n */\n projectRoot?: string\n /** Kind-specific payload, ≤ {@link ARTIFACT_META_MAX_BYTES}. */\n meta?: JsonValue\n createdAt: number\n updatedAt: number\n}\n\n/** What a producer hands to `session.addArtifact` / the metadata namespace. */\nexport interface SessionArtifactInput {\n kind: string\n uri: string\n label: string\n projectRoot?: string\n meta?: JsonValue\n}\n\nexport interface ArtifactFilter {\n sessionId?: string\n /**\n * Tri-state like `SessionStore.list`: string → that project only,\n * `null` → artifacts with no project, omitted → axis ignored.\n */\n projectRoot?: string | null\n kind?: string\n /** Exact locator match — reverse lookup (\"who produced PR #123?\"). Pair with `kind`. */\n uri?: string\n /** Only artifacts with `updatedAt >= since`. */\n since?: number\n limit?: number\n}\n\n/**\n * Validate + normalize a raw input (typically from tool-result metadata,\n * i.e. an untrusted boundary). Returns `null` when the entry is unusable\n * — missing kind/uri/label or oversized in a way truncation can't fix.\n * `label` is clipped, `meta` is dropped (not the artifact) when it exceeds\n * the byte bound.\n */\nexport function normalizeArtifactInput(raw: unknown): SessionArtifactInput | null {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw))\n return null\n const r = raw as Record<string, unknown>\n const kind = typeof r.kind === 'string' ? r.kind.trim() : ''\n const uri = typeof r.uri === 'string' ? r.uri.trim() : ''\n if (!kind || !uri)\n return null\n if (kind.length > ARTIFACT_KIND_MAX_CHARS || uri.length > ARTIFACT_URI_MAX_CHARS)\n return null\n if (!ARTIFACT_KIND_PATTERN.test(kind))\n return null\n let label = typeof r.label === 'string' && r.label.trim() ? r.label.trim() : uri\n if (label.length > ARTIFACT_LABEL_MAX_CHARS)\n label = `${label.slice(0, ARTIFACT_LABEL_MAX_CHARS - 1)}…`\n const out: SessionArtifactInput = { kind, uri, label }\n if (typeof r.projectRoot === 'string' && r.projectRoot)\n out.projectRoot = r.projectRoot\n if (r.meta !== undefined && r.meta !== null) {\n const meta = boundedMeta(r.meta)\n if (meta !== undefined)\n out.meta = meta\n }\n return out\n}\n\n/** `meta` when JSON-serializable and within bounds, else `undefined` (dropped). */\nexport function boundedMeta(value: unknown): JsonValue | undefined {\n let json: string | undefined\n try {\n json = JSON.stringify(value)\n }\n catch {\n return undefined\n }\n if (json === undefined || Buffer.byteLength(json, 'utf8') > ARTIFACT_META_MAX_BYTES)\n return undefined\n return JSON.parse(json) as JsonValue\n}\n\n/**\n * Apply an upsert to an existing row: identity fields (`id`, `runId`,\n * `turnId`, `createdAt`) stay, presentation (`label`, `meta`,\n * `projectRoot`) refresh, `updatedAt` bumps. Shared by every store so the\n * merge semantics can't drift.\n */\nexport function mergeArtifact(existing: SessionArtifact, incoming: SessionArtifact): SessionArtifact {\n return {\n ...existing,\n label: incoming.label,\n ...(incoming.meta !== undefined ? { meta: incoming.meta } : existing.meta !== undefined ? { meta: existing.meta } : {}),\n ...(incoming.projectRoot ? { projectRoot: incoming.projectRoot } : existing.projectRoot ? { projectRoot: existing.projectRoot } : {}),\n updatedAt: Math.max(existing.updatedAt, incoming.updatedAt),\n }\n}\n\n/**\n * Which artifacts to evict so a session stays at or under `cap` after\n * one more insert. `file` artifacts go first (noisiest, cheapest to\n * regenerate), oldest first within a kind; ties keep the caller's order\n * (stable sort), so pass rows in insertion order. Pure — callers delete\n * the returned ids.\n */\nexport function selectArtifactEvictions(\n current: readonly SessionArtifact[],\n cap = ARTIFACTS_PER_SESSION_CAP,\n): string[] {\n const overflow = current.length + 1 - cap\n if (overflow <= 0)\n return []\n const byPriority = [...current].sort((a, b) => {\n const af = a.kind === ARTIFACT_KINDS.file ? 0 : 1\n const bf = b.kind === ARTIFACT_KINDS.file ? 0 : 1\n if (af !== bf)\n return af - bf\n return a.createdAt - b.createdAt\n })\n return byPriority.slice(0, overflow).map(a => a.id)\n}\n\nexport function matchesArtifactFilter(artifact: SessionArtifact, filter: ArtifactFilter | undefined): boolean {\n if (!filter)\n return true\n if (filter.sessionId !== undefined && artifact.sessionId !== filter.sessionId)\n return false\n if (filter.kind !== undefined && artifact.kind !== filter.kind)\n return false\n if (filter.uri !== undefined && artifact.uri !== filter.uri)\n return false\n if ('projectRoot' in filter) {\n if (filter.projectRoot === null && artifact.projectRoot != null)\n return false\n if (typeof filter.projectRoot === 'string' && artifact.projectRoot !== filter.projectRoot)\n return false\n }\n if (filter.since !== undefined && artifact.updatedAt < filter.since)\n return false\n return true\n}\n\n/** Newest first, stable on id. */\nexport function sortArtifacts(artifacts: SessionArtifact[]): SessionArtifact[] {\n return artifacts.sort((a, b) => b.updatedAt - a.updatedAt || b.createdAt - a.createdAt || a.id.localeCompare(b.id))\n}\n"],"mappings":";;;AA2BA,MAAa,iBAAiB;CAC5B,aAAa;CACb,QAAQ;CACR,QAAQ;CACR,MAAM;AACR;;;;;;AAOA,MAAa,yBAAyB;AAEtC,MAAa,0BAA0B;AAEvC,MAAa,yBAAyB;AAEtC,MAAa,4BAA4B;;AAEzC,MAAa,wBAAwB;;;;;;;;AAgErC,SAAgB,uBAAuB,KAA2C;CAChF,IAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,GACtD,OAAO;CACT,MAAM,IAAI;CACV,MAAM,OAAO,OAAO,EAAE,SAAS,WAAW,EAAE,KAAK,KAAK,IAAI;CAC1D,MAAM,MAAM,OAAO,EAAE,QAAQ,WAAW,EAAE,IAAI,KAAK,IAAI;CACvD,IAAI,CAAC,QAAQ,CAAC,KACZ,OAAO;CACT,IAAI,KAAK,SAAA,MAAoC,IAAI,SAAA,MAC/C,OAAO;CACT,IAAI,CAAC,sBAAsB,KAAK,IAAI,GAClC,OAAO;CACT,IAAI,QAAQ,OAAO,EAAE,UAAU,YAAY,EAAE,MAAM,KAAK,IAAI,EAAE,MAAM,KAAK,IAAI;CAC7E,IAAI,MAAM,SAAA,KACR,QAAQ,GAAG,MAAM,MAAM,GAAA,GAA+B,EAAE;CAC1D,MAAM,MAA4B;EAAE;EAAM;EAAK;CAAM;CACrD,IAAI,OAAO,EAAE,gBAAgB,YAAY,EAAE,aACzC,IAAI,cAAc,EAAE;CACtB,IAAI,EAAE,SAAS,KAAA,KAAa,EAAE,SAAS,MAAM;EAC3C,MAAM,OAAO,YAAY,EAAE,IAAI;EAC/B,IAAI,SAAS,KAAA,GACX,IAAI,OAAO;CACf;CACA,OAAO;AACT;;AAGA,SAAgB,YAAY,OAAuC;CACjE,IAAI;CACJ,IAAI;EACF,OAAO,KAAK,UAAU,KAAK;CAC7B,QACM;EACJ;CACF;CACA,IAAI,SAAS,KAAA,KAAa,OAAO,WAAW,MAAM,MAAM,IAAA,OACtD,OAAO,KAAA;CACT,OAAO,KAAK,MAAM,IAAI;AACxB;;;;;;;AAQA,SAAgB,cAAc,UAA2B,UAA4C;CACnG,OAAO;EACL,GAAG;EACH,OAAO,SAAS;EAChB,GAAI,SAAS,SAAS,KAAA,IAAY,EAAE,MAAM,SAAS,KAAK,IAAI,SAAS,SAAS,KAAA,IAAY,EAAE,MAAM,SAAS,KAAK,IAAI,CAAC;EACrH,GAAI,SAAS,cAAc,EAAE,aAAa,SAAS,YAAY,IAAI,SAAS,cAAc,EAAE,aAAa,SAAS,YAAY,IAAI,CAAC;EACnI,WAAW,KAAK,IAAI,SAAS,WAAW,SAAS,SAAS;CAC5D;AACF;;;;;;;;AASA,SAAgB,wBACd,SACA,MAAA,KACU;CACV,MAAM,WAAW,QAAQ,SAAS,IAAI;CACtC,IAAI,YAAY,GACd,OAAO,CAAC;CAQV,OAPmB,CAAC,GAAG,OAAO,CAAC,CAAC,MAAM,GAAG,MAAM;EAC7C,MAAM,KAAK,EAAE,SAAS,eAAe,OAAO,IAAI;EAChD,MAAM,KAAK,EAAE,SAAS,eAAe,OAAO,IAAI;EAChD,IAAI,OAAO,IACT,OAAO,KAAK;EACd,OAAO,EAAE,YAAY,EAAE;CACzB,CACgB,CAAC,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC,KAAI,MAAK,EAAE,EAAE;AACpD;AAEA,SAAgB,sBAAsB,UAA2B,QAA6C;CAC5G,IAAI,CAAC,QACH,OAAO;CACT,IAAI,OAAO,cAAc,KAAA,KAAa,SAAS,cAAc,OAAO,WAClE,OAAO;CACT,IAAI,OAAO,SAAS,KAAA,KAAa,SAAS,SAAS,OAAO,MACxD,OAAO;CACT,IAAI,OAAO,QAAQ,KAAA,KAAa,SAAS,QAAQ,OAAO,KACtD,OAAO;CACT,IAAI,iBAAiB,QAAQ;EAC3B,IAAI,OAAO,gBAAgB,QAAQ,SAAS,eAAe,MACzD,OAAO;EACT,IAAI,OAAO,OAAO,gBAAgB,YAAY,SAAS,gBAAgB,OAAO,aAC5E,OAAO;CACX;CACA,IAAI,OAAO,UAAU,KAAA,KAAa,SAAS,YAAY,OAAO,OAC5D,OAAO;CACT,OAAO;AACT;;AAGA,SAAgB,cAAc,WAAiD;CAC7E,OAAO,UAAU,MAAM,GAAG,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,cAAc,EAAE,EAAE,CAAC;AACpH"}
|
|
1
|
+
{"version":3,"file":"artifacts-CV2hUKnL.js","names":[],"sources":["../src/session/artifacts.ts"],"sourcesContent":["/**\n * Session artifacts — durable, typed pointers to things a session produced\n * OUTSIDE its transcript: a pull request, a branch, a commit, a file, a\n * deployment, an issue. The artifact stores the locator plus enough\n * metadata to display and re-resolve it; the content stays where it lives.\n *\n * Design constraints (see the store contracts in `./index.ts`):\n *\n * - Artifacts are NOT part of `SessionData`. They live in their own\n * table / map so `load()` / `save()` / export / compaction never see\n * them, and stores that don't implement the optional artifact methods\n * keep working unchanged.\n * - `kind` is an open string. Core knows nothing about what a\n * `pull_request` is; extensions register kinds (detection, rendering,\n * refresh) and unknown kinds always fall back to `label` + `uri`.\n * - `(sessionId, kind, uri)` is the identity: re-emitting the same\n * artifact upserts (refreshes `label` / `meta` / `updatedAt`) instead\n * of duplicating, and keeps the ORIGINAL `id` / `runId` / `turnId` /\n * `createdAt` so the transcript anchor points at the producing turn.\n * - Bounded: `meta` ≤ 16 KB, ≤ 200 artifacts per session. A `find` over\n * 50k files must not become 50k rows.\n */\n\nimport type { JsonValue } from '../types'\nimport { Buffer } from 'node:buffer'\n\n/** Built-in kinds. Open set — extensions add their own. */\nexport const ARTIFACT_KINDS = {\n pullRequest: 'pull_request',\n branch: 'branch',\n commit: 'commit',\n file: 'file',\n} as const\n\n/**\n * Reserved tool-result metadata namespace. Tools (and extension\n * `detect` hooks) emit `metadata.artifacts = ArtifactInput[]` and the\n * loop lifts each entry into the session's artifact store.\n */\nexport const ARTIFACTS_METADATA_KEY = 'artifacts'\n\nexport const ARTIFACT_META_MAX_BYTES = 16_384\nexport const ARTIFACT_LABEL_MAX_CHARS = 512\nexport const ARTIFACT_URI_MAX_CHARS = 2_048\nexport const ARTIFACT_KIND_MAX_CHARS = 64\nexport const ARTIFACTS_PER_SESSION_CAP = 200\n/** Allowed `kind` shape: word chars plus `.`, `:` and `-` for namespacing. */\nexport const ARTIFACT_KIND_PATTERN = /^[\\w.:-]+$/\n\nexport interface SessionArtifact {\n /** Stable id (uuid). Preserved across upserts of the same `(kind, uri)`. */\n id: string\n sessionId: string\n /**\n * Run that produced it. A `persist`-spawned subagent shares the parent\n * session and records under its OWN run id (detection reaches it via the\n * `child:tool:transform` bubble; see `presets/artifacts.ts`).\n */\n runId?: string\n /** Tool-result turn that produced it — the transcript anchor. */\n turnId?: string\n /** Open kind string. Built-ins in {@link ARTIFACT_KINDS}. */\n kind: string\n /** Canonical locator: PR URL, `git:<repo>#<branch>`, `file://<abs path>`, … */\n uri: string\n /** Human line. Always present — the rendering fallback for unknown kinds. */\n label: string\n /**\n * Project the artifact landed in, resolved at emission time from where\n * the thing actually is (a worktree, a sibling repo), defaulting to the\n * session's own `projectRoot`. Drives \"everything produced from this\n * repo\" queries.\n */\n projectRoot?: string\n /** Kind-specific payload, ≤ {@link ARTIFACT_META_MAX_BYTES}. */\n meta?: JsonValue\n createdAt: number\n updatedAt: number\n}\n\n/** What a producer hands to `session.addArtifact` / the metadata namespace. */\nexport interface SessionArtifactInput {\n kind: string\n uri: string\n label: string\n projectRoot?: string\n meta?: JsonValue\n}\n\nexport interface ArtifactFilter {\n sessionId?: string\n /**\n * Tri-state like `SessionStore.list`: string → that project only,\n * `null` → artifacts with no project, omitted → axis ignored.\n */\n projectRoot?: string | null\n kind?: string\n /** Exact locator match — reverse lookup (\"who produced PR #123?\"). Pair with `kind`. */\n uri?: string\n /** Only artifacts with `updatedAt >= since`. */\n since?: number\n limit?: number\n}\n\n/**\n * Validate + normalize a raw input (typically from tool-result metadata,\n * i.e. an untrusted boundary). Returns `null` when the entry is unusable\n * — missing kind/uri/label or oversized in a way truncation can't fix.\n * `label` is clipped, `meta` is dropped (not the artifact) when it exceeds\n * the byte bound.\n */\nexport function normalizeArtifactInput(raw: unknown): SessionArtifactInput | null {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw))\n return null\n const r = raw as Record<string, unknown>\n const kind = typeof r.kind === 'string' ? r.kind.trim() : ''\n const uri = typeof r.uri === 'string' ? r.uri.trim() : ''\n if (!kind || !uri)\n return null\n if (kind.length > ARTIFACT_KIND_MAX_CHARS || uri.length > ARTIFACT_URI_MAX_CHARS)\n return null\n if (!ARTIFACT_KIND_PATTERN.test(kind))\n return null\n let label = typeof r.label === 'string' && r.label.trim() ? r.label.trim() : uri\n if (label.length > ARTIFACT_LABEL_MAX_CHARS)\n label = `${label.slice(0, ARTIFACT_LABEL_MAX_CHARS - 1)}…`\n const out: SessionArtifactInput = { kind, uri, label }\n if (typeof r.projectRoot === 'string' && r.projectRoot)\n out.projectRoot = r.projectRoot\n if (r.meta !== undefined && r.meta !== null) {\n const meta = boundedMeta(r.meta)\n if (meta !== undefined)\n out.meta = meta\n }\n return out\n}\n\n/** `meta` when JSON-serializable and within bounds, else `undefined` (dropped). */\nexport function boundedMeta(value: unknown): JsonValue | undefined {\n let json: string | undefined\n try {\n json = JSON.stringify(value)\n }\n catch {\n return undefined\n }\n if (json === undefined || Buffer.byteLength(json, 'utf8') > ARTIFACT_META_MAX_BYTES)\n return undefined\n return JSON.parse(json) as JsonValue\n}\n\n/**\n * Apply an upsert to an existing row: identity fields (`id`, `runId`,\n * `turnId`, `createdAt`) stay, presentation (`label`, `meta`,\n * `projectRoot`) refresh, `updatedAt` bumps. Shared by every store so the\n * merge semantics can't drift.\n */\nexport function mergeArtifact(existing: SessionArtifact, incoming: SessionArtifact): SessionArtifact {\n return {\n ...existing,\n label: incoming.label,\n ...(incoming.meta !== undefined ? { meta: incoming.meta } : existing.meta !== undefined ? { meta: existing.meta } : {}),\n ...(incoming.projectRoot ? { projectRoot: incoming.projectRoot } : existing.projectRoot ? { projectRoot: existing.projectRoot } : {}),\n updatedAt: Math.max(existing.updatedAt, incoming.updatedAt),\n }\n}\n\n/**\n * Which artifacts to evict so a session stays at or under `cap` after\n * one more insert. `file` artifacts go first (noisiest, cheapest to\n * regenerate), oldest first within a kind; ties keep the caller's order\n * (stable sort), so pass rows in insertion order. Pure — callers delete\n * the returned ids.\n */\nexport function selectArtifactEvictions(\n current: readonly SessionArtifact[],\n cap = ARTIFACTS_PER_SESSION_CAP,\n): string[] {\n const overflow = current.length + 1 - cap\n if (overflow <= 0)\n return []\n const byPriority = [...current].sort((a, b) => {\n const af = a.kind === ARTIFACT_KINDS.file ? 0 : 1\n const bf = b.kind === ARTIFACT_KINDS.file ? 0 : 1\n if (af !== bf)\n return af - bf\n return a.createdAt - b.createdAt\n })\n return byPriority.slice(0, overflow).map(a => a.id)\n}\n\nexport function matchesArtifactFilter(artifact: SessionArtifact, filter: ArtifactFilter | undefined): boolean {\n if (!filter)\n return true\n if (filter.sessionId !== undefined && artifact.sessionId !== filter.sessionId)\n return false\n if (filter.kind !== undefined && artifact.kind !== filter.kind)\n return false\n if (filter.uri !== undefined && artifact.uri !== filter.uri)\n return false\n if ('projectRoot' in filter) {\n if (filter.projectRoot === null && artifact.projectRoot != null)\n return false\n if (typeof filter.projectRoot === 'string' && artifact.projectRoot !== filter.projectRoot)\n return false\n }\n if (filter.since !== undefined && artifact.updatedAt < filter.since)\n return false\n return true\n}\n\n/** Newest first, stable on id. */\nexport function sortArtifacts(artifacts: SessionArtifact[]): SessionArtifact[] {\n return artifacts.sort((a, b) => b.updatedAt - a.updatedAt || b.createdAt - a.createdAt || a.id.localeCompare(b.id))\n}\n"],"mappings":"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"}
|