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.
- package/dist/{chunk-KQ5RHIZP.js → chunk-BRY7MF6N.js} +652 -36
- 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-KQ5RHIZP.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,556 +1,30 @@
|
|
|
1
1
|
import {
|
|
2
|
+
applyClaudeCodeUpstreamBodyFields,
|
|
2
3
|
checkCCCompat,
|
|
4
|
+
clampEffortAfterRejection,
|
|
5
|
+
clampUnsupportedEffortInBody,
|
|
3
6
|
compareVersions,
|
|
7
|
+
composeClaudeCodeBillingSystemEntry,
|
|
8
|
+
createClaudeCodePerRequestHeaders,
|
|
9
|
+
createClaudeCodeStaticHeaders,
|
|
4
10
|
detectCliVersion,
|
|
5
11
|
detectDrift,
|
|
6
12
|
fingerprint_data_default,
|
|
13
|
+
isClaudeCode1mModelLabel,
|
|
14
|
+
isClaudeFableModel,
|
|
15
|
+
loadClaudeCodeSharedRequestProfile,
|
|
7
16
|
loadTemplate,
|
|
8
|
-
|
|
9
|
-
|
|
17
|
+
orderClaudeCodeHeadersForOutbound,
|
|
18
|
+
parseEffortCapabilityRejection,
|
|
19
|
+
refreshLiveFingerprintAsync,
|
|
20
|
+
resolveClaudeCodeCacheControl,
|
|
21
|
+
resolveClaudeCodeModelAlias,
|
|
22
|
+
stampClaudeCodeCch,
|
|
23
|
+
toClaudeCodeWireModelId
|
|
24
|
+
} from "./chunk-BRY7MF6N.js";
|
|
10
25
|
import "./chunk-ITZJ5FTB.js";
|
|
11
26
|
import "./chunk-FQBFDF73.js";
|
|
12
27
|
|
|
13
|
-
// ../providers/claude-code/src/opencode-shared.ts
|
|
14
|
-
import { createHash, randomUUID } from "crypto";
|
|
15
|
-
|
|
16
|
-
// ../providers/claude-code/src/fingerprint-template.ts
|
|
17
|
-
var template = fingerprint_data_default;
|
|
18
|
-
var toolNames = new Set(template.tools.map((tool) => tool.name));
|
|
19
|
-
function getClaudeCodeTemplateMetadata() {
|
|
20
|
-
return {
|
|
21
|
-
agentIdentity: template.agent_identity,
|
|
22
|
-
anthropicBeta: template.anthropic_beta,
|
|
23
|
-
bodyFieldOrder: template.body_field_order ? [...template.body_field_order] : void 0,
|
|
24
|
-
ccVersion: template.cc_version,
|
|
25
|
-
headerValues: { ...template.header_values },
|
|
26
|
-
headerOrder: template.header_order ? [...template.header_order] : void 0,
|
|
27
|
-
systemPrompt: template.system_prompt,
|
|
28
|
-
systemPromptFable: template.system_prompt_fable,
|
|
29
|
-
toolNames: template.tool_names ? [...template.tool_names] : template.tools.map((tool) => tool.name)
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// ../providers/claude-code/src/cch.ts
|
|
34
|
-
var CCH_SEEDS = {
|
|
35
|
-
"2.1.177": 0x4d659218e32a3268n
|
|
36
|
-
// 2.1.178 was checked during the issue #91 review; the 2.1.177 seed did
|
|
37
|
-
// not reproduce the captured cch, so leave it unstamped until a new seed is
|
|
38
|
-
// independently extracted and verified.
|
|
39
|
-
};
|
|
40
|
-
var MASK = 0xfffffn;
|
|
41
|
-
var U64 = (1n << 64n) - 1n;
|
|
42
|
-
var P1 = 0x9e3779b185ebca87n;
|
|
43
|
-
var P2 = 0xc2b2ae3d27d4eb4fn;
|
|
44
|
-
var P3 = 0x165667b19e3779f9n;
|
|
45
|
-
var P4 = 0x85ebca77c2b2ae63n;
|
|
46
|
-
var P5 = 0x27d4eb2f165667c5n;
|
|
47
|
-
var BILLING_HEADER_PREFIX = "x-anthropic-billing-header:";
|
|
48
|
-
var CCH_RE = /(cc_entrypoint=[a-z0-9-]{1,32}; cch=)[0-9a-fA-F]{5}(?=;)/;
|
|
49
|
-
var CC_VERSION_RE = /\bcc_version=([0-9]+(?:\.[0-9]+){2})(?:\.[0-9a-f]+)?;/;
|
|
50
|
-
function rotl(value, bits) {
|
|
51
|
-
return (value << bits | value >> 64n - bits) & U64;
|
|
52
|
-
}
|
|
53
|
-
function round(accumulator, input) {
|
|
54
|
-
let next = accumulator + input * P2 & U64;
|
|
55
|
-
next = rotl(next, 31n);
|
|
56
|
-
return next * P1 & U64;
|
|
57
|
-
}
|
|
58
|
-
function mergeRound(accumulator, value) {
|
|
59
|
-
const rounded = round(0n, value);
|
|
60
|
-
const next = (accumulator ^ rounded) & U64;
|
|
61
|
-
return next * P1 + P4 & U64;
|
|
62
|
-
}
|
|
63
|
-
function xxh64(data, seed) {
|
|
64
|
-
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
65
|
-
const length = data.length;
|
|
66
|
-
let offset = 0;
|
|
67
|
-
let hash;
|
|
68
|
-
if (length >= 32) {
|
|
69
|
-
let v1 = seed + P1 + P2 & U64;
|
|
70
|
-
let v22 = seed + P2 & U64;
|
|
71
|
-
let v32 = seed & U64;
|
|
72
|
-
let v4 = seed - P1 & U64;
|
|
73
|
-
const limit = length - 32;
|
|
74
|
-
while (offset <= limit) {
|
|
75
|
-
v1 = round(v1, view.getBigUint64(offset, true));
|
|
76
|
-
offset += 8;
|
|
77
|
-
v22 = round(v22, view.getBigUint64(offset, true));
|
|
78
|
-
offset += 8;
|
|
79
|
-
v32 = round(v32, view.getBigUint64(offset, true));
|
|
80
|
-
offset += 8;
|
|
81
|
-
v4 = round(v4, view.getBigUint64(offset, true));
|
|
82
|
-
offset += 8;
|
|
83
|
-
}
|
|
84
|
-
hash = rotl(v1, 1n) + rotl(v22, 7n) + rotl(v32, 12n) + rotl(v4, 18n) & U64;
|
|
85
|
-
hash = mergeRound(hash, v1);
|
|
86
|
-
hash = mergeRound(hash, v22);
|
|
87
|
-
hash = mergeRound(hash, v32);
|
|
88
|
-
hash = mergeRound(hash, v4);
|
|
89
|
-
} else {
|
|
90
|
-
hash = seed + P5 & U64;
|
|
91
|
-
}
|
|
92
|
-
hash = hash + BigInt(length) & U64;
|
|
93
|
-
while (offset + 8 <= length) {
|
|
94
|
-
const k1 = round(0n, view.getBigUint64(offset, true));
|
|
95
|
-
hash = (hash ^ k1) & U64;
|
|
96
|
-
hash = rotl(hash, 27n) * P1 + P4 & U64;
|
|
97
|
-
offset += 8;
|
|
98
|
-
}
|
|
99
|
-
if (offset + 4 <= length) {
|
|
100
|
-
hash = (hash ^ BigInt(view.getUint32(offset, true)) * P1 & U64) & U64;
|
|
101
|
-
hash = rotl(hash, 23n) * P2 + P3 & U64;
|
|
102
|
-
offset += 4;
|
|
103
|
-
}
|
|
104
|
-
while (offset < length) {
|
|
105
|
-
hash = (hash ^ BigInt(data[offset] ?? 0) * P5 & U64) & U64;
|
|
106
|
-
hash = rotl(hash, 11n) * P1 & U64;
|
|
107
|
-
offset += 1;
|
|
108
|
-
}
|
|
109
|
-
hash = (hash ^ hash >> 33n) & U64;
|
|
110
|
-
hash = hash * P2 & U64;
|
|
111
|
-
hash = (hash ^ hash >> 29n) & U64;
|
|
112
|
-
hash = hash * P3 & U64;
|
|
113
|
-
hash = (hash ^ hash >> 32n) & U64;
|
|
114
|
-
return hash;
|
|
115
|
-
}
|
|
116
|
-
function replaceBillingCch(body, cch) {
|
|
117
|
-
const system = body.system;
|
|
118
|
-
if (!Array.isArray(system)) return { replaced: false };
|
|
119
|
-
for (const entry of system) {
|
|
120
|
-
if (!entry || typeof entry !== "object") continue;
|
|
121
|
-
const systemEntry = entry;
|
|
122
|
-
if (typeof systemEntry.text !== "string") continue;
|
|
123
|
-
if (!systemEntry.text.startsWith(BILLING_HEADER_PREFIX)) continue;
|
|
124
|
-
if (!CCH_RE.test(systemEntry.text)) continue;
|
|
125
|
-
const version = CC_VERSION_RE.exec(systemEntry.text)?.[1];
|
|
126
|
-
systemEntry.text = systemEntry.text.replace(CCH_RE, (_match, prefix) => `${prefix}${cch}`);
|
|
127
|
-
return { replaced: true, version };
|
|
128
|
-
}
|
|
129
|
-
return { replaced: false };
|
|
130
|
-
}
|
|
131
|
-
function cchMaterial(bodyText) {
|
|
132
|
-
const body = JSON.parse(bodyText);
|
|
133
|
-
const { replaced, version } = replaceBillingCch(body, "00000");
|
|
134
|
-
if (!replaced) return null;
|
|
135
|
-
body.model = "";
|
|
136
|
-
delete body.fallbacks;
|
|
137
|
-
delete body.fallback_credit_token;
|
|
138
|
-
delete body.max_tokens;
|
|
139
|
-
return { bytes: new TextEncoder().encode(JSON.stringify(body)), version };
|
|
140
|
-
}
|
|
141
|
-
function cchForBody(bodyText, version) {
|
|
142
|
-
let material;
|
|
143
|
-
try {
|
|
144
|
-
material = cchMaterial(bodyText);
|
|
145
|
-
} catch {
|
|
146
|
-
return null;
|
|
147
|
-
}
|
|
148
|
-
if (!material) return null;
|
|
149
|
-
const seed = CCH_SEEDS[material.version ?? version ?? ""];
|
|
150
|
-
if (seed === void 0) return null;
|
|
151
|
-
const hash = xxh64(material.bytes, seed) & MASK;
|
|
152
|
-
return hash.toString(16).padStart(5, "0");
|
|
153
|
-
}
|
|
154
|
-
function stampClaudeCodeCch(bodyText, version) {
|
|
155
|
-
const cch = cchForBody(bodyText, version);
|
|
156
|
-
if (cch === null) return bodyText;
|
|
157
|
-
try {
|
|
158
|
-
const body = JSON.parse(bodyText);
|
|
159
|
-
const { replaced } = replaceBillingCch(body, cch);
|
|
160
|
-
return replaced ? JSON.stringify(body) : bodyText;
|
|
161
|
-
} catch {
|
|
162
|
-
return bodyText;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// ../providers/claude-code/src/effort-capability.ts
|
|
167
|
-
var EFFORT_PREFERENCE = ["xhigh", "max", "high", "medium", "low"];
|
|
168
|
-
function readRecord(value) {
|
|
169
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
170
|
-
}
|
|
171
|
-
function normalizeEffortValue(value) {
|
|
172
|
-
return value.trim().toLowerCase().replace(/[^a-z_-]+$/g, "");
|
|
173
|
-
}
|
|
174
|
-
function parseEffortCapabilityRejection(body) {
|
|
175
|
-
const match = /does not support effort level\s+['"`]?([^'"`.\s]+)['"`]?\.?\s*Supported levels:\s*([a-z,\s_-]+)/i.exec(body);
|
|
176
|
-
if (!match?.[1] || !match[2]) {
|
|
177
|
-
return null;
|
|
178
|
-
}
|
|
179
|
-
const supported = match[2].split(",").map(normalizeEffortValue).filter(Boolean);
|
|
180
|
-
return supported.length > 0 ? { rejected: normalizeEffortValue(match[1]), supported } : null;
|
|
181
|
-
}
|
|
182
|
-
function bestSupportedEffort(supported) {
|
|
183
|
-
for (const effort of EFFORT_PREFERENCE) {
|
|
184
|
-
if (supported.includes(effort)) {
|
|
185
|
-
return effort;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
return supported[0] ?? "high";
|
|
189
|
-
}
|
|
190
|
-
function clampUnsupportedEffortInBody(body, supportedEffortsByModel) {
|
|
191
|
-
if (typeof body !== "string") {
|
|
192
|
-
return { body, changed: false };
|
|
193
|
-
}
|
|
194
|
-
try {
|
|
195
|
-
const parsed = JSON.parse(body);
|
|
196
|
-
const record = readRecord(parsed);
|
|
197
|
-
const modelId = typeof record?.model === "string" ? record.model : void 0;
|
|
198
|
-
const outputConfig = readRecord(record?.output_config);
|
|
199
|
-
const effort = typeof outputConfig?.effort === "string" ? outputConfig.effort : void 0;
|
|
200
|
-
if (!modelId || !outputConfig || !effort) {
|
|
201
|
-
return { body, changed: false, modelId };
|
|
202
|
-
}
|
|
203
|
-
const supported = supportedEffortsByModel.get(modelId);
|
|
204
|
-
if (!supported || supported.includes(effort)) {
|
|
205
|
-
return { body, changed: false, modelId, effort };
|
|
206
|
-
}
|
|
207
|
-
const clamped = bestSupportedEffort(supported);
|
|
208
|
-
outputConfig.effort = clamped;
|
|
209
|
-
return { body: JSON.stringify(record), changed: true, modelId, effort: clamped };
|
|
210
|
-
} catch {
|
|
211
|
-
return { body, changed: false };
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
function clampEffortAfterRejection(body, rejection, supportedEffortsByModel) {
|
|
215
|
-
if (typeof body !== "string") {
|
|
216
|
-
return { body, changed: false };
|
|
217
|
-
}
|
|
218
|
-
try {
|
|
219
|
-
const parsed = JSON.parse(body);
|
|
220
|
-
const record = readRecord(parsed);
|
|
221
|
-
const modelId = typeof record?.model === "string" ? record.model : void 0;
|
|
222
|
-
const outputConfig = readRecord(record?.output_config);
|
|
223
|
-
const effort = typeof outputConfig?.effort === "string" ? outputConfig.effort : void 0;
|
|
224
|
-
if (!modelId || !outputConfig || !effort) {
|
|
225
|
-
return { body, changed: false, modelId };
|
|
226
|
-
}
|
|
227
|
-
supportedEffortsByModel.set(modelId, [...rejection.supported]);
|
|
228
|
-
if (rejection.supported.includes(effort)) {
|
|
229
|
-
return { body, changed: false, modelId, effort };
|
|
230
|
-
}
|
|
231
|
-
const clamped = bestSupportedEffort(rejection.supported);
|
|
232
|
-
outputConfig.effort = clamped;
|
|
233
|
-
return { body: JSON.stringify(record), changed: true, modelId, effort: clamped };
|
|
234
|
-
} catch {
|
|
235
|
-
return { body, changed: false };
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// ../providers/claude-code/src/model-aliases.ts
|
|
240
|
-
var MODEL_FAMILIES = ["fable", "opus", "sonnet", "haiku"];
|
|
241
|
-
var FAMILY_RANK = { fable: 0, opus: 1, sonnet: 2, haiku: 3 };
|
|
242
|
-
var CLAUDE_FABLE_MODEL_ID = "claude-fable-5";
|
|
243
|
-
var CLAUDE_FABLE_1M_MODEL_ID = `${CLAUDE_FABLE_MODEL_ID}[1m]`;
|
|
244
|
-
var CLAUDE_SONNET_MODEL_ID = "claude-sonnet-5";
|
|
245
|
-
var CLAUDE_SONNET_1M_MODEL_ID = `${CLAUDE_SONNET_MODEL_ID}[1m]`;
|
|
246
|
-
var FALLBACK_CLAUDE_CODE_BASE_MODEL_IDS = [
|
|
247
|
-
CLAUDE_FABLE_MODEL_ID,
|
|
248
|
-
"claude-opus-4-8",
|
|
249
|
-
"claude-opus-4-7",
|
|
250
|
-
"claude-opus-4-6",
|
|
251
|
-
CLAUDE_SONNET_MODEL_ID,
|
|
252
|
-
"claude-sonnet-4-6",
|
|
253
|
-
"claude-haiku-4-5"
|
|
254
|
-
];
|
|
255
|
-
var STATIC_MODEL_ALIASES = {
|
|
256
|
-
opus47: "claude-opus-4-7",
|
|
257
|
-
opus46: "claude-opus-4-6",
|
|
258
|
-
sonnet46: "claude-sonnet-4-6"
|
|
259
|
-
};
|
|
260
|
-
var cachedBaseModelIds = [...FALLBACK_CLAUDE_CODE_BASE_MODEL_IDS];
|
|
261
|
-
function stripClaudeCodeProviderPrefix(modelId) {
|
|
262
|
-
const slash = modelId.indexOf("/");
|
|
263
|
-
if (slash === -1) return modelId;
|
|
264
|
-
const provider = modelId.slice(0, slash).toLowerCase();
|
|
265
|
-
return provider === "anthropic" || provider === "claude-code" ? modelId.slice(slash + 1) : modelId;
|
|
266
|
-
}
|
|
267
|
-
function resolveClaudeCodeModelAlias(modelId) {
|
|
268
|
-
const unprefixed = stripClaudeCodeProviderPrefix(modelId.trim());
|
|
269
|
-
return resolveAliasAgainst(unprefixed, cachedBaseModelIds) ?? STATIC_MODEL_ALIASES[unprefixed.toLowerCase()] ?? unprefixed;
|
|
270
|
-
}
|
|
271
|
-
function stripClaudeCodeContext1mTag(modelId) {
|
|
272
|
-
return modelId.replace(/\[1m\]$/i, "");
|
|
273
|
-
}
|
|
274
|
-
function toClaudeCodeWireModelId(modelId) {
|
|
275
|
-
return stripClaudeCodeContext1mTag(resolveClaudeCodeModelAlias(modelId));
|
|
276
|
-
}
|
|
277
|
-
function isClaudeCode1mModelLabel(modelId) {
|
|
278
|
-
return /\[1m\]$/i.test(resolveClaudeCodeModelAlias(modelId));
|
|
279
|
-
}
|
|
280
|
-
function isClaudeFableModel(modelId) {
|
|
281
|
-
return resolveClaudeCodeModelAlias(modelId).toLowerCase().includes("fable");
|
|
282
|
-
}
|
|
283
|
-
function resolveFamilyBase(family, baseIds) {
|
|
284
|
-
return baseIds.filter((id) => modelFamily(id) === family && !id.includes("[")).sort(compareClaudeCodeBaseModelIds)[0];
|
|
285
|
-
}
|
|
286
|
-
function longContextEligible(id) {
|
|
287
|
-
const normalized = id.toLowerCase();
|
|
288
|
-
return normalized.startsWith("claude-") && !normalized.includes("haiku") && !normalized.endsWith("[1m]");
|
|
289
|
-
}
|
|
290
|
-
function compareClaudeCodeBaseModelIds(a, b) {
|
|
291
|
-
const aRank = FAMILY_RANK[modelFamily(a) ?? ""] ?? 99;
|
|
292
|
-
const bRank = FAMILY_RANK[modelFamily(b) ?? ""] ?? 99;
|
|
293
|
-
if (aRank !== bRank) return aRank - bRank;
|
|
294
|
-
return compareVersionDesc(modelVersionKey(a), modelVersionKey(b));
|
|
295
|
-
}
|
|
296
|
-
function modelFamily(id) {
|
|
297
|
-
const normalized = stripClaudeCodeContext1mTag(stripClaudeCodeProviderPrefix(id)).toLowerCase();
|
|
298
|
-
for (const family of MODEL_FAMILIES) {
|
|
299
|
-
if (normalized.includes(family)) return family;
|
|
300
|
-
}
|
|
301
|
-
return void 0;
|
|
302
|
-
}
|
|
303
|
-
function resolveAliasAgainst(modelId, baseIds) {
|
|
304
|
-
const normalized = stripClaudeCodeProviderPrefix(modelId).trim().toLowerCase();
|
|
305
|
-
if (isModelFamily(normalized)) return resolveFamilyBase(normalized, baseIds) ?? void 0;
|
|
306
|
-
const match = /^([a-z]+)1m$/.exec(normalized);
|
|
307
|
-
if (match?.[1] && isModelFamily(match[1])) {
|
|
308
|
-
const base = resolveFamilyBase(match[1], baseIds);
|
|
309
|
-
return base && longContextEligible(base) ? `${base}[1m]` : void 0;
|
|
310
|
-
}
|
|
311
|
-
return void 0;
|
|
312
|
-
}
|
|
313
|
-
function isModelFamily(value) {
|
|
314
|
-
return MODEL_FAMILIES.includes(value);
|
|
315
|
-
}
|
|
316
|
-
function modelVersionKey(id) {
|
|
317
|
-
return id.match(/\d+/g)?.map(Number) ?? [];
|
|
318
|
-
}
|
|
319
|
-
function compareVersionDesc(a, b) {
|
|
320
|
-
const length = Math.max(a.length, b.length);
|
|
321
|
-
for (let index = 0; index < length; index += 1) {
|
|
322
|
-
const diff = (b[index] ?? -1) - (a[index] ?? -1);
|
|
323
|
-
if (diff !== 0) return diff;
|
|
324
|
-
}
|
|
325
|
-
return 0;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
// ../providers/claude-code/src/opencode-shared.ts
|
|
329
|
-
var CLAUDE_CODE_API_BASE_URL = "https://api.anthropic.com";
|
|
330
|
-
var STAINLESS_PACKAGE_VERSION = "0.81.0";
|
|
331
|
-
var DEFAULT_OPENCODE_TIMEOUT_SECONDS = "300";
|
|
332
|
-
var BILLING_SEED = "59cf53e54c78";
|
|
333
|
-
var templateMetadata = getClaudeCodeTemplateMetadata();
|
|
334
|
-
var templateHeaders = templateMetadata.headerValues;
|
|
335
|
-
var CLAUDE_CODE_VERSION = templateMetadata.ccVersion ?? "2.1.137";
|
|
336
|
-
var CCH_REMOVED_VERSION = "2.1.183";
|
|
337
|
-
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";
|
|
338
|
-
function loadClaudeCodeSharedRequestProfile() {
|
|
339
|
-
return {
|
|
340
|
-
anthropicBeta: templateMetadata.anthropicBeta ?? templateHeaders["anthropic-beta"] ?? "oauth-2025-04-20",
|
|
341
|
-
anthropicVersion: templateHeaders["anthropic-version"] ?? "2023-06-01",
|
|
342
|
-
apiV1BaseUrl: `${CLAUDE_CODE_API_BASE_URL}/v1`,
|
|
343
|
-
baseUrl: CLAUDE_CODE_API_BASE_URL,
|
|
344
|
-
ccVersion: CLAUDE_CODE_VERSION,
|
|
345
|
-
headerOrder: templateMetadata.headerOrder ? [...templateMetadata.headerOrder] : void 0,
|
|
346
|
-
headerValues: { ...templateHeaders },
|
|
347
|
-
packageVersion: templateHeaders["x-stainless-package-version"] ?? STAINLESS_PACKAGE_VERSION,
|
|
348
|
-
userAgent: templateHeaders["user-agent"] ?? `claude-cli/${CLAUDE_CODE_VERSION} (external, sdk-cli)`,
|
|
349
|
-
xApp: templateHeaders["x-app"] ?? "cli"
|
|
350
|
-
};
|
|
351
|
-
}
|
|
352
|
-
function createClaudeCodeStaticHeaders(input) {
|
|
353
|
-
return {
|
|
354
|
-
"accept": "application/json",
|
|
355
|
-
"content-type": "application/json",
|
|
356
|
-
"anthropic-dangerous-direct-browser-access": "true",
|
|
357
|
-
"user-agent": input.userAgent,
|
|
358
|
-
"x-app": input.xApp,
|
|
359
|
-
"x-stainless-arch": process.arch,
|
|
360
|
-
"x-stainless-lang": "js",
|
|
361
|
-
"x-stainless-os": getOsName(),
|
|
362
|
-
"x-stainless-package-version": input.packageVersion ?? STAINLESS_PACKAGE_VERSION,
|
|
363
|
-
"x-stainless-retry-count": "0",
|
|
364
|
-
"x-stainless-runtime": "node",
|
|
365
|
-
"x-stainless-runtime-version": process.version,
|
|
366
|
-
...input.headerValues ?? {}
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
function createClaudeCodePerRequestHeaders(input) {
|
|
370
|
-
return {
|
|
371
|
-
"x-claude-code-session-id": input.sessionId,
|
|
372
|
-
"x-client-request-id": randomUUID(),
|
|
373
|
-
"anthropic-version": input.anthropicVersion,
|
|
374
|
-
"x-stainless-timeout": input.timeoutSeconds ?? DEFAULT_OPENCODE_TIMEOUT_SECONDS
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
|
-
function orderClaudeCodeHeadersForOutbound(headers, headerOrder) {
|
|
378
|
-
if (!Array.isArray(headerOrder) || headerOrder.length === 0) return headers;
|
|
379
|
-
const lowerToValue = /* @__PURE__ */ new Map();
|
|
380
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
381
|
-
lowerToValue.set(key.toLowerCase(), value);
|
|
382
|
-
}
|
|
383
|
-
const ordered = [];
|
|
384
|
-
const seen = /* @__PURE__ */ new Set();
|
|
385
|
-
for (const name of headerOrder) {
|
|
386
|
-
const key = name.toLowerCase();
|
|
387
|
-
const value = lowerToValue.get(key);
|
|
388
|
-
if (value === void 0 || seen.has(key)) continue;
|
|
389
|
-
ordered.push([name, value]);
|
|
390
|
-
seen.add(key);
|
|
391
|
-
}
|
|
392
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
393
|
-
if (seen.has(key.toLowerCase())) continue;
|
|
394
|
-
ordered.push([key, value]);
|
|
395
|
-
}
|
|
396
|
-
return ordered;
|
|
397
|
-
}
|
|
398
|
-
function computeClaudeCodeBuildTag(userMessage, version) {
|
|
399
|
-
const chars = [4, 7, 20].map((index) => userMessage[index] ?? "0").join("");
|
|
400
|
-
return createHash("sha256").update(`${BILLING_SEED}${chars}${version}`).digest("hex").slice(0, 3);
|
|
401
|
-
}
|
|
402
|
-
function composeClaudeCodeBillingSystemEntry(firstUserMessage, version, cch = "00000") {
|
|
403
|
-
const buildTag = computeClaudeCodeBuildTag(firstUserMessage, version);
|
|
404
|
-
const base = `x-anthropic-billing-header: cc_version=${version}.${buildTag}; cc_entrypoint=sdk-cli;`;
|
|
405
|
-
return claudeCodeBillingUsesCch(version) ? `${base} cch=${cch};` : base;
|
|
406
|
-
}
|
|
407
|
-
function claudeCodeBillingUsesCch(version) {
|
|
408
|
-
const comparison = compareSemver(version, CCH_REMOVED_VERSION);
|
|
409
|
-
return comparison === null || comparison < 0;
|
|
410
|
-
}
|
|
411
|
-
function compareSemver(left, right) {
|
|
412
|
-
const leftParts = parseSemver(left);
|
|
413
|
-
const rightParts = parseSemver(right);
|
|
414
|
-
if (!leftParts || !rightParts) return null;
|
|
415
|
-
for (let index = 0; index < leftParts.length; index += 1) {
|
|
416
|
-
const diff = leftParts[index] - rightParts[index];
|
|
417
|
-
if (diff !== 0) return diff;
|
|
418
|
-
}
|
|
419
|
-
return 0;
|
|
420
|
-
}
|
|
421
|
-
function parseSemver(version) {
|
|
422
|
-
const match = /^(\d+)\.(\d+)\.(\d+)/.exec(version);
|
|
423
|
-
if (!match) return null;
|
|
424
|
-
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
425
|
-
}
|
|
426
|
-
function applyClaudeCodePromptCaching(body, cacheControl = { type: "ephemeral" }) {
|
|
427
|
-
const tools = body.tools;
|
|
428
|
-
if (Array.isArray(tools) && tools.length > 0) {
|
|
429
|
-
const clonedTools = tools.map((tool) => {
|
|
430
|
-
const cloned = { ...tool };
|
|
431
|
-
delete cloned.cache_control;
|
|
432
|
-
return cloned;
|
|
433
|
-
});
|
|
434
|
-
clonedTools[clonedTools.length - 1] = {
|
|
435
|
-
...clonedTools[clonedTools.length - 1],
|
|
436
|
-
cache_control: cacheControl
|
|
437
|
-
};
|
|
438
|
-
body.tools = clonedTools;
|
|
439
|
-
}
|
|
440
|
-
const messages = body.messages;
|
|
441
|
-
if (!Array.isArray(messages) || messages.length === 0) {
|
|
442
|
-
return;
|
|
443
|
-
}
|
|
444
|
-
const lastMessage = messages[messages.length - 1];
|
|
445
|
-
const content = lastMessage?.content;
|
|
446
|
-
if (!Array.isArray(content) || content.length === 0) {
|
|
447
|
-
return;
|
|
448
|
-
}
|
|
449
|
-
content[content.length - 1] = {
|
|
450
|
-
...content[content.length - 1],
|
|
451
|
-
cache_control: cacheControl
|
|
452
|
-
};
|
|
453
|
-
}
|
|
454
|
-
function applyClaudeCodeUpstreamBodyFields(body, input) {
|
|
455
|
-
const firstUserMessage = input.firstUserMessage ?? extractFirstUserText(body.messages);
|
|
456
|
-
const billingHeader = composeClaudeCodeBillingSystemEntry(
|
|
457
|
-
firstUserMessage,
|
|
458
|
-
input.ccVersion,
|
|
459
|
-
input.cch
|
|
460
|
-
);
|
|
461
|
-
const systemTexts = input.systemTexts ?? normalizeClaudeCodeSystemTexts(body.system);
|
|
462
|
-
const injectedSystemTexts = filterInjectedSystemTexts(systemTexts, {
|
|
463
|
-
agentIdentity: input.agentIdentity,
|
|
464
|
-
billingHeader,
|
|
465
|
-
systemPrompt: input.systemPrompt
|
|
466
|
-
});
|
|
467
|
-
const mergedSystemPrompt = injectedSystemTexts.length > 0 ? `${input.systemPrompt}${CLIENT_SYSTEM_PREFACE}${injectedSystemTexts.join("\n\n")}` : input.systemPrompt;
|
|
468
|
-
body.system = [
|
|
469
|
-
{ type: "text", text: billingHeader },
|
|
470
|
-
{
|
|
471
|
-
type: "text",
|
|
472
|
-
text: input.agentIdentity,
|
|
473
|
-
cache_control: { type: "ephemeral" }
|
|
474
|
-
},
|
|
475
|
-
{
|
|
476
|
-
type: "text",
|
|
477
|
-
text: mergedSystemPrompt,
|
|
478
|
-
cache_control: { type: "ephemeral" }
|
|
479
|
-
}
|
|
480
|
-
];
|
|
481
|
-
body.metadata = {
|
|
482
|
-
...readRecord2(body.metadata),
|
|
483
|
-
user_id: JSON.stringify({
|
|
484
|
-
device_id: input.identity.deviceId,
|
|
485
|
-
account_uuid: input.identity.accountUuid,
|
|
486
|
-
session_id: input.sessionId
|
|
487
|
-
})
|
|
488
|
-
};
|
|
489
|
-
if (input.defaultTools && (!Array.isArray(body.tools) || body.tools.length === 0)) {
|
|
490
|
-
body.tools = input.defaultTools.map((tool) => ({ ...tool }));
|
|
491
|
-
}
|
|
492
|
-
applyClaudeCodePromptCaching(body);
|
|
493
|
-
return orderClaudeCodeBodyForOutbound(body, input.bodyFieldOrder);
|
|
494
|
-
}
|
|
495
|
-
function orderClaudeCodeBodyForOutbound(body, fieldOrder) {
|
|
496
|
-
if (!Array.isArray(fieldOrder) || fieldOrder.length === 0) return body;
|
|
497
|
-
const ordered = {};
|
|
498
|
-
const seen = /* @__PURE__ */ new Set();
|
|
499
|
-
for (const field of fieldOrder) {
|
|
500
|
-
if (seen.has(field)) continue;
|
|
501
|
-
if (Object.prototype.hasOwnProperty.call(body, field)) {
|
|
502
|
-
ordered[field] = body[field];
|
|
503
|
-
seen.add(field);
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
for (const [field, value] of Object.entries(body)) {
|
|
507
|
-
if (seen.has(field)) continue;
|
|
508
|
-
ordered[field] = value;
|
|
509
|
-
}
|
|
510
|
-
return ordered;
|
|
511
|
-
}
|
|
512
|
-
function normalizeClaudeCodeSystemTexts(system) {
|
|
513
|
-
if (typeof system === "string" && system.length > 0) return [system];
|
|
514
|
-
if (!Array.isArray(system)) return [];
|
|
515
|
-
const texts = [];
|
|
516
|
-
for (const entry of system) {
|
|
517
|
-
if (typeof entry === "string" && entry.length > 0) {
|
|
518
|
-
texts.push(entry);
|
|
519
|
-
continue;
|
|
520
|
-
}
|
|
521
|
-
const record = readRecord2(entry);
|
|
522
|
-
const text = typeof record?.text === "string" && record.text.length > 0 ? record.text : void 0;
|
|
523
|
-
if (text) texts.push(text);
|
|
524
|
-
}
|
|
525
|
-
return texts;
|
|
526
|
-
}
|
|
527
|
-
function filterInjectedSystemTexts(systemTexts, input) {
|
|
528
|
-
return systemTexts.filter((entry) => entry !== input.billingHeader && entry !== input.agentIdentity && entry !== input.systemPrompt && !entry.startsWith("x-anthropic-billing-header:"));
|
|
529
|
-
}
|
|
530
|
-
function extractFirstUserText(messages) {
|
|
531
|
-
if (!Array.isArray(messages)) return "";
|
|
532
|
-
for (const message of messages) {
|
|
533
|
-
const record = readRecord2(message);
|
|
534
|
-
if (record?.role !== "user") continue;
|
|
535
|
-
if (typeof record.content === "string") return record.content;
|
|
536
|
-
if (!Array.isArray(record.content)) return "";
|
|
537
|
-
return record.content.map((block) => {
|
|
538
|
-
const text = readRecord2(block)?.text;
|
|
539
|
-
return typeof text === "string" && text.length > 0 ? text : void 0;
|
|
540
|
-
}).filter((text) => Boolean(text)).join("\n\n");
|
|
541
|
-
}
|
|
542
|
-
return "";
|
|
543
|
-
}
|
|
544
|
-
function readRecord2(value) {
|
|
545
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
546
|
-
}
|
|
547
|
-
function getOsName() {
|
|
548
|
-
const platform2 = process.platform;
|
|
549
|
-
if (platform2 === "win32") return "Windows";
|
|
550
|
-
if (platform2 === "darwin") return "MacOS";
|
|
551
|
-
return "Linux";
|
|
552
|
-
}
|
|
553
|
-
|
|
554
28
|
// src/index.ts
|
|
555
29
|
import {
|
|
556
30
|
CascadeStateManager,
|
|
@@ -600,7 +74,7 @@ var {
|
|
|
600
74
|
|
|
601
75
|
// src/oauth/anthropic-oauth.ts
|
|
602
76
|
import { exec } from "child_process";
|
|
603
|
-
import { randomUUID
|
|
77
|
+
import { randomUUID } from "crypto";
|
|
604
78
|
import * as v3 from "valibot";
|
|
605
79
|
|
|
606
80
|
// src/fixtures/defaults/cc-derived-defaults.json
|
|
@@ -621,7 +95,7 @@ var cc_derived_defaults_default = {
|
|
|
621
95
|
};
|
|
622
96
|
|
|
623
97
|
// src/claude-code/oauth-config/detect.ts
|
|
624
|
-
import { createHash
|
|
98
|
+
import { createHash } from "crypto";
|
|
625
99
|
import { execFileSync as defaultExecFileSync } from "child_process";
|
|
626
100
|
import { existsSync } from "fs";
|
|
627
101
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
@@ -1025,7 +499,7 @@ function findCCBinary() {
|
|
|
1025
499
|
}
|
|
1026
500
|
async function fingerprintBinary(path) {
|
|
1027
501
|
const binaryContents = await readFile(path);
|
|
1028
|
-
return
|
|
502
|
+
return createHash("sha256").update(binaryContents).digest("hex").slice(0, 16);
|
|
1029
503
|
}
|
|
1030
504
|
function scanBinaryForOAuthConfig(buf) {
|
|
1031
505
|
const binaryText = buf.toString("latin1");
|
|
@@ -1120,13 +594,13 @@ var DEFAULT_ANTHROPIC_VERSION = bundledTemplate.header_values?.["anthropic-versi
|
|
|
1120
594
|
var DEFAULT_X_APP = bundledTemplate.header_values?.["x-app"] || sharedProfile.xApp || derivedDefaults2.request?.xApp || "cli";
|
|
1121
595
|
var DEFAULT_BETA_HEADER = bundledTemplate.anthropic_beta || bundledTemplate.header_values?.["anthropic-beta"] || sharedProfile.anthropicBeta || derivedDefaults2.request?.betaHeader || "oauth-2025-04-20,interleaved-thinking-2025-05-14";
|
|
1122
596
|
function loadCCDerivedRequestProfile() {
|
|
1123
|
-
const
|
|
597
|
+
const template = loadTemplate();
|
|
1124
598
|
const cliVersion = detectCliVersion();
|
|
1125
|
-
const anthropicVersion =
|
|
1126
|
-
const betaHeader =
|
|
1127
|
-
const xApp =
|
|
599
|
+
const anthropicVersion = template.header_values?.["anthropic-version"] || DEFAULT_ANTHROPIC_VERSION;
|
|
600
|
+
const betaHeader = template.anthropic_beta || template.header_values?.["anthropic-beta"] || DEFAULT_BETA_HEADER;
|
|
601
|
+
const xApp = template.header_values?.["x-app"] || DEFAULT_X_APP;
|
|
1128
602
|
return {
|
|
1129
|
-
template
|
|
603
|
+
template,
|
|
1130
604
|
cliVersion,
|
|
1131
605
|
userAgent: `claude-cli/${cliVersion} (external, cli)`,
|
|
1132
606
|
anthropicVersion,
|
|
@@ -1311,13 +785,13 @@ function startCallbackServer(options) {
|
|
|
1311
785
|
}
|
|
1312
786
|
|
|
1313
787
|
// src/oauth/pkce.ts
|
|
1314
|
-
import { createHash as
|
|
788
|
+
import { createHash as createHash2, randomBytes } from "crypto";
|
|
1315
789
|
function base64url(buffer) {
|
|
1316
790
|
return buffer.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
1317
791
|
}
|
|
1318
792
|
function generatePKCE() {
|
|
1319
793
|
const verifier = base64url(randomBytes(32));
|
|
1320
|
-
const challenge = base64url(
|
|
794
|
+
const challenge = base64url(createHash2("sha256").update(verifier).digest());
|
|
1321
795
|
return { verifier, challenge };
|
|
1322
796
|
}
|
|
1323
797
|
function generateState() {
|
|
@@ -1622,8 +1096,8 @@ function openBrowser(url) {
|
|
|
1622
1096
|
}
|
|
1623
1097
|
function resolveStoredClaudeIdentity(tokens) {
|
|
1624
1098
|
const localIdentity = claudeCodeIntegration.loadIdentity();
|
|
1625
|
-
const accountUuid = tokens.account?.uuid || localIdentity.accountUuid ||
|
|
1626
|
-
const deviceId = localIdentity.deviceId ||
|
|
1099
|
+
const accountUuid = tokens.account?.uuid || localIdentity.accountUuid || randomUUID();
|
|
1100
|
+
const deviceId = localIdentity.deviceId || randomUUID();
|
|
1627
1101
|
return {
|
|
1628
1102
|
accountId: accountUuid,
|
|
1629
1103
|
accountUuid,
|
|
@@ -2206,7 +1680,7 @@ var AccountStore = class extends CoreAccountStore {
|
|
|
2206
1680
|
};
|
|
2207
1681
|
|
|
2208
1682
|
// src/auth-ux/handler.ts
|
|
2209
|
-
import { randomUUID as
|
|
1683
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
2210
1684
|
function makeFailedFlowResult(message) {
|
|
2211
1685
|
return {
|
|
2212
1686
|
url: "",
|
|
@@ -2321,7 +1795,7 @@ async function persistFallback(auth, email, metadata) {
|
|
|
2321
1795
|
const store = new AccountStore();
|
|
2322
1796
|
const now2 = Date.now();
|
|
2323
1797
|
const account = {
|
|
2324
|
-
uuid:
|
|
1798
|
+
uuid: randomUUID2(),
|
|
2325
1799
|
email,
|
|
2326
1800
|
refreshToken: auth.refresh,
|
|
2327
1801
|
accessToken: auth.access,
|
|
@@ -2515,7 +1989,7 @@ var ProactiveRefreshQueue = createProactiveRefreshQueueForProvider({
|
|
|
2515
1989
|
import { TokenRefreshError } from "opencode-multi-account-core";
|
|
2516
1990
|
|
|
2517
1991
|
// src/request/transform.ts
|
|
2518
|
-
import { randomUUID as
|
|
1992
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
2519
1993
|
|
|
2520
1994
|
// src/model/config.ts
|
|
2521
1995
|
var FABLE_FALLBACK_CREDIT_BETA = "fallback-credit-2026-06-01";
|
|
@@ -2647,7 +2121,7 @@ function getModelBetas(modelId, excluded) {
|
|
|
2647
2121
|
}
|
|
2648
2122
|
|
|
2649
2123
|
// src/request/upstream-request.ts
|
|
2650
|
-
import { randomUUID as
|
|
2124
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
2651
2125
|
|
|
2652
2126
|
// src/model/capabilities.ts
|
|
2653
2127
|
var runtimeModelCapabilities = /* @__PURE__ */ new Map();
|
|
@@ -3048,13 +2522,13 @@ var DEFAULT_OUTPUT_EFFORT = "high";
|
|
|
3048
2522
|
var VALID_OUTPUT_EFFORT_VALUES = /* @__PURE__ */ new Set(["low", "medium", "high", "xhigh", "ultracode", "max", "client"]);
|
|
3049
2523
|
var OPENCODE_OUTPUT_EFFORT_HEADER = "x-kyoli-opencode-effort";
|
|
3050
2524
|
var upstreamRequestTestOverrides = {};
|
|
3051
|
-
var sessionId =
|
|
2525
|
+
var sessionId = randomUUID3();
|
|
3052
2526
|
var sessionLastUsed = 0;
|
|
3053
2527
|
function now() {
|
|
3054
2528
|
return upstreamRequestTestOverrides.now?.() ?? Date.now();
|
|
3055
2529
|
}
|
|
3056
2530
|
function createSessionId() {
|
|
3057
|
-
return upstreamRequestTestOverrides.createSessionId?.() ??
|
|
2531
|
+
return upstreamRequestTestOverrides.createSessionId?.() ?? randomUUID3();
|
|
3058
2532
|
}
|
|
3059
2533
|
function getActiveSessionId() {
|
|
3060
2534
|
const currentTime = now();
|
|
@@ -3115,8 +2589,8 @@ function resolveOutputEffort(inputBody, configuredEffort = getConfiguredOutputEf
|
|
|
3115
2589
|
function isHaikuModel(modelId) {
|
|
3116
2590
|
return resolveClaudeCodeModelAlias(modelId).toLowerCase().includes("haiku");
|
|
3117
2591
|
}
|
|
3118
|
-
function getSystemPromptForModel(
|
|
3119
|
-
return modelId.toLowerCase().includes("fable") &&
|
|
2592
|
+
function getSystemPromptForModel(template, modelId) {
|
|
2593
|
+
return modelId.toLowerCase().includes("fable") && template.system_prompt_fable ? template.system_prompt_fable : template.system_prompt;
|
|
3120
2594
|
}
|
|
3121
2595
|
function collectToolUseIds(message) {
|
|
3122
2596
|
if (!Array.isArray(message.content)) {
|
|
@@ -3183,14 +2657,14 @@ function resolveMaxTokens(requestedMaxTokens) {
|
|
|
3183
2657
|
}
|
|
3184
2658
|
return Math.min(normalized, DEFAULT_MAX_OUTPUT_TOKENS);
|
|
3185
2659
|
}
|
|
3186
|
-
function
|
|
3187
|
-
return systemTexts.filter((entry) => entry !== billingHeader && entry !==
|
|
2660
|
+
function filterInjectedSystemTexts(systemTexts, template, billingHeader) {
|
|
2661
|
+
return systemTexts.filter((entry) => entry !== billingHeader && entry !== template.agent_identity && entry !== template.system_prompt && !entry.startsWith("x-anthropic-billing-header:"));
|
|
3188
2662
|
}
|
|
3189
|
-
function getCcVersion(
|
|
3190
|
-
return
|
|
2663
|
+
function getCcVersion(template) {
|
|
2664
|
+
return template?.cc_version ?? claudeCodeIntegration.detectCliVersion();
|
|
3191
2665
|
}
|
|
3192
|
-
function buildBillingHeader(firstUserMessage,
|
|
3193
|
-
const version = getCcVersion(
|
|
2666
|
+
function buildBillingHeader(firstUserMessage, template) {
|
|
2667
|
+
const version = getCcVersion(template);
|
|
3194
2668
|
return composeClaudeCodeBillingSystemEntry(firstUserMessage, version);
|
|
3195
2669
|
}
|
|
3196
2670
|
function getReverseName(name, reverseLookup) {
|
|
@@ -3233,14 +2707,15 @@ function remapSseLine(line, reverseLookup) {
|
|
|
3233
2707
|
return line;
|
|
3234
2708
|
}
|
|
3235
2709
|
}
|
|
3236
|
-
function buildUpstreamRequest(inputBody, identity,
|
|
2710
|
+
function buildUpstreamRequest(inputBody, identity, template, options) {
|
|
2711
|
+
const cacheControl = resolveClaudeCodeCacheControl(inputBody);
|
|
3237
2712
|
const { body, firstUserMessage, systemTexts } = normalizeAnthropicClientRequest(inputBody);
|
|
3238
2713
|
const activeSessionId = options?.sessionId ?? getActiveSessionId();
|
|
3239
2714
|
const configuredEffort = getConfiguredOutputEffort() ?? options?.outputEffort;
|
|
3240
2715
|
const incomingTools = Array.isArray(body.tools) ? body.tools : [];
|
|
3241
2716
|
const selectedTools = selectOpenCodeNativeTools({
|
|
3242
2717
|
incomingTools,
|
|
3243
|
-
templateTools:
|
|
2718
|
+
templateTools: template.tools
|
|
3244
2719
|
});
|
|
3245
2720
|
body.tools = selectedTools.tools;
|
|
3246
2721
|
const modelId = typeof body.model === "string" ? resolveClaudeCodeModelAlias(body.model) : "";
|
|
@@ -3259,20 +2734,21 @@ function buildUpstreamRequest(inputBody, identity, template2, options) {
|
|
|
3259
2734
|
}
|
|
3260
2735
|
body.max_tokens = resolveMaxTokens(body.max_tokens);
|
|
3261
2736
|
return applyClaudeCodeUpstreamBodyFields(body, {
|
|
3262
|
-
agentIdentity:
|
|
3263
|
-
bodyFieldOrder:
|
|
3264
|
-
|
|
2737
|
+
agentIdentity: template.agent_identity,
|
|
2738
|
+
bodyFieldOrder: template.body_field_order,
|
|
2739
|
+
cacheControl,
|
|
2740
|
+
ccVersion: getCcVersion(template),
|
|
3265
2741
|
firstUserMessage,
|
|
3266
2742
|
identity: {
|
|
3267
2743
|
accountUuid: identity.accountUuid,
|
|
3268
2744
|
deviceId: identity.deviceId
|
|
3269
2745
|
},
|
|
3270
2746
|
sessionId: activeSessionId,
|
|
3271
|
-
systemPrompt: getSystemPromptForModel(
|
|
3272
|
-
systemTexts:
|
|
2747
|
+
systemPrompt: getSystemPromptForModel(template, modelId),
|
|
2748
|
+
systemTexts: filterInjectedSystemTexts(
|
|
3273
2749
|
systemTexts,
|
|
3274
|
-
|
|
3275
|
-
buildBillingHeader(firstUserMessage,
|
|
2750
|
+
template,
|
|
2751
|
+
buildBillingHeader(firstUserMessage, template)
|
|
3276
2752
|
)
|
|
3277
2753
|
});
|
|
3278
2754
|
}
|
|
@@ -3332,7 +2808,7 @@ function createStreamingReverseMapper(response, reverseLookup) {
|
|
|
3332
2808
|
}
|
|
3333
2809
|
|
|
3334
2810
|
// src/tools/flow.ts
|
|
3335
|
-
import { createHash as
|
|
2811
|
+
import { createHash as createHash3 } from "crypto";
|
|
3336
2812
|
var TOOL_MASK_PREFIX = "tool_";
|
|
3337
2813
|
function isRecord4(value) {
|
|
3338
2814
|
return typeof value === "object" && value !== null;
|
|
@@ -3344,7 +2820,7 @@ function shouldMaskToolName(name, claudeToolNames, options) {
|
|
|
3344
2820
|
return !claudeToolNames.has(name) && !name.startsWith("mcp__") && (!options.preserveToolPrefix || !name.startsWith(TOOL_MASK_PREFIX));
|
|
3345
2821
|
}
|
|
3346
2822
|
function buildMaskedToolName(toolName, length = 8) {
|
|
3347
|
-
const digest =
|
|
2823
|
+
const digest = createHash3("sha256").update(`tool-mask:${toolName}`).digest("hex").slice(0, length);
|
|
3348
2824
|
return `${TOOL_MASK_PREFIX}${digest}`;
|
|
3349
2825
|
}
|
|
3350
2826
|
function isOutgoingNameAvailable(name, registry) {
|
|
@@ -3503,13 +2979,13 @@ function applyOutboundToolFlow(parsed, claudeToolNames) {
|
|
|
3503
2979
|
}
|
|
3504
2980
|
|
|
3505
2981
|
// src/request/headers.ts
|
|
3506
|
-
var
|
|
2982
|
+
var STAINLESS_PACKAGE_VERSION = "0.81.0";
|
|
3507
2983
|
var BILLABLE_BETA_PREFIXES = ["extended-cache-ttl-"];
|
|
3508
2984
|
function getStaticHeaders() {
|
|
3509
2985
|
const profile = claudeCodeIntegration.loadRequestProfile();
|
|
3510
2986
|
return createClaudeCodeStaticHeaders({
|
|
3511
2987
|
headerValues: profile.template.header_values,
|
|
3512
|
-
packageVersion:
|
|
2988
|
+
packageVersion: STAINLESS_PACKAGE_VERSION,
|
|
3513
2989
|
userAgent: profile.userAgent,
|
|
3514
2990
|
xApp: profile.xApp
|
|
3515
2991
|
});
|
|
@@ -3527,8 +3003,8 @@ function getBetaHeader() {
|
|
|
3527
3003
|
return claudeCodeIntegration.loadRequestProfile().betaHeader;
|
|
3528
3004
|
}
|
|
3529
3005
|
function orderHeadersForOutbound(headers, overrideHeaderOrder) {
|
|
3530
|
-
const { template
|
|
3531
|
-
return orderClaudeCodeHeadersForOutbound(headers, overrideHeaderOrder ??
|
|
3006
|
+
const { template } = claudeCodeIntegration.loadRequestProfile();
|
|
3007
|
+
return orderClaudeCodeHeadersForOutbound(headers, overrideHeaderOrder ?? template.header_order);
|
|
3532
3008
|
}
|
|
3533
3009
|
function filterBillableBetas(betas) {
|
|
3534
3010
|
return betas.split(",").map((beta) => beta.trim()).filter(
|
|
@@ -3608,13 +3084,13 @@ async function saveObservedToolInventory(inventory) {
|
|
|
3608
3084
|
await fs.chmod(targetPath, FILE_MODE).catch(() => {
|
|
3609
3085
|
});
|
|
3610
3086
|
}
|
|
3611
|
-
async function recordObservedToolNames(
|
|
3612
|
-
if (
|
|
3087
|
+
async function recordObservedToolNames(toolNames) {
|
|
3088
|
+
if (toolNames.length === 0) {
|
|
3613
3089
|
return;
|
|
3614
3090
|
}
|
|
3615
3091
|
const inventory = await loadObservedToolInventory();
|
|
3616
3092
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
3617
|
-
for (const toolName of
|
|
3093
|
+
for (const toolName of toolNames) {
|
|
3618
3094
|
const entry = inventory.observedTools[toolName];
|
|
3619
3095
|
if (!entry) {
|
|
3620
3096
|
inventory.observedTools[toolName] = {
|
|
@@ -3792,17 +3268,17 @@ function transformBodyToUpstream(body, identity, sessionId2, outputEffort) {
|
|
|
3792
3268
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
3793
3269
|
return { body, reverseLookup: /* @__PURE__ */ new Map(), validationError: null };
|
|
3794
3270
|
}
|
|
3795
|
-
const
|
|
3271
|
+
const template = claudeCodeIntegration.loadTemplate();
|
|
3796
3272
|
const upstreamRequest = buildUpstreamRequest(
|
|
3797
3273
|
parsed,
|
|
3798
3274
|
identity,
|
|
3799
|
-
|
|
3275
|
+
template,
|
|
3800
3276
|
{ sessionId: sessionId2, outputEffort }
|
|
3801
3277
|
);
|
|
3802
3278
|
const validationError = getDanglingToolUseError(
|
|
3803
3279
|
Array.isArray(upstreamRequest.messages) ? upstreamRequest.messages : []
|
|
3804
3280
|
);
|
|
3805
|
-
const maskedRequest = applyRequestToolMasking(upstreamRequest,
|
|
3281
|
+
const maskedRequest = applyRequestToolMasking(upstreamRequest, template.tool_names);
|
|
3806
3282
|
return {
|
|
3807
3283
|
...maskedRequest,
|
|
3808
3284
|
validationError
|
|
@@ -4237,7 +3713,7 @@ function getSessionId() {
|
|
|
4237
3713
|
if (process.env.CLAUDE_MULTI_ACCOUNT_TRACE_PLUGIN === "1") {
|
|
4238
3714
|
console.error("[anthropic-multi-account] module loaded");
|
|
4239
3715
|
}
|
|
4240
|
-
function
|
|
3716
|
+
function extractFirstUserText(input) {
|
|
4241
3717
|
try {
|
|
4242
3718
|
const raw = input;
|
|
4243
3719
|
const messages = raw.messages ?? raw.request?.messages;
|
|
@@ -4283,11 +3759,11 @@ var ClaudeMultiAuthPlugin = async (ctx) => {
|
|
|
4283
3759
|
const { client } = ctx;
|
|
4284
3760
|
await loadConfig();
|
|
4285
3761
|
const requestProfile = claudeCodeIntegration.loadRequestProfile();
|
|
4286
|
-
const
|
|
3762
|
+
const template = requestProfile.template;
|
|
4287
3763
|
const claudeIdentity = claudeCodeIntegration.loadIdentity();
|
|
4288
|
-
const claudeCodeVersion =
|
|
4289
|
-
const upstreamAgentIdentity =
|
|
4290
|
-
const upstreamSystemPrompt =
|
|
3764
|
+
const claudeCodeVersion = template.cc_version ?? requestProfile.cliVersion;
|
|
3765
|
+
const upstreamAgentIdentity = template.agent_identity;
|
|
3766
|
+
const upstreamSystemPrompt = template.system_prompt;
|
|
4291
3767
|
let heartbeatHandle = null;
|
|
4292
3768
|
let heartbeatToken = null;
|
|
4293
3769
|
let heartbeatSessionId = null;
|
|
@@ -4318,7 +3794,7 @@ var ClaudeMultiAuthPlugin = async (ctx) => {
|
|
|
4318
3794
|
accessToken
|
|
4319
3795
|
});
|
|
4320
3796
|
};
|
|
4321
|
-
const startupDrift = claudeCodeIntegration.detectDrift(
|
|
3797
|
+
const startupDrift = claudeCodeIntegration.detectDrift(template);
|
|
4322
3798
|
if (startupDrift.drifted) {
|
|
4323
3799
|
client.app.log({
|
|
4324
3800
|
body: {
|
|
@@ -4349,7 +3825,7 @@ var ClaudeMultiAuthPlugin = async (ctx) => {
|
|
|
4349
3825
|
});
|
|
4350
3826
|
}
|
|
4351
3827
|
void claudeCodeIntegration.refreshLiveFingerprint({ silent: true }).then((refreshedTemplate) => {
|
|
4352
|
-
const refreshedDrift = claudeCodeIntegration.detectDrift(refreshedTemplate ??
|
|
3828
|
+
const refreshedDrift = claudeCodeIntegration.detectDrift(refreshedTemplate ?? template);
|
|
4353
3829
|
if (!refreshedDrift.drifted) {
|
|
4354
3830
|
return;
|
|
4355
3831
|
}
|
|
@@ -4525,7 +4001,7 @@ var ClaudeMultiAuthPlugin = async (ctx) => {
|
|
|
4525
4001
|
output.headers[OPENCODE_OUTPUT_EFFORT_HEADER] = outputEffort;
|
|
4526
4002
|
},
|
|
4527
4003
|
"experimental.chat.system.transform": async (input, output) => {
|
|
4528
|
-
const billingHeader = composeBillingSystemEntry(
|
|
4004
|
+
const billingHeader = composeBillingSystemEntry(extractFirstUserText(input), claudeCodeVersion);
|
|
4529
4005
|
prependMissingSystemEntries(output, [
|
|
4530
4006
|
billingHeader,
|
|
4531
4007
|
upstreamAgentIdentity,
|