opencode-anthropic-multi-account 0.2.93 → 0.2.94

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.
@@ -1768,6 +1768,594 @@ function compareVersionStrings(left, right) {
1768
1768
 
1769
1769
  // ../providers/claude-code/src/fingerprint-capture.ts
1770
1770
  import { getConfigDir } from "opencode-multi-account-core";
1771
+
1772
+ // ../providers/claude-code/src/opencode-shared.ts
1773
+ import { createHash as createHash2, randomUUID } from "crypto";
1774
+
1775
+ // ../providers/claude-code/src/fingerprint-template.ts
1776
+ var template = fingerprint_data_default;
1777
+ var toolNames = new Set(template.tools.map((tool) => tool.name));
1778
+ function getClaudeCodeTemplateMetadata() {
1779
+ return {
1780
+ agentIdentity: template.agent_identity,
1781
+ anthropicBeta: template.anthropic_beta,
1782
+ bodyFieldOrder: template.body_field_order ? [...template.body_field_order] : void 0,
1783
+ ccVersion: template.cc_version,
1784
+ headerValues: { ...template.header_values },
1785
+ headerOrder: template.header_order ? [...template.header_order] : void 0,
1786
+ systemPrompt: template.system_prompt,
1787
+ systemPromptFable: template.system_prompt_fable,
1788
+ toolNames: template.tool_names ? [...template.tool_names] : template.tools.map((tool) => tool.name)
1789
+ };
1790
+ }
1791
+
1792
+ // ../providers/claude-code/src/cch.ts
1793
+ var CCH_SEEDS = {
1794
+ "2.1.177": 0x4d659218e32a3268n
1795
+ // 2.1.178 was checked during the issue #91 review; the 2.1.177 seed did
1796
+ // not reproduce the captured cch, so leave it unstamped until a new seed is
1797
+ // independently extracted and verified.
1798
+ };
1799
+ var MASK = 0xfffffn;
1800
+ var U64 = (1n << 64n) - 1n;
1801
+ var P1 = 0x9e3779b185ebca87n;
1802
+ var P2 = 0xc2b2ae3d27d4eb4fn;
1803
+ var P3 = 0x165667b19e3779f9n;
1804
+ var P4 = 0x85ebca77c2b2ae63n;
1805
+ var P5 = 0x27d4eb2f165667c5n;
1806
+ var BILLING_HEADER_PREFIX = "x-anthropic-billing-header:";
1807
+ var CCH_RE = /(cc_entrypoint=[a-z0-9-]{1,32}; cch=)[0-9a-fA-F]{5}(?=;)/;
1808
+ var CC_VERSION_RE = /\bcc_version=([0-9]+(?:\.[0-9]+){2})(?:\.[0-9a-f]+)?;/;
1809
+ function rotl(value, bits) {
1810
+ return (value << bits | value >> 64n - bits) & U64;
1811
+ }
1812
+ function round(accumulator, input) {
1813
+ let next = accumulator + input * P2 & U64;
1814
+ next = rotl(next, 31n);
1815
+ return next * P1 & U64;
1816
+ }
1817
+ function mergeRound(accumulator, value) {
1818
+ const rounded = round(0n, value);
1819
+ const next = (accumulator ^ rounded) & U64;
1820
+ return next * P1 + P4 & U64;
1821
+ }
1822
+ function xxh64(data, seed) {
1823
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
1824
+ const length = data.length;
1825
+ let offset = 0;
1826
+ let hash;
1827
+ if (length >= 32) {
1828
+ let v1 = seed + P1 + P2 & U64;
1829
+ let v2 = seed + P2 & U64;
1830
+ let v3 = seed & U64;
1831
+ let v4 = seed - P1 & U64;
1832
+ const limit = length - 32;
1833
+ while (offset <= limit) {
1834
+ v1 = round(v1, view.getBigUint64(offset, true));
1835
+ offset += 8;
1836
+ v2 = round(v2, view.getBigUint64(offset, true));
1837
+ offset += 8;
1838
+ v3 = round(v3, view.getBigUint64(offset, true));
1839
+ offset += 8;
1840
+ v4 = round(v4, view.getBigUint64(offset, true));
1841
+ offset += 8;
1842
+ }
1843
+ hash = rotl(v1, 1n) + rotl(v2, 7n) + rotl(v3, 12n) + rotl(v4, 18n) & U64;
1844
+ hash = mergeRound(hash, v1);
1845
+ hash = mergeRound(hash, v2);
1846
+ hash = mergeRound(hash, v3);
1847
+ hash = mergeRound(hash, v4);
1848
+ } else {
1849
+ hash = seed + P5 & U64;
1850
+ }
1851
+ hash = hash + BigInt(length) & U64;
1852
+ while (offset + 8 <= length) {
1853
+ const k1 = round(0n, view.getBigUint64(offset, true));
1854
+ hash = (hash ^ k1) & U64;
1855
+ hash = rotl(hash, 27n) * P1 + P4 & U64;
1856
+ offset += 8;
1857
+ }
1858
+ if (offset + 4 <= length) {
1859
+ hash = (hash ^ BigInt(view.getUint32(offset, true)) * P1 & U64) & U64;
1860
+ hash = rotl(hash, 23n) * P2 + P3 & U64;
1861
+ offset += 4;
1862
+ }
1863
+ while (offset < length) {
1864
+ hash = (hash ^ BigInt(data[offset] ?? 0) * P5 & U64) & U64;
1865
+ hash = rotl(hash, 11n) * P1 & U64;
1866
+ offset += 1;
1867
+ }
1868
+ hash = (hash ^ hash >> 33n) & U64;
1869
+ hash = hash * P2 & U64;
1870
+ hash = (hash ^ hash >> 29n) & U64;
1871
+ hash = hash * P3 & U64;
1872
+ hash = (hash ^ hash >> 32n) & U64;
1873
+ return hash;
1874
+ }
1875
+ function replaceBillingCch(body, cch) {
1876
+ const system = body.system;
1877
+ if (!Array.isArray(system)) return { replaced: false };
1878
+ for (const entry of system) {
1879
+ if (!entry || typeof entry !== "object") continue;
1880
+ const systemEntry = entry;
1881
+ if (typeof systemEntry.text !== "string") continue;
1882
+ if (!systemEntry.text.startsWith(BILLING_HEADER_PREFIX)) continue;
1883
+ if (!CCH_RE.test(systemEntry.text)) continue;
1884
+ const version = CC_VERSION_RE.exec(systemEntry.text)?.[1];
1885
+ systemEntry.text = systemEntry.text.replace(CCH_RE, (_match, prefix) => `${prefix}${cch}`);
1886
+ return { replaced: true, version };
1887
+ }
1888
+ return { replaced: false };
1889
+ }
1890
+ function cchMaterial(bodyText) {
1891
+ const body = JSON.parse(bodyText);
1892
+ const { replaced, version } = replaceBillingCch(body, "00000");
1893
+ if (!replaced) return null;
1894
+ body.model = "";
1895
+ delete body.fallbacks;
1896
+ delete body.fallback_credit_token;
1897
+ delete body.max_tokens;
1898
+ return { bytes: new TextEncoder().encode(JSON.stringify(body)), version };
1899
+ }
1900
+ function cchForBody(bodyText, version) {
1901
+ let material;
1902
+ try {
1903
+ material = cchMaterial(bodyText);
1904
+ } catch {
1905
+ return null;
1906
+ }
1907
+ if (!material) return null;
1908
+ const seed = CCH_SEEDS[material.version ?? version ?? ""];
1909
+ if (seed === void 0) return null;
1910
+ const hash = xxh64(material.bytes, seed) & MASK;
1911
+ return hash.toString(16).padStart(5, "0");
1912
+ }
1913
+ function stampClaudeCodeCch(bodyText, version) {
1914
+ const cch = cchForBody(bodyText, version);
1915
+ if (cch === null) return bodyText;
1916
+ try {
1917
+ const body = JSON.parse(bodyText);
1918
+ const { replaced } = replaceBillingCch(body, cch);
1919
+ return replaced ? JSON.stringify(body) : bodyText;
1920
+ } catch {
1921
+ return bodyText;
1922
+ }
1923
+ }
1924
+
1925
+ // ../providers/claude-code/src/effort-capability.ts
1926
+ var EFFORT_PREFERENCE = ["xhigh", "max", "high", "medium", "low"];
1927
+ function readRecord(value) {
1928
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
1929
+ }
1930
+ function normalizeEffortValue(value) {
1931
+ return value.trim().toLowerCase().replace(/[^a-z_-]+$/g, "");
1932
+ }
1933
+ function parseEffortCapabilityRejection(body) {
1934
+ const match = /does not support effort level\s+['"`]?([^'"`.\s]+)['"`]?\.?\s*Supported levels:\s*([a-z,\s_-]+)/i.exec(body);
1935
+ if (!match?.[1] || !match[2]) {
1936
+ return null;
1937
+ }
1938
+ const supported = match[2].split(",").map(normalizeEffortValue).filter(Boolean);
1939
+ return supported.length > 0 ? { rejected: normalizeEffortValue(match[1]), supported } : null;
1940
+ }
1941
+ function bestSupportedEffort(supported) {
1942
+ for (const effort of EFFORT_PREFERENCE) {
1943
+ if (supported.includes(effort)) {
1944
+ return effort;
1945
+ }
1946
+ }
1947
+ return supported[0] ?? "high";
1948
+ }
1949
+ function clampUnsupportedEffortInBody(body, supportedEffortsByModel) {
1950
+ if (typeof body !== "string") {
1951
+ return { body, changed: false };
1952
+ }
1953
+ try {
1954
+ const parsed = JSON.parse(body);
1955
+ const record = readRecord(parsed);
1956
+ const modelId = typeof record?.model === "string" ? record.model : void 0;
1957
+ const outputConfig = readRecord(record?.output_config);
1958
+ const effort = typeof outputConfig?.effort === "string" ? outputConfig.effort : void 0;
1959
+ if (!modelId || !outputConfig || !effort) {
1960
+ return { body, changed: false, modelId };
1961
+ }
1962
+ const supported = supportedEffortsByModel.get(modelId);
1963
+ if (!supported || supported.includes(effort)) {
1964
+ return { body, changed: false, modelId, effort };
1965
+ }
1966
+ const clamped = bestSupportedEffort(supported);
1967
+ outputConfig.effort = clamped;
1968
+ return { body: JSON.stringify(record), changed: true, modelId, effort: clamped };
1969
+ } catch {
1970
+ return { body, changed: false };
1971
+ }
1972
+ }
1973
+ function clampEffortAfterRejection(body, rejection, supportedEffortsByModel) {
1974
+ if (typeof body !== "string") {
1975
+ return { body, changed: false };
1976
+ }
1977
+ try {
1978
+ const parsed = JSON.parse(body);
1979
+ const record = readRecord(parsed);
1980
+ const modelId = typeof record?.model === "string" ? record.model : void 0;
1981
+ const outputConfig = readRecord(record?.output_config);
1982
+ const effort = typeof outputConfig?.effort === "string" ? outputConfig.effort : void 0;
1983
+ if (!modelId || !outputConfig || !effort) {
1984
+ return { body, changed: false, modelId };
1985
+ }
1986
+ supportedEffortsByModel.set(modelId, [...rejection.supported]);
1987
+ if (rejection.supported.includes(effort)) {
1988
+ return { body, changed: false, modelId, effort };
1989
+ }
1990
+ const clamped = bestSupportedEffort(rejection.supported);
1991
+ outputConfig.effort = clamped;
1992
+ return { body: JSON.stringify(record), changed: true, modelId, effort: clamped };
1993
+ } catch {
1994
+ return { body, changed: false };
1995
+ }
1996
+ }
1997
+
1998
+ // ../providers/claude-code/src/model-aliases.ts
1999
+ var MODEL_FAMILIES = ["fable", "opus", "sonnet", "haiku"];
2000
+ var FAMILY_RANK = { fable: 0, opus: 1, sonnet: 2, haiku: 3 };
2001
+ var CLAUDE_FABLE_MODEL_ID = "claude-fable-5";
2002
+ var CLAUDE_FABLE_1M_MODEL_ID = `${CLAUDE_FABLE_MODEL_ID}[1m]`;
2003
+ var CLAUDE_SONNET_MODEL_ID = "claude-sonnet-5";
2004
+ var CLAUDE_SONNET_1M_MODEL_ID = `${CLAUDE_SONNET_MODEL_ID}[1m]`;
2005
+ var FALLBACK_CLAUDE_CODE_BASE_MODEL_IDS = [
2006
+ CLAUDE_FABLE_MODEL_ID,
2007
+ "claude-opus-4-8",
2008
+ "claude-opus-4-7",
2009
+ "claude-opus-4-6",
2010
+ CLAUDE_SONNET_MODEL_ID,
2011
+ "claude-sonnet-4-6",
2012
+ "claude-haiku-4-5"
2013
+ ];
2014
+ var STATIC_MODEL_ALIASES = {
2015
+ opus47: "claude-opus-4-7",
2016
+ opus46: "claude-opus-4-6",
2017
+ sonnet46: "claude-sonnet-4-6"
2018
+ };
2019
+ var cachedBaseModelIds = [...FALLBACK_CLAUDE_CODE_BASE_MODEL_IDS];
2020
+ function stripClaudeCodeProviderPrefix(modelId) {
2021
+ const slash = modelId.indexOf("/");
2022
+ if (slash === -1) return modelId;
2023
+ const provider = modelId.slice(0, slash).toLowerCase();
2024
+ return provider === "anthropic" || provider === "claude-code" ? modelId.slice(slash + 1) : modelId;
2025
+ }
2026
+ function resolveClaudeCodeModelAlias(modelId) {
2027
+ const unprefixed = stripClaudeCodeProviderPrefix(modelId.trim());
2028
+ return resolveAliasAgainst(unprefixed, cachedBaseModelIds) ?? STATIC_MODEL_ALIASES[unprefixed.toLowerCase()] ?? unprefixed;
2029
+ }
2030
+ function stripClaudeCodeContext1mTag(modelId) {
2031
+ return modelId.replace(/\[1m\]$/i, "");
2032
+ }
2033
+ function toClaudeCodeWireModelId(modelId) {
2034
+ return stripClaudeCodeContext1mTag(resolveClaudeCodeModelAlias(modelId));
2035
+ }
2036
+ function isClaudeCode1mModelLabel(modelId) {
2037
+ return /\[1m\]$/i.test(resolveClaudeCodeModelAlias(modelId));
2038
+ }
2039
+ function isClaudeFableModel(modelId) {
2040
+ return resolveClaudeCodeModelAlias(modelId).toLowerCase().includes("fable");
2041
+ }
2042
+ function resolveFamilyBase(family, baseIds) {
2043
+ return baseIds.filter((id) => modelFamily(id) === family && !id.includes("[")).sort(compareClaudeCodeBaseModelIds)[0];
2044
+ }
2045
+ function longContextEligible(id) {
2046
+ const normalized = id.toLowerCase();
2047
+ return normalized.startsWith("claude-") && !normalized.includes("haiku") && !normalized.endsWith("[1m]");
2048
+ }
2049
+ function compareClaudeCodeBaseModelIds(a, b) {
2050
+ const aRank = FAMILY_RANK[modelFamily(a) ?? ""] ?? 99;
2051
+ const bRank = FAMILY_RANK[modelFamily(b) ?? ""] ?? 99;
2052
+ if (aRank !== bRank) return aRank - bRank;
2053
+ return compareVersionDesc(modelVersionKey(a), modelVersionKey(b));
2054
+ }
2055
+ function modelFamily(id) {
2056
+ const normalized = stripClaudeCodeContext1mTag(stripClaudeCodeProviderPrefix(id)).toLowerCase();
2057
+ for (const family of MODEL_FAMILIES) {
2058
+ if (normalized.includes(family)) return family;
2059
+ }
2060
+ return void 0;
2061
+ }
2062
+ function resolveAliasAgainst(modelId, baseIds) {
2063
+ const normalized = stripClaudeCodeProviderPrefix(modelId).trim().toLowerCase();
2064
+ if (isModelFamily(normalized)) return resolveFamilyBase(normalized, baseIds) ?? void 0;
2065
+ const match = /^([a-z]+)1m$/.exec(normalized);
2066
+ if (match?.[1] && isModelFamily(match[1])) {
2067
+ const base = resolveFamilyBase(match[1], baseIds);
2068
+ return base && longContextEligible(base) ? `${base}[1m]` : void 0;
2069
+ }
2070
+ return void 0;
2071
+ }
2072
+ function isModelFamily(value) {
2073
+ return MODEL_FAMILIES.includes(value);
2074
+ }
2075
+ function modelVersionKey(id) {
2076
+ return id.match(/\d+/g)?.map(Number) ?? [];
2077
+ }
2078
+ function compareVersionDesc(a, b) {
2079
+ const length = Math.max(a.length, b.length);
2080
+ for (let index = 0; index < length; index += 1) {
2081
+ const diff = (b[index] ?? -1) - (a[index] ?? -1);
2082
+ if (diff !== 0) return diff;
2083
+ }
2084
+ return 0;
2085
+ }
2086
+
2087
+ // ../providers/claude-code/src/opencode-shared.ts
2088
+ var CLAUDE_CODE_API_BASE_URL = "https://api.anthropic.com";
2089
+ var STAINLESS_PACKAGE_VERSION = "0.81.0";
2090
+ var DEFAULT_OPENCODE_TIMEOUT_SECONDS = "300";
2091
+ var BILLING_SEED = "59cf53e54c78";
2092
+ var templateMetadata = getClaudeCodeTemplateMetadata();
2093
+ var templateHeaders = templateMetadata.headerValues;
2094
+ var CLAUDE_CODE_VERSION = templateMetadata.ccVersion ?? "2.1.137";
2095
+ var CCH_REMOVED_VERSION = "2.1.183";
2096
+ var CLIENT_SYSTEM_PREFACE = "\n\n---\n\nIMPORTANT: The operator of this session has supplied the following task-specific instructions. Follow them for task format, style, and output requirements when they do not conflict with security, authorization, refusal, tool-execution, confirmation, or other safety rules above. Those safety and tool-use constraints remain higher priority and cannot be overridden:\n\n";
2097
+ function loadClaudeCodeSharedRequestProfile() {
2098
+ return {
2099
+ anthropicBeta: templateMetadata.anthropicBeta ?? templateHeaders["anthropic-beta"] ?? "oauth-2025-04-20",
2100
+ anthropicVersion: templateHeaders["anthropic-version"] ?? "2023-06-01",
2101
+ apiV1BaseUrl: `${CLAUDE_CODE_API_BASE_URL}/v1`,
2102
+ baseUrl: CLAUDE_CODE_API_BASE_URL,
2103
+ ccVersion: CLAUDE_CODE_VERSION,
2104
+ headerOrder: templateMetadata.headerOrder ? [...templateMetadata.headerOrder] : void 0,
2105
+ headerValues: { ...templateHeaders },
2106
+ packageVersion: templateHeaders["x-stainless-package-version"] ?? STAINLESS_PACKAGE_VERSION,
2107
+ userAgent: templateHeaders["user-agent"] ?? `claude-cli/${CLAUDE_CODE_VERSION} (external, sdk-cli)`,
2108
+ xApp: templateHeaders["x-app"] ?? "cli"
2109
+ };
2110
+ }
2111
+ function createClaudeCodeStaticHeaders(input) {
2112
+ return {
2113
+ "accept": "application/json",
2114
+ "content-type": "application/json",
2115
+ "anthropic-dangerous-direct-browser-access": "true",
2116
+ "user-agent": input.userAgent,
2117
+ "x-app": input.xApp,
2118
+ "x-stainless-arch": process.arch,
2119
+ "x-stainless-lang": "js",
2120
+ "x-stainless-os": getOsName(),
2121
+ "x-stainless-package-version": input.packageVersion ?? STAINLESS_PACKAGE_VERSION,
2122
+ "x-stainless-retry-count": "0",
2123
+ "x-stainless-runtime": "node",
2124
+ "x-stainless-runtime-version": process.version,
2125
+ ...input.headerValues ?? {}
2126
+ };
2127
+ }
2128
+ function createClaudeCodePerRequestHeaders(input) {
2129
+ return {
2130
+ "x-claude-code-session-id": input.sessionId,
2131
+ "x-client-request-id": randomUUID(),
2132
+ "anthropic-version": input.anthropicVersion,
2133
+ "x-stainless-timeout": input.timeoutSeconds ?? DEFAULT_OPENCODE_TIMEOUT_SECONDS
2134
+ };
2135
+ }
2136
+ function orderClaudeCodeHeadersForOutbound(headers, headerOrder) {
2137
+ if (!Array.isArray(headerOrder) || headerOrder.length === 0) return headers;
2138
+ const lowerToValue = /* @__PURE__ */ new Map();
2139
+ for (const [key, value] of Object.entries(headers)) {
2140
+ lowerToValue.set(key.toLowerCase(), value);
2141
+ }
2142
+ const ordered = [];
2143
+ const seen = /* @__PURE__ */ new Set();
2144
+ for (const name of headerOrder) {
2145
+ const key = name.toLowerCase();
2146
+ const value = lowerToValue.get(key);
2147
+ if (value === void 0 || seen.has(key)) continue;
2148
+ ordered.push([name, value]);
2149
+ seen.add(key);
2150
+ }
2151
+ for (const [key, value] of Object.entries(headers)) {
2152
+ if (seen.has(key.toLowerCase())) continue;
2153
+ ordered.push([key, value]);
2154
+ }
2155
+ return ordered;
2156
+ }
2157
+ function computeClaudeCodeBuildTag(userMessage, version) {
2158
+ const chars = [4, 7, 20].map((index) => userMessage[index] ?? "0").join("");
2159
+ return createHash2("sha256").update(`${BILLING_SEED}${chars}${version}`).digest("hex").slice(0, 3);
2160
+ }
2161
+ function composeClaudeCodeBillingSystemEntry(firstUserMessage, version, cch = "00000") {
2162
+ const buildTag = computeClaudeCodeBuildTag(firstUserMessage, version);
2163
+ const base = `x-anthropic-billing-header: cc_version=${version}.${buildTag}; cc_entrypoint=sdk-cli;`;
2164
+ return claudeCodeBillingUsesCch(version) ? `${base} cch=${cch};` : base;
2165
+ }
2166
+ function claudeCodeBillingUsesCch(version) {
2167
+ const comparison = compareSemver(version, CCH_REMOVED_VERSION);
2168
+ return comparison === null || comparison < 0;
2169
+ }
2170
+ function compareSemver(left, right) {
2171
+ const leftParts = parseSemver(left);
2172
+ const rightParts = parseSemver(right);
2173
+ if (!leftParts || !rightParts) return null;
2174
+ for (let index = 0; index < leftParts.length; index += 1) {
2175
+ const diff = leftParts[index] - rightParts[index];
2176
+ if (diff !== 0) return diff;
2177
+ }
2178
+ return 0;
2179
+ }
2180
+ function parseSemver(version) {
2181
+ const match = /^(\d+)\.(\d+)\.(\d+)/.exec(version);
2182
+ if (!match) return null;
2183
+ return [Number(match[1]), Number(match[2]), Number(match[3])];
2184
+ }
2185
+ function summarizeClaudeCodeCacheControls(body) {
2186
+ const observations = [];
2187
+ const observe = (value, path) => {
2188
+ const record = readRecord2(value);
2189
+ if (!record || !Object.hasOwn(record, "cache_control")) {
2190
+ return;
2191
+ }
2192
+ const cacheControl = readRecord2(record.cache_control);
2193
+ observations.push({
2194
+ path,
2195
+ type: typeof cacheControl?.type === "string" ? cacheControl.type : null,
2196
+ ttl: typeof cacheControl?.ttl === "string" ? cacheControl.ttl : null
2197
+ });
2198
+ };
2199
+ if (Array.isArray(body.system)) {
2200
+ body.system.forEach((block, index) => {
2201
+ observe(block, `system[${index}].cache_control`);
2202
+ });
2203
+ }
2204
+ if (Array.isArray(body.tools)) {
2205
+ body.tools.forEach((tool, index) => {
2206
+ observe(tool, `tools[${index}].cache_control`);
2207
+ });
2208
+ }
2209
+ if (Array.isArray(body.messages)) {
2210
+ body.messages.forEach((message, messageIndex) => {
2211
+ const content = readRecord2(message)?.content;
2212
+ if (!Array.isArray(content)) return;
2213
+ content.forEach((block, contentIndex) => {
2214
+ observe(
2215
+ block,
2216
+ `messages[${messageIndex}].content[${contentIndex}].cache_control`
2217
+ );
2218
+ });
2219
+ });
2220
+ }
2221
+ return observations;
2222
+ }
2223
+ function resolveClaudeCodeCacheControl(body) {
2224
+ const observations = summarizeClaudeCodeCacheControls(body);
2225
+ return observations.length > 0 && observations.every(
2226
+ (cacheControl) => cacheControl.type === "ephemeral" && cacheControl.ttl === "1h"
2227
+ ) ? { type: "ephemeral", ttl: "1h" } : { type: "ephemeral" };
2228
+ }
2229
+ function applyClaudeCodePromptCaching(body, cacheControl = { type: "ephemeral" }) {
2230
+ const tools = body.tools;
2231
+ if (Array.isArray(tools) && tools.length > 0) {
2232
+ const clonedTools = tools.map((tool) => {
2233
+ const cloned = { ...tool };
2234
+ delete cloned.cache_control;
2235
+ return cloned;
2236
+ });
2237
+ clonedTools[clonedTools.length - 1] = {
2238
+ ...clonedTools[clonedTools.length - 1],
2239
+ cache_control: cacheControl
2240
+ };
2241
+ body.tools = clonedTools;
2242
+ }
2243
+ const messages = body.messages;
2244
+ if (!Array.isArray(messages) || messages.length === 0) {
2245
+ return;
2246
+ }
2247
+ const lastMessage = messages[messages.length - 1];
2248
+ const content = lastMessage?.content;
2249
+ if (!Array.isArray(content) || content.length === 0) {
2250
+ return;
2251
+ }
2252
+ content[content.length - 1] = {
2253
+ ...content[content.length - 1],
2254
+ cache_control: cacheControl
2255
+ };
2256
+ }
2257
+ function applyClaudeCodeUpstreamBodyFields(body, input) {
2258
+ const cacheControl = input.cacheControl ?? { type: "ephemeral" };
2259
+ const firstUserMessage = input.firstUserMessage ?? extractFirstUserText(body.messages);
2260
+ const billingHeader = composeClaudeCodeBillingSystemEntry(
2261
+ firstUserMessage,
2262
+ input.ccVersion,
2263
+ input.cch
2264
+ );
2265
+ const systemTexts = input.systemTexts ?? normalizeClaudeCodeSystemTexts(body.system);
2266
+ const injectedSystemTexts = filterInjectedSystemTexts(systemTexts, {
2267
+ agentIdentity: input.agentIdentity,
2268
+ billingHeader,
2269
+ systemPrompt: input.systemPrompt
2270
+ });
2271
+ const mergedSystemPrompt = injectedSystemTexts.length > 0 ? `${input.systemPrompt}${CLIENT_SYSTEM_PREFACE}${injectedSystemTexts.join("\n\n")}` : input.systemPrompt;
2272
+ body.system = [
2273
+ { type: "text", text: billingHeader },
2274
+ {
2275
+ type: "text",
2276
+ text: input.agentIdentity,
2277
+ cache_control: cacheControl
2278
+ },
2279
+ {
2280
+ type: "text",
2281
+ text: mergedSystemPrompt,
2282
+ cache_control: cacheControl
2283
+ }
2284
+ ];
2285
+ body.metadata = {
2286
+ ...readRecord2(body.metadata),
2287
+ user_id: JSON.stringify({
2288
+ device_id: input.identity.deviceId,
2289
+ account_uuid: input.identity.accountUuid,
2290
+ session_id: input.sessionId
2291
+ })
2292
+ };
2293
+ if (input.defaultTools && (!Array.isArray(body.tools) || body.tools.length === 0)) {
2294
+ body.tools = input.defaultTools.map((tool) => ({ ...tool }));
2295
+ }
2296
+ applyClaudeCodePromptCaching(body, cacheControl);
2297
+ return orderClaudeCodeBodyForOutbound(body, input.bodyFieldOrder);
2298
+ }
2299
+ function orderClaudeCodeBodyForOutbound(body, fieldOrder) {
2300
+ if (!Array.isArray(fieldOrder) || fieldOrder.length === 0) return body;
2301
+ const ordered = {};
2302
+ const seen = /* @__PURE__ */ new Set();
2303
+ for (const field of fieldOrder) {
2304
+ if (seen.has(field)) continue;
2305
+ if (Object.prototype.hasOwnProperty.call(body, field)) {
2306
+ ordered[field] = body[field];
2307
+ seen.add(field);
2308
+ }
2309
+ }
2310
+ for (const [field, value] of Object.entries(body)) {
2311
+ if (seen.has(field)) continue;
2312
+ ordered[field] = value;
2313
+ }
2314
+ return ordered;
2315
+ }
2316
+ function normalizeClaudeCodeSystemTexts(system) {
2317
+ if (typeof system === "string" && system.length > 0) return [system];
2318
+ if (!Array.isArray(system)) return [];
2319
+ const texts = [];
2320
+ for (const entry of system) {
2321
+ if (typeof entry === "string" && entry.length > 0) {
2322
+ texts.push(entry);
2323
+ continue;
2324
+ }
2325
+ const record = readRecord2(entry);
2326
+ const text = typeof record?.text === "string" && record.text.length > 0 ? record.text : void 0;
2327
+ if (text) texts.push(text);
2328
+ }
2329
+ return texts;
2330
+ }
2331
+ function filterInjectedSystemTexts(systemTexts, input) {
2332
+ return systemTexts.filter((entry) => entry !== input.billingHeader && entry !== input.agentIdentity && entry !== input.systemPrompt && !entry.startsWith("x-anthropic-billing-header:"));
2333
+ }
2334
+ function extractFirstUserText(messages) {
2335
+ if (!Array.isArray(messages)) return "";
2336
+ for (const message of messages) {
2337
+ const record = readRecord2(message);
2338
+ if (record?.role !== "user") continue;
2339
+ if (typeof record.content === "string") return record.content;
2340
+ if (!Array.isArray(record.content)) return "";
2341
+ return record.content.map((block) => {
2342
+ const text = readRecord2(block)?.text;
2343
+ return typeof text === "string" && text.length > 0 ? text : void 0;
2344
+ }).filter((text) => Boolean(text)).join("\n\n");
2345
+ }
2346
+ return "";
2347
+ }
2348
+ function readRecord2(value) {
2349
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
2350
+ }
2351
+ function getOsName() {
2352
+ const platform2 = process.platform;
2353
+ if (platform2 === "win32") return "Windows";
2354
+ if (platform2 === "darwin") return "MacOS";
2355
+ return "Linux";
2356
+ }
2357
+
2358
+ // ../providers/claude-code/src/fingerprint-capture.ts
1771
2359
  var CURRENT_SCHEMA_VERSION = 1;
1772
2360
  var LIVE_TTL_MS = 24 * 60 * 60 * 1e3;
1773
2361
  var DEFAULT_CAPTURE_TIMEOUT_MS = 1e4;
@@ -1814,35 +2402,35 @@ function isTemplateData(value) {
1814
2402
  }
1815
2403
  return typeof value._version === "number" && typeof value._captured === "string" && typeof value._source === "string" && typeof value.agent_identity === "string" && typeof value.system_prompt === "string" && Array.isArray(value.tools) && value.tools.every(isTemplateTool) && Array.isArray(value.tool_names) && value.tool_names.every((toolName) => typeof toolName === "string");
1816
2404
  }
1817
- function hasUsableToolSchemas(template) {
1818
- return template.tools.length > 0 && template.tools.every((tool) => tool.name.startsWith("mcp__") || isRecord(tool.input_schema));
2405
+ function hasUsableToolSchemas(template2) {
2406
+ return template2.tools.length > 0 && template2.tools.every((tool) => tool.name.startsWith("mcp__") || isRecord(tool.input_schema));
1819
2407
  }
1820
- function isUsableTemplate(template) {
1821
- return template._schemaVersion === CURRENT_SCHEMA_VERSION && hasUsableToolSchemas(template);
2408
+ function isUsableTemplate(template2) {
2409
+ return template2._schemaVersion === CURRENT_SCHEMA_VERSION && hasUsableToolSchemas(template2);
1822
2410
  }
1823
- function cloneTemplate(template, sourceOverride) {
2411
+ function cloneTemplate(template2, sourceOverride) {
1824
2412
  return {
1825
- ...template,
1826
- _source: sourceOverride ?? template._source,
1827
- tools: template.tools.map((tool) => ({ ...tool })),
1828
- tool_names: [...template.tool_names],
1829
- header_order: template.header_order ? [...template.header_order] : void 0,
1830
- header_values: template.header_values ? { ...template.header_values } : void 0,
1831
- body_field_order: template.body_field_order ? [...template.body_field_order] : void 0
2413
+ ...template2,
2414
+ _source: sourceOverride ?? template2._source,
2415
+ tools: template2.tools.map((tool) => ({ ...tool })),
2416
+ tool_names: [...template2.tool_names],
2417
+ header_order: template2.header_order ? [...template2.header_order] : void 0,
2418
+ header_values: template2.header_values ? { ...template2.header_values } : void 0,
2419
+ body_field_order: template2.body_field_order ? [...template2.body_field_order] : void 0
1832
2420
  };
1833
2421
  }
1834
- function applyBundledTemplateFallbacks(template) {
2422
+ function applyBundledTemplateFallbacks(template2) {
1835
2423
  const bundledFablePrompt = bundledTemplate.system_prompt_fable;
1836
- if (template.system_prompt_fable || typeof bundledFablePrompt !== "string" || bundledFablePrompt.length === 0) {
1837
- return template;
2424
+ if (template2.system_prompt_fable || typeof bundledFablePrompt !== "string" || bundledFablePrompt.length === 0) {
2425
+ return template2;
1838
2426
  }
1839
2427
  return {
1840
- ...template,
2428
+ ...template2,
1841
2429
  system_prompt_fable: bundledFablePrompt
1842
2430
  };
1843
2431
  }
1844
- function prepareBundledTemplate(template) {
1845
- const rest = cloneTemplate(template, "bundled");
2432
+ function prepareBundledTemplate(template2) {
2433
+ const rest = cloneTemplate(template2, "bundled");
1846
2434
  return {
1847
2435
  ...rest,
1848
2436
  _version: CURRENT_SCHEMA_VERSION,
@@ -1851,14 +2439,14 @@ function prepareBundledTemplate(template) {
1851
2439
  tool_names: rest.tools.map((tool) => tool.name)
1852
2440
  };
1853
2441
  }
1854
- function matchesBundledClaudeCodeFingerprint(template, reference = bundledTemplate) {
2442
+ function matchesBundledClaudeCodeFingerprint(template2, reference = bundledTemplate) {
1855
2443
  const expectedToolNames = comparableHeadlessToolNames(reference.tool_names);
1856
- const actualToolNames = comparableHeadlessToolNames(template.tools.map((tool) => tool.name));
2444
+ const actualToolNames = comparableHeadlessToolNames(template2.tools.map((tool) => tool.name));
1857
2445
  const matchesExpectedTools = actualToolNames.length === expectedToolNames.length && expectedToolNames.every((name, index) => actualToolNames[index] === name);
1858
- return template.agent_identity === reference.agent_identity && matchesExpectedTools;
2446
+ return template2.agent_identity === reference.agent_identity && matchesExpectedTools;
1859
2447
  }
1860
- function comparableHeadlessToolNames(toolNames) {
1861
- return toolNames.filter((toolName) => !INTERACTIVE_ONLY_TOOL_NAMES.has(toolName));
2448
+ function comparableHeadlessToolNames(toolNames2) {
2449
+ return toolNames2.filter((toolName) => !INTERACTIVE_ONLY_TOOL_NAMES.has(toolName));
1862
2450
  }
1863
2451
  function loadBundledTemplate() {
1864
2452
  if (bundledTemplate._schemaVersion !== CURRENT_SCHEMA_VERSION) {
@@ -1900,11 +2488,11 @@ function readLiveCacheSync(sourceOverride = "cached") {
1900
2488
  return null;
1901
2489
  }
1902
2490
  }
1903
- function getCapturedAt(template) {
1904
- return Date.parse(template._captured);
2491
+ function getCapturedAt(template2) {
2492
+ return Date.parse(template2._captured);
1905
2493
  }
1906
- function isFreshTemplate(template) {
1907
- const capturedAt = getCapturedAt(template);
2494
+ function isFreshTemplate(template2) {
2495
+ const capturedAt = getCapturedAt(template2);
1908
2496
  return Number.isFinite(capturedAt) && now() - capturedAt < LIVE_TTL_MS;
1909
2497
  }
1910
2498
  function pickTemplate(cached, bundled) {
@@ -1928,8 +2516,8 @@ async function atomicWriteJson(targetPath, payload) {
1928
2516
  `, "utf8");
1929
2517
  await rename(tmpPath, targetPath);
1930
2518
  }
1931
- async function writeLiveCache(template) {
1932
- await atomicWriteJson(getCachePath(), cloneTemplate(template, "live"));
2519
+ async function writeLiveCache(template2) {
2520
+ await atomicWriteJson(getCachePath(), cloneTemplate(template2, "live"));
1933
2521
  }
1934
2522
  function toText(value) {
1935
2523
  if (typeof value === "string") {
@@ -2103,7 +2691,7 @@ function extractTemplate(captured) {
2103
2691
  if (!billingHeader || !agentIdentity || !systemPrompt || extractedTools.length === 0) {
2104
2692
  return null;
2105
2693
  }
2106
- const toolNames = extractedTools.map((tool) => tool.name);
2694
+ const toolNames2 = extractedTools.map((tool) => tool.name);
2107
2695
  const headerValues = extractStaticHeaderValues(captured.headers);
2108
2696
  const bodyFieldOrder = Object.keys(captured.body);
2109
2697
  return {
@@ -2114,7 +2702,7 @@ function extractTemplate(captured) {
2114
2702
  agent_identity: agentIdentity,
2115
2703
  system_prompt: systemPrompt,
2116
2704
  tools: extractedTools,
2117
- tool_names: toolNames,
2705
+ tool_names: toolNames2,
2118
2706
  anthropic_beta: captured.headers["anthropic-beta"],
2119
2707
  cc_version: extractCCVersion(billingHeader, captured.headers["user-agent"]),
2120
2708
  header_order: extractHeaderOrder(captured.rawHeaders),
@@ -2164,10 +2752,23 @@ async function captureLiveTemplateAsync(timeoutMs = DEFAULT_CAPTURE_TIMEOUT_MS,
2164
2752
  });
2165
2753
  const baseUrl = `http://${LOOPBACK_HOST}:${address.port}`;
2166
2754
  await runClaudeCapture({ binaryPath, baseUrl, timeoutMs, model: options.model });
2167
- if (!capturedRequest) {
2755
+ const captured = capturedRequest;
2756
+ if (!captured) {
2168
2757
  return null;
2169
2758
  }
2170
- return extractTemplate(capturedRequest);
2759
+ const template2 = extractTemplate(captured);
2760
+ if (template2 && options.cacheControlEvidencePath) {
2761
+ await writeFile2(
2762
+ options.cacheControlEvidencePath,
2763
+ `${JSON.stringify({
2764
+ cc_version: template2.cc_version,
2765
+ cache_controls: summarizeClaudeCodeCacheControls(captured.body)
2766
+ }, null, 2)}
2767
+ `,
2768
+ "utf8"
2769
+ );
2770
+ }
2771
+ return template2;
2171
2772
  } catch {
2172
2773
  return null;
2173
2774
  } finally {
@@ -2229,8 +2830,8 @@ function compareVersions(left, right) {
2229
2830
  }
2230
2831
  return leftPatch - rightPatch;
2231
2832
  }
2232
- function detectDrift(template, installedOverride) {
2233
- const cachedVersion = template.cc_version ?? null;
2833
+ function detectDrift(template2, installedOverride) {
2834
+ const cachedVersion = template2.cc_version ?? null;
2234
2835
  const installedVersion = installedOverride ?? probeInstalledCCVersion();
2235
2836
  if (!cachedVersion) {
2236
2837
  return {
@@ -2315,6 +2916,21 @@ function resetFingerprintCaptureForTest() {
2315
2916
 
2316
2917
  export {
2317
2918
  fingerprint_data_default,
2919
+ stampClaudeCodeCch,
2920
+ parseEffortCapabilityRejection,
2921
+ clampUnsupportedEffortInBody,
2922
+ clampEffortAfterRejection,
2923
+ resolveClaudeCodeModelAlias,
2924
+ toClaudeCodeWireModelId,
2925
+ isClaudeCode1mModelLabel,
2926
+ isClaudeFableModel,
2927
+ loadClaudeCodeSharedRequestProfile,
2928
+ createClaudeCodeStaticHeaders,
2929
+ createClaudeCodePerRequestHeaders,
2930
+ orderClaudeCodeHeadersForOutbound,
2931
+ composeClaudeCodeBillingSystemEntry,
2932
+ resolveClaudeCodeCacheControl,
2933
+ applyClaudeCodeUpstreamBodyFields,
2318
2934
  detectCliVersion,
2319
2935
  LIVE_TTL_MS,
2320
2936
  SUPPORTED_CC_RANGE,
@@ -2330,4 +2946,4 @@ export {
2330
2946
  setFingerprintCaptureTestOverridesForTest,
2331
2947
  resetFingerprintCaptureForTest
2332
2948
  };
2333
- //# sourceMappingURL=chunk-KQ5RHIZP.js.map
2949
+ //# sourceMappingURL=chunk-BRY7MF6N.js.map