opencode-anthropic-multi-account 0.2.23 → 0.2.25
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-RAX4SFCO.js → chunk-3CTML5AX.js} +5 -6
- package/dist/chunk-3CTML5AX.js.map +1 -0
- package/dist/{chunk-2SN3UVSM.js → chunk-II7N6KHL.js} +244 -113
- package/dist/chunk-II7N6KHL.js.map +1 -0
- package/dist/fingerprint-capture.d.ts +4 -2
- package/dist/fingerprint-capture.js +4 -2
- package/dist/index.js +140 -174
- package/dist/index.js.map +1 -1
- package/dist/scrub-template.d.ts +13 -3
- package/dist/scrub-template.js +1 -1
- package/package.json +7 -6
- package/dist/chunk-2SN3UVSM.js.map +0 -1
- package/dist/chunk-RAX4SFCO.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -10,11 +10,11 @@ import {
|
|
|
10
10
|
cc_derived_defaults_default,
|
|
11
11
|
checkCCCompat,
|
|
12
12
|
createMinimalClient,
|
|
13
|
+
data_default,
|
|
13
14
|
debugLog,
|
|
14
15
|
detectCliVersion,
|
|
15
16
|
detectDrift,
|
|
16
17
|
detectOAuthConfig,
|
|
17
|
-
fingerprint_data_default,
|
|
18
18
|
formatWaitTime,
|
|
19
19
|
getAccountLabel,
|
|
20
20
|
getConfig,
|
|
@@ -25,11 +25,11 @@ import {
|
|
|
25
25
|
showToast,
|
|
26
26
|
sleep,
|
|
27
27
|
updateConfigField
|
|
28
|
-
} from "./chunk-
|
|
29
|
-
import "./chunk-
|
|
28
|
+
} from "./chunk-II7N6KHL.js";
|
|
29
|
+
import "./chunk-3CTML5AX.js";
|
|
30
30
|
|
|
31
31
|
// src/index.ts
|
|
32
|
-
import { tool } from "@opencode-ai/plugin";
|
|
32
|
+
import { tool } from "@opencode-ai/plugin/tool";
|
|
33
33
|
import {
|
|
34
34
|
CascadeStateManager,
|
|
35
35
|
loadPoolChainConfig,
|
|
@@ -37,10 +37,10 @@ import {
|
|
|
37
37
|
PoolManager
|
|
38
38
|
} from "opencode-multi-account-core";
|
|
39
39
|
|
|
40
|
-
// src/
|
|
40
|
+
// src/accounts/manager.ts
|
|
41
41
|
import { createAccountManagerForProvider } from "opencode-multi-account-core";
|
|
42
42
|
|
|
43
|
-
// src/claims.ts
|
|
43
|
+
// src/accounts/claims.ts
|
|
44
44
|
import { createClaimsManager } from "opencode-multi-account-core";
|
|
45
45
|
var claimsManager = createClaimsManager(CLAIMS_FILENAME);
|
|
46
46
|
var {
|
|
@@ -50,12 +50,12 @@ var {
|
|
|
50
50
|
writeClaim
|
|
51
51
|
} = claimsManager;
|
|
52
52
|
|
|
53
|
-
// src/anthropic-oauth.ts
|
|
53
|
+
// src/oauth/anthropic-oauth.ts
|
|
54
54
|
import { exec } from "child_process";
|
|
55
55
|
import * as v3 from "valibot";
|
|
56
56
|
|
|
57
|
-
// src/
|
|
58
|
-
var bundledTemplate =
|
|
57
|
+
// src/claude-code/derived-profile.ts
|
|
58
|
+
var bundledTemplate = data_default;
|
|
59
59
|
var derivedDefaults = cc_derived_defaults_default;
|
|
60
60
|
var DEFAULT_BASE_API_URL = derivedDefaults.request?.baseApiUrl || "https://api.anthropic.com";
|
|
61
61
|
var DEFAULT_ANTHROPIC_VERSION = bundledTemplate.header_values?.["anthropic-version"] || derivedDefaults.request?.anthropicVersion || "2023-06-01";
|
|
@@ -90,7 +90,7 @@ async function loadCCDerivedAuthProfile() {
|
|
|
90
90
|
};
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
// src/oauth
|
|
93
|
+
// src/oauth/callback-server.ts
|
|
94
94
|
import { createServer } from "http";
|
|
95
95
|
var DEFAULT_TIMEOUT_MS = 3e5;
|
|
96
96
|
var SUCCESS_REDIRECT_URL = "https://platform.claude.com/oauth/code/success?app=claude-code";
|
|
@@ -186,7 +186,7 @@ function startCallbackServer(options) {
|
|
|
186
186
|
});
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
// src/oauth
|
|
189
|
+
// src/oauth/pkce.ts
|
|
190
190
|
import { createHash, randomBytes } from "crypto";
|
|
191
191
|
function base64url(buffer) {
|
|
192
192
|
return buffer.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
@@ -200,7 +200,7 @@ function generateState() {
|
|
|
200
200
|
return base64url(randomBytes(32));
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
// src/token-node-request.ts
|
|
203
|
+
// src/oauth/token-node-request.ts
|
|
204
204
|
import * as childProcess from "child_process";
|
|
205
205
|
function buildNodeTokenRequestScript() {
|
|
206
206
|
return `
|
|
@@ -259,7 +259,7 @@ request.end();
|
|
|
259
259
|
async function defaultRunNodeTokenRequest(options) {
|
|
260
260
|
const script = buildNodeTokenRequestScript();
|
|
261
261
|
const contentType = options.contentType ?? "application/json";
|
|
262
|
-
return
|
|
262
|
+
return new Promise((resolve, reject) => {
|
|
263
263
|
childProcess.execFile(
|
|
264
264
|
options.executable,
|
|
265
265
|
["-e", script],
|
|
@@ -292,13 +292,13 @@ async function defaultRunNodeTokenRequest(options) {
|
|
|
292
292
|
}
|
|
293
293
|
var nodeTokenRequestRunner = defaultRunNodeTokenRequest;
|
|
294
294
|
async function runNodeTokenRequest(options) {
|
|
295
|
-
return
|
|
295
|
+
return nodeTokenRequestRunner(options);
|
|
296
296
|
}
|
|
297
297
|
|
|
298
298
|
// src/usage.ts
|
|
299
299
|
import * as v2 from "valibot";
|
|
300
300
|
|
|
301
|
-
// src/types.ts
|
|
301
|
+
// src/shared/types.ts
|
|
302
302
|
import * as v from "valibot";
|
|
303
303
|
var OAuthCredentialsSchema = v.object({
|
|
304
304
|
type: v.literal("oauth"),
|
|
@@ -461,7 +461,7 @@ function getPlanLabel(account) {
|
|
|
461
461
|
return PLAN_LABELS[account.planTier] ?? account.planTier.charAt(0).toUpperCase() + account.planTier.slice(1);
|
|
462
462
|
}
|
|
463
463
|
|
|
464
|
-
// src/anthropic-oauth.ts
|
|
464
|
+
// src/oauth/anthropic-oauth.ts
|
|
465
465
|
var TOKEN_REQUEST_EXECUTABLE = process.env.OPENCODE_REFRESH_NODE_EXECUTABLE || "node";
|
|
466
466
|
var browserExec = (command, callback) => {
|
|
467
467
|
exec(command, callback);
|
|
@@ -509,6 +509,18 @@ function openBrowser(url) {
|
|
|
509
509
|
} catch {
|
|
510
510
|
}
|
|
511
511
|
}
|
|
512
|
+
function buildAuthorizeUrl(params) {
|
|
513
|
+
const url = new URL(params.authorizeUrl);
|
|
514
|
+
url.searchParams.set("code", "true");
|
|
515
|
+
url.searchParams.set("client_id", params.clientId);
|
|
516
|
+
url.searchParams.set("response_type", "code");
|
|
517
|
+
url.searchParams.set("redirect_uri", params.redirectUri);
|
|
518
|
+
url.searchParams.set("scope", params.scopes);
|
|
519
|
+
url.searchParams.set("code_challenge", params.codeChallenge);
|
|
520
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
521
|
+
url.searchParams.set("state", params.state);
|
|
522
|
+
return url.toString();
|
|
523
|
+
}
|
|
512
524
|
async function postTokenEndpoint(contentType, body, timeoutMs = TOKEN_REFRESH_TIMEOUT_MS, userAgent) {
|
|
513
525
|
const derivedProfile = await loadCCDerivedAuthProfile();
|
|
514
526
|
const oauthConfig = derivedProfile.oauthConfig;
|
|
@@ -561,16 +573,14 @@ async function loginWithOAuth(callbacks) {
|
|
|
561
573
|
const { port, waitForCode, stop } = await callbackServerStarter({ expectedState: state });
|
|
562
574
|
const redirectUri = `http://localhost:${port}/callback`;
|
|
563
575
|
try {
|
|
564
|
-
const authorizeUrl =
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
code_challenge: codeChallenge,
|
|
571
|
-
code_challenge_method: "S256",
|
|
576
|
+
const authorizeUrl = buildAuthorizeUrl({
|
|
577
|
+
authorizeUrl: cfg.authorizeUrl,
|
|
578
|
+
clientId: cfg.clientId,
|
|
579
|
+
scopes: cfg.scopes,
|
|
580
|
+
redirectUri,
|
|
581
|
+
codeChallenge,
|
|
572
582
|
state
|
|
573
|
-
})
|
|
583
|
+
});
|
|
574
584
|
callbacks.onAuth({
|
|
575
585
|
url: authorizeUrl,
|
|
576
586
|
instructions: "Complete authorization in your browser."
|
|
@@ -636,7 +646,7 @@ async function refreshWithOAuth(currentRefreshToken) {
|
|
|
636
646
|
return patch;
|
|
637
647
|
}
|
|
638
648
|
|
|
639
|
-
// src/token.ts
|
|
649
|
+
// src/oauth/token.ts
|
|
640
650
|
var PERMANENT_FAILURE_MESSAGE_PATTERNS = [
|
|
641
651
|
/\binvalid_grant\b/i,
|
|
642
652
|
/\binvalid_scope\b/i,
|
|
@@ -659,8 +669,7 @@ async function refreshToken(currentRefreshToken, accountId, client) {
|
|
|
659
669
|
return { ok: true, patch };
|
|
660
670
|
} catch (error) {
|
|
661
671
|
const message = error instanceof Error ? error.message : String(error);
|
|
662
|
-
const
|
|
663
|
-
const isPermanent = hasPermanentMessage;
|
|
672
|
+
const isPermanent = PERMANENT_FAILURE_MESSAGE_PATTERNS.some((pattern) => pattern.test(message));
|
|
664
673
|
await client.app.log({
|
|
665
674
|
body: {
|
|
666
675
|
service: ANTHROPIC_OAUTH_ADAPTER.serviceLogName,
|
|
@@ -679,7 +688,7 @@ async function refreshToken(currentRefreshToken, accountId, client) {
|
|
|
679
688
|
return refreshPromise;
|
|
680
689
|
}
|
|
681
690
|
|
|
682
|
-
// src/
|
|
691
|
+
// src/accounts/manager.ts
|
|
683
692
|
var AccountManager = createAccountManagerForProvider({
|
|
684
693
|
providerAuthId: "anthropic",
|
|
685
694
|
getConfig,
|
|
@@ -690,10 +699,10 @@ var AccountManager = createAccountManagerForProvider({
|
|
|
690
699
|
writeClaim
|
|
691
700
|
});
|
|
692
701
|
|
|
693
|
-
// src/executor.ts
|
|
702
|
+
// src/runtime/executor.ts
|
|
694
703
|
import { createExecutorForProvider as createExecutorForProvider2, getClearedOAuthBody } from "opencode-multi-account-core";
|
|
695
704
|
|
|
696
|
-
// src/rate-limit.ts
|
|
705
|
+
// src/accounts/rate-limit.ts
|
|
697
706
|
import { createRateLimitHandlers } from "opencode-multi-account-core";
|
|
698
707
|
var {
|
|
699
708
|
fetchUsageLimits,
|
|
@@ -708,7 +717,7 @@ var {
|
|
|
708
717
|
showToast
|
|
709
718
|
});
|
|
710
719
|
|
|
711
|
-
// src/pool-chain
|
|
720
|
+
// src/runtime/pool-chain.ts
|
|
712
721
|
import { createExecutorForProvider } from "opencode-multi-account-core";
|
|
713
722
|
function buildCascadePrompt(input, init) {
|
|
714
723
|
if (typeof init?.body === "string" && init.body.length > 0) {
|
|
@@ -793,7 +802,7 @@ async function executeWithPoolChainRotation(manager, runtimeFactory, poolManager
|
|
|
793
802
|
}
|
|
794
803
|
}
|
|
795
804
|
|
|
796
|
-
// src/executor.ts
|
|
805
|
+
// src/runtime/executor.ts
|
|
797
806
|
var { executeWithAccountRotation: executeWithCoreAccountRotation } = createExecutorForProvider2("Anthropic", {
|
|
798
807
|
handleRateLimitResponse: async (manager, client, account, response) => handleRateLimitResponse(
|
|
799
808
|
manager,
|
|
@@ -845,22 +854,22 @@ async function executeWithAccountRotation(manager, runtimeFactory, client, input
|
|
|
845
854
|
}
|
|
846
855
|
}
|
|
847
856
|
|
|
848
|
-
// src/
|
|
857
|
+
// src/auth-ux/menu/ansi.ts
|
|
849
858
|
import {
|
|
850
859
|
ANSI,
|
|
851
860
|
isTTY,
|
|
852
861
|
parseKey
|
|
853
862
|
} from "opencode-multi-account-core";
|
|
854
863
|
|
|
855
|
-
// src/
|
|
864
|
+
// src/auth-ux/menu/select.ts
|
|
856
865
|
import {
|
|
857
866
|
select
|
|
858
867
|
} from "opencode-multi-account-core";
|
|
859
868
|
|
|
860
|
-
// src/
|
|
869
|
+
// src/auth-ux/menu/confirm.ts
|
|
861
870
|
import { confirm } from "opencode-multi-account-core";
|
|
862
871
|
|
|
863
|
-
// src/
|
|
872
|
+
// src/auth-ux/menu/menu.ts
|
|
864
873
|
function formatRelativeTime(timestamp) {
|
|
865
874
|
if (!timestamp) return "never";
|
|
866
875
|
const days = Math.floor((Date.now() - timestamp) / 864e5);
|
|
@@ -904,12 +913,10 @@ function buildAccountMenuItem(account) {
|
|
|
904
913
|
const label = getAccountLabel(account);
|
|
905
914
|
const status = getAccountStatus(account);
|
|
906
915
|
const badge = STATUS_BADGE[status];
|
|
907
|
-
const fullLabel = `${label} ${badge}`;
|
|
908
916
|
return {
|
|
909
|
-
label:
|
|
917
|
+
label: `${label} ${badge}`,
|
|
910
918
|
hint: account.lastUsed ? `used ${formatRelativeTime(account.lastUsed)}` : "",
|
|
911
|
-
value: account
|
|
912
|
-
disabled: false
|
|
919
|
+
value: account
|
|
913
920
|
};
|
|
914
921
|
}
|
|
915
922
|
async function showAuthMenu(accounts) {
|
|
@@ -1064,7 +1071,7 @@ function printQuotaError(account, error) {
|
|
|
1064
1071
|
`);
|
|
1065
1072
|
}
|
|
1066
1073
|
|
|
1067
|
-
// src/
|
|
1074
|
+
// src/accounts/store.ts
|
|
1068
1075
|
import {
|
|
1069
1076
|
AccountStore as CoreAccountStore
|
|
1070
1077
|
} from "opencode-multi-account-core";
|
|
@@ -1074,9 +1081,8 @@ var AccountStore = class extends CoreAccountStore {
|
|
|
1074
1081
|
}
|
|
1075
1082
|
};
|
|
1076
1083
|
|
|
1077
|
-
// src/auth-handler.ts
|
|
1084
|
+
// src/auth-ux/handler.ts
|
|
1078
1085
|
import { randomUUID } from "crypto";
|
|
1079
|
-
import { exec as exec2 } from "child_process";
|
|
1080
1086
|
function makeFailedFlowResult(message) {
|
|
1081
1087
|
return {
|
|
1082
1088
|
url: "",
|
|
@@ -1162,7 +1168,7 @@ function wrapCallbackWithManagerSync(result, manager) {
|
|
|
1162
1168
|
\u2139\uFE0F Account already exists in multi-auth pool (${countAfter} total).
|
|
1163
1169
|
`);
|
|
1164
1170
|
} else {
|
|
1165
|
-
await persistFallback(auth);
|
|
1171
|
+
await persistFallback(auth, email);
|
|
1166
1172
|
console.log("\n\u2705 Account saved.\n");
|
|
1167
1173
|
}
|
|
1168
1174
|
}
|
|
@@ -1170,12 +1176,13 @@ function wrapCallbackWithManagerSync(result, manager) {
|
|
|
1170
1176
|
}
|
|
1171
1177
|
};
|
|
1172
1178
|
}
|
|
1173
|
-
async function persistFallback(auth) {
|
|
1179
|
+
async function persistFallback(auth, email) {
|
|
1174
1180
|
try {
|
|
1175
1181
|
const store = new AccountStore();
|
|
1176
1182
|
const now2 = Date.now();
|
|
1177
1183
|
const account = {
|
|
1178
1184
|
uuid: randomUUID(),
|
|
1185
|
+
email,
|
|
1179
1186
|
refreshToken: auth.refresh,
|
|
1180
1187
|
accessToken: auth.access,
|
|
1181
1188
|
expiresAt: auth.expires,
|
|
@@ -1350,7 +1357,7 @@ Retrying authentication for ${label}...
|
|
|
1350
1357
|
return { triggerOAuth: false };
|
|
1351
1358
|
}
|
|
1352
1359
|
|
|
1353
|
-
// src/proactive-refresh.ts
|
|
1360
|
+
// src/accounts/proactive-refresh.ts
|
|
1354
1361
|
import { createProactiveRefreshQueueForProvider } from "opencode-multi-account-core";
|
|
1355
1362
|
var ProactiveRefreshQueue = createProactiveRefreshQueueForProvider({
|
|
1356
1363
|
providerAuthId: "anthropic",
|
|
@@ -1360,13 +1367,13 @@ var ProactiveRefreshQueue = createProactiveRefreshQueueForProvider({
|
|
|
1360
1367
|
debugLog
|
|
1361
1368
|
});
|
|
1362
1369
|
|
|
1363
|
-
// src/runtime
|
|
1370
|
+
// src/runtime/factory.ts
|
|
1364
1371
|
import { TokenRefreshError } from "opencode-multi-account-core";
|
|
1365
1372
|
|
|
1366
|
-
// src/request
|
|
1373
|
+
// src/request/transform.ts
|
|
1367
1374
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
1368
1375
|
|
|
1369
|
-
// src/model
|
|
1376
|
+
// src/model/config.ts
|
|
1370
1377
|
function splitBetaFlags(value) {
|
|
1371
1378
|
return value.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
1372
1379
|
}
|
|
@@ -1392,7 +1399,7 @@ function getModelOverride(modelId) {
|
|
|
1392
1399
|
return null;
|
|
1393
1400
|
}
|
|
1394
1401
|
|
|
1395
|
-
// src/betas.ts
|
|
1402
|
+
// src/request/betas.ts
|
|
1396
1403
|
var LONG_CONTEXT_BETAS = config.longContextBetas;
|
|
1397
1404
|
var OAUTH_BETA = "oauth-2025-04-20";
|
|
1398
1405
|
var excludedBetas = /* @__PURE__ */ new Map();
|
|
@@ -1449,8 +1456,8 @@ function supports1mContext(modelId) {
|
|
|
1449
1456
|
if (!versionMatch) {
|
|
1450
1457
|
return false;
|
|
1451
1458
|
}
|
|
1452
|
-
const major = Number.parseInt(versionMatch[2]
|
|
1453
|
-
const minor = Number.parseInt(versionMatch[3]
|
|
1459
|
+
const major = Number.parseInt(versionMatch[2], 10);
|
|
1460
|
+
const minor = Number.parseInt(versionMatch[3], 10);
|
|
1454
1461
|
const effectiveMinor = minor > 99 ? 0 : minor;
|
|
1455
1462
|
return major > 4 || major === 4 && effectiveMinor >= 6;
|
|
1456
1463
|
}
|
|
@@ -1482,7 +1489,7 @@ function getModelBetas(modelId, excluded) {
|
|
|
1482
1489
|
return betas.filter((beta) => !excluded.has(beta));
|
|
1483
1490
|
}
|
|
1484
1491
|
|
|
1485
|
-
// src/claude-identity.ts
|
|
1492
|
+
// src/claude-code/identity.ts
|
|
1486
1493
|
import { readFileSync, readdirSync } from "fs";
|
|
1487
1494
|
import { homedir } from "os";
|
|
1488
1495
|
import { join } from "path";
|
|
@@ -1526,22 +1533,19 @@ function loadClaudeIdentity() {
|
|
|
1526
1533
|
if (testOverrideIdentity) {
|
|
1527
1534
|
return testOverrideIdentity;
|
|
1528
1535
|
}
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
return identity;
|
|
1534
|
-
}
|
|
1536
|
+
for (const path of getCandidatePaths()) {
|
|
1537
|
+
const identity = parseIdentityFile(path);
|
|
1538
|
+
if (identity) {
|
|
1539
|
+
return identity;
|
|
1535
1540
|
}
|
|
1536
|
-
} catch {
|
|
1537
1541
|
}
|
|
1538
1542
|
return EMPTY_IDENTITY;
|
|
1539
1543
|
}
|
|
1540
1544
|
|
|
1541
|
-
// src/upstream-request.ts
|
|
1545
|
+
// src/request/upstream-request.ts
|
|
1542
1546
|
import { createHash as createHash2, randomUUID as randomUUID2 } from "crypto";
|
|
1543
1547
|
|
|
1544
|
-
// src/model
|
|
1548
|
+
// src/model/capabilities.ts
|
|
1545
1549
|
var runtimeModelCapabilities = /* @__PURE__ */ new Map();
|
|
1546
1550
|
function isRecord(value) {
|
|
1547
1551
|
return typeof value === "object" && value !== null;
|
|
@@ -1584,13 +1588,13 @@ function getRuntimeModelCapability(modelId) {
|
|
|
1584
1588
|
return runtimeModelCapabilities.get(normalizeModelId(modelId));
|
|
1585
1589
|
}
|
|
1586
1590
|
|
|
1587
|
-
// src/upstream-request.ts
|
|
1591
|
+
// src/request/upstream-request.ts
|
|
1588
1592
|
var BILLING_SEED = "59cf53e54c78";
|
|
1589
1593
|
var SESSION_IDLE_ROTATE_MS = 15 * 60 * 1e3;
|
|
1590
1594
|
var MAX_TOOL_RESULT_TEXT_LENGTH = 30 * 1024;
|
|
1591
1595
|
var TRUNCATION_SUFFIX = "[...truncated]";
|
|
1592
1596
|
var DEFAULT_CONTEXT_MANAGEMENT = {};
|
|
1593
|
-
var DEFAULT_OUTPUT_CONFIG = {};
|
|
1597
|
+
var DEFAULT_OUTPUT_CONFIG = { effort: "high" };
|
|
1594
1598
|
var ORCHESTRATION_TAG_NAMES = [
|
|
1595
1599
|
"system-reminder",
|
|
1596
1600
|
"env",
|
|
@@ -1805,34 +1809,27 @@ var ADAPTIVE_THINKING_MODEL_MATCHERS = [
|
|
|
1805
1809
|
(modelId) => modelId.includes("claude-opus-4-6") || modelId.includes("claude-opus-4.6"),
|
|
1806
1810
|
(modelId) => /claude-opus-4[-._]([7-9]|\d{2,})/.test(modelId)
|
|
1807
1811
|
];
|
|
1808
|
-
var DEFAULT_MAX_OUTPUT_TOKENS =
|
|
1809
|
-
function normalizeModelId2(modelId) {
|
|
1810
|
-
return modelId.trim().toLowerCase();
|
|
1811
|
-
}
|
|
1812
|
+
var DEFAULT_MAX_OUTPUT_TOKENS = 32e3;
|
|
1812
1813
|
function supportsAdaptiveThinking(modelId) {
|
|
1813
1814
|
const runtimeCapability = getRuntimeModelCapability(modelId);
|
|
1814
1815
|
if (typeof runtimeCapability?.supportsThinking === "boolean") {
|
|
1815
1816
|
return runtimeCapability.supportsThinking;
|
|
1816
1817
|
}
|
|
1817
|
-
const normalized =
|
|
1818
|
+
const normalized = modelId.trim().toLowerCase();
|
|
1818
1819
|
if (normalized.includes("haiku")) {
|
|
1819
1820
|
return false;
|
|
1820
1821
|
}
|
|
1821
1822
|
return ADAPTIVE_THINKING_MODEL_MATCHERS.some((matches) => matches(normalized));
|
|
1822
1823
|
}
|
|
1823
|
-
function getModelMaxOutputTokens() {
|
|
1824
|
-
return DEFAULT_MAX_OUTPUT_TOKENS;
|
|
1825
|
-
}
|
|
1826
1824
|
function resolveMaxTokens(requestedMaxTokens) {
|
|
1827
|
-
const modelCap = getModelMaxOutputTokens();
|
|
1828
1825
|
if (typeof requestedMaxTokens !== "number" || !Number.isFinite(requestedMaxTokens)) {
|
|
1829
|
-
return
|
|
1826
|
+
return DEFAULT_MAX_OUTPUT_TOKENS;
|
|
1830
1827
|
}
|
|
1831
1828
|
const normalized = Math.floor(requestedMaxTokens);
|
|
1832
1829
|
if (normalized <= 0) {
|
|
1833
|
-
return
|
|
1830
|
+
return DEFAULT_MAX_OUTPUT_TOKENS;
|
|
1834
1831
|
}
|
|
1835
|
-
return Math.min(normalized,
|
|
1832
|
+
return Math.min(normalized, DEFAULT_MAX_OUTPUT_TOKENS);
|
|
1836
1833
|
}
|
|
1837
1834
|
function normalizeSystemTexts(system) {
|
|
1838
1835
|
if (typeof system === "string") {
|
|
@@ -1912,7 +1909,7 @@ function getCcVersion(template) {
|
|
|
1912
1909
|
function buildBillingHeader(firstUserMessage, template) {
|
|
1913
1910
|
const version = getCcVersion(template);
|
|
1914
1911
|
const buildTag = computeBuildTag(firstUserMessage, version);
|
|
1915
|
-
return `x-anthropic-billing-header: cc_version=${version}.${buildTag}; cc_entrypoint=cli; cch=00000;`;
|
|
1912
|
+
return `x-anthropic-billing-header: cc_version=${version}.${buildTag}; cc_entrypoint=sdk-cli; cch=00000;`;
|
|
1916
1913
|
}
|
|
1917
1914
|
function truncateToolResultText(text) {
|
|
1918
1915
|
if (text.length <= MAX_TOOL_RESULT_TEXT_LENGTH) {
|
|
@@ -1927,7 +1924,7 @@ function getReverseName(name, reverseLookup) {
|
|
|
1927
1924
|
if (reverseLookup instanceof Map) {
|
|
1928
1925
|
return reverseLookup.get(name) ?? name;
|
|
1929
1926
|
}
|
|
1930
|
-
return typeof reverseLookup[name] === "string" ?
|
|
1927
|
+
return typeof reverseLookup[name] === "string" ? reverseLookup[name] : name;
|
|
1931
1928
|
}
|
|
1932
1929
|
function reverseMapToolUseNames(value, reverseLookup) {
|
|
1933
1930
|
if (Array.isArray(value)) {
|
|
@@ -1981,6 +1978,9 @@ function sanitizeMessages(body) {
|
|
|
1981
1978
|
block.text = sanitizeContent(block.text);
|
|
1982
1979
|
}
|
|
1983
1980
|
}
|
|
1981
|
+
message.content = message.content.filter((block) => {
|
|
1982
|
+
return !isRecord2(block) || block.type !== "text" || block.text !== "";
|
|
1983
|
+
});
|
|
1984
1984
|
}
|
|
1985
1985
|
}
|
|
1986
1986
|
function scrubFrameworkIdentifiers(text) {
|
|
@@ -2147,7 +2147,7 @@ function createStreamingReverseMapper(response, reverseLookup) {
|
|
|
2147
2147
|
});
|
|
2148
2148
|
}
|
|
2149
2149
|
|
|
2150
|
-
// src/
|
|
2150
|
+
// src/tools/flow.ts
|
|
2151
2151
|
import { createHash as createHash3 } from "crypto";
|
|
2152
2152
|
var TOOL_MASK_PREFIX = "tool_";
|
|
2153
2153
|
function isRecord3(value) {
|
|
@@ -2272,7 +2272,7 @@ function applyOutboundToolFlow(parsed, claudeToolNames) {
|
|
|
2272
2272
|
};
|
|
2273
2273
|
}
|
|
2274
2274
|
|
|
2275
|
-
// src/
|
|
2275
|
+
// src/request/headers.ts
|
|
2276
2276
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
2277
2277
|
var UPSTREAM_TIMEOUT_MS = 3e5;
|
|
2278
2278
|
var STAINLESS_PACKAGE_VERSION = "0.81.0";
|
|
@@ -2357,7 +2357,7 @@ function filterBillableBetas(betas) {
|
|
|
2357
2357
|
).join(",");
|
|
2358
2358
|
}
|
|
2359
2359
|
|
|
2360
|
-
// src/request
|
|
2360
|
+
// src/request/transform.ts
|
|
2361
2361
|
function applyRequestToolMasking(parsed, claudeToolNames) {
|
|
2362
2362
|
return applyOutboundToolFlow(parsed, claudeToolNames);
|
|
2363
2363
|
}
|
|
@@ -2404,7 +2404,7 @@ function extractToolNamesFromRequestBody(body) {
|
|
|
2404
2404
|
}
|
|
2405
2405
|
}
|
|
2406
2406
|
|
|
2407
|
-
// src/
|
|
2407
|
+
// src/tools/observation.ts
|
|
2408
2408
|
import { promises as fs } from "fs";
|
|
2409
2409
|
import { dirname, join as join2 } from "path";
|
|
2410
2410
|
var OBSERVED_TOOL_FILE = "anthropic-observed-tools.json";
|
|
@@ -2451,7 +2451,7 @@ async function recordObservedToolNames(toolNames) {
|
|
|
2451
2451
|
await saveObservedToolInventory(inventory);
|
|
2452
2452
|
}
|
|
2453
2453
|
|
|
2454
|
-
// src/error-utils.ts
|
|
2454
|
+
// src/shared/error-utils.ts
|
|
2455
2455
|
function sanitizeError(err) {
|
|
2456
2456
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2457
2457
|
return msg.replace(/sk-ant-[a-zA-Z0-9_-]+/g, "[REDACTED]").replace(/eyJ[a-zA-Z0-9_-]+\.eyJ[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+/g, "[REDACTED_JWT]").replace(/Bearer\s+[^\s,;]+/gi, "Bearer [REDACTED]");
|
|
@@ -2495,10 +2495,10 @@ function enrich429(body, headers) {
|
|
|
2495
2495
|
}
|
|
2496
2496
|
}
|
|
2497
2497
|
|
|
2498
|
-
// src/pacing.ts
|
|
2498
|
+
// src/runtime/pacing.ts
|
|
2499
2499
|
function pickNonNegativeInt(...values) {
|
|
2500
2500
|
for (const v4 of values) {
|
|
2501
|
-
if (v4 === void 0
|
|
2501
|
+
if (v4 === void 0) continue;
|
|
2502
2502
|
const n = typeof v4 === "number" ? v4 : Number.parseInt(v4, 10);
|
|
2503
2503
|
if (Number.isFinite(n) && n >= 0) return n;
|
|
2504
2504
|
}
|
|
@@ -2520,7 +2520,7 @@ function resolvePacingConfig(explicit = {}, env = process.env) {
|
|
|
2520
2520
|
return { minGapMs: minGap, jitterMs: jitter };
|
|
2521
2521
|
}
|
|
2522
2522
|
|
|
2523
|
-
// src/runtime
|
|
2523
|
+
// src/runtime/factory.ts
|
|
2524
2524
|
var TOKEN_REFRESH_PERMANENT_FAILURE_STATUS = 401;
|
|
2525
2525
|
function mergeHeaders(target, headers) {
|
|
2526
2526
|
if (!headers) {
|
|
@@ -2837,7 +2837,7 @@ var AccountRuntimeFactory = class {
|
|
|
2837
2837
|
}
|
|
2838
2838
|
};
|
|
2839
2839
|
|
|
2840
|
-
// src/bootstrap
|
|
2840
|
+
// src/oauth/bootstrap.ts
|
|
2841
2841
|
import { promises as fs2 } from "fs";
|
|
2842
2842
|
import { join as join3 } from "path";
|
|
2843
2843
|
import { getConfigDir as getConfigDir2 } from "opencode-multi-account-core";
|
|
@@ -2857,7 +2857,7 @@ function selectBootstrapAccount(accounts, activeAccountUuid) {
|
|
|
2857
2857
|
const firstUsableAccount = completeAccounts.find(
|
|
2858
2858
|
(account) => account.enabled !== false && account.isAuthDisabled !== true
|
|
2859
2859
|
);
|
|
2860
|
-
return firstUsableAccount ?? completeAccounts[0]
|
|
2860
|
+
return firstUsableAccount ?? completeAccounts[0];
|
|
2861
2861
|
}
|
|
2862
2862
|
async function readCurrentAuth(providerId) {
|
|
2863
2863
|
const authPath = join3(getConfigDir2(), AUTH_JSON_FILENAME);
|
|
@@ -3009,7 +3009,7 @@ function extractFirstUserText(input) {
|
|
|
3009
3009
|
}
|
|
3010
3010
|
function composeBillingSystemEntry(firstUserMessage, version) {
|
|
3011
3011
|
const buildTag = computeBuildTag(firstUserMessage, version);
|
|
3012
|
-
return `x-anthropic-billing-header: cc_version=${version}.${buildTag}; cc_entrypoint=cli; cch=00000;`;
|
|
3012
|
+
return `x-anthropic-billing-header: cc_version=${version}.${buildTag}; cc_entrypoint=sdk-cli; cch=00000;`;
|
|
3013
3013
|
}
|
|
3014
3014
|
function prependMissingSystemEntries(output, entries) {
|
|
3015
3015
|
output.system ??= [];
|
|
@@ -3062,6 +3062,52 @@ var ClaudeMultiAuthPlugin = async (ctx) => {
|
|
|
3062
3062
|
accessToken
|
|
3063
3063
|
});
|
|
3064
3064
|
};
|
|
3065
|
+
const ensurePoolInfrastructure = () => {
|
|
3066
|
+
if (!poolManager || !cascadeStateManager) {
|
|
3067
|
+
poolManager = new PoolManager();
|
|
3068
|
+
poolManager.loadPools(poolChainConfig.pools);
|
|
3069
|
+
cascadeStateManager = new CascadeStateManager();
|
|
3070
|
+
}
|
|
3071
|
+
};
|
|
3072
|
+
const createAuthLoaderResult = (activeManager) => ({
|
|
3073
|
+
apiKey: "",
|
|
3074
|
+
"chat.headers": async (input, output) => {
|
|
3075
|
+
if (input.provider?.info?.id !== ANTHROPIC_OAUTH_ADAPTER.authProviderId) return;
|
|
3076
|
+
const sessionId2 = getUpstreamSessionId();
|
|
3077
|
+
applyOrderedHeaders(output, {
|
|
3078
|
+
...output.headers,
|
|
3079
|
+
...getStaticHeaders(),
|
|
3080
|
+
...getPerRequestHeaders(sessionId2),
|
|
3081
|
+
"anthropic-beta": getBetaHeader()
|
|
3082
|
+
});
|
|
3083
|
+
},
|
|
3084
|
+
async fetch(input, init) {
|
|
3085
|
+
if (!activeManager || !runtimeFactory) {
|
|
3086
|
+
stopHeartbeat();
|
|
3087
|
+
return fetch(input, init);
|
|
3088
|
+
}
|
|
3089
|
+
if (activeManager.getAccountCount() === 0) {
|
|
3090
|
+
stopHeartbeat();
|
|
3091
|
+
throw new Error(
|
|
3092
|
+
"No Anthropic accounts configured. Run `opencode auth login` to add an account."
|
|
3093
|
+
);
|
|
3094
|
+
}
|
|
3095
|
+
ensureHeartbeat(activeManager.getActiveAccount()?.accessToken);
|
|
3096
|
+
ensurePoolInfrastructure();
|
|
3097
|
+
return executeWithAccountRotation(
|
|
3098
|
+
activeManager,
|
|
3099
|
+
runtimeFactory,
|
|
3100
|
+
client,
|
|
3101
|
+
input,
|
|
3102
|
+
init,
|
|
3103
|
+
{
|
|
3104
|
+
poolManager,
|
|
3105
|
+
cascadeStateManager,
|
|
3106
|
+
poolChainConfig
|
|
3107
|
+
}
|
|
3108
|
+
);
|
|
3109
|
+
}
|
|
3110
|
+
});
|
|
3065
3111
|
const startupDrift = detectDrift(template);
|
|
3066
3112
|
if (startupDrift.drifted) {
|
|
3067
3113
|
client.app.log({
|
|
@@ -3312,48 +3358,8 @@ var ClaudeMultiAuthPlugin = async (ctx) => {
|
|
|
3312
3358
|
}
|
|
3313
3359
|
const authProfile2 = await loadCCDerivedAuthProfile();
|
|
3314
3360
|
return {
|
|
3315
|
-
|
|
3316
|
-
baseURL: authProfile2.apiV1BaseUrl
|
|
3317
|
-
"chat.headers": async (input, output) => {
|
|
3318
|
-
if (input.provider?.info?.id !== ANTHROPIC_OAUTH_ADAPTER.authProviderId) return;
|
|
3319
|
-
const sessionId2 = getUpstreamSessionId();
|
|
3320
|
-
applyOrderedHeaders(output, {
|
|
3321
|
-
...output.headers,
|
|
3322
|
-
...getStaticHeaders(),
|
|
3323
|
-
...getPerRequestHeaders(sessionId2),
|
|
3324
|
-
"anthropic-beta": getBetaHeader()
|
|
3325
|
-
});
|
|
3326
|
-
},
|
|
3327
|
-
async fetch(input, init) {
|
|
3328
|
-
if (!manager || !runtimeFactory) {
|
|
3329
|
-
stopHeartbeat();
|
|
3330
|
-
return fetch(input, init);
|
|
3331
|
-
}
|
|
3332
|
-
if (manager.getAccountCount() === 0) {
|
|
3333
|
-
stopHeartbeat();
|
|
3334
|
-
throw new Error(
|
|
3335
|
-
"No Anthropic accounts configured. Run `opencode auth login` to add an account."
|
|
3336
|
-
);
|
|
3337
|
-
}
|
|
3338
|
-
ensureHeartbeat(manager.getActiveAccount()?.accessToken);
|
|
3339
|
-
if (!poolManager || !cascadeStateManager) {
|
|
3340
|
-
poolManager = new PoolManager();
|
|
3341
|
-
poolManager.loadPools(poolChainConfig.pools);
|
|
3342
|
-
cascadeStateManager = new CascadeStateManager();
|
|
3343
|
-
}
|
|
3344
|
-
return executeWithAccountRotation(
|
|
3345
|
-
manager,
|
|
3346
|
-
runtimeFactory,
|
|
3347
|
-
client,
|
|
3348
|
-
input,
|
|
3349
|
-
init,
|
|
3350
|
-
{
|
|
3351
|
-
poolManager,
|
|
3352
|
-
cascadeStateManager,
|
|
3353
|
-
poolChainConfig
|
|
3354
|
-
}
|
|
3355
|
-
);
|
|
3356
|
-
}
|
|
3361
|
+
...createAuthLoaderResult(manager),
|
|
3362
|
+
baseURL: authProfile2.apiV1BaseUrl
|
|
3357
3363
|
};
|
|
3358
3364
|
}
|
|
3359
3365
|
for (const model of Object.values(providerModels)) {
|
|
@@ -3393,48 +3399,8 @@ var ClaudeMultiAuthPlugin = async (ctx) => {
|
|
|
3393
3399
|
}
|
|
3394
3400
|
const authProfile = await loadCCDerivedAuthProfile();
|
|
3395
3401
|
return {
|
|
3396
|
-
|
|
3397
|
-
baseURL: authProfile.apiV1BaseUrl
|
|
3398
|
-
"chat.headers": async (input, output) => {
|
|
3399
|
-
if (input.provider?.info?.id !== ANTHROPIC_OAUTH_ADAPTER.authProviderId) return;
|
|
3400
|
-
const sessionId2 = getUpstreamSessionId();
|
|
3401
|
-
applyOrderedHeaders(output, {
|
|
3402
|
-
...output.headers,
|
|
3403
|
-
...getStaticHeaders(),
|
|
3404
|
-
...getPerRequestHeaders(sessionId2),
|
|
3405
|
-
"anthropic-beta": getBetaHeader()
|
|
3406
|
-
});
|
|
3407
|
-
},
|
|
3408
|
-
async fetch(input, init) {
|
|
3409
|
-
if (!initializedManager || !runtimeFactory) {
|
|
3410
|
-
stopHeartbeat();
|
|
3411
|
-
return fetch(input, init);
|
|
3412
|
-
}
|
|
3413
|
-
if (initializedManager.getAccountCount() === 0) {
|
|
3414
|
-
stopHeartbeat();
|
|
3415
|
-
throw new Error(
|
|
3416
|
-
"No Anthropic accounts configured. Run `opencode auth login` to add an account."
|
|
3417
|
-
);
|
|
3418
|
-
}
|
|
3419
|
-
ensureHeartbeat(initializedManager.getActiveAccount()?.accessToken);
|
|
3420
|
-
if (!poolManager || !cascadeStateManager) {
|
|
3421
|
-
poolManager = new PoolManager();
|
|
3422
|
-
poolManager.loadPools(poolChainConfig.pools);
|
|
3423
|
-
cascadeStateManager = new CascadeStateManager();
|
|
3424
|
-
}
|
|
3425
|
-
return executeWithAccountRotation(
|
|
3426
|
-
initializedManager,
|
|
3427
|
-
runtimeFactory,
|
|
3428
|
-
client,
|
|
3429
|
-
input,
|
|
3430
|
-
init,
|
|
3431
|
-
{
|
|
3432
|
-
poolManager,
|
|
3433
|
-
cascadeStateManager,
|
|
3434
|
-
poolChainConfig
|
|
3435
|
-
}
|
|
3436
|
-
);
|
|
3437
|
-
}
|
|
3402
|
+
...createAuthLoaderResult(initializedManager),
|
|
3403
|
+
baseURL: authProfile.apiV1BaseUrl
|
|
3438
3404
|
};
|
|
3439
3405
|
}
|
|
3440
3406
|
}
|