opencode-anthropic-multi-account 0.2.20 → 0.2.22
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-IETVH43F.js → chunk-RAX4SFCO.js} +14 -2
- package/dist/chunk-RAX4SFCO.js.map +1 -0
- package/dist/chunk-TOCJ3XJM.js +2458 -0
- package/dist/chunk-TOCJ3XJM.js.map +1 -0
- package/dist/fingerprint-capture.d.ts +3 -2
- package/dist/fingerprint-capture.js +4 -2
- package/dist/index.js +115 -28
- package/dist/index.js.map +1 -1
- package/dist/scrub-template.js +1 -1
- package/package.json +3 -2
- package/dist/chunk-IETVH43F.js.map +0 -1
- package/dist/chunk-RVXWLAVK.js +0 -1130
- package/dist/chunk-RVXWLAVK.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -25,8 +25,8 @@ import {
|
|
|
25
25
|
showToast,
|
|
26
26
|
sleep,
|
|
27
27
|
updateConfigField
|
|
28
|
-
} from "./chunk-
|
|
29
|
-
import "./chunk-
|
|
28
|
+
} from "./chunk-TOCJ3XJM.js";
|
|
29
|
+
import "./chunk-RAX4SFCO.js";
|
|
30
30
|
|
|
31
31
|
// src/index.ts
|
|
32
32
|
import { tool } from "@opencode-ai/plugin";
|
|
@@ -637,7 +637,6 @@ async function refreshWithOAuth(currentRefreshToken) {
|
|
|
637
637
|
}
|
|
638
638
|
|
|
639
639
|
// src/token.ts
|
|
640
|
-
var PERMANENT_FAILURE_HTTP_STATUSES = /* @__PURE__ */ new Set([400, 401, 403]);
|
|
641
640
|
var PERMANENT_FAILURE_MESSAGE_PATTERNS = [
|
|
642
641
|
/\binvalid_grant\b/i,
|
|
643
642
|
/\binvalid_scope\b/i,
|
|
@@ -660,10 +659,8 @@ async function refreshToken(currentRefreshToken, accountId, client) {
|
|
|
660
659
|
return { ok: true, patch };
|
|
661
660
|
} catch (error) {
|
|
662
661
|
const message = error instanceof Error ? error.message : String(error);
|
|
663
|
-
const statusMatch = message.match(/\b(400|401|403)\b/);
|
|
664
|
-
const hasPermanentStatus = statusMatch !== null && PERMANENT_FAILURE_HTTP_STATUSES.has(Number(statusMatch[1]));
|
|
665
662
|
const hasPermanentMessage = PERMANENT_FAILURE_MESSAGE_PATTERNS.some((pattern) => pattern.test(message));
|
|
666
|
-
const isPermanent =
|
|
663
|
+
const isPermanent = hasPermanentMessage;
|
|
667
664
|
await client.app.log({
|
|
668
665
|
body: {
|
|
669
666
|
service: ANTHROPIC_OAUTH_ADAPTER.serviceLogName,
|
|
@@ -722,7 +719,7 @@ function buildCascadePrompt(input, init) {
|
|
|
722
719
|
}
|
|
723
720
|
function createQueueAwareManager(manager, queue, cascadeStateManager) {
|
|
724
721
|
return Object.create(manager, {
|
|
725
|
-
selectAccount: { value: async function selectAccount() {
|
|
722
|
+
selectAccount: { value: async function selectAccount(stickyKey) {
|
|
726
723
|
await manager.refresh();
|
|
727
724
|
while (queue.length > 0) {
|
|
728
725
|
const next = queue.shift();
|
|
@@ -737,7 +734,7 @@ function createQueueAwareManager(manager, queue, cascadeStateManager) {
|
|
|
737
734
|
}
|
|
738
735
|
return account;
|
|
739
736
|
}
|
|
740
|
-
return manager.selectAccount();
|
|
737
|
+
return manager.selectAccount(stickyKey);
|
|
741
738
|
} }
|
|
742
739
|
});
|
|
743
740
|
}
|
|
@@ -1761,12 +1758,7 @@ var ADAPTIVE_THINKING_MODEL_MATCHERS = [
|
|
|
1761
1758
|
(modelId) => modelId.includes("claude-opus-4-6") || modelId.includes("claude-opus-4.6"),
|
|
1762
1759
|
(modelId) => /claude-opus-4[-._]([7-9]|\d{2,})/.test(modelId)
|
|
1763
1760
|
];
|
|
1764
|
-
var LARGE_OUTPUT_MODEL_MATCHERS = [
|
|
1765
|
-
(modelId) => modelId.includes("claude-opus-4-6") || modelId.includes("claude-opus-4.6"),
|
|
1766
|
-
(modelId) => /claude-opus-4[-._]([7-9]|\d{2,})/.test(modelId)
|
|
1767
|
-
];
|
|
1768
1761
|
var DEFAULT_MAX_OUTPUT_TOKENS = 64e3;
|
|
1769
|
-
var LARGE_MODEL_MAX_OUTPUT_TOKENS = 128e3;
|
|
1770
1762
|
function normalizeModelId2(modelId) {
|
|
1771
1763
|
return modelId.trim().toLowerCase();
|
|
1772
1764
|
}
|
|
@@ -1781,16 +1773,11 @@ function supportsAdaptiveThinking(modelId) {
|
|
|
1781
1773
|
}
|
|
1782
1774
|
return ADAPTIVE_THINKING_MODEL_MATCHERS.some((matches) => matches(normalized));
|
|
1783
1775
|
}
|
|
1784
|
-
function getModelMaxOutputTokens(
|
|
1785
|
-
|
|
1786
|
-
if (typeof runtimeCapability?.maxOutputTokens === "number") {
|
|
1787
|
-
return runtimeCapability.maxOutputTokens;
|
|
1788
|
-
}
|
|
1789
|
-
const normalized = normalizeModelId2(modelId);
|
|
1790
|
-
return LARGE_OUTPUT_MODEL_MATCHERS.some((matches) => matches(normalized)) ? LARGE_MODEL_MAX_OUTPUT_TOKENS : DEFAULT_MAX_OUTPUT_TOKENS;
|
|
1776
|
+
function getModelMaxOutputTokens() {
|
|
1777
|
+
return DEFAULT_MAX_OUTPUT_TOKENS;
|
|
1791
1778
|
}
|
|
1792
|
-
function resolveMaxTokens(
|
|
1793
|
-
const modelCap = getModelMaxOutputTokens(
|
|
1779
|
+
function resolveMaxTokens(requestedMaxTokens) {
|
|
1780
|
+
const modelCap = getModelMaxOutputTokens();
|
|
1794
1781
|
if (typeof requestedMaxTokens !== "number" || !Number.isFinite(requestedMaxTokens)) {
|
|
1795
1782
|
return modelCap;
|
|
1796
1783
|
}
|
|
@@ -2039,7 +2026,7 @@ function buildUpstreamRequest(inputBody, identity, template, options) {
|
|
|
2039
2026
|
body.context_management = DEFAULT_CONTEXT_MANAGEMENT;
|
|
2040
2027
|
body.output_config = DEFAULT_OUTPUT_CONFIG;
|
|
2041
2028
|
}
|
|
2042
|
-
body.max_tokens = resolveMaxTokens(
|
|
2029
|
+
body.max_tokens = resolveMaxTokens(body.max_tokens);
|
|
2043
2030
|
return orderBodyForOutbound(body, template.body_field_order);
|
|
2044
2031
|
}
|
|
2045
2032
|
function orderBodyForOutbound(body, overrideOrder) {
|
|
@@ -2942,6 +2929,9 @@ var EMPTY_OAUTH_CREDENTIALS = {
|
|
|
2942
2929
|
access: "",
|
|
2943
2930
|
expires: 0
|
|
2944
2931
|
};
|
|
2932
|
+
if (process.env.CLAUDE_MULTI_ACCOUNT_TRACE_PLUGIN === "1") {
|
|
2933
|
+
console.error("[anthropic-multi-account] module loaded");
|
|
2934
|
+
}
|
|
2945
2935
|
function extractFirstUserText2(input) {
|
|
2946
2936
|
try {
|
|
2947
2937
|
const raw = input;
|
|
@@ -2977,6 +2967,9 @@ function applyOrderedHeaders(output, headers) {
|
|
|
2977
2967
|
output.headers = Array.isArray(orderedHeaders) ? Object.fromEntries(orderedHeaders) : orderedHeaders;
|
|
2978
2968
|
}
|
|
2979
2969
|
var ClaudeMultiAuthPlugin = async (ctx) => {
|
|
2970
|
+
if (process.env.CLAUDE_MULTI_ACCOUNT_TRACE_PLUGIN === "1") {
|
|
2971
|
+
console.error("[anthropic-multi-account] plugin function called");
|
|
2972
|
+
}
|
|
2980
2973
|
const { client } = ctx;
|
|
2981
2974
|
await loadConfig();
|
|
2982
2975
|
const requestProfile = loadCCDerivedRequestProfile();
|
|
@@ -3073,7 +3066,20 @@ var ClaudeMultiAuthPlugin = async (ctx) => {
|
|
|
3073
3066
|
});
|
|
3074
3067
|
});
|
|
3075
3068
|
const store = new AccountStore();
|
|
3076
|
-
await syncBootstrapAuth(client, store).
|
|
3069
|
+
await syncBootstrapAuth(client, store).then((synced) => {
|
|
3070
|
+
debugLog(client, "Bootstrap auth sync completed", { synced });
|
|
3071
|
+
}).catch((error) => {
|
|
3072
|
+
client.app.log({
|
|
3073
|
+
body: {
|
|
3074
|
+
service: ANTHROPIC_OAUTH_ADAPTER.serviceLogName,
|
|
3075
|
+
level: "debug",
|
|
3076
|
+
message: "bootstrap auth sync failed",
|
|
3077
|
+
extra: {
|
|
3078
|
+
error: sanitizeError(error)
|
|
3079
|
+
}
|
|
3080
|
+
}
|
|
3081
|
+
}).catch(() => {
|
|
3082
|
+
});
|
|
3077
3083
|
});
|
|
3078
3084
|
let manager = null;
|
|
3079
3085
|
let runtimeFactory = null;
|
|
@@ -3210,13 +3216,90 @@ var ClaudeMultiAuthPlugin = async (ctx) => {
|
|
|
3210
3216
|
{ type: "api", label: "Manually enter API Key" }
|
|
3211
3217
|
],
|
|
3212
3218
|
async loader(getAuth, provider) {
|
|
3213
|
-
|
|
3219
|
+
const providerModels = provider.models ?? {};
|
|
3220
|
+
ingestProviderModelsCapabilities(providerModels);
|
|
3221
|
+
debugLog(client, "Auth loader received provider metadata", {
|
|
3222
|
+
providerId: typeof provider.id === "string" ? provider.id : void 0,
|
|
3223
|
+
providerName: typeof provider.name === "string" ? provider.name : void 0,
|
|
3224
|
+
modelCount: Object.keys(providerModels).length,
|
|
3225
|
+
modelIds: Object.keys(providerModels)
|
|
3226
|
+
});
|
|
3214
3227
|
const auth = await getAuth();
|
|
3228
|
+
debugLog(client, "Auth loader resolved auth payload", {
|
|
3229
|
+
authType: typeof auth.type === "string" ? auth.type : void 0,
|
|
3230
|
+
authKeys: Object.keys(auth)
|
|
3231
|
+
});
|
|
3215
3232
|
if (auth.type !== "oauth") {
|
|
3216
|
-
|
|
3217
|
-
|
|
3233
|
+
await syncBootstrapAuth(client, store).then((synced) => {
|
|
3234
|
+
debugLog(client, "Auth loader requested bootstrap auth sync", { synced });
|
|
3235
|
+
}).catch((error) => {
|
|
3236
|
+
client.app.log({
|
|
3237
|
+
body: {
|
|
3238
|
+
service: ANTHROPIC_OAUTH_ADAPTER.serviceLogName,
|
|
3239
|
+
level: "debug",
|
|
3240
|
+
message: "auth loader bootstrap sync failed",
|
|
3241
|
+
extra: {
|
|
3242
|
+
error: sanitizeError(error)
|
|
3243
|
+
}
|
|
3244
|
+
}
|
|
3245
|
+
}).catch(() => {
|
|
3246
|
+
});
|
|
3247
|
+
});
|
|
3248
|
+
const recoveredFromStore = await initializeManagerFromStore();
|
|
3249
|
+
debugLog(client, "Auth loader attempted store recovery", {
|
|
3250
|
+
recoveredFromStore
|
|
3251
|
+
});
|
|
3252
|
+
if (!recoveredFromStore || !manager || !runtimeFactory) {
|
|
3253
|
+
stopHeartbeat();
|
|
3254
|
+
return { apiKey: "", fetch };
|
|
3255
|
+
}
|
|
3256
|
+
const authProfile2 = await loadCCDerivedAuthProfile();
|
|
3257
|
+
return {
|
|
3258
|
+
apiKey: "",
|
|
3259
|
+
baseURL: authProfile2.apiV1BaseUrl,
|
|
3260
|
+
"chat.headers": async (input, output) => {
|
|
3261
|
+
if (input.provider?.info?.id !== ANTHROPIC_OAUTH_ADAPTER.authProviderId) return;
|
|
3262
|
+
const sessionId2 = getUpstreamSessionId();
|
|
3263
|
+
applyOrderedHeaders(output, {
|
|
3264
|
+
...output.headers,
|
|
3265
|
+
...getStaticHeaders(),
|
|
3266
|
+
...getPerRequestHeaders(sessionId2),
|
|
3267
|
+
"anthropic-beta": getBetaHeader()
|
|
3268
|
+
});
|
|
3269
|
+
},
|
|
3270
|
+
async fetch(input, init) {
|
|
3271
|
+
if (!manager || !runtimeFactory) {
|
|
3272
|
+
stopHeartbeat();
|
|
3273
|
+
return fetch(input, init);
|
|
3274
|
+
}
|
|
3275
|
+
if (manager.getAccountCount() === 0) {
|
|
3276
|
+
stopHeartbeat();
|
|
3277
|
+
throw new Error(
|
|
3278
|
+
"No Anthropic accounts configured. Run `opencode auth login` to add an account."
|
|
3279
|
+
);
|
|
3280
|
+
}
|
|
3281
|
+
ensureHeartbeat(manager.getActiveAccount()?.accessToken);
|
|
3282
|
+
if (!poolManager || !cascadeStateManager) {
|
|
3283
|
+
poolManager = new PoolManager();
|
|
3284
|
+
poolManager.loadPools(poolChainConfig.pools);
|
|
3285
|
+
cascadeStateManager = new CascadeStateManager();
|
|
3286
|
+
}
|
|
3287
|
+
return executeWithAccountRotation(
|
|
3288
|
+
manager,
|
|
3289
|
+
runtimeFactory,
|
|
3290
|
+
client,
|
|
3291
|
+
input,
|
|
3292
|
+
init,
|
|
3293
|
+
{
|
|
3294
|
+
poolManager,
|
|
3295
|
+
cascadeStateManager,
|
|
3296
|
+
poolChainConfig
|
|
3297
|
+
}
|
|
3298
|
+
);
|
|
3299
|
+
}
|
|
3300
|
+
};
|
|
3218
3301
|
}
|
|
3219
|
-
for (const model of Object.values(
|
|
3302
|
+
for (const model of Object.values(providerModels)) {
|
|
3220
3303
|
if (model) {
|
|
3221
3304
|
model.cost = { input: 0, output: 0, cache: { read: 0, write: 0 } };
|
|
3222
3305
|
}
|
|
@@ -3229,6 +3312,10 @@ var ClaudeMultiAuthPlugin = async (ctx) => {
|
|
|
3229
3312
|
if (!initializedManager) {
|
|
3230
3313
|
return { apiKey: "", fetch };
|
|
3231
3314
|
}
|
|
3315
|
+
debugLog(client, "Auth loader initialized manager state", {
|
|
3316
|
+
accountCount: initializedManager.getAccountCount(),
|
|
3317
|
+
activeAccountUuid: initializedManager.getActiveAccount()?.uuid
|
|
3318
|
+
});
|
|
3232
3319
|
if (initializedManager.getAccountCount() > 0) {
|
|
3233
3320
|
const activeAccount = initializedManager.getActiveAccount();
|
|
3234
3321
|
const activeLabel = activeAccount ? getAccountLabel(activeAccount) : "none";
|