opencode-anthropic-multi-account 0.2.24 → 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 +133 -170
- 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,7 +1588,7 @@ 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;
|
|
@@ -1806,33 +1810,26 @@ var ADAPTIVE_THINKING_MODEL_MATCHERS = [
|
|
|
1806
1810
|
(modelId) => /claude-opus-4[-._]([7-9]|\d{2,})/.test(modelId)
|
|
1807
1811
|
];
|
|
1808
1812
|
var DEFAULT_MAX_OUTPUT_TOKENS = 32e3;
|
|
1809
|
-
function normalizeModelId2(modelId) {
|
|
1810
|
-
return modelId.trim().toLowerCase();
|
|
1811
|
-
}
|
|
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") {
|
|
@@ -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)) {
|
|
@@ -2150,7 +2147,7 @@ function createStreamingReverseMapper(response, reverseLookup) {
|
|
|
2150
2147
|
});
|
|
2151
2148
|
}
|
|
2152
2149
|
|
|
2153
|
-
// src/
|
|
2150
|
+
// src/tools/flow.ts
|
|
2154
2151
|
import { createHash as createHash3 } from "crypto";
|
|
2155
2152
|
var TOOL_MASK_PREFIX = "tool_";
|
|
2156
2153
|
function isRecord3(value) {
|
|
@@ -2275,7 +2272,7 @@ function applyOutboundToolFlow(parsed, claudeToolNames) {
|
|
|
2275
2272
|
};
|
|
2276
2273
|
}
|
|
2277
2274
|
|
|
2278
|
-
// src/
|
|
2275
|
+
// src/request/headers.ts
|
|
2279
2276
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
2280
2277
|
var UPSTREAM_TIMEOUT_MS = 3e5;
|
|
2281
2278
|
var STAINLESS_PACKAGE_VERSION = "0.81.0";
|
|
@@ -2360,7 +2357,7 @@ function filterBillableBetas(betas) {
|
|
|
2360
2357
|
).join(",");
|
|
2361
2358
|
}
|
|
2362
2359
|
|
|
2363
|
-
// src/request
|
|
2360
|
+
// src/request/transform.ts
|
|
2364
2361
|
function applyRequestToolMasking(parsed, claudeToolNames) {
|
|
2365
2362
|
return applyOutboundToolFlow(parsed, claudeToolNames);
|
|
2366
2363
|
}
|
|
@@ -2407,7 +2404,7 @@ function extractToolNamesFromRequestBody(body) {
|
|
|
2407
2404
|
}
|
|
2408
2405
|
}
|
|
2409
2406
|
|
|
2410
|
-
// src/
|
|
2407
|
+
// src/tools/observation.ts
|
|
2411
2408
|
import { promises as fs } from "fs";
|
|
2412
2409
|
import { dirname, join as join2 } from "path";
|
|
2413
2410
|
var OBSERVED_TOOL_FILE = "anthropic-observed-tools.json";
|
|
@@ -2454,7 +2451,7 @@ async function recordObservedToolNames(toolNames) {
|
|
|
2454
2451
|
await saveObservedToolInventory(inventory);
|
|
2455
2452
|
}
|
|
2456
2453
|
|
|
2457
|
-
// src/error-utils.ts
|
|
2454
|
+
// src/shared/error-utils.ts
|
|
2458
2455
|
function sanitizeError(err) {
|
|
2459
2456
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2460
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]");
|
|
@@ -2498,10 +2495,10 @@ function enrich429(body, headers) {
|
|
|
2498
2495
|
}
|
|
2499
2496
|
}
|
|
2500
2497
|
|
|
2501
|
-
// src/pacing.ts
|
|
2498
|
+
// src/runtime/pacing.ts
|
|
2502
2499
|
function pickNonNegativeInt(...values) {
|
|
2503
2500
|
for (const v4 of values) {
|
|
2504
|
-
if (v4 === void 0
|
|
2501
|
+
if (v4 === void 0) continue;
|
|
2505
2502
|
const n = typeof v4 === "number" ? v4 : Number.parseInt(v4, 10);
|
|
2506
2503
|
if (Number.isFinite(n) && n >= 0) return n;
|
|
2507
2504
|
}
|
|
@@ -2523,7 +2520,7 @@ function resolvePacingConfig(explicit = {}, env = process.env) {
|
|
|
2523
2520
|
return { minGapMs: minGap, jitterMs: jitter };
|
|
2524
2521
|
}
|
|
2525
2522
|
|
|
2526
|
-
// src/runtime
|
|
2523
|
+
// src/runtime/factory.ts
|
|
2527
2524
|
var TOKEN_REFRESH_PERMANENT_FAILURE_STATUS = 401;
|
|
2528
2525
|
function mergeHeaders(target, headers) {
|
|
2529
2526
|
if (!headers) {
|
|
@@ -2840,7 +2837,7 @@ var AccountRuntimeFactory = class {
|
|
|
2840
2837
|
}
|
|
2841
2838
|
};
|
|
2842
2839
|
|
|
2843
|
-
// src/bootstrap
|
|
2840
|
+
// src/oauth/bootstrap.ts
|
|
2844
2841
|
import { promises as fs2 } from "fs";
|
|
2845
2842
|
import { join as join3 } from "path";
|
|
2846
2843
|
import { getConfigDir as getConfigDir2 } from "opencode-multi-account-core";
|
|
@@ -2860,7 +2857,7 @@ function selectBootstrapAccount(accounts, activeAccountUuid) {
|
|
|
2860
2857
|
const firstUsableAccount = completeAccounts.find(
|
|
2861
2858
|
(account) => account.enabled !== false && account.isAuthDisabled !== true
|
|
2862
2859
|
);
|
|
2863
|
-
return firstUsableAccount ?? completeAccounts[0]
|
|
2860
|
+
return firstUsableAccount ?? completeAccounts[0];
|
|
2864
2861
|
}
|
|
2865
2862
|
async function readCurrentAuth(providerId) {
|
|
2866
2863
|
const authPath = join3(getConfigDir2(), AUTH_JSON_FILENAME);
|
|
@@ -3065,6 +3062,52 @@ var ClaudeMultiAuthPlugin = async (ctx) => {
|
|
|
3065
3062
|
accessToken
|
|
3066
3063
|
});
|
|
3067
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
|
+
});
|
|
3068
3111
|
const startupDrift = detectDrift(template);
|
|
3069
3112
|
if (startupDrift.drifted) {
|
|
3070
3113
|
client.app.log({
|
|
@@ -3315,48 +3358,8 @@ var ClaudeMultiAuthPlugin = async (ctx) => {
|
|
|
3315
3358
|
}
|
|
3316
3359
|
const authProfile2 = await loadCCDerivedAuthProfile();
|
|
3317
3360
|
return {
|
|
3318
|
-
|
|
3319
|
-
baseURL: authProfile2.apiV1BaseUrl
|
|
3320
|
-
"chat.headers": async (input, output) => {
|
|
3321
|
-
if (input.provider?.info?.id !== ANTHROPIC_OAUTH_ADAPTER.authProviderId) return;
|
|
3322
|
-
const sessionId2 = getUpstreamSessionId();
|
|
3323
|
-
applyOrderedHeaders(output, {
|
|
3324
|
-
...output.headers,
|
|
3325
|
-
...getStaticHeaders(),
|
|
3326
|
-
...getPerRequestHeaders(sessionId2),
|
|
3327
|
-
"anthropic-beta": getBetaHeader()
|
|
3328
|
-
});
|
|
3329
|
-
},
|
|
3330
|
-
async fetch(input, init) {
|
|
3331
|
-
if (!manager || !runtimeFactory) {
|
|
3332
|
-
stopHeartbeat();
|
|
3333
|
-
return fetch(input, init);
|
|
3334
|
-
}
|
|
3335
|
-
if (manager.getAccountCount() === 0) {
|
|
3336
|
-
stopHeartbeat();
|
|
3337
|
-
throw new Error(
|
|
3338
|
-
"No Anthropic accounts configured. Run `opencode auth login` to add an account."
|
|
3339
|
-
);
|
|
3340
|
-
}
|
|
3341
|
-
ensureHeartbeat(manager.getActiveAccount()?.accessToken);
|
|
3342
|
-
if (!poolManager || !cascadeStateManager) {
|
|
3343
|
-
poolManager = new PoolManager();
|
|
3344
|
-
poolManager.loadPools(poolChainConfig.pools);
|
|
3345
|
-
cascadeStateManager = new CascadeStateManager();
|
|
3346
|
-
}
|
|
3347
|
-
return executeWithAccountRotation(
|
|
3348
|
-
manager,
|
|
3349
|
-
runtimeFactory,
|
|
3350
|
-
client,
|
|
3351
|
-
input,
|
|
3352
|
-
init,
|
|
3353
|
-
{
|
|
3354
|
-
poolManager,
|
|
3355
|
-
cascadeStateManager,
|
|
3356
|
-
poolChainConfig
|
|
3357
|
-
}
|
|
3358
|
-
);
|
|
3359
|
-
}
|
|
3361
|
+
...createAuthLoaderResult(manager),
|
|
3362
|
+
baseURL: authProfile2.apiV1BaseUrl
|
|
3360
3363
|
};
|
|
3361
3364
|
}
|
|
3362
3365
|
for (const model of Object.values(providerModels)) {
|
|
@@ -3396,48 +3399,8 @@ var ClaudeMultiAuthPlugin = async (ctx) => {
|
|
|
3396
3399
|
}
|
|
3397
3400
|
const authProfile = await loadCCDerivedAuthProfile();
|
|
3398
3401
|
return {
|
|
3399
|
-
|
|
3400
|
-
baseURL: authProfile.apiV1BaseUrl
|
|
3401
|
-
"chat.headers": async (input, output) => {
|
|
3402
|
-
if (input.provider?.info?.id !== ANTHROPIC_OAUTH_ADAPTER.authProviderId) return;
|
|
3403
|
-
const sessionId2 = getUpstreamSessionId();
|
|
3404
|
-
applyOrderedHeaders(output, {
|
|
3405
|
-
...output.headers,
|
|
3406
|
-
...getStaticHeaders(),
|
|
3407
|
-
...getPerRequestHeaders(sessionId2),
|
|
3408
|
-
"anthropic-beta": getBetaHeader()
|
|
3409
|
-
});
|
|
3410
|
-
},
|
|
3411
|
-
async fetch(input, init) {
|
|
3412
|
-
if (!initializedManager || !runtimeFactory) {
|
|
3413
|
-
stopHeartbeat();
|
|
3414
|
-
return fetch(input, init);
|
|
3415
|
-
}
|
|
3416
|
-
if (initializedManager.getAccountCount() === 0) {
|
|
3417
|
-
stopHeartbeat();
|
|
3418
|
-
throw new Error(
|
|
3419
|
-
"No Anthropic accounts configured. Run `opencode auth login` to add an account."
|
|
3420
|
-
);
|
|
3421
|
-
}
|
|
3422
|
-
ensureHeartbeat(initializedManager.getActiveAccount()?.accessToken);
|
|
3423
|
-
if (!poolManager || !cascadeStateManager) {
|
|
3424
|
-
poolManager = new PoolManager();
|
|
3425
|
-
poolManager.loadPools(poolChainConfig.pools);
|
|
3426
|
-
cascadeStateManager = new CascadeStateManager();
|
|
3427
|
-
}
|
|
3428
|
-
return executeWithAccountRotation(
|
|
3429
|
-
initializedManager,
|
|
3430
|
-
runtimeFactory,
|
|
3431
|
-
client,
|
|
3432
|
-
input,
|
|
3433
|
-
init,
|
|
3434
|
-
{
|
|
3435
|
-
poolManager,
|
|
3436
|
-
cascadeStateManager,
|
|
3437
|
-
poolChainConfig
|
|
3438
|
-
}
|
|
3439
|
-
);
|
|
3440
|
-
}
|
|
3402
|
+
...createAuthLoaderResult(initializedManager),
|
|
3403
|
+
baseURL: authProfile.apiV1BaseUrl
|
|
3441
3404
|
};
|
|
3442
3405
|
}
|
|
3443
3406
|
}
|