opencode-anthropic-multi-account 0.2.21 → 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/index.js CHANGED
@@ -25,8 +25,8 @@ import {
25
25
  showToast,
26
26
  sleep,
27
27
  updateConfigField
28
- } from "./chunk-RVXWLAVK.js";
29
- import "./chunk-IETVH43F.js";
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";
@@ -719,7 +719,7 @@ function buildCascadePrompt(input, init) {
719
719
  }
720
720
  function createQueueAwareManager(manager, queue, cascadeStateManager) {
721
721
  return Object.create(manager, {
722
- selectAccount: { value: async function selectAccount() {
722
+ selectAccount: { value: async function selectAccount(stickyKey) {
723
723
  await manager.refresh();
724
724
  while (queue.length > 0) {
725
725
  const next = queue.shift();
@@ -734,7 +734,7 @@ function createQueueAwareManager(manager, queue, cascadeStateManager) {
734
734
  }
735
735
  return account;
736
736
  }
737
- return manager.selectAccount();
737
+ return manager.selectAccount(stickyKey);
738
738
  } }
739
739
  });
740
740
  }
@@ -1758,12 +1758,7 @@ var ADAPTIVE_THINKING_MODEL_MATCHERS = [
1758
1758
  (modelId) => modelId.includes("claude-opus-4-6") || modelId.includes("claude-opus-4.6"),
1759
1759
  (modelId) => /claude-opus-4[-._]([7-9]|\d{2,})/.test(modelId)
1760
1760
  ];
1761
- var LARGE_OUTPUT_MODEL_MATCHERS = [
1762
- (modelId) => modelId.includes("claude-opus-4-6") || modelId.includes("claude-opus-4.6"),
1763
- (modelId) => /claude-opus-4[-._]([7-9]|\d{2,})/.test(modelId)
1764
- ];
1765
1761
  var DEFAULT_MAX_OUTPUT_TOKENS = 64e3;
1766
- var LARGE_MODEL_MAX_OUTPUT_TOKENS = 128e3;
1767
1762
  function normalizeModelId2(modelId) {
1768
1763
  return modelId.trim().toLowerCase();
1769
1764
  }
@@ -1778,16 +1773,11 @@ function supportsAdaptiveThinking(modelId) {
1778
1773
  }
1779
1774
  return ADAPTIVE_THINKING_MODEL_MATCHERS.some((matches) => matches(normalized));
1780
1775
  }
1781
- function getModelMaxOutputTokens(modelId) {
1782
- const runtimeCapability = getRuntimeModelCapability(modelId);
1783
- if (typeof runtimeCapability?.maxOutputTokens === "number") {
1784
- return runtimeCapability.maxOutputTokens;
1785
- }
1786
- const normalized = normalizeModelId2(modelId);
1787
- 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;
1788
1778
  }
1789
- function resolveMaxTokens(modelId, requestedMaxTokens) {
1790
- const modelCap = getModelMaxOutputTokens(modelId);
1779
+ function resolveMaxTokens(requestedMaxTokens) {
1780
+ const modelCap = getModelMaxOutputTokens();
1791
1781
  if (typeof requestedMaxTokens !== "number" || !Number.isFinite(requestedMaxTokens)) {
1792
1782
  return modelCap;
1793
1783
  }
@@ -2036,7 +2026,7 @@ function buildUpstreamRequest(inputBody, identity, template, options) {
2036
2026
  body.context_management = DEFAULT_CONTEXT_MANAGEMENT;
2037
2027
  body.output_config = DEFAULT_OUTPUT_CONFIG;
2038
2028
  }
2039
- body.max_tokens = resolveMaxTokens(modelId, body.max_tokens);
2029
+ body.max_tokens = resolveMaxTokens(body.max_tokens);
2040
2030
  return orderBodyForOutbound(body, template.body_field_order);
2041
2031
  }
2042
2032
  function orderBodyForOutbound(body, overrideOrder) {
@@ -2939,6 +2929,9 @@ var EMPTY_OAUTH_CREDENTIALS = {
2939
2929
  access: "",
2940
2930
  expires: 0
2941
2931
  };
2932
+ if (process.env.CLAUDE_MULTI_ACCOUNT_TRACE_PLUGIN === "1") {
2933
+ console.error("[anthropic-multi-account] module loaded");
2934
+ }
2942
2935
  function extractFirstUserText2(input) {
2943
2936
  try {
2944
2937
  const raw = input;
@@ -2974,6 +2967,9 @@ function applyOrderedHeaders(output, headers) {
2974
2967
  output.headers = Array.isArray(orderedHeaders) ? Object.fromEntries(orderedHeaders) : orderedHeaders;
2975
2968
  }
2976
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
+ }
2977
2973
  const { client } = ctx;
2978
2974
  await loadConfig();
2979
2975
  const requestProfile = loadCCDerivedRequestProfile();
@@ -3070,7 +3066,20 @@ var ClaudeMultiAuthPlugin = async (ctx) => {
3070
3066
  });
3071
3067
  });
3072
3068
  const store = new AccountStore();
3073
- await syncBootstrapAuth(client, store).catch(() => {
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
+ });
3074
3083
  });
3075
3084
  let manager = null;
3076
3085
  let runtimeFactory = null;
@@ -3207,13 +3216,90 @@ var ClaudeMultiAuthPlugin = async (ctx) => {
3207
3216
  { type: "api", label: "Manually enter API Key" }
3208
3217
  ],
3209
3218
  async loader(getAuth, provider) {
3210
- ingestProviderModelsCapabilities(provider.models ?? {});
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
+ });
3211
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
+ });
3212
3232
  if (auth.type !== "oauth") {
3213
- stopHeartbeat();
3214
- return { apiKey: "", fetch };
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
+ };
3215
3301
  }
3216
- for (const model of Object.values(provider.models ?? {})) {
3302
+ for (const model of Object.values(providerModels)) {
3217
3303
  if (model) {
3218
3304
  model.cost = { input: 0, output: 0, cache: { read: 0, write: 0 } };
3219
3305
  }
@@ -3226,6 +3312,10 @@ var ClaudeMultiAuthPlugin = async (ctx) => {
3226
3312
  if (!initializedManager) {
3227
3313
  return { apiKey: "", fetch };
3228
3314
  }
3315
+ debugLog(client, "Auth loader initialized manager state", {
3316
+ accountCount: initializedManager.getAccountCount(),
3317
+ activeAccountUuid: initializedManager.getActiveAccount()?.uuid
3318
+ });
3229
3319
  if (initializedManager.getAccountCount() > 0) {
3230
3320
  const activeAccount = initializedManager.getActiveAccount();
3231
3321
  const activeLabel = activeAccount ? getAccountLabel(activeAccount) : "none";