opencode-anthropic-multi-account 0.2.92 → 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.
- package/dist/{chunk-5ADYNYT2.js → chunk-BRY7MF6N.js} +669 -41
- package/dist/chunk-BRY7MF6N.js.map +1 -0
- package/dist/fingerprint-capture.d.ts +1 -0
- package/dist/fingerprint-capture.js +1 -1
- package/dist/index.js +74 -598
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-5ADYNYT2.js.map +0 -1
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
var data_default = {
|
|
22
22
|
_version: 1,
|
|
23
23
|
_schemaVersion: 1,
|
|
24
|
-
_captured: "2026-07-
|
|
24
|
+
_captured: "2026-07-15T23:20:51.699Z",
|
|
25
25
|
_source: "bundled",
|
|
26
26
|
agent_identity: "You are a Claude agent, built on Anthropic's Claude Agent SDK.",
|
|
27
27
|
system_prompt: `You are an interactive agent that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.
|
|
@@ -132,10 +132,11 @@ If the target is already known, use the direct tool: Read for a known path, \`gr
|
|
|
132
132
|
## Usage notes
|
|
133
133
|
|
|
134
134
|
- Always include a short description summarizing what the agent will do
|
|
135
|
-
- When the agent is done,
|
|
135
|
+
- When the agent is done, its final report is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.
|
|
136
136
|
- Trust but verify: an agent's summary describes what it intended to do, not necessarily what it did. When an agent writes or edits code, check the actual changes before reporting the work as done.
|
|
137
137
|
- Agents run in the background by default. When an agent runs in the background, you will be automatically notified when it completes \u2014 do NOT sleep, poll, or proactively check on its progress. Continue with other work or respond to the user instead.
|
|
138
138
|
- **Foreground vs background**: Pass \`run_in_background: false\` to run an agent in the foreground when you need its results before you can proceed \u2014 e.g., research agents whose findings inform your next steps. Otherwise let it run in the background (the default) so you can keep working in parallel.
|
|
139
|
+
- **Don't race**: after launching a background agent, you know nothing about its results. Never fabricate or predict them in any format \u2014 not as prose, summary, or structured output. The completion notification arrives in a later turn; it is never something you write yourself. If the user asks before it lands, say the agent is still running \u2014 give status, not a guess.
|
|
139
140
|
- To continue a previously spawned agent, use SendMessage with the agent's ID or name as the \`to\` field \u2014 that resumes it with full context. A new Agent call starts a fresh agent with no memory of prior runs, so the prompt must be self-contained.
|
|
140
141
|
- Each agent type's model, reasoning effort, and tool access are set in its definition (\`.claude/agents/*.md\` frontmatter, or the SDK \`agents\` option); the \`model\` parameter here overrides the definition for this one call.
|
|
141
142
|
- Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since a fresh agent is not aware of the user's intent
|
|
@@ -165,9 +166,20 @@ Agent({
|
|
|
165
166
|
description: "Branch ship-readiness audit",
|
|
166
167
|
prompt: "Audit what's left before this branch can ship. Check: uncommitted changes, commits ahead of main, whether tests exist, whether the GrowthBook gate is wired up, whether CI-relevant files changed. Report a punch list \u2014 done vs. missing. Under 200 words."
|
|
167
168
|
})
|
|
169
|
+
assistant: Ship-readiness audit running in the background.
|
|
168
170
|
<commentary>
|
|
169
|
-
The prompt is self-contained: it states the goal, lists what to check, and caps the response length. The agent
|
|
171
|
+
The prompt is self-contained: it states the goal, lists what to check, and caps the response length. The agent runs in the background (the default), so the turn ends here \u2014 nothing about its findings is known yet. The report arrives in a SEPARATE turn, as a completion notification from outside; it is never something you write yourself.
|
|
170
172
|
</commentary>
|
|
173
|
+
[later turn \u2014 notification arrives as user message]
|
|
174
|
+
assistant: Audit's back. Three blockers: no tests for the new prompt path, GrowthBook gate wired but not in build_flags.yaml, and one uncommitted file.
|
|
175
|
+
</example>
|
|
176
|
+
|
|
177
|
+
<example>
|
|
178
|
+
user: "so is the gate wired up or not"
|
|
179
|
+
<commentary>
|
|
180
|
+
User asks mid-wait. The audit was launched to answer exactly this, and it hasn't returned. Give status, not a fabricated result.
|
|
181
|
+
</commentary>
|
|
182
|
+
assistant: Still waiting on the audit \u2014 that's one of the things it's checking. Should land shortly.
|
|
171
183
|
</example>
|
|
172
184
|
|
|
173
185
|
<example>
|
|
@@ -1595,7 +1607,7 @@ IMPORTANT - Use the correct year in search queries:
|
|
|
1595
1607
|
"Write"
|
|
1596
1608
|
],
|
|
1597
1609
|
anthropic_beta: "claude-code-20250219,oauth-2025-04-20,interleaved-thinking-2025-05-14,thinking-token-count-2026-05-13,context-management-2025-06-27,prompt-caching-scope-2026-01-05,mid-conversation-system-2026-04-07,advisor-tool-2026-03-01,effort-2025-11-24,extended-cache-ttl-2025-04-11",
|
|
1598
|
-
cc_version: "2.1.
|
|
1610
|
+
cc_version: "2.1.211",
|
|
1599
1611
|
header_order: [
|
|
1600
1612
|
"Accept",
|
|
1601
1613
|
"Authorization",
|
|
@@ -1625,7 +1637,7 @@ IMPORTANT - Use the correct year in search queries:
|
|
|
1625
1637
|
"anthropic-dangerous-direct-browser-access": "true",
|
|
1626
1638
|
"anthropic-version": "2023-06-01",
|
|
1627
1639
|
"content-type": "application/json",
|
|
1628
|
-
"user-agent": "claude-cli/2.1.
|
|
1640
|
+
"user-agent": "claude-cli/2.1.211 (external, sdk-cli)",
|
|
1629
1641
|
"x-app": "cli",
|
|
1630
1642
|
"x-stainless-timeout": "600"
|
|
1631
1643
|
},
|
|
@@ -1756,6 +1768,594 @@ function compareVersionStrings(left, right) {
|
|
|
1756
1768
|
|
|
1757
1769
|
// ../providers/claude-code/src/fingerprint-capture.ts
|
|
1758
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
|
|
1759
2359
|
var CURRENT_SCHEMA_VERSION = 1;
|
|
1760
2360
|
var LIVE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
1761
2361
|
var DEFAULT_CAPTURE_TIMEOUT_MS = 1e4;
|
|
@@ -1802,35 +2402,35 @@ function isTemplateData(value) {
|
|
|
1802
2402
|
}
|
|
1803
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");
|
|
1804
2404
|
}
|
|
1805
|
-
function hasUsableToolSchemas(
|
|
1806
|
-
return
|
|
2405
|
+
function hasUsableToolSchemas(template2) {
|
|
2406
|
+
return template2.tools.length > 0 && template2.tools.every((tool) => tool.name.startsWith("mcp__") || isRecord(tool.input_schema));
|
|
1807
2407
|
}
|
|
1808
|
-
function isUsableTemplate(
|
|
1809
|
-
return
|
|
2408
|
+
function isUsableTemplate(template2) {
|
|
2409
|
+
return template2._schemaVersion === CURRENT_SCHEMA_VERSION && hasUsableToolSchemas(template2);
|
|
1810
2410
|
}
|
|
1811
|
-
function cloneTemplate(
|
|
2411
|
+
function cloneTemplate(template2, sourceOverride) {
|
|
1812
2412
|
return {
|
|
1813
|
-
...
|
|
1814
|
-
_source: sourceOverride ??
|
|
1815
|
-
tools:
|
|
1816
|
-
tool_names: [...
|
|
1817
|
-
header_order:
|
|
1818
|
-
header_values:
|
|
1819
|
-
body_field_order:
|
|
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
|
|
1820
2420
|
};
|
|
1821
2421
|
}
|
|
1822
|
-
function applyBundledTemplateFallbacks(
|
|
2422
|
+
function applyBundledTemplateFallbacks(template2) {
|
|
1823
2423
|
const bundledFablePrompt = bundledTemplate.system_prompt_fable;
|
|
1824
|
-
if (
|
|
1825
|
-
return
|
|
2424
|
+
if (template2.system_prompt_fable || typeof bundledFablePrompt !== "string" || bundledFablePrompt.length === 0) {
|
|
2425
|
+
return template2;
|
|
1826
2426
|
}
|
|
1827
2427
|
return {
|
|
1828
|
-
...
|
|
2428
|
+
...template2,
|
|
1829
2429
|
system_prompt_fable: bundledFablePrompt
|
|
1830
2430
|
};
|
|
1831
2431
|
}
|
|
1832
|
-
function prepareBundledTemplate(
|
|
1833
|
-
const rest = cloneTemplate(
|
|
2432
|
+
function prepareBundledTemplate(template2) {
|
|
2433
|
+
const rest = cloneTemplate(template2, "bundled");
|
|
1834
2434
|
return {
|
|
1835
2435
|
...rest,
|
|
1836
2436
|
_version: CURRENT_SCHEMA_VERSION,
|
|
@@ -1839,14 +2439,14 @@ function prepareBundledTemplate(template) {
|
|
|
1839
2439
|
tool_names: rest.tools.map((tool) => tool.name)
|
|
1840
2440
|
};
|
|
1841
2441
|
}
|
|
1842
|
-
function matchesBundledClaudeCodeFingerprint(
|
|
2442
|
+
function matchesBundledClaudeCodeFingerprint(template2, reference = bundledTemplate) {
|
|
1843
2443
|
const expectedToolNames = comparableHeadlessToolNames(reference.tool_names);
|
|
1844
|
-
const actualToolNames = comparableHeadlessToolNames(
|
|
2444
|
+
const actualToolNames = comparableHeadlessToolNames(template2.tools.map((tool) => tool.name));
|
|
1845
2445
|
const matchesExpectedTools = actualToolNames.length === expectedToolNames.length && expectedToolNames.every((name, index) => actualToolNames[index] === name);
|
|
1846
|
-
return
|
|
2446
|
+
return template2.agent_identity === reference.agent_identity && matchesExpectedTools;
|
|
1847
2447
|
}
|
|
1848
|
-
function comparableHeadlessToolNames(
|
|
1849
|
-
return
|
|
2448
|
+
function comparableHeadlessToolNames(toolNames2) {
|
|
2449
|
+
return toolNames2.filter((toolName) => !INTERACTIVE_ONLY_TOOL_NAMES.has(toolName));
|
|
1850
2450
|
}
|
|
1851
2451
|
function loadBundledTemplate() {
|
|
1852
2452
|
if (bundledTemplate._schemaVersion !== CURRENT_SCHEMA_VERSION) {
|
|
@@ -1888,11 +2488,11 @@ function readLiveCacheSync(sourceOverride = "cached") {
|
|
|
1888
2488
|
return null;
|
|
1889
2489
|
}
|
|
1890
2490
|
}
|
|
1891
|
-
function getCapturedAt(
|
|
1892
|
-
return Date.parse(
|
|
2491
|
+
function getCapturedAt(template2) {
|
|
2492
|
+
return Date.parse(template2._captured);
|
|
1893
2493
|
}
|
|
1894
|
-
function isFreshTemplate(
|
|
1895
|
-
const capturedAt = getCapturedAt(
|
|
2494
|
+
function isFreshTemplate(template2) {
|
|
2495
|
+
const capturedAt = getCapturedAt(template2);
|
|
1896
2496
|
return Number.isFinite(capturedAt) && now() - capturedAt < LIVE_TTL_MS;
|
|
1897
2497
|
}
|
|
1898
2498
|
function pickTemplate(cached, bundled) {
|
|
@@ -1916,8 +2516,8 @@ async function atomicWriteJson(targetPath, payload) {
|
|
|
1916
2516
|
`, "utf8");
|
|
1917
2517
|
await rename(tmpPath, targetPath);
|
|
1918
2518
|
}
|
|
1919
|
-
async function writeLiveCache(
|
|
1920
|
-
await atomicWriteJson(getCachePath(), cloneTemplate(
|
|
2519
|
+
async function writeLiveCache(template2) {
|
|
2520
|
+
await atomicWriteJson(getCachePath(), cloneTemplate(template2, "live"));
|
|
1921
2521
|
}
|
|
1922
2522
|
function toText(value) {
|
|
1923
2523
|
if (typeof value === "string") {
|
|
@@ -2091,7 +2691,7 @@ function extractTemplate(captured) {
|
|
|
2091
2691
|
if (!billingHeader || !agentIdentity || !systemPrompt || extractedTools.length === 0) {
|
|
2092
2692
|
return null;
|
|
2093
2693
|
}
|
|
2094
|
-
const
|
|
2694
|
+
const toolNames2 = extractedTools.map((tool) => tool.name);
|
|
2095
2695
|
const headerValues = extractStaticHeaderValues(captured.headers);
|
|
2096
2696
|
const bodyFieldOrder = Object.keys(captured.body);
|
|
2097
2697
|
return {
|
|
@@ -2102,7 +2702,7 @@ function extractTemplate(captured) {
|
|
|
2102
2702
|
agent_identity: agentIdentity,
|
|
2103
2703
|
system_prompt: systemPrompt,
|
|
2104
2704
|
tools: extractedTools,
|
|
2105
|
-
tool_names:
|
|
2705
|
+
tool_names: toolNames2,
|
|
2106
2706
|
anthropic_beta: captured.headers["anthropic-beta"],
|
|
2107
2707
|
cc_version: extractCCVersion(billingHeader, captured.headers["user-agent"]),
|
|
2108
2708
|
header_order: extractHeaderOrder(captured.rawHeaders),
|
|
@@ -2152,10 +2752,23 @@ async function captureLiveTemplateAsync(timeoutMs = DEFAULT_CAPTURE_TIMEOUT_MS,
|
|
|
2152
2752
|
});
|
|
2153
2753
|
const baseUrl = `http://${LOOPBACK_HOST}:${address.port}`;
|
|
2154
2754
|
await runClaudeCapture({ binaryPath, baseUrl, timeoutMs, model: options.model });
|
|
2155
|
-
|
|
2755
|
+
const captured = capturedRequest;
|
|
2756
|
+
if (!captured) {
|
|
2156
2757
|
return null;
|
|
2157
2758
|
}
|
|
2158
|
-
|
|
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;
|
|
2159
2772
|
} catch {
|
|
2160
2773
|
return null;
|
|
2161
2774
|
} finally {
|
|
@@ -2217,8 +2830,8 @@ function compareVersions(left, right) {
|
|
|
2217
2830
|
}
|
|
2218
2831
|
return leftPatch - rightPatch;
|
|
2219
2832
|
}
|
|
2220
|
-
function detectDrift(
|
|
2221
|
-
const cachedVersion =
|
|
2833
|
+
function detectDrift(template2, installedOverride) {
|
|
2834
|
+
const cachedVersion = template2.cc_version ?? null;
|
|
2222
2835
|
const installedVersion = installedOverride ?? probeInstalledCCVersion();
|
|
2223
2836
|
if (!cachedVersion) {
|
|
2224
2837
|
return {
|
|
@@ -2303,6 +2916,21 @@ function resetFingerprintCaptureForTest() {
|
|
|
2303
2916
|
|
|
2304
2917
|
export {
|
|
2305
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,
|
|
2306
2934
|
detectCliVersion,
|
|
2307
2935
|
LIVE_TTL_MS,
|
|
2308
2936
|
SUPPORTED_CC_RANGE,
|
|
@@ -2318,4 +2946,4 @@ export {
|
|
|
2318
2946
|
setFingerprintCaptureTestOverridesForTest,
|
|
2319
2947
|
resetFingerprintCaptureForTest
|
|
2320
2948
|
};
|
|
2321
|
-
//# sourceMappingURL=chunk-
|
|
2949
|
+
//# sourceMappingURL=chunk-BRY7MF6N.js.map
|