privateer-agent 0.15.5 → 0.15.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/README.md +11 -0
  2. package/bin/boot-bundle.d.mts +2 -0
  3. package/bin/boot-bundle.mjs +44 -0
  4. package/bin/privateer-launch.mjs +14 -2
  5. package/bin/privateer-verify.mjs +12 -0
  6. package/dist-boot/boot.mjs +3 -0
  7. package/dist-boot/c-27JKSMWL.mjs +1460 -0
  8. package/dist-boot/c-2BMRFV24.mjs +269 -0
  9. package/dist-boot/c-2CTF6JA3.mjs +166 -0
  10. package/dist-boot/c-2G3BBHRJ.mjs +84 -0
  11. package/dist-boot/c-2IDLKXX6.mjs +250 -0
  12. package/dist-boot/c-2NJD5VYM.mjs +8 -0
  13. package/dist-boot/c-2S5EEQPW.mjs +1602 -0
  14. package/dist-boot/c-2WRDCUVI.mjs +25 -0
  15. package/dist-boot/c-2YN3M256.mjs +14 -0
  16. package/dist-boot/c-37GM3GMU.mjs +187 -0
  17. package/dist-boot/c-3STKRSVO.mjs +2480 -0
  18. package/dist-boot/c-3TPV6TQQ.mjs +2320 -0
  19. package/dist-boot/c-3UVHLQDJ.mjs +225 -0
  20. package/dist-boot/c-42PUUZYC.mjs +697 -0
  21. package/dist-boot/c-4D5UMWVW.mjs +683 -0
  22. package/dist-boot/c-4ETZRMTA.mjs +46 -0
  23. package/dist-boot/c-4QT25BD5.mjs +1482 -0
  24. package/dist-boot/c-4WVR32AP.mjs +2579 -0
  25. package/dist-boot/c-5EMM567G.mjs +152 -0
  26. package/dist-boot/c-5FA4CV63.mjs +145 -0
  27. package/dist-boot/c-5GV3X3RB.mjs +14 -0
  28. package/dist-boot/c-5JCEPRIY.mjs +52 -0
  29. package/dist-boot/c-5NDKIIWT.mjs +16 -0
  30. package/dist-boot/c-5QL3AR26.mjs +4665 -0
  31. package/dist-boot/c-5XY6MFKN.mjs +5142 -0
  32. package/dist-boot/c-65UZIZC7.mjs +2897 -0
  33. package/dist-boot/c-6FUXKHOK.mjs +1969 -0
  34. package/dist-boot/c-6JHWQE4V.mjs +18242 -0
  35. package/dist-boot/c-6LOBR4I6.mjs +5280 -0
  36. package/dist-boot/c-6QHOZXKQ.mjs +14394 -0
  37. package/dist-boot/c-6ZO2SADQ.mjs +178 -0
  38. package/dist-boot/c-6ZORVVZP.mjs +1449 -0
  39. package/dist-boot/c-76QH4UCP.mjs +2441 -0
  40. package/dist-boot/c-77GO5L5Y.mjs +20982 -0
  41. package/dist-boot/c-7M23XFTN.mjs +5052 -0
  42. package/dist-boot/c-7TC367E2.mjs +32 -0
  43. package/dist-boot/c-7UOG7POX.mjs +1524 -0
  44. package/dist-boot/c-7VHP3FLN.mjs +376 -0
  45. package/dist-boot/c-A73JHZP2.mjs +13207 -0
  46. package/dist-boot/c-ABXULAFL.mjs +71 -0
  47. package/dist-boot/c-ANDD2AQO.mjs +74 -0
  48. package/dist-boot/c-AOY77AZL.mjs +1430 -0
  49. package/dist-boot/c-AXEPZ22I.mjs +108 -0
  50. package/dist-boot/c-B2Y7VNHU.mjs +427 -0
  51. package/dist-boot/c-B7VJUH73.mjs +77 -0
  52. package/dist-boot/c-BFW6CDVL.mjs +24 -0
  53. package/dist-boot/c-BHNIF2AR.mjs +188 -0
  54. package/dist-boot/c-BKF2O6BL.mjs +23 -0
  55. package/dist-boot/c-BOZXFTZN.mjs +8 -0
  56. package/dist-boot/c-BRNYJWZL.mjs +28 -0
  57. package/dist-boot/c-C3N4Z2HO.mjs +93 -0
  58. package/dist-boot/c-C4IV7ZFG.mjs +717 -0
  59. package/dist-boot/c-C5NK6UYV.mjs +793 -0
  60. package/dist-boot/c-C67644MB.mjs +1659 -0
  61. package/dist-boot/c-C6S2YB53.mjs +620 -0
  62. package/dist-boot/c-CDBEJSBF.mjs +37 -0
  63. package/dist-boot/c-CG47HBKU.mjs +435 -0
  64. package/dist-boot/c-CKCTWCT5.mjs +51 -0
  65. package/dist-boot/c-CN77DCGF.mjs +60 -0
  66. package/dist-boot/c-CRBXNKFO.mjs +1795 -0
  67. package/dist-boot/c-CRIHASQ6.mjs +973 -0
  68. package/dist-boot/c-CU4NGAUO.mjs +3786 -0
  69. package/dist-boot/c-CWRFLGQU.mjs +1883 -0
  70. package/dist-boot/c-CYQB2USO.mjs +32 -0
  71. package/dist-boot/c-DEE67DJO.mjs +379 -0
  72. package/dist-boot/c-DIFDBYOP.mjs +1258 -0
  73. package/dist-boot/c-DOSGVXDZ.mjs +34879 -0
  74. package/dist-boot/c-DR7XQI32.mjs +381 -0
  75. package/dist-boot/c-DTGPSB46.mjs +14666 -0
  76. package/dist-boot/c-DTHDNA4P.mjs +320 -0
  77. package/dist-boot/c-E4Z3Y5B5.mjs +3864 -0
  78. package/dist-boot/c-E66Z2TI7.mjs +203 -0
  79. package/dist-boot/c-EBU6RLRV.mjs +1527 -0
  80. package/dist-boot/c-EBZZNGSF.mjs +432 -0
  81. package/dist-boot/c-EC3LJ2KF.mjs +1032 -0
  82. package/dist-boot/c-EQBKXWNX.mjs +15829 -0
  83. package/dist-boot/c-EUEPIW4S.mjs +574 -0
  84. package/dist-boot/c-EX4YVWAT.mjs +378 -0
  85. package/dist-boot/c-EYZGSAJU.mjs +98 -0
  86. package/dist-boot/c-F75VRKY4.mjs +172 -0
  87. package/dist-boot/c-FH4NXKHV.mjs +177 -0
  88. package/dist-boot/c-FHNUCTEM.mjs +140 -0
  89. package/dist-boot/c-FJ5T42DS.mjs +5349 -0
  90. package/dist-boot/c-FPCNRL7G.mjs +1728 -0
  91. package/dist-boot/c-G4DLN7Q4.mjs +8 -0
  92. package/dist-boot/c-G56GYQFZ.mjs +2507 -0
  93. package/dist-boot/c-GLIOERDQ.mjs +1200 -0
  94. package/dist-boot/c-GMJ5HUBM.mjs +14 -0
  95. package/dist-boot/c-H3HSGMAQ.mjs +461 -0
  96. package/dist-boot/c-HIKTO6P7.mjs +275 -0
  97. package/dist-boot/c-I2MCJ34O.mjs +464 -0
  98. package/dist-boot/c-I3C6LBW4.mjs +765 -0
  99. package/dist-boot/c-I54OKQHW.mjs +387 -0
  100. package/dist-boot/c-IFSP3R4D.mjs +80 -0
  101. package/dist-boot/c-IZK77VB7.mjs +171 -0
  102. package/dist-boot/c-J3Y25UGE.mjs +54 -0
  103. package/dist-boot/c-J5IESS7W.mjs +27750 -0
  104. package/dist-boot/c-JJWZBY7L.mjs +254 -0
  105. package/dist-boot/c-JKTFXTGF.mjs +463 -0
  106. package/dist-boot/c-JN57AXQ4.mjs +77 -0
  107. package/dist-boot/c-KFIO6LUW.mjs +1096 -0
  108. package/dist-boot/c-KIEMEFWW.mjs +478 -0
  109. package/dist-boot/c-KIVXWBYD.mjs +28 -0
  110. package/dist-boot/c-KP6CRIP4.mjs +580 -0
  111. package/dist-boot/c-L26VOJX4.mjs +11558 -0
  112. package/dist-boot/c-L5GHWG5G.mjs +5988 -0
  113. package/dist-boot/c-M7NSQAKK.mjs +353 -0
  114. package/dist-boot/c-MCEWOPBW.mjs +56 -0
  115. package/dist-boot/c-MGPIEG7I.mjs +20 -0
  116. package/dist-boot/c-NREXJV3M.mjs +393 -0
  117. package/dist-boot/c-O5PP6CTX.mjs +162 -0
  118. package/dist-boot/c-OBQDHSXM.mjs +1774 -0
  119. package/dist-boot/c-OLQHHDD4.mjs +21 -0
  120. package/dist-boot/c-OXW4JQQH.mjs +319 -0
  121. package/dist-boot/c-P3D7ZUWN.mjs +1288 -0
  122. package/dist-boot/c-P4PQZVV5.mjs +948 -0
  123. package/dist-boot/c-P63T3XL2.mjs +26373 -0
  124. package/dist-boot/c-P6N5DQGZ.mjs +194 -0
  125. package/dist-boot/c-P7MLKQFC.mjs +58 -0
  126. package/dist-boot/c-PB3PZJL5.mjs +1276 -0
  127. package/dist-boot/c-PTN4S6G2.mjs +1259 -0
  128. package/dist-boot/c-PYCE5J7U.mjs +1083 -0
  129. package/dist-boot/c-Q4HYCRLB.mjs +19410 -0
  130. package/dist-boot/c-QUXMETGG.mjs +68 -0
  131. package/dist-boot/c-RDMJZCOX.mjs +356 -0
  132. package/dist-boot/c-ROGJK76M.mjs +17 -0
  133. package/dist-boot/c-RQJJ26T4.mjs +708 -0
  134. package/dist-boot/c-RSKCUPJF.mjs +7559 -0
  135. package/dist-boot/c-RVJU4O6P.mjs +37 -0
  136. package/dist-boot/c-S2RVHR3M.mjs +165 -0
  137. package/dist-boot/c-SKMK3PEE.mjs +91120 -0
  138. package/dist-boot/c-TI7SM4EG.mjs +20 -0
  139. package/dist-boot/c-TILJ6GXD.mjs +1235 -0
  140. package/dist-boot/c-TT6BCUJD.mjs +114 -0
  141. package/dist-boot/c-U4ITOXAN.mjs +2107 -0
  142. package/dist-boot/c-UGERXVO2.mjs +7120 -0
  143. package/dist-boot/c-UPBH5AXY.mjs +1363 -0
  144. package/dist-boot/c-US2PUNZL.mjs +597 -0
  145. package/dist-boot/c-UU4WZPPE.mjs +20 -0
  146. package/dist-boot/c-UWVIYPQS.mjs +39 -0
  147. package/dist-boot/c-V4RHQBPQ.mjs +17683 -0
  148. package/dist-boot/c-V5MRVK47.mjs +351 -0
  149. package/dist-boot/c-V6CL266R.mjs +1755 -0
  150. package/dist-boot/c-VJTMFKYE.mjs +14975 -0
  151. package/dist-boot/c-VJTRUKIB.mjs +773 -0
  152. package/dist-boot/c-W4IFSHPW.mjs +43 -0
  153. package/dist-boot/c-WETGB2CF.mjs +113 -0
  154. package/dist-boot/c-WO3QSZUU.mjs +1337 -0
  155. package/dist-boot/c-WQLH73TY.mjs +242 -0
  156. package/dist-boot/c-XL735JW5.mjs +500 -0
  157. package/dist-boot/c-Y7HADL5B.mjs +1107 -0
  158. package/dist-boot/c-YGQHSVSK.mjs +41 -0
  159. package/dist-boot/c-YMP2AMEB.mjs +10350 -0
  160. package/dist-boot/c-YRDO2WEF.mjs +12012 -0
  161. package/dist-boot/c-YUSTRATJ.mjs +8 -0
  162. package/dist-boot/c-Z2262R22.mjs +2697 -0
  163. package/dist-boot/c-Z4ALQMJC.mjs +709 -0
  164. package/dist-boot/c-Z5ZUQVUY.mjs +62 -0
  165. package/dist-boot/c-ZDZUKXF7.mjs +874 -0
  166. package/dist-boot/c-ZJYLGIC3.mjs +32 -0
  167. package/dist-boot/c-ZNA5CDMI.mjs +77 -0
  168. package/dist-boot/c-ZSO6DI3M.mjs +204 -0
  169. package/dist-boot/c-ZWUVHKMK.mjs +100 -0
  170. package/dist-boot/c-ZY4MESEW.mjs +832 -0
  171. package/dist-boot/c-ZZ5REI4L.mjs +329 -0
  172. package/dist-boot/cli.mjs +51 -0
  173. package/dist-boot/ext-anthropic-attribution.mjs +207 -0
  174. package/dist-boot/ext-pi-background-tasks.mjs +7234 -0
  175. package/dist-boot/ext-pi-subagents.mjs +37 -0
  176. package/dist-boot/ext-privateer-account.mjs +4426 -0
  177. package/dist-boot/ext-privateer-brand.mjs +5274 -0
  178. package/dist-boot/ext-privateer-codemode.mjs +37 -0
  179. package/dist-boot/ext-privateer-computer.mjs +626 -0
  180. package/dist-boot/ext-privateer-connect.mjs +1862 -0
  181. package/dist-boot/ext-privateer-context.mjs +323 -0
  182. package/dist-boot/ext-privateer-desktop.mjs +92 -0
  183. package/dist-boot/ext-privateer-final-audit.mjs +48 -0
  184. package/dist-boot/ext-privateer-fresh.mjs +81 -0
  185. package/dist-boot/ext-privateer-gate.mjs +5959 -0
  186. package/dist-boot/ext-privateer-hints.mjs +236 -0
  187. package/dist-boot/ext-privateer-media.mjs +2626 -0
  188. package/dist-boot/ext-privateer-models.mjs +3397 -0
  189. package/dist-boot/ext-privateer-posture.mjs +3006 -0
  190. package/dist-boot/ext-privateer-privacy.mjs +4578 -0
  191. package/dist-boot/ext-privateer-recovery.mjs +287 -0
  192. package/dist-boot/ext-privateer-speak.mjs +4754 -0
  193. package/dist-boot/ext-privateer-terminals.mjs +725 -0
  194. package/dist-boot/ext-privateer-tools.mjs +528 -0
  195. package/dist-boot/ext-privateer-truncation.mjs +74 -0
  196. package/dist-boot/ext-privateer-update.mjs +210 -0
  197. package/dist-boot/ext-privateer-vision.mjs +148 -0
  198. package/dist-boot/ext-privateer-web.mjs +543 -0
  199. package/dist-boot/ext-rpiv-ask-user-question.mjs +710 -0
  200. package/dist-boot/manifest.json +9 -0
  201. package/extensions/privateer-brand.ts +3 -1
  202. package/extensions/privateer-context.ts +4 -2
  203. package/extensions/privateer-final-audit.ts +17 -0
  204. package/extensions/privateer-gate.ts +41 -8
  205. package/extensions/privateer-web.ts +4 -4
  206. package/package.json +3 -1
  207. package/patches/@earendil-works+pi-coding-agent+1.3.0.patch +110 -2
  208. package/patches/pi-background-tasks+2.6.10.patch +91 -7
  209. package/src/config/moatManifest.json +1 -0
  210. package/src/config/whatsNew.json +2 -2
  211. package/src/context.ts +33 -5
  212. package/src/engine/finalAudit.ts +38 -0
  213. package/src/engine/stallWatchdog.ts +8 -1
  214. package/src/providers/account.ts +34 -3
@@ -0,0 +1,2697 @@
1
+ import{createRequire as __pvCR}from"node:module";import{fileURLToPath as __pvF}from"node:url";import{dirname as __pvD}from"node:path";const require=__pvCR(import.meta.url);const __pvUrl=(r)=>new URL(r,import.meta.url).href;const __pvFile=(r)=>__pvF(new URL(r,import.meta.url));
2
+ import {
3
+ __name
4
+ } from "./c-CN77DCGF.mjs";
5
+
6
+ // node_modules/pi-background-tasks/src/core/anthropic-attribution.ts?ext=anthropic-attribution
7
+ import { createHash, randomUUID } from "node:crypto";
8
+ import { appendFileSync, readFileSync } from "node:fs";
9
+ import { homedir } from "node:os";
10
+ import { isAbsolute, join } from "node:path";
11
+ var CLAUDE_CODE_SESSION_HEADER = "X-Claude-Code-Session-Id";
12
+ var CLAUDE_CODE_VERSION = "2.1.280";
13
+ var CLAUDE_CODE_ENTRYPOINT = "sdk-cli";
14
+ var CLAUDE_CODE_USER_AGENT = "claude-cli/2.1.280 (external, sdk-cli)";
15
+ var ANTHROPIC_1M_CONTEXT_BETA = "context-1m-2025-08-07";
16
+ var CLAUDE_CODE_200K_SUBSCRIPTION_CONTEXT_WINDOW = 2e5;
17
+ var CLAUDE_CODE_LEGACY_BETA_VALUES = [
18
+ "claude-code-20250219",
19
+ "oauth-2025-04-20",
20
+ "interleaved-thinking-2025-05-14",
21
+ "thinking-token-count-2026-05-13",
22
+ "context-management-2025-06-27",
23
+ "prompt-caching-scope-2026-01-05",
24
+ "advisor-tool-2026-03-01",
25
+ "structured-outputs-2025-12-15"
26
+ ];
27
+ var CLAUDE_CODE_ADAPTIVE_200K_BETA_VALUES = [
28
+ "claude-code-20250219",
29
+ "oauth-2025-04-20",
30
+ "interleaved-thinking-2025-05-14",
31
+ "thinking-token-count-2026-05-13",
32
+ "context-management-2025-06-27",
33
+ "prompt-caching-scope-2026-01-05",
34
+ "mid-conversation-system-2026-04-07"
35
+ ];
36
+ var CLAUDE_CODE_FABLE_5_1_200K_BETA_VALUES = [
37
+ ...CLAUDE_CODE_ADAPTIVE_200K_BETA_VALUES,
38
+ "thinking-binding-controls-2026-08-01",
39
+ "cache-diagnosis-2026-04-07"
40
+ ];
41
+ function build200KSubscriptionBetaHeader(values) {
42
+ if (values.includes(ANTHROPIC_1M_CONTEXT_BETA)) {
43
+ throw new Error(
44
+ `Anthropic attribution 200K subscription policy must not emit ${ANTHROPIC_1M_CONTEXT_BETA}`
45
+ );
46
+ }
47
+ return values.join(",");
48
+ }
49
+ __name(build200KSubscriptionBetaHeader, "build200KSubscriptionBetaHeader");
50
+ var CLAUDE_CODE_BETA = build200KSubscriptionBetaHeader(CLAUDE_CODE_LEGACY_BETA_VALUES);
51
+ var CLAUDE_CODE_ADAPTIVE_200K_BETA = build200KSubscriptionBetaHeader(
52
+ CLAUDE_CODE_ADAPTIVE_200K_BETA_VALUES
53
+ );
54
+ var CLAUDE_CODE_FABLE_5_1_200K_BETA = build200KSubscriptionBetaHeader(
55
+ CLAUDE_CODE_FABLE_5_1_200K_BETA_VALUES
56
+ );
57
+ var CLAUDE_AGENT_SDK_SYSTEM_TEXT = "You are a Claude agent, built on Anthropic's Claude Agent SDK.";
58
+ var FINGERPRINT_SALT = "59cf53e54c78";
59
+ var AUDIT_ENV = "PIPELINE_ANTHROPIC_ATTRIBUTION_AUDIT_PATH";
60
+ var CACHE_RETENTION_ENV = "PI_CACHE_RETENTION";
61
+ var ANTHROPIC_ACCOUNT_CONFIG_PATH_ENV = "PI_ANTHROPIC_ACCOUNT_CONFIG_PATH";
62
+ var ANTHROPIC_CACHE_RETENTION_ENTRY = "pipeline-anthropic-cache-retention";
63
+ var ANTHROPIC_CACHE_RETENTION_SCHEMA = "pipeline.anthropic_cache_retention.v1";
64
+ var ANTHROPIC_ATTRIBUTION_CLAIM_CHANNEL = "pi-anthropic-attribution:claim:v1";
65
+ var ANTHROPIC_ATTRIBUTION_CLAIM_SCHEMA = "pi-anthropic-attribution.claim.v1";
66
+ var NATIVE_ATTESTATION_PLACEHOLDER = "00000";
67
+ var ANTHROPIC_CACHE_CONTROL_BREAKPOINT_LIMIT = 4;
68
+ var ANTHROPIC_LINEAGE_DIAGNOSTIC_TYPE = "anthropic-cache-lineage";
69
+ var ANTHROPIC_LINEAGE_SCHEMA = "pi-anthropic-attribution.lineage.v1";
70
+ var ANTHROPIC_PROJECTION_VERSION = 3;
71
+ var ANTHROPIC_OFFICIAL_ORIGIN = "https://api.anthropic.com";
72
+ var ANTHROPIC_BETA_MESSAGES_URL = `${ANTHROPIC_OFFICIAL_ORIGIN}/v1/messages?beta=true`;
73
+ var ANTHROPIC_CACHE_DIAGNOSTICS_BETA = "cache-diagnosis-2026-04-07";
74
+ var ANTHROPIC_THINKING_BINDING_BETA = "thinking-binding-controls-2026-08-01";
75
+ var COMPACTION_SUMMARY_PREFIX = "The conversation history before this point was compacted into the following summary:";
76
+ var ANTHROPIC_SYSTEM_PROMPT_BAD_LINE_PREFIXES = [
77
+ "- When asked about: extensions (docs/extensions.md, examples/extensions/)",
78
+ "- When working on pi topics, read the docs and examples, and follow .md cross-references before implementing"
79
+ ];
80
+ function isAnthropicSystemPromptBadLine(line) {
81
+ return ANTHROPIC_SYSTEM_PROMPT_BAD_LINE_PREFIXES.some((prefix) => line.startsWith(prefix));
82
+ }
83
+ __name(isAnthropicSystemPromptBadLine, "isAnthropicSystemPromptBadLine");
84
+ var parseJsonSource = JSON.parse.bind(JSON);
85
+ function parseJsonValue(text, label) {
86
+ try {
87
+ return parseJsonSource(text);
88
+ } catch (error) {
89
+ throw new Error(
90
+ `${label} is invalid JSON: ${error instanceof Error ? error.message : String(error)}`
91
+ );
92
+ }
93
+ }
94
+ __name(parseJsonValue, "parseJsonValue");
95
+ function parseJsonObject(text, label) {
96
+ const parsed = parseJsonValue(text, label);
97
+ if (!isPlainObject(parsed)) throw new Error(`${label} must be a JSON object`);
98
+ return parsed;
99
+ }
100
+ __name(parseJsonObject, "parseJsonObject");
101
+ function claudeCode200KSubscriptionPolicy(modelId, beta, thinkingPolicy, features = {}) {
102
+ if (beta.split(",").includes(ANTHROPIC_1M_CONTEXT_BETA)) {
103
+ throw new Error(
104
+ `Anthropic attribution 200K subscription policy for ${modelId} must not emit ${ANTHROPIC_1M_CONTEXT_BETA}`
105
+ );
106
+ }
107
+ return {
108
+ modelId,
109
+ beta,
110
+ thinkingPolicy,
111
+ contextWindow: CLAUDE_CODE_200K_SUBSCRIPTION_CONTEXT_WINDOW,
112
+ enforcesThinkingPrefixBinding: features.enforcesThinkingPrefixBinding === true,
113
+ supportsCacheDiagnostics: features.supportsCacheDiagnostics === true
114
+ };
115
+ }
116
+ __name(claudeCode200KSubscriptionPolicy, "claudeCode200KSubscriptionPolicy");
117
+ var CLAUDE_CODE_MODEL_POLICIES = Object.freeze({
118
+ "claude-3-5-haiku-20241022": claudeCode200KSubscriptionPolicy(
119
+ "claude-3-5-haiku-20241022",
120
+ CLAUDE_CODE_BETA,
121
+ "fixed-budget"
122
+ ),
123
+ "claude-3-5-haiku-latest": claudeCode200KSubscriptionPolicy(
124
+ "claude-3-5-haiku-latest",
125
+ CLAUDE_CODE_BETA,
126
+ "fixed-budget"
127
+ ),
128
+ "claude-3-5-sonnet-20240620": claudeCode200KSubscriptionPolicy(
129
+ "claude-3-5-sonnet-20240620",
130
+ CLAUDE_CODE_BETA,
131
+ "fixed-budget"
132
+ ),
133
+ "claude-3-5-sonnet-20241022": claudeCode200KSubscriptionPolicy(
134
+ "claude-3-5-sonnet-20241022",
135
+ CLAUDE_CODE_BETA,
136
+ "fixed-budget"
137
+ ),
138
+ "claude-3-7-sonnet-20250219": claudeCode200KSubscriptionPolicy(
139
+ "claude-3-7-sonnet-20250219",
140
+ CLAUDE_CODE_BETA,
141
+ "fixed-budget"
142
+ ),
143
+ "claude-3-haiku-20240307": claudeCode200KSubscriptionPolicy(
144
+ "claude-3-haiku-20240307",
145
+ CLAUDE_CODE_BETA,
146
+ "fixed-budget"
147
+ ),
148
+ "claude-3-opus-20240229": claudeCode200KSubscriptionPolicy(
149
+ "claude-3-opus-20240229",
150
+ CLAUDE_CODE_BETA,
151
+ "fixed-budget"
152
+ ),
153
+ "claude-3-sonnet-20240229": claudeCode200KSubscriptionPolicy(
154
+ "claude-3-sonnet-20240229",
155
+ CLAUDE_CODE_BETA,
156
+ "fixed-budget"
157
+ ),
158
+ "claude-fable-5": claudeCode200KSubscriptionPolicy(
159
+ "claude-fable-5",
160
+ CLAUDE_CODE_ADAPTIVE_200K_BETA,
161
+ "adaptive-effort"
162
+ ),
163
+ "claude-fable-5-1": claudeCode200KSubscriptionPolicy(
164
+ "claude-fable-5-1",
165
+ CLAUDE_CODE_FABLE_5_1_200K_BETA,
166
+ "adaptive-effort",
167
+ { enforcesThinkingPrefixBinding: true, supportsCacheDiagnostics: true }
168
+ ),
169
+ "claude-haiku-4-5": claudeCode200KSubscriptionPolicy(
170
+ "claude-haiku-4-5",
171
+ CLAUDE_CODE_BETA,
172
+ "fixed-budget"
173
+ ),
174
+ "claude-haiku-4-5-20251001": claudeCode200KSubscriptionPolicy(
175
+ "claude-haiku-4-5-20251001",
176
+ CLAUDE_CODE_BETA,
177
+ "fixed-budget"
178
+ ),
179
+ "claude-opus-4-0": claudeCode200KSubscriptionPolicy(
180
+ "claude-opus-4-0",
181
+ CLAUDE_CODE_BETA,
182
+ "fixed-budget"
183
+ ),
184
+ "claude-opus-4-1": claudeCode200KSubscriptionPolicy(
185
+ "claude-opus-4-1",
186
+ CLAUDE_CODE_BETA,
187
+ "fixed-budget"
188
+ ),
189
+ "claude-opus-4-1-20250805": claudeCode200KSubscriptionPolicy(
190
+ "claude-opus-4-1-20250805",
191
+ CLAUDE_CODE_BETA,
192
+ "fixed-budget"
193
+ ),
194
+ "claude-opus-4-20250514": claudeCode200KSubscriptionPolicy(
195
+ "claude-opus-4-20250514",
196
+ CLAUDE_CODE_BETA,
197
+ "fixed-budget"
198
+ ),
199
+ "claude-opus-4-5": claudeCode200KSubscriptionPolicy(
200
+ "claude-opus-4-5",
201
+ CLAUDE_CODE_BETA,
202
+ "fixed-budget"
203
+ ),
204
+ "claude-opus-4-5-20251101": claudeCode200KSubscriptionPolicy(
205
+ "claude-opus-4-5-20251101",
206
+ CLAUDE_CODE_BETA,
207
+ "fixed-budget"
208
+ ),
209
+ "claude-opus-4-6": claudeCode200KSubscriptionPolicy(
210
+ "claude-opus-4-6",
211
+ CLAUDE_CODE_ADAPTIVE_200K_BETA,
212
+ "adaptive-effort"
213
+ ),
214
+ "claude-opus-4-7": claudeCode200KSubscriptionPolicy(
215
+ "claude-opus-4-7",
216
+ CLAUDE_CODE_ADAPTIVE_200K_BETA,
217
+ "adaptive-effort"
218
+ ),
219
+ "claude-opus-4-8": claudeCode200KSubscriptionPolicy(
220
+ "claude-opus-4-8",
221
+ CLAUDE_CODE_ADAPTIVE_200K_BETA,
222
+ "adaptive-effort"
223
+ ),
224
+ "claude-opus-5": claudeCode200KSubscriptionPolicy(
225
+ "claude-opus-5",
226
+ CLAUDE_CODE_ADAPTIVE_200K_BETA,
227
+ "adaptive-effort"
228
+ ),
229
+ "claude-opus-5-5": claudeCode200KSubscriptionPolicy(
230
+ "claude-opus-5-5",
231
+ CLAUDE_CODE_ADAPTIVE_200K_BETA,
232
+ "adaptive-effort"
233
+ ),
234
+ "claude-sonnet-4-0": claudeCode200KSubscriptionPolicy(
235
+ "claude-sonnet-4-0",
236
+ CLAUDE_CODE_BETA,
237
+ "fixed-budget"
238
+ ),
239
+ "claude-sonnet-4-20250514": claudeCode200KSubscriptionPolicy(
240
+ "claude-sonnet-4-20250514",
241
+ CLAUDE_CODE_BETA,
242
+ "fixed-budget"
243
+ ),
244
+ "claude-sonnet-4-5": claudeCode200KSubscriptionPolicy(
245
+ "claude-sonnet-4-5",
246
+ CLAUDE_CODE_BETA,
247
+ "fixed-budget"
248
+ ),
249
+ "claude-sonnet-4-5-20250929": claudeCode200KSubscriptionPolicy(
250
+ "claude-sonnet-4-5-20250929",
251
+ CLAUDE_CODE_BETA,
252
+ "fixed-budget"
253
+ ),
254
+ "claude-sonnet-4-6": claudeCode200KSubscriptionPolicy(
255
+ "claude-sonnet-4-6",
256
+ CLAUDE_CODE_ADAPTIVE_200K_BETA,
257
+ "adaptive-effort"
258
+ ),
259
+ "claude-sonnet-5": claudeCode200KSubscriptionPolicy(
260
+ "claude-sonnet-5",
261
+ CLAUDE_CODE_ADAPTIVE_200K_BETA,
262
+ "adaptive-effort"
263
+ ),
264
+ "claude-sonnet-5-5": claudeCode200KSubscriptionPolicy(
265
+ "claude-sonnet-5-5",
266
+ CLAUDE_CODE_ADAPTIVE_200K_BETA,
267
+ "adaptive-effort"
268
+ )
269
+ });
270
+ function resolveHostAnthropicMessagesApi(host) {
271
+ const factory = Reflect.get(host, "anthropicMessagesApi");
272
+ if (typeof factory !== "function") {
273
+ const condition = factory === void 0 ? "missing" : "invalid";
274
+ throw new Error(
275
+ `pi_anthropic_attribution_host_adapter_${condition}: the host must expose compat.anthropicMessagesApi. Upgrade the host; only ambient attribution may be disabled with PI_BG_FEATURES (Anthropic children remain mandatory).`
276
+ );
277
+ }
278
+ return factory;
279
+ }
280
+ __name(resolveHostAnthropicMessagesApi, "resolveHostAnthropicMessagesApi");
281
+ function transcriptError(message) {
282
+ return new Error(`pi_anthropic_attribution_transcript_unsupported: ${message}`);
283
+ }
284
+ __name(transcriptError, "transcriptError");
285
+ function isPiTool(value) {
286
+ return isPlainObject(value) && typeof value["name"] === "string" && value["name"].length > 0 && (value["description"] === void 0 || typeof value["description"] === "string") && (value["parameters"] === void 0 || isPlainObject(value["parameters"]));
287
+ }
288
+ __name(isPiTool, "isPiTool");
289
+ function resolveHostTranscriptHelpers(host) {
290
+ const prompt = Reflect.get(host, "getCurrentSystemPrompt");
291
+ const tools = Reflect.get(host, "getCurrentTools");
292
+ if (prompt === void 0 && tools === void 0) return void 0;
293
+ if (typeof prompt !== "function" || typeof tools !== "function") {
294
+ throw transcriptError("Pi must supply both getCurrentSystemPrompt and getCurrentTools");
295
+ }
296
+ return {
297
+ getCurrentSystemPrompt(messages) {
298
+ const result = Reflect.apply(prompt, host, [messages]);
299
+ if (typeof result !== "string") throw transcriptError("Pi returned an invalid system prompt");
300
+ return result;
301
+ },
302
+ getCurrentTools(messages) {
303
+ const result = Reflect.apply(tools, host, [messages]);
304
+ if (!Array.isArray(result) || !result.every(isPiTool)) {
305
+ throw transcriptError("Pi returned invalid tool declarations");
306
+ }
307
+ return result;
308
+ }
309
+ };
310
+ }
311
+ __name(resolveHostTranscriptHelpers, "resolveHostTranscriptHelpers");
312
+ function validateSystemMessage(message) {
313
+ if (typeof message.timestamp !== "number" || !Number.isFinite(message.timestamp)) {
314
+ throw transcriptError("system message timestamp must be finite");
315
+ }
316
+ if (typeof message.content !== "string" && (!Array.isArray(message.content) || !message.content.every(
317
+ (block) => isPlainObject(block) && block["type"] === "text" && typeof block["text"] === "string"
318
+ ))) {
319
+ throw transcriptError("system message content must be text");
320
+ }
321
+ if (message.sections !== void 0 && (!isPlainObject(message.sections) || !Object.values(message.sections).every(
322
+ (value) => value === null || typeof value === "string"
323
+ ))) {
324
+ throw transcriptError("system message sections must be strings or null");
325
+ }
326
+ if (message.toolsAdded !== void 0 && (!Array.isArray(message.toolsAdded) || !message.toolsAdded.every(isPiTool))) {
327
+ throw transcriptError("system message toolsAdded must contain tool declarations");
328
+ }
329
+ if (message.toolsRemoved !== void 0 && (!Array.isArray(message.toolsRemoved) || !message.toolsRemoved.every(
330
+ (tool) => isPlainObject(tool) && typeof tool["name"] === "string" && tool["name"].length > 0
331
+ ))) {
332
+ throw transcriptError("system message toolsRemoved must contain tool names");
333
+ }
334
+ }
335
+ __name(validateSystemMessage, "validateSystemMessage");
336
+ function resolveAnthropicTranscript(context, helpers) {
337
+ if (!context.messages.some((message) => message.role === "system")) return context;
338
+ if (helpers === void 0) {
339
+ throw transcriptError("system messages require gateway-injected Pi transcript helpers");
340
+ }
341
+ for (const message of context.messages) {
342
+ if (message.role === "system") validateSystemMessage(message);
343
+ }
344
+ const replay = context.systemPrompt !== void 0 || context.tools !== void 0 ? [
345
+ {
346
+ role: "system",
347
+ content: context.systemPrompt ?? "",
348
+ ...context.tools === void 0 ? {} : { toolsAdded: context.tools },
349
+ timestamp: 0
350
+ },
351
+ ...context.messages
352
+ ] : context.messages;
353
+ return {
354
+ systemPrompt: helpers.getCurrentSystemPrompt(replay),
355
+ tools: helpers.getCurrentTools(replay),
356
+ // Normalize before compaction detection, signature-epoch selection, and wire
357
+ // conversion so every lineage proof sees the same conversation-only sequence.
358
+ messages: context.messages.filter((message) => message.role !== "system")
359
+ };
360
+ }
361
+ __name(resolveAnthropicTranscript, "resolveAnthropicTranscript");
362
+ var LocalAssistantMessageEventStream = class {
363
+ static {
364
+ __name(this, "LocalAssistantMessageEventStream");
365
+ }
366
+ queue = [];
367
+ waiting = [];
368
+ done = false;
369
+ finalResultPromise;
370
+ resolveFinalResult;
371
+ constructor() {
372
+ this.finalResultPromise = new Promise((resolve) => {
373
+ this.resolveFinalResult = resolve;
374
+ });
375
+ }
376
+ push(event) {
377
+ if (this.done) return;
378
+ if (event.type === "done") {
379
+ this.done = true;
380
+ this.resolveFinalResult(event.message);
381
+ } else if (event.type === "error") {
382
+ this.done = true;
383
+ this.resolveFinalResult(event.error);
384
+ }
385
+ const waiter = this.waiting.shift();
386
+ if (waiter) waiter({ value: event, done: false });
387
+ else this.queue.push(event);
388
+ }
389
+ end(result) {
390
+ this.done = true;
391
+ if (result !== void 0) this.resolveFinalResult(result);
392
+ while (this.waiting.length > 0) {
393
+ this.waiting.shift()?.({ value: void 0, done: true });
394
+ }
395
+ }
396
+ async *[Symbol.asyncIterator]() {
397
+ for (; ; ) {
398
+ const queued = this.queue.shift();
399
+ if (queued) {
400
+ yield queued;
401
+ } else if (this.done) {
402
+ return;
403
+ } else {
404
+ const next = await new Promise(
405
+ (resolve) => this.waiting.push(resolve)
406
+ );
407
+ if (next.done) return;
408
+ yield next.value;
409
+ }
410
+ }
411
+ }
412
+ result() {
413
+ return this.finalResultPromise;
414
+ }
415
+ };
416
+ function createAssistantMessageEventStream() {
417
+ return new LocalAssistantMessageEventStream();
418
+ }
419
+ __name(createAssistantMessageEventStream, "createAssistantMessageEventStream");
420
+ function isPlainObject(value) {
421
+ return value !== null && typeof value === "object" && !Array.isArray(value);
422
+ }
423
+ __name(isPlainObject, "isPlainObject");
424
+ function providerEnvValue(name, env) {
425
+ return env?.[name] ?? process.env[name];
426
+ }
427
+ __name(providerEnvValue, "providerEnvValue");
428
+ function parseCacheRetention(value, source) {
429
+ if (value === "none" || value === "short" || value === "long") return value;
430
+ throw new Error(
431
+ `Anthropic attribution ${source} must be one of none, short, or long; got ${JSON.stringify(value)}`
432
+ );
433
+ }
434
+ __name(parseCacheRetention, "parseCacheRetention");
435
+ function resolveCacheRetentionPreference(options, sessionOverride) {
436
+ if (options?.cacheRetention !== void 0) return options.cacheRetention;
437
+ if (sessionOverride !== void 0) return sessionOverride;
438
+ const configured = providerEnvValue(CACHE_RETENTION_ENV, options?.env);
439
+ if (configured !== void 0) return parseCacheRetention(configured, CACHE_RETENTION_ENV);
440
+ return "long";
441
+ }
442
+ __name(resolveCacheRetentionPreference, "resolveCacheRetentionPreference");
443
+ function resolveRegisteredCacheRetention(options, sessionOverride) {
444
+ if (options?.cacheRetention === "none") return "none";
445
+ if (sessionOverride !== void 0) return sessionOverride;
446
+ const configured = providerEnvValue(CACHE_RETENTION_ENV, options?.env);
447
+ if (configured !== void 0) return parseCacheRetention(configured, CACHE_RETENTION_ENV);
448
+ if (options?.cacheRetention === "long") return "long";
449
+ return "long";
450
+ }
451
+ __name(resolveRegisteredCacheRetention, "resolveRegisteredCacheRetention");
452
+ function restoreAnthropicSessionCacheRetention(entries) {
453
+ let restored;
454
+ for (const entry of entries) {
455
+ if (!isPlainObject(entry) || entry["type"] !== "custom") continue;
456
+ if (entry["customType"] !== ANTHROPIC_CACHE_RETENTION_ENTRY) continue;
457
+ const data = entry["data"];
458
+ if (!isPlainObject(data) || data["schema_version"] !== ANTHROPIC_CACHE_RETENTION_SCHEMA || data["retention"] !== "default" && data["retention"] !== "short" && data["retention"] !== "long") {
459
+ throw new Error("Anthropic attribution found a malformed persisted cache retention entry");
460
+ }
461
+ restored = data["retention"] === "default" ? void 0 : data["retention"];
462
+ }
463
+ return restored;
464
+ }
465
+ __name(restoreAnthropicSessionCacheRetention, "restoreAnthropicSessionCacheRetention");
466
+ function resolveAnthropicCacheControl(model, options) {
467
+ const retention = resolveCacheRetentionPreference(options);
468
+ if (retention === "none") return void 0;
469
+ const ttl = retention === "long" && (model?.compat?.supportsLongCacheRetention ?? true) ? "1h" : void 0;
470
+ return ttl === void 0 ? { type: "ephemeral" } : { type: "ephemeral", ttl };
471
+ }
472
+ __name(resolveAnthropicCacheControl, "resolveAnthropicCacheControl");
473
+ function cloneAnthropicCacheControl(value) {
474
+ if (value === void 0) return void 0;
475
+ if (!isPlainObject(value)) {
476
+ throw new Error(
477
+ "Anthropic attribution cannot safely process malformed cache_control; expected an object"
478
+ );
479
+ }
480
+ if (value["type"] !== "ephemeral") {
481
+ throw new Error(
482
+ 'Anthropic attribution cannot safely process malformed cache_control.type; expected "ephemeral"'
483
+ );
484
+ }
485
+ const ttl = value["ttl"];
486
+ if (ttl !== void 0 && ttl !== "1h" && ttl !== "5m") {
487
+ throw new Error(
488
+ 'Anthropic attribution cannot safely process malformed cache_control.ttl; expected "1h" or "5m"'
489
+ );
490
+ }
491
+ return {
492
+ ...value,
493
+ type: "ephemeral",
494
+ ...ttl === void 0 ? {} : { ttl }
495
+ };
496
+ }
497
+ __name(cloneAnthropicCacheControl, "cloneAnthropicCacheControl");
498
+ function mergedCacheControl(existing, desired) {
499
+ const existingControl = cloneAnthropicCacheControl(existing);
500
+ if (existingControl === void 0) return desired === void 0 ? void 0 : { ...desired };
501
+ if (desired?.ttl === "1h" && existingControl.ttl !== "1h")
502
+ return { ...existingControl, ttl: "1h" };
503
+ return existingControl;
504
+ }
505
+ __name(mergedCacheControl, "mergedCacheControl");
506
+ function cloneBlockWithCacheControl(block, desired) {
507
+ const next = { ...block };
508
+ const cacheControl = mergedCacheControl(next["cache_control"], desired);
509
+ if (cacheControl !== void 0) next["cache_control"] = cacheControl;
510
+ return next;
511
+ }
512
+ __name(cloneBlockWithCacheControl, "cloneBlockWithCacheControl");
513
+ function stripAnthropicSystemPromptBadLines(text) {
514
+ return text.split("\n").filter((line) => !isAnthropicSystemPromptBadLine(line)).join("\n");
515
+ }
516
+ __name(stripAnthropicSystemPromptBadLines, "stripAnthropicSystemPromptBadLines");
517
+ function inspectCacheControls(payload) {
518
+ let count = 0;
519
+ let hasLong = false;
520
+ const inspectBlock = /* @__PURE__ */ __name((block) => {
521
+ if (!isPlainObject(block) || block["cache_control"] === void 0) return;
522
+ const cacheControl = cloneAnthropicCacheControl(block["cache_control"]);
523
+ count += 1;
524
+ if (cacheControl?.ttl === "1h") hasLong = true;
525
+ }, "inspectBlock");
526
+ const system = payload["system"];
527
+ if (Array.isArray(system)) {
528
+ for (const block of system) inspectBlock(block);
529
+ }
530
+ const tools = payload["tools"];
531
+ if (Array.isArray(tools)) {
532
+ for (const tool of tools) inspectBlock(tool);
533
+ }
534
+ const messages = payload["messages"];
535
+ if (Array.isArray(messages)) {
536
+ for (const message of messages) {
537
+ if (!isPlainObject(message)) continue;
538
+ const content = message["content"];
539
+ if (Array.isArray(content)) {
540
+ for (const block of content) inspectBlock(block);
541
+ }
542
+ }
543
+ }
544
+ return { count, retention: count === 0 ? void 0 : hasLong ? "long" : "short" };
545
+ }
546
+ __name(inspectCacheControls, "inspectCacheControls");
547
+ function cacheControlOccurrences(payload) {
548
+ const occurrences = [];
549
+ const inspectBlocks = /* @__PURE__ */ __name((value, path) => {
550
+ if (!Array.isArray(value)) return;
551
+ value.forEach((block, index) => {
552
+ if (!isPlainObject(block)) return;
553
+ const blockPath = `${path}[${String(index)}]`;
554
+ if (block["cache_control"] !== void 0) {
555
+ const control = cloneAnthropicCacheControl(block["cache_control"]);
556
+ if (control !== void 0) occurrences.push({ path: blockPath, control });
557
+ }
558
+ if (block["type"] === "tool_result") inspectBlocks(block["content"], `${blockPath}.content`);
559
+ });
560
+ }, "inspectBlocks");
561
+ if (payload["cache_control"] !== void 0) {
562
+ const control = cloneAnthropicCacheControl(payload["cache_control"]);
563
+ if (control !== void 0) occurrences.push({ path: "$", control });
564
+ }
565
+ inspectBlocks(payload["system"], "$.system");
566
+ inspectBlocks(payload["tools"], "$.tools");
567
+ const messages = payload["messages"];
568
+ if (Array.isArray(messages)) {
569
+ messages.forEach((message, index) => {
570
+ if (isPlainObject(message))
571
+ inspectBlocks(message["content"], `$.messages[${String(index)}].content`);
572
+ });
573
+ }
574
+ return occurrences;
575
+ }
576
+ __name(cacheControlOccurrences, "cacheControlOccurrences");
577
+ function countCacheControlBreakpoints(payload) {
578
+ return cacheControlOccurrences(payload).length;
579
+ }
580
+ __name(countCacheControlBreakpoints, "countCacheControlBreakpoints");
581
+ function cacheControlTopologySha256(payload) {
582
+ return sha256Canonical(cacheControlOccurrences(payload));
583
+ }
584
+ __name(cacheControlTopologySha256, "cacheControlTopologySha256");
585
+ function assertCacheControlBreakpointLimit(payload) {
586
+ const count = countCacheControlBreakpoints(payload);
587
+ if (count > ANTHROPIC_CACHE_CONTROL_BREAKPOINT_LIMIT) {
588
+ throw new Error(
589
+ `Anthropic attribution produced ${count} cache_control breakpoints; Anthropic supports at most ${ANTHROPIC_CACHE_CONTROL_BREAKPOINT_LIMIT}`
590
+ );
591
+ }
592
+ }
593
+ __name(assertCacheControlBreakpointLimit, "assertCacheControlBreakpointLimit");
594
+ function assertNonEmptyString(value, fieldName, configPath) {
595
+ if (typeof value !== "string" || value.trim().length === 0) {
596
+ throw new Error(
597
+ `Anthropic attribution config ${configPath} missing/malformed required field ${fieldName}`
598
+ );
599
+ }
600
+ return value;
601
+ }
602
+ __name(assertNonEmptyString, "assertNonEmptyString");
603
+ function extractClaudeAttributionAccount(parsedConfig, configPath) {
604
+ if (!isPlainObject(parsedConfig)) {
605
+ throw new Error(`Anthropic attribution config ${configPath} is not a JSON object`);
606
+ }
607
+ const oauthAccount = parsedConfig["oauthAccount"];
608
+ if (!isPlainObject(oauthAccount)) {
609
+ throw new Error(
610
+ `Anthropic attribution config ${configPath} missing/malformed required field oauthAccount.accountUuid`
611
+ );
612
+ }
613
+ return {
614
+ deviceId: assertNonEmptyString(parsedConfig["userID"], "userID", configPath),
615
+ accountUuid: assertNonEmptyString(
616
+ oauthAccount["accountUuid"],
617
+ "oauthAccount.accountUuid",
618
+ configPath
619
+ )
620
+ };
621
+ }
622
+ __name(extractClaudeAttributionAccount, "extractClaudeAttributionAccount");
623
+ function resolveClaudeAttributionConfigPath(explicitConfigPath, env, homeDirectory = homedir()) {
624
+ const configuredPath = providerEnvValue(ANTHROPIC_ACCOUNT_CONFIG_PATH_ENV, env);
625
+ const selectedPath = explicitConfigPath ?? configuredPath ?? join(homeDirectory, ".claude.json");
626
+ const source = explicitConfigPath !== void 0 ? "explicit configPath" : configuredPath !== void 0 ? ANTHROPIC_ACCOUNT_CONFIG_PATH_ENV : "default ~/.claude.json path";
627
+ if (selectedPath.trim().length === 0 || !isAbsolute(selectedPath)) {
628
+ throw new Error(
629
+ `Anthropic attribution ${source} must be a non-empty absolute file path; got ${JSON.stringify(selectedPath)}`
630
+ );
631
+ }
632
+ return selectedPath;
633
+ }
634
+ __name(resolveClaudeAttributionConfigPath, "resolveClaudeAttributionConfigPath");
635
+ function loadClaudeAttributionAccount(configPath, env) {
636
+ const selectedPath = resolveClaudeAttributionConfigPath(configPath, env);
637
+ let configText;
638
+ try {
639
+ configText = readFileSync(selectedPath, "utf8");
640
+ } catch (error) {
641
+ throw new Error(
642
+ `Anthropic attribution config ${selectedPath} could not be read: ${error instanceof Error ? error.message : String(error)}`
643
+ );
644
+ }
645
+ return extractClaudeAttributionAccount(
646
+ parseJsonValue(configText, `Anthropic attribution config ${selectedPath}`),
647
+ selectedPath
648
+ );
649
+ }
650
+ __name(loadClaudeAttributionAccount, "loadClaudeAttributionAccount");
651
+ function isAnthropicContext(ctx) {
652
+ return ctx.model?.provider === "anthropic";
653
+ }
654
+ __name(isAnthropicContext, "isAnthropicContext");
655
+ function requireSessionId(value, source) {
656
+ if (typeof value !== "string" || value.trim().length === 0) {
657
+ throw new Error(`Anthropic attribution requires a non-empty ${source}`);
658
+ }
659
+ return value;
660
+ }
661
+ __name(requireSessionId, "requireSessionId");
662
+ function getSessionId(ctx) {
663
+ return requireSessionId(ctx.sessionManager.getSessionId(), "Pi session id");
664
+ }
665
+ __name(getSessionId, "getSessionId");
666
+ function normalizedAnthropicModelId(model) {
667
+ if (typeof model.id !== "string" || model.id.trim().length === 0) {
668
+ throw new Error("Anthropic attribution requires a non-empty model id");
669
+ }
670
+ const providerPrefix = "anthropic/";
671
+ return model.id.startsWith(providerPrefix) ? model.id.slice(providerPrefix.length) : model.id;
672
+ }
673
+ __name(normalizedAnthropicModelId, "normalizedAnthropicModelId");
674
+ function resolveClaudeCodeModelPolicy(model) {
675
+ const modelId = normalizedAnthropicModelId(model);
676
+ const policy = CLAUDE_CODE_MODEL_POLICIES[modelId];
677
+ if (policy === void 0) {
678
+ throw new Error(`Anthropic attribution has no Claude Code model policy for ${modelId}`);
679
+ }
680
+ return policy;
681
+ }
682
+ __name(resolveClaudeCodeModelPolicy, "resolveClaudeCodeModelPolicy");
683
+ function resolveAnthropicMaxTokens(model) {
684
+ return assertPositiveInteger(
685
+ model.maxTokens,
686
+ `model.maxTokens for ${normalizedAnthropicModelId(model)}`
687
+ );
688
+ }
689
+ __name(resolveAnthropicMaxTokens, "resolveAnthropicMaxTokens");
690
+ function computeClaudeCodeFingerprint(messageText, version = CLAUDE_CODE_VERSION) {
691
+ const chars = [4, 7, 20].map((index) => messageText[index] || "0").join("");
692
+ return createHash("sha256").update(`${FINGERPRINT_SALT}${chars}${version}`).digest("hex").slice(0, 3);
693
+ }
694
+ __name(computeClaudeCodeFingerprint, "computeClaudeCodeFingerprint");
695
+ function firstUserMessageTextFromPayload(payload) {
696
+ const messages = payload["messages"];
697
+ if (!Array.isArray(messages)) return "";
698
+ for (const message of messages) {
699
+ if (!isPlainObject(message) || message["role"] !== "user") continue;
700
+ const content = message["content"];
701
+ if (typeof content === "string") return content;
702
+ if (Array.isArray(content)) {
703
+ const textBlock = content.find(
704
+ (block) => isPlainObject(block) && block["type"] === "text" && typeof block["text"] === "string"
705
+ );
706
+ if (isPlainObject(textBlock) && typeof textBlock["text"] === "string")
707
+ return textBlock["text"];
708
+ }
709
+ }
710
+ return "";
711
+ }
712
+ __name(firstUserMessageTextFromPayload, "firstUserMessageTextFromPayload");
713
+ function buildClaudeCodeBillingSystemText(firstUserMessageText) {
714
+ const fingerprint = computeClaudeCodeFingerprint(firstUserMessageText);
715
+ return `x-anthropic-billing-header: cc_version=${CLAUDE_CODE_VERSION}.${fingerprint}; cc_entrypoint=${CLAUDE_CODE_ENTRYPOINT}; cch=${NATIVE_ATTESTATION_PLACEHOLDER};`;
716
+ }
717
+ __name(buildClaudeCodeBillingSystemText, "buildClaudeCodeBillingSystemText");
718
+ function buildAnthropicAttributionHeaders(sessionId, model) {
719
+ const beta = model === void 0 ? CLAUDE_CODE_BETA : resolveClaudeCodeModelPolicy(model).beta;
720
+ return {
721
+ [CLAUDE_CODE_SESSION_HEADER]: sessionId,
722
+ "anthropic-beta": beta,
723
+ "anthropic-version": "2023-06-01",
724
+ "User-Agent": CLAUDE_CODE_USER_AGENT,
725
+ "x-app": "cli",
726
+ "anthropic-dangerous-direct-browser-access": "true"
727
+ };
728
+ }
729
+ __name(buildAnthropicAttributionHeaders, "buildAnthropicAttributionHeaders");
730
+ function registerAnthropicAttributionProvider(pi, ctx, getSessionOverride = () => void 0, dependencies = {}) {
731
+ if (!isAnthropicContext(ctx)) return;
732
+ pi.registerProvider("anthropic", {
733
+ api: "anthropic-messages",
734
+ headers: buildAnthropicAttributionHeaders(getSessionId(ctx), ctx.model),
735
+ streamSimple: /* @__PURE__ */ __name((model, context, options) => streamAnthropicViaBetaMessages(
736
+ model,
737
+ context,
738
+ model.provider === "anthropic" ? {
739
+ ...options ?? {},
740
+ cacheRetention: resolveRegisteredCacheRetention(options, getSessionOverride())
741
+ } : options,
742
+ dependencies
743
+ ), "streamSimple")
744
+ });
745
+ }
746
+ __name(registerAnthropicAttributionProvider, "registerAnthropicAttributionProvider");
747
+ function assertPositiveInteger(value, fieldName) {
748
+ if (!Number.isInteger(value) || typeof value !== "number" || value <= 0) {
749
+ throw new Error(
750
+ `Anthropic attribution cannot safely process malformed ${fieldName}; expected a positive integer`
751
+ );
752
+ }
753
+ return value;
754
+ }
755
+ __name(assertPositiveInteger, "assertPositiveInteger");
756
+ function rewriteThinking(payload, maxTokens) {
757
+ if (payload["thinking"] === void 0) return { thinking: void 0, budgetTokens: void 0 };
758
+ if (!isPlainObject(payload["thinking"])) {
759
+ throw new Error(
760
+ "Anthropic attribution cannot safely process malformed thinking; expected an object"
761
+ );
762
+ }
763
+ const thinking = { ...payload["thinking"] };
764
+ if (thinking["type"] === "disabled")
765
+ return { thinking: { type: "disabled" }, budgetTokens: void 0 };
766
+ if (thinking["budget_tokens"] === void 0) return { thinking, budgetTokens: void 0 };
767
+ const existingBudget = assertPositiveInteger(thinking["budget_tokens"], "thinking.budget_tokens");
768
+ if (maxTokens !== void 0 && existingBudget >= maxTokens) {
769
+ thinking["budget_tokens"] = maxTokens - 1;
770
+ }
771
+ if (typeof thinking["budget_tokens"] === "number" && thinking["budget_tokens"] <= 0) {
772
+ throw new Error(
773
+ "Anthropic attribution cannot satisfy thinking.budget_tokens < max_tokens when max_tokens <= 1"
774
+ );
775
+ }
776
+ return { thinking, budgetTokens: thinking["budget_tokens"] };
777
+ }
778
+ __name(rewriteThinking, "rewriteThinking");
779
+ function isClaudeCodeIdentityText(text) {
780
+ return text.startsWith("x-anthropic-billing-header:") || text === CLAUDE_AGENT_SDK_SYSTEM_TEXT || text === "You are Claude Code, Anthropic's official CLI for Claude." || text === "You are Claude Code, Anthropic's official CLI for Claude, running within the Claude Agent SDK.";
781
+ }
782
+ __name(isClaudeCodeIdentityText, "isClaudeCodeIdentityText");
783
+ function normalizeSystemBlock(block) {
784
+ if (!isPlainObject(block)) return block;
785
+ const next = { ...block };
786
+ if (typeof next["text"] === "string")
787
+ next["text"] = stripAnthropicSystemPromptBadLines(next["text"]);
788
+ if (next["cache_control"] !== void 0)
789
+ next["cache_control"] = cloneAnthropicCacheControl(next["cache_control"]);
790
+ return next;
791
+ }
792
+ __name(normalizeSystemBlock, "normalizeSystemBlock");
793
+ function hasCacheControl(block) {
794
+ return isPlainObject(block) && block["cache_control"] !== void 0;
795
+ }
796
+ __name(hasCacheControl, "hasCacheControl");
797
+ function isSystemCacheSurface(block) {
798
+ return isPlainObject(block) && typeof block["text"] === "string";
799
+ }
800
+ __name(isSystemCacheSurface, "isSystemCacheSurface");
801
+ function markSystemCacheSurface(blocks, desired) {
802
+ const output = blocks.map((block) => isPlainObject(block) ? { ...block } : block);
803
+ if (desired === void 0) return output;
804
+ let lastTextBlockIndex = -1;
805
+ for (let index = 0; index < output.length; index += 1) {
806
+ if (isSystemCacheSurface(output[index])) lastTextBlockIndex = index;
807
+ }
808
+ if (lastTextBlockIndex === -1) return output;
809
+ const withLongRetentionUpgrades = desired.ttl === "1h" ? output.map(
810
+ (block) => hasCacheControl(block) ? cloneBlockWithCacheControl(block, desired) : block
811
+ ) : output;
812
+ withLongRetentionUpgrades[lastTextBlockIndex] = cloneBlockWithCacheControl(
813
+ withLongRetentionUpgrades[lastTextBlockIndex],
814
+ desired
815
+ );
816
+ return withLongRetentionUpgrades;
817
+ }
818
+ __name(markSystemCacheSurface, "markSystemCacheSurface");
819
+ function withClaudeCodeSystemIdentity(system, billingSystemText, cacheControl) {
820
+ const identityBlocks = [
821
+ { type: "text", text: billingSystemText },
822
+ { type: "text", text: CLAUDE_AGENT_SDK_SYSTEM_TEXT }
823
+ ];
824
+ if (system === void 0) return markSystemCacheSurface(identityBlocks, cacheControl);
825
+ if (Array.isArray(system)) {
826
+ const withoutPriorIdentity = system.filter((entry) => {
827
+ if (!isPlainObject(entry) || typeof entry["text"] !== "string") return true;
828
+ return !isClaudeCodeIdentityText(entry["text"]);
829
+ }).map(normalizeSystemBlock);
830
+ return markSystemCacheSurface([...identityBlocks, ...withoutPriorIdentity], cacheControl);
831
+ }
832
+ if (typeof system === "string") {
833
+ return markSystemCacheSurface(
834
+ [...identityBlocks, { type: "text", text: stripAnthropicSystemPromptBadLines(system) }],
835
+ cacheControl
836
+ );
837
+ }
838
+ throw new Error(
839
+ "Anthropic attribution cannot safely apply Claude Code system identity to malformed system payload"
840
+ );
841
+ }
842
+ __name(withClaudeCodeSystemIdentity, "withClaudeCodeSystemIdentity");
843
+ function appendAuditRecord(args) {
844
+ const auditPath = process.env[AUDIT_ENV];
845
+ if (auditPath === void 0 || auditPath.length === 0) return;
846
+ const record = {
847
+ schema_version: "pipeline.anthropic_attribution_audit.v1",
848
+ provider: args.provider,
849
+ header_name: CLAUDE_CODE_SESSION_HEADER,
850
+ header_registered: args.headerRegistered,
851
+ anthropic_beta: args.beta,
852
+ anthropic_version: "2023-06-01",
853
+ beta_resource_path: args.betaResourcePath,
854
+ native_attestation: args.nativeAttestation,
855
+ metadata_user_id_keys: ["account_uuid", "device_id", "session_id"],
856
+ metadata_session_id_matches_header: args.metadataSessionMatchesHeader,
857
+ account_uuid_present: true,
858
+ device_id_present: true,
859
+ max_tokens: args.maxTokens,
860
+ thinking_budget_tokens: args.thinkingBudgetTokens
861
+ };
862
+ appendFileSync(auditPath, `${JSON.stringify(record)}
863
+ `, { encoding: "utf8", mode: 384 });
864
+ }
865
+ __name(appendAuditRecord, "appendAuditRecord");
866
+ function requireAttributionAccount(value) {
867
+ if (!isPlainObject(value) || typeof value["deviceId"] !== "string" || value["deviceId"].trim().length === 0 || typeof value["accountUuid"] !== "string" || value["accountUuid"].trim().length === 0) {
868
+ throw new Error("Anthropic attribution account loader returned malformed account identity");
869
+ }
870
+ return { deviceId: value["deviceId"], accountUuid: value["accountUuid"] };
871
+ }
872
+ __name(requireAttributionAccount, "requireAttributionAccount");
873
+ function anthropicMetadataUserId(account, sessionId) {
874
+ return JSON.stringify({
875
+ account_uuid: account.accountUuid,
876
+ device_id: account.deviceId,
877
+ session_id: sessionId
878
+ });
879
+ }
880
+ __name(anthropicMetadataUserId, "anthropicMetadataUserId");
881
+ function rewriteAnthropicRequestPayloadForSession(args) {
882
+ if (!isPlainObject(args.payload)) {
883
+ throw new Error("Anthropic attribution expected provider payload to be a JSON object");
884
+ }
885
+ const sessionId = requireSessionId(args.sessionId, "provider options.sessionId");
886
+ const metadata = args.payload["metadata"] === void 0 ? {} : args.payload["metadata"];
887
+ if (!isPlainObject(metadata)) {
888
+ throw new Error("Anthropic attribution expected payload.metadata to be an object when present");
889
+ }
890
+ const policy = resolveClaudeCodeModelPolicy(args.model);
891
+ const maxTokens = args.payload["max_tokens"] === void 0 ? void 0 : assertPositiveInteger(args.payload["max_tokens"], "max_tokens");
892
+ const { thinking, budgetTokens } = rewriteThinking(args.payload, maxTokens);
893
+ const billingSystemText = buildClaudeCodeBillingSystemText(
894
+ firstUserMessageTextFromPayload(args.payload)
895
+ );
896
+ const incomingCache = inspectCacheControls(args.payload);
897
+ const configuredCacheRetention = args.cacheRetention ?? incomingCache.retention;
898
+ const cacheControl = configuredCacheRetention === void 0 ? void 0 : resolveAnthropicCacheControl(args.model, {
899
+ cacheRetention: configuredCacheRetention
900
+ });
901
+ const rewritten = {
902
+ ...args.payload,
903
+ metadata: {
904
+ ...metadata,
905
+ user_id: anthropicMetadataUserId(args.account, sessionId)
906
+ },
907
+ system: withClaudeCodeSystemIdentity(args.payload["system"], billingSystemText, cacheControl)
908
+ };
909
+ if (thinking !== void 0) rewritten["thinking"] = thinking;
910
+ assertCacheControlBreakpointLimit(rewritten);
911
+ appendAuditRecord({
912
+ provider: "anthropic",
913
+ headerRegistered: args.headerRegistered ?? true,
914
+ metadataSessionMatchesHeader: true,
915
+ maxTokens,
916
+ thinkingBudgetTokens: budgetTokens,
917
+ beta: policy.beta,
918
+ betaResourcePath: "/v1/messages?beta=true",
919
+ nativeAttestation: "placeholder-pending-live"
920
+ });
921
+ return rewritten;
922
+ }
923
+ __name(rewriteAnthropicRequestPayloadForSession, "rewriteAnthropicRequestPayloadForSession");
924
+ function assertProtectedAnthropicAttribution(args) {
925
+ if (args.payload["model"] !== args.modelId || args.payload["stream"] !== true) {
926
+ throw new Error(
927
+ "Anthropic protected attribution model/stream route changed during payload middleware"
928
+ );
929
+ }
930
+ const metadata = args.payload["metadata"];
931
+ if (!isPlainObject(metadata) || metadata["user_id"] !== anthropicMetadataUserId(args.account, args.sessionId)) {
932
+ throw new Error(
933
+ "Anthropic protected attribution metadata.user_id/account/device/session_id changed during payload middleware"
934
+ );
935
+ }
936
+ const system = args.payload["system"];
937
+ if (!Array.isArray(system)) {
938
+ throw new Error(
939
+ "Anthropic protected attribution system identity was removed during payload middleware"
940
+ );
941
+ }
942
+ const billingBlocks = system.filter(
943
+ (block) => isPlainObject(block) && typeof block["text"] === "string" && block["text"].startsWith("x-anthropic-billing-header:")
944
+ );
945
+ const sdkBlocks = system.filter(
946
+ (block) => isPlainObject(block) && block["text"] === CLAUDE_AGENT_SDK_SYSTEM_TEXT
947
+ );
948
+ if (billingBlocks.length !== 1 || billingBlocks[0]?.["text"] !== args.billingSystemText || sdkBlocks.length !== 1 || system[0] !== billingBlocks[0] || system[1] !== sdkBlocks[0]) {
949
+ throw new Error(
950
+ "Anthropic protected attribution system identity changed during payload middleware"
951
+ );
952
+ }
953
+ assertCacheControlBreakpointLimit(args.payload);
954
+ if (cacheControlTopologySha256(args.payload) !== args.cacheControlTopologySha256) {
955
+ throw new Error("Anthropic protected cache-control topology changed during payload middleware");
956
+ }
957
+ }
958
+ __name(assertProtectedAnthropicAttribution, "assertProtectedAnthropicAttribution");
959
+ function rewriteAnthropicRequestPayload(args) {
960
+ if (!isAnthropicContext(args.ctx)) return void 0;
961
+ return rewriteAnthropicRequestPayloadForSession({
962
+ payload: args.payload,
963
+ model: args.ctx.model ?? {},
964
+ sessionId: getSessionId(args.ctx),
965
+ account: args.account,
966
+ ...args.headerRegistered === void 0 ? {} : { headerRegistered: args.headerRegistered },
967
+ ...args.cacheRetention === void 0 ? {} : { cacheRetention: args.cacheRetention }
968
+ });
969
+ }
970
+ __name(rewriteAnthropicRequestPayload, "rewriteAnthropicRequestPayload");
971
+ function sanitizeSurrogates(text) {
972
+ let sanitized = "";
973
+ for (let index = 0; index < text.length; index += 1) {
974
+ const code = text.charCodeAt(index);
975
+ if (code >= 55296 && code <= 56319) {
976
+ const next = index + 1 < text.length ? text.charCodeAt(index + 1) : -1;
977
+ if (next >= 56320 && next <= 57343) {
978
+ sanitized += text[index] ?? "";
979
+ sanitized += text[index + 1] ?? "";
980
+ index += 1;
981
+ } else {
982
+ sanitized += "\uFFFD";
983
+ }
984
+ } else if (code >= 56320 && code <= 57343) {
985
+ sanitized += "\uFFFD";
986
+ } else {
987
+ sanitized += text[index] ?? "";
988
+ }
989
+ }
990
+ return sanitized;
991
+ }
992
+ __name(sanitizeSurrogates, "sanitizeSurrogates");
993
+ function convertContentBlocks(content) {
994
+ const blocks = content.map((block) => {
995
+ if (block.type === "text") return { type: "text", text: sanitizeSurrogates(block.text) };
996
+ return {
997
+ type: "image",
998
+ source: { type: "base64", media_type: block.mimeType, data: block.data }
999
+ };
1000
+ });
1001
+ if (blocks.length === 0) blocks.push({ type: "text", text: "" });
1002
+ if (!blocks.some((block) => block["type"] === "text"))
1003
+ blocks.unshift({ type: "text", text: "(see attached image)" });
1004
+ return blocks;
1005
+ }
1006
+ __name(convertContentBlocks, "convertContentBlocks");
1007
+ function cloneMessageForCacheControl(message) {
1008
+ const content = message["content"];
1009
+ return {
1010
+ ...message,
1011
+ ...Array.isArray(content) ? { content: content.map((block) => isPlainObject(block) ? { ...block } : block) } : {}
1012
+ };
1013
+ }
1014
+ __name(cloneMessageForCacheControl, "cloneMessageForCacheControl");
1015
+ function isCacheableConversationBlock(role, block) {
1016
+ if (role === "assistant") return block["type"] === "text";
1017
+ return block["type"] === "text" || block["type"] === "image" || block["type"] === "tool_result";
1018
+ }
1019
+ __name(isCacheableConversationBlock, "isCacheableConversationBlock");
1020
+ function markMessageContentCacheSurface(message, cacheControl) {
1021
+ const role = message["role"];
1022
+ if (role !== "user" && role !== "assistant") return false;
1023
+ const content = message["content"];
1024
+ if (typeof content === "string") {
1025
+ throw new Error(
1026
+ "Anthropic attribution cache projection encountered non-canonical string message content"
1027
+ );
1028
+ }
1029
+ if (!Array.isArray(content)) return false;
1030
+ for (let index = content.length - 1; index >= 0; index -= 1) {
1031
+ const block = content[index];
1032
+ if (!isPlainObject(block) || !isCacheableConversationBlock(role, block)) continue;
1033
+ content[index] = cloneBlockWithCacheControl(block, cacheControl);
1034
+ return true;
1035
+ }
1036
+ return false;
1037
+ }
1038
+ __name(markMessageContentCacheSurface, "markMessageContentCacheSurface");
1039
+ function markLastConversationCacheSurface(messages, cacheControl) {
1040
+ const output = messages.map(cloneMessageForCacheControl);
1041
+ if (cacheControl === void 0) return output;
1042
+ for (let index = output.length - 1; index >= 0; index -= 1) {
1043
+ const message = output[index];
1044
+ if (message !== void 0 && markMessageContentCacheSurface(message, cacheControl)) break;
1045
+ }
1046
+ return output;
1047
+ }
1048
+ __name(markLastConversationCacheSurface, "markLastConversationCacheSurface");
1049
+ function canonicalizeJson(value) {
1050
+ if (Array.isArray(value)) return value.map(canonicalizeJson);
1051
+ if (!isPlainObject(value)) return value;
1052
+ const output = {};
1053
+ for (const key of Object.keys(value).sort()) {
1054
+ const child = value[key];
1055
+ if (child !== void 0) output[key] = canonicalizeJson(child);
1056
+ }
1057
+ return output;
1058
+ }
1059
+ __name(canonicalizeJson, "canonicalizeJson");
1060
+ function canonicalJson(value) {
1061
+ return JSON.stringify(canonicalizeJson(value));
1062
+ }
1063
+ __name(canonicalJson, "canonicalJson");
1064
+ function sha256Canonical(value) {
1065
+ return createHash("sha256").update(canonicalJson(value), "utf8").digest("hex");
1066
+ }
1067
+ __name(sha256Canonical, "sha256Canonical");
1068
+ function isSha256(value) {
1069
+ return typeof value === "string" && /^[a-f0-9]{64}$/u.test(value);
1070
+ }
1071
+ __name(isSha256, "isSha256");
1072
+ function isNonEmptyString(value) {
1073
+ return typeof value === "string" && value.trim().length > 0;
1074
+ }
1075
+ __name(isNonEmptyString, "isNonEmptyString");
1076
+ function blockWithoutCacheControl(block) {
1077
+ if (!isPlainObject(block)) return block;
1078
+ const output = { ...block };
1079
+ delete output["cache_control"];
1080
+ return output;
1081
+ }
1082
+ __name(blockWithoutCacheControl, "blockWithoutCacheControl");
1083
+ function promptMessagesWithoutCacheControls(messages) {
1084
+ return messages.map((message) => {
1085
+ const content = message["content"];
1086
+ return {
1087
+ ...message,
1088
+ ...Array.isArray(content) ? { content: content.map(blockWithoutCacheControl) } : {}
1089
+ };
1090
+ });
1091
+ }
1092
+ __name(promptMessagesWithoutCacheControls, "promptMessagesWithoutCacheControls");
1093
+ function promptMessagesHash(messages) {
1094
+ return sha256Canonical(promptMessagesWithoutCacheControls(messages));
1095
+ }
1096
+ __name(promptMessagesHash, "promptMessagesHash");
1097
+ function assistantContentHash(content) {
1098
+ return sha256Canonical(content);
1099
+ }
1100
+ __name(assistantContentHash, "assistantContentHash");
1101
+ function parseAnthropicLineageDetails(message) {
1102
+ const diagnostic = [...message.diagnostics ?? []].reverse().find((candidate) => candidate.type === ANTHROPIC_LINEAGE_DIAGNOSTIC_TYPE);
1103
+ const details = diagnostic?.details;
1104
+ if (!isPlainObject(details)) return void 0;
1105
+ const sourceModel = details["source_model"];
1106
+ const responseId = details["response_id"];
1107
+ const assistantContentSha256 = details["assistant_content_sha256"];
1108
+ const conversationStaticSha256 = details["conversation_static_sha256"];
1109
+ const requestMessageCount = details["request_message_count"];
1110
+ const requestMessagesSha256 = details["request_messages_sha256"];
1111
+ const cacheProfileSha256 = details["cache_profile_sha256"];
1112
+ const cacheRetention = details["cache_retention"];
1113
+ const compactionBoundarySha256 = details["compaction_boundary_sha256"];
1114
+ const signatureEpochSha256 = details["signature_epoch_sha256"];
1115
+ const signatureEpochInheritsPrior = details["signature_epoch_inherits_prior"];
1116
+ const previousMessageId = details["previous_message_id"];
1117
+ if (details["schema_version"] !== ANTHROPIC_LINEAGE_SCHEMA || details["projection_version"] !== ANTHROPIC_PROJECTION_VERSION || details["source_provider"] !== "anthropic" || details["source_api"] !== "anthropic-messages" || !isNonEmptyString(sourceModel) || !isNonEmptyString(responseId) || !isSha256(assistantContentSha256) || !isSha256(conversationStaticSha256) || typeof requestMessageCount !== "number" || !Number.isSafeInteger(requestMessageCount) || requestMessageCount < 0 || !isSha256(requestMessagesSha256) || !isSha256(cacheProfileSha256) || cacheRetention !== "none" && cacheRetention !== "short" && cacheRetention !== "long" || compactionBoundarySha256 !== null && !isSha256(compactionBoundarySha256) || !isSha256(signatureEpochSha256) || typeof signatureEpochInheritsPrior !== "boolean" || previousMessageId !== null && !isNonEmptyString(previousMessageId)) {
1118
+ return void 0;
1119
+ }
1120
+ return {
1121
+ schema_version: ANTHROPIC_LINEAGE_SCHEMA,
1122
+ projection_version: ANTHROPIC_PROJECTION_VERSION,
1123
+ source_provider: "anthropic",
1124
+ source_api: "anthropic-messages",
1125
+ source_model: sourceModel,
1126
+ response_id: responseId,
1127
+ assistant_content_sha256: assistantContentSha256,
1128
+ conversation_static_sha256: conversationStaticSha256,
1129
+ request_message_count: requestMessageCount,
1130
+ request_messages_sha256: requestMessagesSha256,
1131
+ cache_profile_sha256: cacheProfileSha256,
1132
+ cache_retention: cacheRetention,
1133
+ compaction_boundary_sha256: compactionBoundarySha256,
1134
+ signature_epoch_sha256: signatureEpochSha256,
1135
+ signature_epoch_inherits_prior: signatureEpochInheritsPrior,
1136
+ previous_message_id: previousMessageId
1137
+ };
1138
+ }
1139
+ __name(parseAnthropicLineageDetails, "parseAnthropicLineageDetails");
1140
+ function isSuccessfulLineageStopReason(stopReason) {
1141
+ return stopReason === "stop" || stopReason === "length" || stopReason === "toolUse";
1142
+ }
1143
+ __name(isSuccessfulLineageStopReason, "isSuccessfulLineageStopReason");
1144
+ function lineageBindsContainingAssistant(message, lineage) {
1145
+ return message.provider === lineage.source_provider && message.api === lineage.source_api && isNonEmptyString(message.model) && message.model === lineage.source_model && isSuccessfulLineageStopReason(message.stopReason) && isNonEmptyString(message.responseId) && message.responseId === lineage.response_id && lineage.assistant_content_sha256 === assistantContentHash(message.content);
1146
+ }
1147
+ __name(lineageBindsContainingAssistant, "lineageBindsContainingAssistant");
1148
+ function canTargetReadAnthropicThinking(sourceModel, targetModel) {
1149
+ if (sourceModel === targetModel) return true;
1150
+ return targetModel === "claude-fable-5-1" && CLAUDE_CODE_MODEL_POLICIES[sourceModel] !== void 0;
1151
+ }
1152
+ __name(canTargetReadAnthropicThinking, "canTargetReadAnthropicThinking");
1153
+ function initialSignatureEpochPolicy(targetModelId, cacheRetention, compactionBoundarySha256) {
1154
+ return {
1155
+ sha256: sha256Canonical({
1156
+ projection_version: ANTHROPIC_PROJECTION_VERSION,
1157
+ kind: "initial",
1158
+ target_model: targetModelId,
1159
+ cache_retention: cacheRetention,
1160
+ compaction_boundary_sha256: compactionBoundarySha256
1161
+ }),
1162
+ inheritsPrior: compactionBoundarySha256 === null
1163
+ };
1164
+ }
1165
+ __name(initialSignatureEpochPolicy, "initialSignatureEpochPolicy");
1166
+ function resolveSignatureEpochPolicy(model, messages, cacheRetention, compactionBoundarySha256) {
1167
+ const targetModelId = normalizedAnthropicModelId(model);
1168
+ const latestState = targetLineageState({ messages }, targetModelId);
1169
+ if (latestState.kind === "none") {
1170
+ return initialSignatureEpochPolicy(targetModelId, cacheRetention, compactionBoundarySha256);
1171
+ }
1172
+ if (latestState.kind === "untrusted") {
1173
+ return {
1174
+ sha256: sha256Canonical({
1175
+ projection_version: ANTHROPIC_PROJECTION_VERSION,
1176
+ kind: "untrusted-lineage-reset",
1177
+ target_model: targetModelId,
1178
+ cache_retention: cacheRetention,
1179
+ compaction_boundary_sha256: compactionBoundarySha256,
1180
+ latest_assistant_sha256: latestState.assistantSha256
1181
+ }),
1182
+ inheritsPrior: false
1183
+ };
1184
+ }
1185
+ const latest = latestState.lineage;
1186
+ const retentionChanged = latest.cache_retention !== cacheRetention;
1187
+ const declaredNewCompaction = compactionBoundarySha256 !== null && compactionBoundarySha256 !== latest.compaction_boundary_sha256;
1188
+ if (retentionChanged || declaredNewCompaction) {
1189
+ return {
1190
+ sha256: sha256Canonical({
1191
+ projection_version: ANTHROPIC_PROJECTION_VERSION,
1192
+ kind: "transition",
1193
+ previous_signature_epoch_sha256: latest.signature_epoch_sha256,
1194
+ target_model: targetModelId,
1195
+ cache_retention: cacheRetention,
1196
+ compaction_boundary_sha256: compactionBoundarySha256,
1197
+ reason: retentionChanged ? "cache-retention" : "compaction"
1198
+ }),
1199
+ inheritsPrior: false
1200
+ };
1201
+ }
1202
+ return {
1203
+ sha256: latest.signature_epoch_sha256,
1204
+ inheritsPrior: latest.signature_epoch_inherits_prior
1205
+ };
1206
+ }
1207
+ __name(resolveSignatureEpochPolicy, "resolveSignatureEpochPolicy");
1208
+ function isTrustedReplayableAnthropicAssistant(message, targetModel, targetCacheRetention, conversationStaticSha256, wireMessagesBeforeAssistant) {
1209
+ if (typeof message.model !== "string") return false;
1210
+ const lineage = parseAnthropicLineageDetails(message);
1211
+ if (lineage === void 0 || !lineageBindsContainingAssistant(message, lineage) || !canTargetReadAnthropicThinking(message.model, normalizedAnthropicModelId(targetModel)) || lineage.cache_retention !== targetCacheRetention || lineage.conversation_static_sha256 !== conversationStaticSha256 || lineage.request_message_count !== wireMessagesBeforeAssistant.length || lineage.request_messages_sha256 !== promptMessagesHash(wireMessagesBeforeAssistant)) {
1212
+ return false;
1213
+ }
1214
+ return true;
1215
+ }
1216
+ __name(isTrustedReplayableAnthropicAssistant, "isTrustedReplayableAnthropicAssistant");
1217
+ function normalizeAnthropicToolCallId(id) {
1218
+ if (/^[a-zA-Z0-9_-]{1,64}$/u.test(id)) return id;
1219
+ const safe = id.replace(/[^a-zA-Z0-9_-]/gu, "_");
1220
+ const digest = createHash("sha256").update(id, "utf8").digest("hex").slice(0, 12);
1221
+ const prefix = safe.slice(0, 64 - digest.length - 1) || "tool";
1222
+ return `${prefix}_${digest}`.slice(0, 64);
1223
+ }
1224
+ __name(normalizeAnthropicToolCallId, "normalizeAnthropicToolCallId");
1225
+ function projectedUserContent(content) {
1226
+ if (typeof content === "string") {
1227
+ return content.trim().length > 0 ? [{ type: "text", text: sanitizeSurrogates(content) }] : [];
1228
+ }
1229
+ const blocks = [];
1230
+ for (const block of content) {
1231
+ if (block.type === "text") {
1232
+ if (block.text.trim().length > 0)
1233
+ blocks.push({ type: "text", text: sanitizeSurrogates(block.text) });
1234
+ continue;
1235
+ }
1236
+ if (block.type === "image") {
1237
+ blocks.push({
1238
+ type: "image",
1239
+ source: { type: "base64", media_type: block.mimeType, data: block.data }
1240
+ });
1241
+ continue;
1242
+ }
1243
+ throw new Error("Anthropic attribution encountered an unsupported user content block");
1244
+ }
1245
+ return blocks;
1246
+ }
1247
+ __name(projectedUserContent, "projectedUserContent");
1248
+ function compactionBoundarySha256FromPiMessages(messages) {
1249
+ const first = messages[0];
1250
+ if (first?.role !== "user") return null;
1251
+ const content = projectedUserContent(first.content);
1252
+ return declaredCompactionBoundarySha256([{ role: "user", content }]);
1253
+ }
1254
+ __name(compactionBoundarySha256FromPiMessages, "compactionBoundarySha256FromPiMessages");
1255
+ function convertMessages(model, messages, conversationStaticSha256, cacheRetention, signatureEpoch, cacheControl) {
1256
+ const params = [];
1257
+ const toolCallIdMap = /* @__PURE__ */ new Map();
1258
+ const normalizedToolCallOwners = /* @__PURE__ */ new Map();
1259
+ let pendingToolCalls = [];
1260
+ let completedPendingToolCallIds = /* @__PURE__ */ new Set();
1261
+ const normalizeToolCallId = /* @__PURE__ */ __name((id) => {
1262
+ const existing = toolCallIdMap.get(id);
1263
+ if (existing !== void 0) return existing;
1264
+ const normalized = normalizeAnthropicToolCallId(id);
1265
+ const owner = normalizedToolCallOwners.get(normalized);
1266
+ if (owner !== void 0 && owner !== id) {
1267
+ throw new Error("Anthropic attribution tool-call ID normalization collision");
1268
+ }
1269
+ normalizedToolCallOwners.set(normalized, id);
1270
+ toolCallIdMap.set(id, normalized);
1271
+ return normalized;
1272
+ }, "normalizeToolCallId");
1273
+ const flushMissingToolResults = /* @__PURE__ */ __name(() => {
1274
+ const missing = pendingToolCalls.filter((call) => !completedPendingToolCallIds.has(call.id));
1275
+ if (missing.length > 0) {
1276
+ params.push({
1277
+ role: "user",
1278
+ content: missing.map((call) => ({
1279
+ type: "tool_result",
1280
+ tool_use_id: call.id,
1281
+ content: "No result provided",
1282
+ is_error: true
1283
+ }))
1284
+ });
1285
+ }
1286
+ pendingToolCalls = [];
1287
+ completedPendingToolCallIds = /* @__PURE__ */ new Set();
1288
+ }, "flushMissingToolResults");
1289
+ for (let index = 0; index < messages.length; index += 1) {
1290
+ const message = messages[index];
1291
+ if (message === void 0) throw new TypeError(`Anthropic message ${index} is missing`);
1292
+ if (message.role === "user") {
1293
+ flushMissingToolResults();
1294
+ const content = projectedUserContent(message.content);
1295
+ if (content.length > 0) params.push({ role: "user", content });
1296
+ continue;
1297
+ }
1298
+ if (message.role === "assistant") {
1299
+ flushMissingToolResults();
1300
+ if (message.stopReason === "error" || message.stopReason === "aborted") continue;
1301
+ const lineage = parseAnthropicLineageDetails(message);
1302
+ const epochAllowsReplay = signatureEpoch.inheritsPrior || lineage?.signature_epoch_sha256 === signatureEpoch.sha256;
1303
+ const preserveThinking = epochAllowsReplay && isTrustedReplayableAnthropicAssistant(
1304
+ message,
1305
+ model,
1306
+ cacheRetention,
1307
+ conversationStaticSha256,
1308
+ params
1309
+ );
1310
+ const content = [];
1311
+ for (const block of message.content) {
1312
+ if (block["type"] === "text") {
1313
+ if (typeof block["text"] !== "string")
1314
+ throw new Error("Anthropic attribution encountered malformed assistant text");
1315
+ if (block["text"].trim().length > 0)
1316
+ content.push({ type: "text", text: sanitizeSurrogates(block["text"]) });
1317
+ continue;
1318
+ }
1319
+ if (block["type"] === "thinking") {
1320
+ if (typeof block["thinking"] !== "string")
1321
+ throw new Error("Anthropic attribution encountered malformed assistant thinking");
1322
+ const signature = typeof block["thinkingSignature"] === "string" ? block["thinkingSignature"] : "";
1323
+ if (preserveThinking && signature.trim().length > 0) {
1324
+ content.push(
1325
+ block["redacted"] === true ? { type: "redacted_thinking", data: signature } : {
1326
+ type: "thinking",
1327
+ // A signature authenticates the exact provider-returned reasoning bytes.
1328
+ // Provenance and lineage checks above make this raw replay safe; changing
1329
+ // even valid non-BMP Unicode here would invalidate the opaque signature.
1330
+ thinking: block["thinking"],
1331
+ signature
1332
+ }
1333
+ );
1334
+ } else if (block["redacted"] !== true && block["thinking"].trim().length > 0) {
1335
+ content.push({ type: "text", text: sanitizeSurrogates(block["thinking"]) });
1336
+ }
1337
+ continue;
1338
+ }
1339
+ if (block["type"] === "toolCall") {
1340
+ if (typeof block["id"] !== "string" || typeof block["name"] !== "string")
1341
+ throw new Error("Anthropic attribution encountered malformed assistant tool call");
1342
+ const id = normalizeToolCallId(block["id"]);
1343
+ content.push({
1344
+ type: "tool_use",
1345
+ id,
1346
+ name: block["name"],
1347
+ input: canonicalizeJson(block["arguments"] ?? {})
1348
+ });
1349
+ continue;
1350
+ }
1351
+ throw new Error(
1352
+ `Anthropic attribution encountered unsupported assistant block type ${JSON.stringify(block["type"])}`
1353
+ );
1354
+ }
1355
+ if (content.length > 0) {
1356
+ params.push({ role: "assistant", content });
1357
+ pendingToolCalls = content.filter((block) => block["type"] === "tool_use").map((block) => ({ id: String(block["id"]), name: String(block["name"]) }));
1358
+ }
1359
+ continue;
1360
+ }
1361
+ if (message.role !== "toolResult") {
1362
+ throw new Error(
1363
+ `Anthropic attribution encountered unsupported message role ${JSON.stringify(Reflect.get(message, "role"))}`
1364
+ );
1365
+ }
1366
+ const toolResults = [];
1367
+ let lookahead = index;
1368
+ while (lookahead < messages.length && messages[lookahead]?.role === "toolResult") {
1369
+ const result = messages[lookahead];
1370
+ const toolUseId = normalizeToolCallId(result.toolCallId);
1371
+ completedPendingToolCallIds.add(toolUseId);
1372
+ toolResults.push({
1373
+ type: "tool_result",
1374
+ tool_use_id: toolUseId,
1375
+ content: convertContentBlocks(result.content),
1376
+ is_error: result.isError === true
1377
+ });
1378
+ lookahead += 1;
1379
+ }
1380
+ index = lookahead - 1;
1381
+ if (toolResults.length > 0) params.push({ role: "user", content: toolResults });
1382
+ }
1383
+ flushMissingToolResults();
1384
+ return markLastConversationCacheSurface(params, cacheControl);
1385
+ }
1386
+ __name(convertMessages, "convertMessages");
1387
+ function convertTools(tools, cacheControl) {
1388
+ if (!tools || tools.length === 0) return [];
1389
+ return tools.map((tool, index) => {
1390
+ const parameters = isPlainObject(tool.parameters) ? tool.parameters : {};
1391
+ const converted = {
1392
+ name: tool.name,
1393
+ description: tool.description ?? "",
1394
+ input_schema: {
1395
+ type: "object",
1396
+ properties: canonicalizeJson(
1397
+ isPlainObject(parameters["properties"]) ? parameters["properties"] : {}
1398
+ ),
1399
+ required: Array.isArray(parameters["required"]) ? [...parameters["required"]] : []
1400
+ }
1401
+ };
1402
+ return cacheControl !== void 0 && index === tools.length - 1 ? cloneBlockWithCacheControl(converted, cacheControl) : converted;
1403
+ });
1404
+ }
1405
+ __name(convertTools, "convertTools");
1406
+ function thinkingBudgetFor(level, maxTokens, custom) {
1407
+ if (level === "max") {
1408
+ throw new Error("Anthropic attribution reasoning=max requires an adaptive-effort model");
1409
+ }
1410
+ const defaults = {
1411
+ minimal: 1024,
1412
+ low: 4096,
1413
+ medium: 10240,
1414
+ high: 20480,
1415
+ xhigh: 32768,
1416
+ off: 0
1417
+ };
1418
+ const requested = level === "off" ? 0 : custom?.[level] ?? defaults[level];
1419
+ return Math.min(maxTokens - 1, requested);
1420
+ }
1421
+ __name(thinkingBudgetFor, "thinkingBudgetFor");
1422
+ function adaptiveEffortFor(level) {
1423
+ switch (level) {
1424
+ case "low":
1425
+ case "medium":
1426
+ case "high":
1427
+ case "xhigh":
1428
+ case "max":
1429
+ return level;
1430
+ case "minimal":
1431
+ throw new Error(
1432
+ "Anthropic attribution cannot map Pi reasoning=minimal to Claude adaptive effort; use low, medium, high, xhigh, or max"
1433
+ );
1434
+ }
1435
+ }
1436
+ __name(adaptiveEffortFor, "adaptiveEffortFor");
1437
+ function conversationStaticHash(system, tools) {
1438
+ const normalizedSystem = system.filter(
1439
+ (block) => !isPlainObject(block) || typeof block["text"] !== "string" || !isClaudeCodeIdentityText(block["text"])
1440
+ ).map(blockWithoutCacheControl);
1441
+ return sha256Canonical({
1442
+ attribution_profile: {
1443
+ claude_code_version: CLAUDE_CODE_VERSION,
1444
+ entrypoint: CLAUDE_CODE_ENTRYPOINT
1445
+ },
1446
+ system: normalizedSystem,
1447
+ tools: tools.map(blockWithoutCacheControl)
1448
+ });
1449
+ }
1450
+ __name(conversationStaticHash, "conversationStaticHash");
1451
+ function buildAnthropicRequestParams(model, context, options, dependencies = {}) {
1452
+ return buildAnthropicRequest(
1453
+ model,
1454
+ resolveAnthropicTranscript(context, dependencies.hostTranscriptHelpers),
1455
+ options
1456
+ ).params;
1457
+ }
1458
+ __name(buildAnthropicRequestParams, "buildAnthropicRequestParams");
1459
+ function buildAnthropicRequest(model, context, options) {
1460
+ const policy = resolveClaudeCodeModelPolicy(model);
1461
+ const maxTokens = resolveAnthropicMaxTokens(model);
1462
+ const cacheControl = resolveAnthropicCacheControl(model, options);
1463
+ const cacheRetention = cacheControl === void 0 ? "none" : cacheControl.ttl === "1h" ? "long" : "short";
1464
+ let signatureEpoch = resolveSignatureEpochPolicy(
1465
+ model,
1466
+ context.messages,
1467
+ cacheRetention,
1468
+ compactionBoundarySha256FromPiMessages(context.messages)
1469
+ );
1470
+ const system = context.systemPrompt && context.systemPrompt.trim().length > 0 ? markSystemCacheSurface(
1471
+ [
1472
+ {
1473
+ type: "text",
1474
+ text: sanitizeSurrogates(stripAnthropicSystemPromptBadLines(context.systemPrompt))
1475
+ }
1476
+ ],
1477
+ cacheControl
1478
+ ) : [];
1479
+ const tools = convertTools(
1480
+ context.tools,
1481
+ model.compat?.supportsCacheControlOnTools === false ? void 0 : cacheControl
1482
+ );
1483
+ const staticSha256 = conversationStaticHash(system, tools);
1484
+ const params = {
1485
+ model: policy.modelId,
1486
+ messages: convertMessages(
1487
+ model,
1488
+ context.messages,
1489
+ staticSha256,
1490
+ cacheRetention,
1491
+ signatureEpoch,
1492
+ cacheControl
1493
+ ),
1494
+ max_tokens: maxTokens,
1495
+ stream: true,
1496
+ tools
1497
+ };
1498
+ if (system.length > 0) params["system"] = system;
1499
+ if (options?.toolChoice !== void 0)
1500
+ params["tool_choice"] = canonicalizeJson(options.toolChoice);
1501
+ const reasoning = options?.reasoning;
1502
+ if (model.reasoning && reasoning !== void 0) {
1503
+ if (reasoning === "off") {
1504
+ if (policy.enforcesThinkingPrefixBinding) {
1505
+ throw new Error("Anthropic attribution cannot disable thinking for Claude Fable 5.1");
1506
+ }
1507
+ params["thinking"] = { type: "disabled" };
1508
+ params["temperature"] = options?.temperature ?? 1;
1509
+ } else if (policy.thinkingPolicy === "adaptive-effort") {
1510
+ params["thinking"] = {
1511
+ type: "adaptive",
1512
+ ...policy.enforcesThinkingPrefixBinding ? { block_binding: { prefix_mismatch_behavior: "error" } } : {}
1513
+ };
1514
+ params["output_config"] = { effort: adaptiveEffortFor(reasoning) };
1515
+ } else {
1516
+ params["thinking"] = {
1517
+ type: "enabled",
1518
+ budget_tokens: thinkingBudgetFor(reasoning, maxTokens, options?.thinkingBudgets)
1519
+ };
1520
+ }
1521
+ } else if (policy.enforcesThinkingPrefixBinding) {
1522
+ params["thinking"] = {
1523
+ type: "adaptive",
1524
+ block_binding: { prefix_mismatch_behavior: "error" }
1525
+ };
1526
+ } else {
1527
+ params["thinking"] = { type: "disabled" };
1528
+ params["temperature"] = options?.temperature ?? 1;
1529
+ }
1530
+ const previous = latestLineageForTarget(context, normalizedAnthropicModelId(model));
1531
+ if (previous !== void 0 && signatureEpoch.sha256 === previous.signature_epoch_sha256 && (previous.cache_profile_sha256 !== cacheProfileHash(model, policy, params, staticSha256) || !hasLineageRequestPrefix(requestMessagesFromPayload(params), previous))) {
1532
+ signatureEpoch = {
1533
+ sha256: sha256Canonical({
1534
+ projection_version: ANTHROPIC_PROJECTION_VERSION,
1535
+ kind: "lineage-reset",
1536
+ previous_signature_epoch_sha256: previous.signature_epoch_sha256,
1537
+ previous_response_id: previous.response_id,
1538
+ cache_profile_sha256: cacheProfileHash(model, policy, params, staticSha256),
1539
+ request_messages_sha256: promptMessagesHash(requestMessagesFromPayload(params))
1540
+ }),
1541
+ inheritsPrior: false
1542
+ };
1543
+ params["messages"] = convertMessages(
1544
+ model,
1545
+ context.messages,
1546
+ staticSha256,
1547
+ cacheRetention,
1548
+ signatureEpoch,
1549
+ cacheControl
1550
+ );
1551
+ }
1552
+ assertCacheControlBreakpointLimit(params);
1553
+ return { params, signatureEpoch };
1554
+ }
1555
+ __name(buildAnthropicRequest, "buildAnthropicRequest");
1556
+ var MIDDLEWARE_PROTECTED_LINEAGE_FIELDS = [
1557
+ "previous_message_id",
1558
+ "conversation_static_sha256",
1559
+ "request_message_count",
1560
+ "request_messages_sha256",
1561
+ "cache_profile_sha256",
1562
+ "cache_retention",
1563
+ "compaction_boundary_sha256",
1564
+ "signature_epoch_sha256",
1565
+ "signature_epoch_inherits_prior"
1566
+ ];
1567
+ function changedMiddlewareProtectedLineageFields(authorized, final) {
1568
+ return MIDDLEWARE_PROTECTED_LINEAGE_FIELDS.filter((field) => authorized[field] !== final[field]);
1569
+ }
1570
+ __name(changedMiddlewareProtectedLineageFields, "changedMiddlewareProtectedLineageFields");
1571
+ function requestMessagesFromPayload(payload) {
1572
+ const messages = payload["messages"];
1573
+ if (!Array.isArray(messages) || messages.some((message) => !isPlainObject(message))) {
1574
+ throw new Error("Anthropic attribution final payload.messages must be an object array");
1575
+ }
1576
+ for (const message of messages) {
1577
+ if (message["role"] !== "user" && message["role"] !== "assistant") {
1578
+ throw new Error("Anthropic attribution final payload message has an unsupported role");
1579
+ }
1580
+ const content = message["content"];
1581
+ if (!Array.isArray(content) || content.some((block) => !isPlainObject(block))) {
1582
+ throw new Error(
1583
+ "Anthropic attribution final payload message content must use canonical block arrays"
1584
+ );
1585
+ }
1586
+ }
1587
+ return messages;
1588
+ }
1589
+ __name(requestMessagesFromPayload, "requestMessagesFromPayload");
1590
+ function systemBlocksFromPayload(payload) {
1591
+ const system = payload["system"];
1592
+ if (system === void 0) return [];
1593
+ if (typeof system === "string") return [{ type: "text", text: system }];
1594
+ if (!Array.isArray(system))
1595
+ throw new Error("Anthropic attribution final payload.system must be a string or block array");
1596
+ return system;
1597
+ }
1598
+ __name(systemBlocksFromPayload, "systemBlocksFromPayload");
1599
+ function toolsFromPayload(payload) {
1600
+ const tools = payload["tools"];
1601
+ if (tools === void 0) return [];
1602
+ if (!Array.isArray(tools) || tools.some((tool) => !isPlainObject(tool))) {
1603
+ throw new Error("Anthropic attribution final payload.tools must be an object array");
1604
+ }
1605
+ return tools;
1606
+ }
1607
+ __name(toolsFromPayload, "toolsFromPayload");
1608
+ function cacheProfileHash(model, policy, payload, staticSha256) {
1609
+ return sha256Canonical({
1610
+ projection_version: ANTHROPIC_PROJECTION_VERSION,
1611
+ model: normalizedAnthropicModelId(model),
1612
+ beta: policy.beta,
1613
+ conversation_static_sha256: staticSha256,
1614
+ thinking: payload["thinking"],
1615
+ output_config: payload["output_config"],
1616
+ tool_choice: payload["tool_choice"]
1617
+ });
1618
+ }
1619
+ __name(cacheProfileHash, "cacheProfileHash");
1620
+ function cacheRetentionFromPayload(payload) {
1621
+ return inspectCacheControls(payload).retention ?? "none";
1622
+ }
1623
+ __name(cacheRetentionFromPayload, "cacheRetentionFromPayload");
1624
+ function untrustedAssistantSha256(message) {
1625
+ return sha256Canonical({
1626
+ provider: message.provider ?? null,
1627
+ api: message.api ?? null,
1628
+ model: message.model ?? null,
1629
+ response_id: message.responseId ?? null,
1630
+ stop_reason: message.stopReason ?? null,
1631
+ assistant_content_sha256: assistantContentHash(message.content),
1632
+ lineage_diagnostics: (message.diagnostics ?? []).filter(
1633
+ (diagnostic) => diagnostic.type === ANTHROPIC_LINEAGE_DIAGNOSTIC_TYPE
1634
+ )
1635
+ });
1636
+ }
1637
+ __name(untrustedAssistantSha256, "untrustedAssistantSha256");
1638
+ function targetLineageState(context, targetModelId) {
1639
+ for (let index = context.messages.length - 1; index >= 0; index -= 1) {
1640
+ const message = context.messages[index];
1641
+ if (message?.role !== "assistant") continue;
1642
+ const lineageDiagnostics = (message.diagnostics ?? []).filter(
1643
+ (diagnostic) => diagnostic.type === ANTHROPIC_LINEAGE_DIAGNOSTIC_TYPE
1644
+ );
1645
+ const latestRawDetails = lineageDiagnostics.at(-1)?.details;
1646
+ const receiptClaimsTarget = latestRawDetails?.["source_model"] === targetModelId;
1647
+ const assistantClaimsTarget = message.model === targetModelId;
1648
+ if (!assistantClaimsTarget && !receiptClaimsTarget) continue;
1649
+ if ((message.stopReason === "error" || message.stopReason === "aborted") && lineageDiagnostics.length === 0) {
1650
+ continue;
1651
+ }
1652
+ const lineage = parseAnthropicLineageDetails(message);
1653
+ if (lineage?.source_model === targetModelId && lineageBindsContainingAssistant(message, lineage)) {
1654
+ return { kind: "trusted", lineage };
1655
+ }
1656
+ return { kind: "untrusted", assistantSha256: untrustedAssistantSha256(message) };
1657
+ }
1658
+ return { kind: "none" };
1659
+ }
1660
+ __name(targetLineageState, "targetLineageState");
1661
+ function latestLineageForTarget(context, targetModelId) {
1662
+ const state = targetLineageState(context, targetModelId);
1663
+ return state.kind === "trusted" ? state.lineage : void 0;
1664
+ }
1665
+ __name(latestLineageForTarget, "latestLineageForTarget");
1666
+ function declaredCompactionBoundarySha256(messages) {
1667
+ const firstMessage = messages[0];
1668
+ if (firstMessage?.["role"] !== "user" || !Array.isArray(firstMessage["content"])) return null;
1669
+ const declaresCompaction = firstMessage["content"].some(
1670
+ (block) => isPlainObject(block) && block["type"] === "text" && typeof block["text"] === "string" && block["text"].startsWith(COMPACTION_SUMMARY_PREFIX)
1671
+ );
1672
+ if (!declaresCompaction) return null;
1673
+ return sha256Canonical(promptMessagesWithoutCacheControls([firstMessage])[0]);
1674
+ }
1675
+ __name(declaredCompactionBoundarySha256, "declaredCompactionBoundarySha256");
1676
+ function hasLineageRequestPrefix(messages, previous) {
1677
+ return messages.length >= previous.request_message_count && promptMessagesHash(messages.slice(0, previous.request_message_count)) === previous.request_messages_sha256;
1678
+ }
1679
+ __name(hasLineageRequestPrefix, "hasLineageRequestPrefix");
1680
+ function prepareAnthropicLineageDetails(args) {
1681
+ const targetModelId = normalizedAnthropicModelId(args.model);
1682
+ const messages = requestMessagesFromPayload(args.payload);
1683
+ const staticSha256 = conversationStaticHash(
1684
+ systemBlocksFromPayload(args.payload),
1685
+ toolsFromPayload(args.payload)
1686
+ );
1687
+ const profileSha256 = cacheProfileHash(args.model, args.policy, args.payload, staticSha256);
1688
+ const cacheRetention = cacheRetentionFromPayload(args.payload);
1689
+ const compactionBoundarySha256 = declaredCompactionBoundarySha256(messages);
1690
+ const signatureEpoch = args.signatureEpoch;
1691
+ let previous = latestLineageForTarget(args.context, targetModelId);
1692
+ if (previous !== void 0 && (signatureEpoch.sha256 !== previous.signature_epoch_sha256 || !hasLineageRequestPrefix(messages, previous) || previous.cache_profile_sha256 !== profileSha256 || previous.cache_retention !== cacheRetention)) {
1693
+ previous = void 0;
1694
+ }
1695
+ return {
1696
+ schema_version: ANTHROPIC_LINEAGE_SCHEMA,
1697
+ projection_version: ANTHROPIC_PROJECTION_VERSION,
1698
+ source_provider: "anthropic",
1699
+ source_api: "anthropic-messages",
1700
+ source_model: targetModelId,
1701
+ conversation_static_sha256: staticSha256,
1702
+ request_message_count: messages.length,
1703
+ request_messages_sha256: promptMessagesHash(messages),
1704
+ cache_profile_sha256: profileSha256,
1705
+ cache_retention: cacheRetention,
1706
+ compaction_boundary_sha256: compactionBoundarySha256,
1707
+ signature_epoch_sha256: signatureEpoch.sha256,
1708
+ signature_epoch_inherits_prior: signatureEpoch.inheritsPrior,
1709
+ previous_message_id: previous?.response_id ?? null
1710
+ };
1711
+ }
1712
+ __name(prepareAnthropicLineageDetails, "prepareAnthropicLineageDetails");
1713
+ var AnthropicLineageCoordinator = class {
1714
+ static {
1715
+ __name(this, "AnthropicLineageCoordinator");
1716
+ }
1717
+ inFlight = /* @__PURE__ */ new Set();
1718
+ prepare(args) {
1719
+ const targetModelId = normalizedAnthropicModelId(args.model);
1720
+ const key = `${args.sessionId}\0${targetModelId}`;
1721
+ if (this.inFlight.has(key)) {
1722
+ throw new Error(
1723
+ `Anthropic cache lineage already has an in-flight request for ${targetModelId}; concurrent continuations must fork`
1724
+ );
1725
+ }
1726
+ const details = prepareAnthropicLineageDetails(args);
1727
+ this.inFlight.add(key);
1728
+ return { key, details };
1729
+ }
1730
+ release(prepared) {
1731
+ this.inFlight.delete(prepared.key);
1732
+ }
1733
+ };
1734
+ var anthropicLineageCoordinator = new AnthropicLineageCoordinator();
1735
+ function createAnthropicLineageDiagnostic(args) {
1736
+ if (!isNonEmptyString(args.responseId)) {
1737
+ throw new Error("Anthropic lineage diagnostic requires a non-empty response ID");
1738
+ }
1739
+ if (args.previousMessageId !== void 0 && args.previousMessageId !== null) {
1740
+ if (!isNonEmptyString(args.previousMessageId)) {
1741
+ throw new Error("Anthropic lineage diagnostic requires a non-empty previous response ID");
1742
+ }
1743
+ }
1744
+ const policy = resolveClaudeCodeModelPolicy(args.model);
1745
+ const messages = requestMessagesFromPayload(args.requestPayload);
1746
+ const staticSha256 = conversationStaticHash(
1747
+ systemBlocksFromPayload(args.requestPayload),
1748
+ toolsFromPayload(args.requestPayload)
1749
+ );
1750
+ const cacheRetention = cacheRetentionFromPayload(args.requestPayload);
1751
+ const compactionBoundarySha256 = declaredCompactionBoundarySha256(messages);
1752
+ const signatureEpoch = initialSignatureEpochPolicy(
1753
+ normalizedAnthropicModelId(args.model),
1754
+ cacheRetention,
1755
+ compactionBoundarySha256
1756
+ );
1757
+ return {
1758
+ type: ANTHROPIC_LINEAGE_DIAGNOSTIC_TYPE,
1759
+ timestamp: Date.now(),
1760
+ details: {
1761
+ schema_version: ANTHROPIC_LINEAGE_SCHEMA,
1762
+ projection_version: ANTHROPIC_PROJECTION_VERSION,
1763
+ source_provider: "anthropic",
1764
+ source_api: "anthropic-messages",
1765
+ source_model: normalizedAnthropicModelId(args.model),
1766
+ response_id: args.responseId,
1767
+ assistant_content_sha256: assistantContentHash(args.assistantContent),
1768
+ conversation_static_sha256: staticSha256,
1769
+ request_message_count: messages.length,
1770
+ request_messages_sha256: promptMessagesHash(messages),
1771
+ cache_profile_sha256: cacheProfileHash(args.model, policy, args.requestPayload, staticSha256),
1772
+ cache_retention: cacheRetention,
1773
+ compaction_boundary_sha256: compactionBoundarySha256,
1774
+ signature_epoch_sha256: signatureEpoch.sha256,
1775
+ signature_epoch_inherits_prior: signatureEpoch.inheritsPrior,
1776
+ previous_message_id: args.previousMessageId ?? null
1777
+ }
1778
+ };
1779
+ }
1780
+ __name(createAnthropicLineageDiagnostic, "createAnthropicLineageDiagnostic");
1781
+ function appendLineageDiagnostic(output, prepared) {
1782
+ if (!isNonEmptyString(output.responseId)) {
1783
+ throw new Error(
1784
+ "Anthropic attribution successful response is missing responseId lineage proof"
1785
+ );
1786
+ }
1787
+ output.diagnostics ??= [];
1788
+ output.diagnostics.push({
1789
+ type: ANTHROPIC_LINEAGE_DIAGNOSTIC_TYPE,
1790
+ timestamp: Date.now(),
1791
+ details: {
1792
+ ...prepared.details,
1793
+ response_id: output.responseId,
1794
+ assistant_content_sha256: assistantContentHash(output.content)
1795
+ }
1796
+ });
1797
+ }
1798
+ __name(appendLineageDiagnostic, "appendLineageDiagnostic");
1799
+ function appendProviderCacheDiagnostic(output, messageStart) {
1800
+ const diagnostics = messageStart["diagnostics"];
1801
+ const inputTransformations = messageStart["input_transformations"];
1802
+ if (diagnostics === void 0 && inputTransformations === void 0) return;
1803
+ output.diagnostics ??= [];
1804
+ output.diagnostics.push({
1805
+ type: "anthropic-provider-cache",
1806
+ timestamp: Date.now(),
1807
+ details: {
1808
+ cache_diagnostics: canonicalizeJson(diagnostics ?? null),
1809
+ input_transformations: canonicalizeJson(inputTransformations ?? [])
1810
+ }
1811
+ });
1812
+ }
1813
+ __name(appendProviderCacheDiagnostic, "appendProviderCacheDiagnostic");
1814
+ function headersToRecord(headers) {
1815
+ return Object.fromEntries([...headers.entries()]);
1816
+ }
1817
+ __name(headersToRecord, "headersToRecord");
1818
+ function lowerHeaderMap(headers) {
1819
+ const output = {};
1820
+ for (const [key, value] of Object.entries(headers ?? {})) output[key.toLowerCase()] = value;
1821
+ return output;
1822
+ }
1823
+ __name(lowerHeaderMap, "lowerHeaderMap");
1824
+ function resolveAnthropicBetaMessagesUrl(model) {
1825
+ const configured = typeof model.baseUrl === "string" && model.baseUrl.trim().length > 0 ? model.baseUrl.trim() : ANTHROPIC_OFFICIAL_ORIGIN;
1826
+ let parsed;
1827
+ try {
1828
+ parsed = new URL(configured);
1829
+ } catch (error) {
1830
+ throw new Error(
1831
+ `Anthropic attribution requires the official Anthropic HTTPS endpoint; invalid model.baseUrl: ${error instanceof Error ? error.message : String(error)}`
1832
+ );
1833
+ }
1834
+ if (parsed.origin !== ANTHROPIC_OFFICIAL_ORIGIN || parsed.protocol !== "https:" || parsed.username.length > 0 || parsed.password.length > 0 || parsed.pathname !== "" && parsed.pathname !== "/" || parsed.search.length > 0 || parsed.hash.length > 0) {
1835
+ throw new Error(
1836
+ `Anthropic attribution requires the official Anthropic HTTPS endpoint ${ANTHROPIC_OFFICIAL_ORIGIN}; refusing model.baseUrl ${JSON.stringify(configured)}`
1837
+ );
1838
+ }
1839
+ return ANTHROPIC_BETA_MESSAGES_URL;
1840
+ }
1841
+ __name(resolveAnthropicBetaMessagesUrl, "resolveAnthropicBetaMessagesUrl");
1842
+ function buildFetchHeaders(options, apiKey, sessionHeader, beta) {
1843
+ const optionHeaders = lowerHeaderMap(options?.headers);
1844
+ return {
1845
+ Accept: "application/json",
1846
+ Authorization: `Bearer ${apiKey}`,
1847
+ "Content-Type": "application/json",
1848
+ "User-Agent": optionHeaders["user-agent"] ?? CLAUDE_CODE_USER_AGENT,
1849
+ [CLAUDE_CODE_SESSION_HEADER]: sessionHeader ?? optionHeaders["x-claude-code-session-id"] ?? "",
1850
+ "anthropic-beta": beta,
1851
+ "anthropic-dangerous-direct-browser-access": "true",
1852
+ "anthropic-version": "2023-06-01",
1853
+ "x-app": "cli"
1854
+ };
1855
+ }
1856
+ __name(buildFetchHeaders, "buildFetchHeaders");
1857
+ function mapStopReason(reason) {
1858
+ switch (reason) {
1859
+ case "end_turn":
1860
+ case "pause_turn":
1861
+ case "stop_sequence":
1862
+ return "stop";
1863
+ case "max_tokens":
1864
+ return "length";
1865
+ case "tool_use":
1866
+ return "toolUse";
1867
+ default:
1868
+ return "error";
1869
+ }
1870
+ }
1871
+ __name(mapStopReason, "mapStopReason");
1872
+ function parseStreamingJsonFragment(text) {
1873
+ try {
1874
+ return parseJsonSource(text);
1875
+ } catch {
1876
+ return {};
1877
+ }
1878
+ }
1879
+ __name(parseStreamingJsonFragment, "parseStreamingJsonFragment");
1880
+ function parseCompletedToolInput(text) {
1881
+ const parsed = parseJsonValue(text, "Anthropic streamed tool input");
1882
+ if (!isPlainObject(parsed)) {
1883
+ throw new Error("Anthropic streamed tool input must complete as a JSON object");
1884
+ }
1885
+ return parsed;
1886
+ }
1887
+ __name(parseCompletedToolInput, "parseCompletedToolInput");
1888
+ function anthropicStreamErrorMessage(event) {
1889
+ const error = event["error"];
1890
+ if (isPlainObject(error) && typeof error["message"] === "string") {
1891
+ const type = typeof error["type"] === "string" ? `${error["type"]}: ` : "";
1892
+ return `Anthropic beta messages stream error: ${type}${error["message"]}`;
1893
+ }
1894
+ return "Anthropic beta messages stream emitted an error event";
1895
+ }
1896
+ __name(anthropicStreamErrorMessage, "anthropicStreamErrorMessage");
1897
+ function validCostRate(value, fallback, field) {
1898
+ if (value === void 0) return fallback;
1899
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
1900
+ throw new Error(
1901
+ `Anthropic attribution model cost.${field} must be a finite non-negative number`
1902
+ );
1903
+ }
1904
+ return value;
1905
+ }
1906
+ __name(validCostRate, "validCostRate");
1907
+ function resolveModelCostRates(model, totalInputTokens) {
1908
+ let selected = model.cost;
1909
+ let matchedThreshold = -1;
1910
+ for (const tier of model.cost?.tiers ?? []) {
1911
+ const threshold = tier.inputTokensAbove;
1912
+ if (typeof threshold === "number" && Number.isFinite(threshold) && threshold >= 0 && totalInputTokens > threshold && threshold > matchedThreshold) {
1913
+ selected = tier;
1914
+ matchedThreshold = threshold;
1915
+ }
1916
+ }
1917
+ return {
1918
+ input: validCostRate(selected?.input, 3, "input"),
1919
+ output: validCostRate(selected?.output, 15, "output"),
1920
+ cacheRead: validCostRate(selected?.cacheRead, 0.3, "cacheRead"),
1921
+ cacheWrite: validCostRate(selected?.cacheWrite, 3.75, "cacheWrite")
1922
+ };
1923
+ }
1924
+ __name(resolveModelCostRates, "resolveModelCostRates");
1925
+ function updateAnthropicUsage(output, usage, model) {
1926
+ if (!usage) return;
1927
+ if (typeof usage["input_tokens"] === "number") output.usage.input = usage["input_tokens"];
1928
+ if (typeof usage["output_tokens"] === "number") output.usage.output = usage["output_tokens"];
1929
+ if (typeof usage["cache_read_input_tokens"] === "number")
1930
+ output.usage.cacheRead = usage["cache_read_input_tokens"];
1931
+ const cacheCreation = usage["cache_creation"];
1932
+ const reportedLongCacheWrite = isPlainObject(cacheCreation) && typeof cacheCreation["ephemeral_1h_input_tokens"] === "number" ? cacheCreation["ephemeral_1h_input_tokens"] : void 0;
1933
+ if (typeof usage["cache_creation_input_tokens"] === "number") {
1934
+ output.usage.cacheWrite = usage["cache_creation_input_tokens"];
1935
+ output.usage.cacheWrite1h = reportedLongCacheWrite ?? 0;
1936
+ } else if (reportedLongCacheWrite !== void 0) {
1937
+ output.usage.cacheWrite1h = reportedLongCacheWrite;
1938
+ }
1939
+ const longCacheWrite = output.usage.cacheWrite1h ?? 0;
1940
+ if (!Number.isFinite(longCacheWrite) || !Number.isInteger(longCacheWrite) || longCacheWrite < 0 || longCacheWrite > output.usage.cacheWrite) {
1941
+ throw new Error(
1942
+ "Anthropic attribution received malformed 1h cache usage exceeding total cache writes"
1943
+ );
1944
+ }
1945
+ output.usage.totalTokens = output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
1946
+ const rates = resolveModelCostRates(
1947
+ model,
1948
+ output.usage.input + output.usage.cacheRead + output.usage.cacheWrite
1949
+ );
1950
+ const shortCacheWrite = output.usage.cacheWrite - longCacheWrite;
1951
+ output.usage.cost.input = output.usage.input * rates.input / 1e6;
1952
+ output.usage.cost.output = output.usage.output * rates.output / 1e6;
1953
+ output.usage.cost.cacheRead = output.usage.cacheRead * rates.cacheRead / 1e6;
1954
+ output.usage.cost.cacheWrite = (shortCacheWrite * rates.cacheWrite + longCacheWrite * rates.input * 2) / 1e6;
1955
+ output.usage.cost.total = output.usage.cost.input + output.usage.cost.output + output.usage.cost.cacheRead + output.usage.cost.cacheWrite;
1956
+ }
1957
+ __name(updateAnthropicUsage, "updateAnthropicUsage");
1958
+ async function* iterateSseEvents(response, signal) {
1959
+ if (!response.body) throw new Error("Anthropic beta messages response had no body");
1960
+ const reader = response.body.getReader();
1961
+ const decoder = new TextDecoder();
1962
+ let buffer = "";
1963
+ let eventName = "";
1964
+ let dataLines = [];
1965
+ function flush() {
1966
+ if (dataLines.length === 0) {
1967
+ eventName = "";
1968
+ return void 0;
1969
+ }
1970
+ const data = dataLines.join("\n");
1971
+ const declaredEventName = eventName;
1972
+ eventName = "";
1973
+ dataLines = [];
1974
+ if (data === "[DONE]") return void 0;
1975
+ const event = parseJsonObject(data, "Anthropic beta messages SSE event");
1976
+ if (declaredEventName.length > 0 && (typeof event["type"] !== "string" || event["type"] !== declaredEventName)) {
1977
+ throw new Error(
1978
+ `Anthropic beta messages SSE event name ${JSON.stringify(declaredEventName)} did not match data.type`
1979
+ );
1980
+ }
1981
+ return event;
1982
+ }
1983
+ __name(flush, "flush");
1984
+ function consumeLine(line) {
1985
+ if (line.length === 0) return flush();
1986
+ if (line.startsWith(":")) return void 0;
1987
+ const colon = line.indexOf(":");
1988
+ const field = colon === -1 ? line : line.slice(0, colon);
1989
+ let value = colon === -1 ? "" : line.slice(colon + 1);
1990
+ if (value.startsWith(" ")) value = value.slice(1);
1991
+ if (field === "event") eventName = value;
1992
+ if (field === "data") dataLines.push(value);
1993
+ return void 0;
1994
+ }
1995
+ __name(consumeLine, "consumeLine");
1996
+ try {
1997
+ for (; ; ) {
1998
+ if (signal?.aborted) throw new Error("Request was aborted");
1999
+ const { value, done } = await reader.read();
2000
+ if (done) break;
2001
+ buffer += decoder.decode(value, { stream: true });
2002
+ for (; ; ) {
2003
+ const match = /\r\n|\n|\r/.exec(buffer);
2004
+ if (match?.index === void 0) break;
2005
+ const line = buffer.slice(0, match.index);
2006
+ buffer = buffer.slice(match.index + match[0].length);
2007
+ const event = consumeLine(line);
2008
+ if (event) yield event;
2009
+ }
2010
+ }
2011
+ buffer += decoder.decode();
2012
+ if (buffer.length > 0) {
2013
+ const event = consumeLine(buffer);
2014
+ if (event) yield event;
2015
+ }
2016
+ const trailing = flush();
2017
+ if (trailing) yield trailing;
2018
+ } finally {
2019
+ reader.releaseLock();
2020
+ }
2021
+ }
2022
+ __name(iterateSseEvents, "iterateSseEvents");
2023
+ function createOutput(model) {
2024
+ return {
2025
+ role: "assistant",
2026
+ content: [],
2027
+ api: model.api,
2028
+ provider: model.provider,
2029
+ model: model.id,
2030
+ usage: {
2031
+ input: 0,
2032
+ output: 0,
2033
+ cacheRead: 0,
2034
+ cacheWrite: 0,
2035
+ totalTokens: 0,
2036
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
2037
+ },
2038
+ stopReason: "stop",
2039
+ timestamp: Date.now()
2040
+ };
2041
+ }
2042
+ __name(createOutput, "createOutput");
2043
+ var TRANSIENT_CONNECTION_CODES = /* @__PURE__ */ new Set([
2044
+ "ECONNRESET",
2045
+ "ECONNREFUSED",
2046
+ "EPIPE",
2047
+ "ETIMEDOUT",
2048
+ "EAI_AGAIN",
2049
+ "ENETUNREACH",
2050
+ "EHOSTUNREACH",
2051
+ "UND_ERR_SOCKET",
2052
+ "UND_ERR_CONNECT_TIMEOUT",
2053
+ "UND_ERR_HEADERS_TIMEOUT"
2054
+ ]);
2055
+ function transientConnectionCode(error, seen = /* @__PURE__ */ new Set(), depth = 0) {
2056
+ if (!(error instanceof Error) || depth > 8 || seen.size >= 32 || seen.has(error))
2057
+ return void 0;
2058
+ seen.add(error);
2059
+ if (error.name === "AbortError") return void 0;
2060
+ if (error instanceof AggregateError) {
2061
+ const errors = error.errors;
2062
+ if (!Array.isArray(errors) || errors.length === 0 || errors.length > 16) return void 0;
2063
+ const codes = [];
2064
+ for (const member of errors) {
2065
+ const code2 = transientConnectionCode(member, seen, depth + 1);
2066
+ if (code2 === void 0) return void 0;
2067
+ codes.push(code2);
2068
+ }
2069
+ return [...new Set(codes)].sort().join(",");
2070
+ }
2071
+ const code = Reflect.get(error, "code");
2072
+ if (code !== void 0) {
2073
+ return typeof code === "string" && TRANSIENT_CONNECTION_CODES.has(code) ? code : void 0;
2074
+ }
2075
+ return transientConnectionCode(error.cause, seen, depth + 1);
2076
+ }
2077
+ __name(transientConnectionCode, "transientConnectionCode");
2078
+ function connectionRetryLimit(value) {
2079
+ if (value === void 0) return 2;
2080
+ if (!Number.isSafeInteger(value) || value < 0 || value >= Number.MAX_SAFE_INTEGER) {
2081
+ throw new Error(
2082
+ "Anthropic attribution options.maxRetries must be a non-negative safe integer below Number.MAX_SAFE_INTEGER"
2083
+ );
2084
+ }
2085
+ return value;
2086
+ }
2087
+ __name(connectionRetryLimit, "connectionRetryLimit");
2088
+ function connectionTimeout(value) {
2089
+ if (value !== void 0 && (!Number.isSafeInteger(value) || value <= 0 || value > 2147483647)) {
2090
+ throw new Error(
2091
+ "Anthropic attribution options.timeoutMs must be an integer from 1 through 2147483647"
2092
+ );
2093
+ }
2094
+ return value;
2095
+ }
2096
+ __name(connectionTimeout, "connectionTimeout");
2097
+ function waitForConnectionRetry(delayMs, signal) {
2098
+ signal?.throwIfAborted();
2099
+ return new Promise((resolve, reject) => {
2100
+ const onAbort = /* @__PURE__ */ __name(() => {
2101
+ clearTimeout(timer);
2102
+ signal?.removeEventListener("abort", onAbort);
2103
+ reject(signal?.reason);
2104
+ }, "onAbort");
2105
+ const timer = setTimeout(() => {
2106
+ signal?.removeEventListener("abort", onAbort);
2107
+ resolve();
2108
+ }, delayMs);
2109
+ signal?.addEventListener("abort", onAbort, { once: true });
2110
+ if (signal?.aborted) onAbort();
2111
+ });
2112
+ }
2113
+ __name(waitForConnectionRetry, "waitForConnectionRetry");
2114
+ async function fetchAnthropicResponse(url, requestInit, maxRetries, timeoutMs, onRetry) {
2115
+ const callerSignal = requestInit.signal ?? void 0;
2116
+ for (let attempt = 0; ; attempt += 1) {
2117
+ callerSignal?.throwIfAborted();
2118
+ const deadline = timeoutMs === void 0 ? void 0 : new AbortController();
2119
+ const signal = deadline === void 0 ? callerSignal : callerSignal === void 0 ? deadline.signal : AbortSignal.any([callerSignal, deadline.signal]);
2120
+ const init = signal === void 0 ? requestInit : { ...requestInit, signal };
2121
+ const timer = timeoutMs === void 0 ? void 0 : setTimeout(() => {
2122
+ deadline?.abort(
2123
+ Object.assign(new Error(`Anthropic connection timed out after ${timeoutMs}ms`), {
2124
+ code: "ETIMEDOUT"
2125
+ })
2126
+ );
2127
+ }, timeoutMs);
2128
+ let response;
2129
+ let retryCode;
2130
+ try {
2131
+ response = await fetch(url, init);
2132
+ } catch (error) {
2133
+ callerSignal?.throwIfAborted();
2134
+ const failure = deadline?.signal.aborted ? deadline.signal.reason : error;
2135
+ retryCode = transientConnectionCode(failure);
2136
+ if (retryCode === void 0) throw failure;
2137
+ if (attempt >= maxRetries) {
2138
+ throw new Error(
2139
+ `Anthropic connection error after ${attempt + 1} attempt(s): ${retryCode}`,
2140
+ { cause: failure }
2141
+ );
2142
+ }
2143
+ } finally {
2144
+ if (timer !== void 0) clearTimeout(timer);
2145
+ }
2146
+ if (retryCode !== void 0) {
2147
+ const delayMs = Math.floor(
2148
+ Math.min(500 * 2 ** Math.min(attempt, 4), 8e3) * (1 - Math.random() * 0.25)
2149
+ );
2150
+ onRetry(attempt + 1, retryCode, delayMs);
2151
+ await waitForConnectionRetry(delayMs, callerSignal);
2152
+ continue;
2153
+ }
2154
+ if (response === void 0) throw new Error("Anthropic fetch returned no response");
2155
+ if (signal?.aborted) {
2156
+ try {
2157
+ await response.body?.cancel();
2158
+ } finally {
2159
+ signal.throwIfAborted();
2160
+ }
2161
+ }
2162
+ return response;
2163
+ }
2164
+ }
2165
+ __name(fetchAnthropicResponse, "fetchAnthropicResponse");
2166
+ function forwardToBuiltInAnthropic(model, context, options, dependencies) {
2167
+ const hostAnthropicMessagesApi = dependencies.hostAnthropicMessagesApi;
2168
+ if (hostAnthropicMessagesApi === void 0) {
2169
+ throw new Error(
2170
+ "pi_anthropic_attribution_host_adapter_missing: the extension gateway did not inject Pi's anthropic-messages adapter"
2171
+ );
2172
+ }
2173
+ const hostApi = hostAnthropicMessagesApi();
2174
+ if (typeof hostApi?.streamSimple !== "function") {
2175
+ throw new Error(
2176
+ "pi_anthropic_attribution_host_adapter_invalid: the host adapter must provide streamSimple"
2177
+ );
2178
+ }
2179
+ const delegated = hostApi.streamSimple(
2180
+ model,
2181
+ context,
2182
+ options
2183
+ );
2184
+ return delegated;
2185
+ }
2186
+ __name(forwardToBuiltInAnthropic, "forwardToBuiltInAnthropic");
2187
+ function streamAnthropicViaBetaMessages(model, context, options, dependencies = {}) {
2188
+ if (model.provider !== "anthropic") {
2189
+ return forwardToBuiltInAnthropic(model, context, options, dependencies);
2190
+ }
2191
+ const stream = createAssistantMessageEventStream();
2192
+ const output = createOutput(model);
2193
+ void (async () => {
2194
+ let preparedLineage;
2195
+ try {
2196
+ options?.signal?.throwIfAborted();
2197
+ const maxRetries = connectionRetryLimit(options?.maxRetries);
2198
+ const timeoutMs = connectionTimeout(options?.timeoutMs);
2199
+ const apiKey = options?.apiKey;
2200
+ if (typeof apiKey !== "string" || apiKey.length === 0) {
2201
+ throw new Error(
2202
+ "Anthropic attribution requires Pi OAuth apiKey/token; no credential was supplied"
2203
+ );
2204
+ }
2205
+ if (!apiKey.includes("sk-ant-oat")) {
2206
+ throw new Error(
2207
+ "Anthropic attribution refuses non-OAuth Anthropic credential; subscription OAuth token is required"
2208
+ );
2209
+ }
2210
+ const sessionId = options?.sessionId === void 0 ? randomUUID() : requireSessionId(options.sessionId, "options.sessionId");
2211
+ const account = requireAttributionAccount(
2212
+ dependencies.loadAccount?.() ?? loadClaudeAttributionAccount(void 0, options?.env)
2213
+ );
2214
+ const url = resolveAnthropicBetaMessagesUrl(model);
2215
+ const policy = resolveClaudeCodeModelPolicy(model);
2216
+ const requestContext = resolveAnthropicTranscript(
2217
+ context,
2218
+ dependencies.hostTranscriptHelpers
2219
+ );
2220
+ const request = buildAnthropicRequest(model, requestContext, options);
2221
+ let params = request.params;
2222
+ const billingSystemText = buildClaudeCodeBillingSystemText(
2223
+ firstUserMessageTextFromPayload(params)
2224
+ );
2225
+ const provisionalLineage = prepareAnthropicLineageDetails({
2226
+ model,
2227
+ policy,
2228
+ context: requestContext,
2229
+ payload: params,
2230
+ signatureEpoch: request.signatureEpoch
2231
+ });
2232
+ if (policy.supportsCacheDiagnostics) {
2233
+ if (!policy.beta.split(",").includes(ANTHROPIC_CACHE_DIAGNOSTICS_BETA)) {
2234
+ throw new Error("Anthropic cache diagnostics policy is missing its required beta header");
2235
+ }
2236
+ params["diagnostics"] = {
2237
+ previous_message_id: provisionalLineage.previous_message_id
2238
+ };
2239
+ }
2240
+ if (policy.enforcesThinkingPrefixBinding && !policy.beta.split(",").includes(ANTHROPIC_THINKING_BINDING_BETA)) {
2241
+ throw new Error("Anthropic thinking-binding policy is missing its required beta header");
2242
+ }
2243
+ params = rewriteAnthropicRequestPayloadForSession({
2244
+ payload: params,
2245
+ model,
2246
+ sessionId,
2247
+ account,
2248
+ headerRegistered: true,
2249
+ ...options?.cacheRetention === void 0 ? {} : { cacheRetention: options.cacheRetention }
2250
+ });
2251
+ const protectedCacheControlTopologySha256 = cacheControlTopologySha256(params);
2252
+ const nextParams = await options?.onPayload?.(params, model);
2253
+ if (nextParams !== void 0) {
2254
+ if (!isPlainObject(nextParams))
2255
+ throw new Error("Anthropic attribution onPayload returned a non-object payload");
2256
+ params = nextParams;
2257
+ }
2258
+ assertProtectedAnthropicAttribution({
2259
+ payload: params,
2260
+ account,
2261
+ sessionId,
2262
+ billingSystemText,
2263
+ modelId: policy.modelId,
2264
+ cacheControlTopologySha256: protectedCacheControlTopologySha256
2265
+ });
2266
+ preparedLineage = anthropicLineageCoordinator.prepare({
2267
+ sessionId,
2268
+ model,
2269
+ policy,
2270
+ context: requestContext,
2271
+ payload: params,
2272
+ signatureEpoch: request.signatureEpoch
2273
+ });
2274
+ const middlewareChangedLineageFields = changedMiddlewareProtectedLineageFields(
2275
+ provisionalLineage,
2276
+ preparedLineage.details
2277
+ );
2278
+ if (middlewareChangedLineageFields.length > 0) {
2279
+ throw new Error(
2280
+ `Anthropic request/cache lineage changed during before_provider_request transforms (${middlewareChangedLineageFields.join(", ")}); payload middleware must not alter the attributed system prompt, tools, messages, cache retention, or compaction boundary`
2281
+ );
2282
+ }
2283
+ if (policy.supportsCacheDiagnostics) {
2284
+ const diagnostics = params["diagnostics"];
2285
+ if (!isPlainObject(diagnostics) || diagnostics["previous_message_id"] !== preparedLineage.details.previous_message_id) {
2286
+ throw new Error(
2287
+ "Anthropic cache diagnostics were removed or changed during before_provider_request transforms"
2288
+ );
2289
+ }
2290
+ }
2291
+ const headers = buildFetchHeaders(options, apiKey, sessionId, policy.beta);
2292
+ const requestInit = {
2293
+ method: "POST",
2294
+ headers,
2295
+ body: JSON.stringify(params),
2296
+ redirect: "error"
2297
+ };
2298
+ if (options?.signal) requestInit.signal = options.signal;
2299
+ const retryDetails = {};
2300
+ const response = await fetchAnthropicResponse(
2301
+ url,
2302
+ requestInit,
2303
+ maxRetries,
2304
+ timeoutMs,
2305
+ (retry, code, delayMs) => {
2306
+ if (retry === 1) {
2307
+ output.diagnostics ??= [];
2308
+ output.diagnostics.push({
2309
+ type: "anthropic-connection-retry",
2310
+ timestamp: Date.now(),
2311
+ details: retryDetails
2312
+ });
2313
+ }
2314
+ Object.assign(retryDetails, {
2315
+ retries_scheduled: retry,
2316
+ retry_limit: maxRetries,
2317
+ last_connection_code: code,
2318
+ last_delay_ms: delayMs
2319
+ });
2320
+ }
2321
+ );
2322
+ await options?.onResponse?.(
2323
+ { status: response.status, headers: headersToRecord(response.headers) },
2324
+ model
2325
+ );
2326
+ if (!response.ok) {
2327
+ throw new Error(
2328
+ `Anthropic beta messages request failed: HTTP ${response.status} ${response.statusText}: ${await response.text()}`
2329
+ );
2330
+ }
2331
+ const contentType = response.headers.get("content-type")?.toLowerCase() ?? "";
2332
+ if (!contentType.includes("text/event-stream")) {
2333
+ throw new Error(
2334
+ `Anthropic beta messages response must be text/event-stream; got ${JSON.stringify(contentType || "(missing)")}`
2335
+ );
2336
+ }
2337
+ stream.push({ type: "start", partial: output });
2338
+ const blocks = output.content;
2339
+ const activeContentIndexes = /* @__PURE__ */ new Set();
2340
+ let sawMessageStart = false;
2341
+ let sawMessageStop = false;
2342
+ let sawTerminalStopReason = false;
2343
+ for await (const event of iterateSseEvents(response, options?.signal)) {
2344
+ const eventType = event["type"];
2345
+ if (typeof eventType !== "string") {
2346
+ throw new Error("Anthropic beta messages SSE event is missing string data.type");
2347
+ }
2348
+ if (eventType === "error") throw new Error(anthropicStreamErrorMessage(event));
2349
+ if (eventType === "ping") continue;
2350
+ if (sawMessageStop) {
2351
+ throw new Error("Anthropic beta messages stream emitted data after message_stop");
2352
+ }
2353
+ if (eventType !== "message_start" && !sawMessageStart) {
2354
+ throw new Error("Anthropic beta messages stream emitted content before message_start");
2355
+ }
2356
+ if (eventType === "message_start") {
2357
+ if (sawMessageStart || !isPlainObject(event["message"])) {
2358
+ throw new Error(
2359
+ "Anthropic beta messages stream emitted malformed/duplicate message_start"
2360
+ );
2361
+ }
2362
+ if (!isNonEmptyString(event["message"]["id"])) {
2363
+ throw new Error("Anthropic beta messages message_start is missing a response id");
2364
+ }
2365
+ sawMessageStart = true;
2366
+ if (typeof event["message"]["id"] === "string")
2367
+ output.responseId = event["message"]["id"];
2368
+ appendProviderCacheDiagnostic(output, event["message"]);
2369
+ updateAnthropicUsage(
2370
+ output,
2371
+ isPlainObject(event["message"]["usage"]) ? event["message"]["usage"] : void 0,
2372
+ model
2373
+ );
2374
+ } else if (eventType === "content_block_start") {
2375
+ const contentIndex = event["index"];
2376
+ const contentBlock = event["content_block"];
2377
+ if (!Number.isSafeInteger(contentIndex) || contentIndex < 0 || !isPlainObject(contentBlock)) {
2378
+ throw new Error("Anthropic beta messages stream emitted malformed content_block_start");
2379
+ }
2380
+ if (activeContentIndexes.has(contentIndex)) {
2381
+ throw new Error("Anthropic beta messages stream duplicated an active content block");
2382
+ }
2383
+ activeContentIndexes.add(contentIndex);
2384
+ if (contentBlock["type"] === "text") {
2385
+ output.content.push({ type: "text", text: "", index: contentIndex });
2386
+ stream.push({
2387
+ type: "text_start",
2388
+ contentIndex: output.content.length - 1,
2389
+ partial: output
2390
+ });
2391
+ } else if (contentBlock["type"] === "thinking") {
2392
+ output.content.push({
2393
+ type: "thinking",
2394
+ thinking: "",
2395
+ thinkingSignature: "",
2396
+ index: contentIndex
2397
+ });
2398
+ stream.push({
2399
+ type: "thinking_start",
2400
+ contentIndex: output.content.length - 1,
2401
+ partial: output
2402
+ });
2403
+ } else if (contentBlock["type"] === "redacted_thinking") {
2404
+ if (typeof contentBlock["data"] !== "string") {
2405
+ throw new Error("Anthropic redacted_thinking block is missing string data");
2406
+ }
2407
+ output.content.push({
2408
+ type: "thinking",
2409
+ thinking: "[Reasoning redacted]",
2410
+ thinkingSignature: contentBlock["data"],
2411
+ redacted: true,
2412
+ index: contentIndex
2413
+ });
2414
+ stream.push({
2415
+ type: "thinking_start",
2416
+ contentIndex: output.content.length - 1,
2417
+ partial: output
2418
+ });
2419
+ } else if (contentBlock["type"] === "tool_use") {
2420
+ if (typeof contentBlock["id"] !== "string" || typeof contentBlock["name"] !== "string" || !isPlainObject(contentBlock["input"] ?? {})) {
2421
+ throw new Error("Anthropic tool_use block is malformed");
2422
+ }
2423
+ output.content.push({
2424
+ type: "toolCall",
2425
+ id: contentBlock["id"],
2426
+ name: contentBlock["name"],
2427
+ arguments: contentBlock["input"] ?? {},
2428
+ partialJson: "",
2429
+ index: contentIndex
2430
+ });
2431
+ stream.push({
2432
+ type: "toolcall_start",
2433
+ contentIndex: output.content.length - 1,
2434
+ partial: output
2435
+ });
2436
+ } else {
2437
+ throw new Error(
2438
+ `Anthropic beta messages stream emitted unsupported content block ${JSON.stringify(contentBlock["type"])}`
2439
+ );
2440
+ }
2441
+ } else if (eventType === "content_block_delta") {
2442
+ const contentIndex = event["index"];
2443
+ const delta = event["delta"];
2444
+ if (!Number.isSafeInteger(contentIndex) || !activeContentIndexes.has(contentIndex) || !isPlainObject(delta)) {
2445
+ throw new Error(
2446
+ "Anthropic beta messages stream emitted malformed/orphan content_block_delta"
2447
+ );
2448
+ }
2449
+ const blockIndex = blocks.findIndex((block2) => block2.index === contentIndex);
2450
+ const block = blocks[blockIndex];
2451
+ if (!block) {
2452
+ throw new Error("Anthropic beta messages stream delta has no projected content block");
2453
+ }
2454
+ if (delta["type"] === "text_delta" && block["type"] === "text" && typeof delta["text"] === "string") {
2455
+ block["text"] = `${String(block["text"] ?? "")}${delta["text"]}`;
2456
+ stream.push({
2457
+ type: "text_delta",
2458
+ contentIndex: blockIndex,
2459
+ delta: delta["text"],
2460
+ partial: output
2461
+ });
2462
+ } else if (delta["type"] === "thinking_delta" && block["type"] === "thinking" && typeof delta["thinking"] === "string") {
2463
+ block["thinking"] = `${String(block["thinking"] ?? "")}${delta["thinking"]}`;
2464
+ stream.push({
2465
+ type: "thinking_delta",
2466
+ contentIndex: blockIndex,
2467
+ delta: delta["thinking"],
2468
+ partial: output
2469
+ });
2470
+ } else if (delta["type"] === "input_json_delta" && block["type"] === "toolCall" && typeof delta["partial_json"] === "string") {
2471
+ block.partialJson = `${block.partialJson ?? ""}${delta["partial_json"]}`;
2472
+ block["arguments"] = parseStreamingJsonFragment(block.partialJson);
2473
+ stream.push({
2474
+ type: "toolcall_delta",
2475
+ contentIndex: blockIndex,
2476
+ delta: delta["partial_json"],
2477
+ partial: output
2478
+ });
2479
+ } else if (delta["type"] === "signature_delta" && block["type"] === "thinking" && typeof delta["signature"] === "string") {
2480
+ block["thinkingSignature"] = `${String(block["thinkingSignature"] ?? "")}${delta["signature"]}`;
2481
+ } else {
2482
+ throw new Error(
2483
+ `Anthropic beta messages stream emitted unsupported/mismatched delta ${JSON.stringify(delta["type"])}`
2484
+ );
2485
+ }
2486
+ } else if (eventType === "content_block_stop") {
2487
+ const contentIndex = event["index"];
2488
+ if (!Number.isSafeInteger(contentIndex) || !activeContentIndexes.delete(contentIndex)) {
2489
+ throw new Error(
2490
+ "Anthropic beta messages stream emitted malformed/orphan content_block_stop"
2491
+ );
2492
+ }
2493
+ const blockIndex = blocks.findIndex((block2) => block2.index === contentIndex);
2494
+ const block = blocks[blockIndex];
2495
+ if (!block) {
2496
+ throw new Error("Anthropic beta messages stream stop has no projected content block");
2497
+ }
2498
+ delete block.index;
2499
+ if (block["type"] === "text") {
2500
+ stream.push({
2501
+ type: "text_end",
2502
+ contentIndex: blockIndex,
2503
+ content: String(block["text"] ?? ""),
2504
+ partial: output
2505
+ });
2506
+ } else if (block["type"] === "thinking") {
2507
+ stream.push({
2508
+ type: "thinking_end",
2509
+ contentIndex: blockIndex,
2510
+ content: String(block["thinking"] ?? ""),
2511
+ partial: output
2512
+ });
2513
+ } else if (block["type"] === "toolCall") {
2514
+ block["arguments"] = block.partialJson && block.partialJson.length > 0 ? parseCompletedToolInput(block.partialJson) : canonicalizeJson(block["arguments"] ?? {});
2515
+ delete block.partialJson;
2516
+ stream.push({
2517
+ type: "toolcall_end",
2518
+ contentIndex: blockIndex,
2519
+ toolCall: block,
2520
+ partial: output
2521
+ });
2522
+ }
2523
+ } else if (eventType === "message_delta") {
2524
+ if (!isPlainObject(event["delta"])) {
2525
+ throw new Error("Anthropic beta messages stream emitted malformed message_delta");
2526
+ }
2527
+ const stopReason = event["delta"]["stop_reason"];
2528
+ if (typeof stopReason === "string") {
2529
+ const mapped = mapStopReason(stopReason);
2530
+ if (mapped === "error") {
2531
+ throw new Error(
2532
+ `Anthropic beta messages stream emitted unsupported stop reason ${JSON.stringify(stopReason)}`
2533
+ );
2534
+ }
2535
+ output.stopReason = mapped;
2536
+ sawTerminalStopReason = true;
2537
+ }
2538
+ updateAnthropicUsage(
2539
+ output,
2540
+ isPlainObject(event["usage"]) ? event["usage"] : void 0,
2541
+ model
2542
+ );
2543
+ } else if (eventType === "message_stop") {
2544
+ if (activeContentIndexes.size > 0) {
2545
+ throw new Error(
2546
+ "Anthropic beta messages message_stop arrived with open content blocks"
2547
+ );
2548
+ }
2549
+ sawMessageStop = true;
2550
+ } else {
2551
+ throw new Error(
2552
+ `Anthropic beta messages stream emitted unsupported event ${JSON.stringify(eventType)}`
2553
+ );
2554
+ }
2555
+ }
2556
+ if (options?.signal?.aborted) throw new Error("Request was aborted");
2557
+ if (!sawMessageStart) {
2558
+ throw new Error("Anthropic beta messages stream ended without message_start");
2559
+ }
2560
+ if (!sawMessageStop) {
2561
+ throw new Error("Anthropic beta messages stream ended without message_stop");
2562
+ }
2563
+ if (!sawTerminalStopReason || output.stopReason === "error") {
2564
+ throw new Error(
2565
+ "Anthropic beta messages stream ended without a valid terminal stop reason"
2566
+ );
2567
+ }
2568
+ if (preparedLineage === void 0)
2569
+ throw new Error("Anthropic attribution completed without prepared cache lineage");
2570
+ appendLineageDiagnostic(output, preparedLineage);
2571
+ stream.push({ type: "done", reason: output.stopReason, message: output });
2572
+ stream.end();
2573
+ } catch (error) {
2574
+ for (const block of output.content) {
2575
+ delete block["index"];
2576
+ delete block["partialJson"];
2577
+ }
2578
+ output.stopReason = options?.signal?.aborted ? "aborted" : "error";
2579
+ output.errorMessage = error instanceof Error ? error.message : String(error);
2580
+ stream.push({ type: "error", reason: output.stopReason, error: output });
2581
+ stream.end();
2582
+ } finally {
2583
+ if (preparedLineage !== void 0) anthropicLineageCoordinator.release(preparedLineage);
2584
+ }
2585
+ })();
2586
+ return stream;
2587
+ }
2588
+ __name(streamAnthropicViaBetaMessages, "streamAnthropicViaBetaMessages");
2589
+ function cacheRetentionLabel(retention) {
2590
+ switch (retention) {
2591
+ case "long":
2592
+ return "1-hour";
2593
+ case "short":
2594
+ return "5-minute";
2595
+ case "none":
2596
+ return "disabled";
2597
+ }
2598
+ }
2599
+ __name(cacheRetentionLabel, "cacheRetentionLabel");
2600
+ function isAnthropicAttributionClaimProbe(value) {
2601
+ return isPlainObject(value) && value["schema_version"] === ANTHROPIC_ATTRIBUTION_CLAIM_SCHEMA && typeof value["acknowledge"] === "function";
2602
+ }
2603
+ __name(isAnthropicAttributionClaimProbe, "isAnthropicAttributionClaimProbe");
2604
+ function spawnAnthropicAttribution(pi, dependencies = {}) {
2605
+ const acknowledgements = [];
2606
+ const probe = {
2607
+ schema_version: ANTHROPIC_ATTRIBUTION_CLAIM_SCHEMA,
2608
+ acknowledge: /* @__PURE__ */ __name(() => {
2609
+ acknowledgements.push(true);
2610
+ }, "acknowledge")
2611
+ };
2612
+ pi.events.emit(ANTHROPIC_ATTRIBUTION_CLAIM_CHANNEL, probe);
2613
+ if (acknowledgements.length > 0) return;
2614
+ let sessionCacheRetention;
2615
+ const getSessionOverride = /* @__PURE__ */ __name(() => sessionCacheRetention, "getSessionOverride");
2616
+ pi.registerProvider("anthropic", {
2617
+ api: "anthropic-messages",
2618
+ streamSimple: /* @__PURE__ */ __name((model, context, options) => streamAnthropicViaBetaMessages(
2619
+ model,
2620
+ context,
2621
+ model.provider === "anthropic" ? {
2622
+ ...options ?? {},
2623
+ cacheRetention: resolveRegisteredCacheRetention(options, getSessionOverride())
2624
+ } : options,
2625
+ dependencies
2626
+ ), "streamSimple")
2627
+ });
2628
+ pi.registerCommand("claude-cache", {
2629
+ description: "Show or set Claude cache retention for this session (short, long, default)",
2630
+ handler: /* @__PURE__ */ __name((args, ctx) => {
2631
+ const action = args.trim().toLowerCase();
2632
+ if (action.length === 0 || action === "status") {
2633
+ const effective2 = resolveCacheRetentionPreference(void 0, sessionCacheRetention);
2634
+ ctx.ui?.notify(
2635
+ `Claude cache retention: ${cacheRetentionLabel(effective2)}${sessionCacheRetention === void 0 ? " (default)" : " (session override)"}`,
2636
+ "info"
2637
+ );
2638
+ return;
2639
+ }
2640
+ if (action !== "short" && action !== "long" && action !== "default") {
2641
+ throw new Error("Usage: /claude-cache [status|short|long|default]");
2642
+ }
2643
+ sessionCacheRetention = action === "default" ? void 0 : action;
2644
+ pi.appendEntry(ANTHROPIC_CACHE_RETENTION_ENTRY, {
2645
+ schema_version: ANTHROPIC_CACHE_RETENTION_SCHEMA,
2646
+ retention: action
2647
+ });
2648
+ const effective = resolveCacheRetentionPreference(void 0, sessionCacheRetention);
2649
+ ctx.ui?.notify(
2650
+ `Claude cache retention set to ${cacheRetentionLabel(effective)} for this session${action === "default" ? " (default policy)" : ""}.`,
2651
+ "info"
2652
+ );
2653
+ }, "handler")
2654
+ });
2655
+ pi.on("session_start", (_event, ctx) => {
2656
+ sessionCacheRetention = restoreAnthropicSessionCacheRetention(ctx.sessionManager.getBranch());
2657
+ });
2658
+ pi.on("session_shutdown", () => {
2659
+ sessionCacheRetention = void 0;
2660
+ });
2661
+ pi.on("session_tree", (_event, ctx) => {
2662
+ sessionCacheRetention = restoreAnthropicSessionCacheRetention(ctx.sessionManager.getBranch());
2663
+ });
2664
+ pi.events.on(ANTHROPIC_ATTRIBUTION_CLAIM_CHANNEL, (value) => {
2665
+ if (isAnthropicAttributionClaimProbe(value)) value.acknowledge();
2666
+ });
2667
+ }
2668
+ __name(spawnAnthropicAttribution, "spawnAnthropicAttribution");
2669
+ export {
2670
+ ANTHROPIC_1M_CONTEXT_BETA,
2671
+ ANTHROPIC_ACCOUNT_CONFIG_PATH_ENV,
2672
+ ANTHROPIC_ATTRIBUTION_CLAIM_CHANNEL,
2673
+ ANTHROPIC_CACHE_RETENTION_ENTRY,
2674
+ CLAUDE_CODE_200K_SUBSCRIPTION_CONTEXT_WINDOW,
2675
+ CLAUDE_CODE_BETA,
2676
+ CLAUDE_CODE_SESSION_HEADER,
2677
+ buildAnthropicAttributionHeaders,
2678
+ buildAnthropicRequestParams,
2679
+ buildClaudeCodeBillingSystemText,
2680
+ computeClaudeCodeFingerprint,
2681
+ createAnthropicLineageDiagnostic,
2682
+ spawnAnthropicAttribution as default,
2683
+ extractClaudeAttributionAccount,
2684
+ isAnthropicContext,
2685
+ loadClaudeAttributionAccount,
2686
+ registerAnthropicAttributionProvider,
2687
+ resolveAnthropicMaxTokens,
2688
+ resolveCacheRetentionPreference,
2689
+ resolveClaudeAttributionConfigPath,
2690
+ resolveClaudeCodeModelPolicy,
2691
+ resolveHostAnthropicMessagesApi,
2692
+ resolveHostTranscriptHelpers,
2693
+ restoreAnthropicSessionCacheRetention,
2694
+ rewriteAnthropicRequestPayload,
2695
+ streamAnthropicViaBetaMessages,
2696
+ updateAnthropicUsage
2697
+ };