@cortexkit/anthropic-auth-core 1.21.0 → 1.22.0

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @cortexkit/anthropic-auth-core
2
2
 
3
- Shared Anthropic OAuth, stable account identity, quota, host-local quota feed, routing, cache, cache-keepalive, fast mode, relay, dump, and request-signing helpers used by CortexKit's OpenCode and Pi integrations.
3
+ Shared Anthropic OAuth, stable account identity, optional Claustrum fallback-custody primitives, model metadata, quota, host-local quota feed, routing, cache, cache-keepalive, fast mode, relay, dump, request-signing, thinking-binding, and Fable 5.1 mid-conversation effort helpers used by CortexKit's OpenCode and Pi integrations.
4
4
 
5
5
  User-facing packages:
6
6
 
@@ -4,6 +4,10 @@ export declare const ACCOUNT_FILE_NAME = "anthropic-auth.json";
4
4
  export declare const ACCOUNT_STATE_FILE_NAME = "anthropic-auth-state.json";
5
5
  export declare const QUOTA_URL = "https://api.anthropic.com/api/oauth/usage";
6
6
  export type QuotaWindowName = 'five_hour' | 'seven_day';
7
+ export declare const QUOTA_FIELD_NAMES: readonly ['five_hour', 'seven_day', 'scoped', 'extraUsage', 'bindingWindow', 'fallbackAdvised'];
8
+ export type QuotaFieldName = (typeof QUOTA_FIELD_NAMES)[number];
9
+ export type QuotaFieldSource = 'poll' | 'headers';
10
+ export type QuotaFieldSources = Partial<Record<QuotaFieldName, QuotaFieldSource>>;
7
11
  export type AccountBase = {
8
12
  id: string;
9
13
  label?: string;
@@ -14,6 +18,7 @@ export type AccountBase = {
14
18
  export type OAuthAccount = AccountBase & {
15
19
  type: 'oauth';
16
20
  authLineageId?: string;
21
+ claustrumHandle?: string;
17
22
  access?: string;
18
23
  refresh: string;
19
24
  expires?: number;
@@ -35,6 +40,12 @@ export type ApiKeyAccount = AccountBase & {
35
40
  authHeader?: 'authorization-bearer' | 'x-api-key';
36
41
  };
37
42
  export type FallbackAccount = OAuthAccount | ApiKeyAccount;
43
+ export type ClaustrumAccountGate = {
44
+ enabled?: boolean;
45
+ };
46
+ export type ClaustrumConfig = {
47
+ accounts?: Record<string, ClaustrumAccountGate>;
48
+ };
38
49
  export declare function isOAuthAccount(account: FallbackAccount): account is OAuthAccount;
39
50
  export declare function isApiKeyAccount(account: FallbackAccount): account is ApiKeyAccount;
40
51
  export declare function isValidApiBaseURL(value: string | undefined): boolean;
@@ -45,6 +56,8 @@ export type AccountOperationError = {
45
56
  retryCount?: number;
46
57
  accountIdentity?: string;
47
58
  tokenHash?: string;
59
+ /** Fingerprint of the refresh token that produced this error. */
60
+ refreshTokenFingerprint?: string;
48
61
  /**
49
62
  * HTTP status of the underlying refresh/quota failure, when known. Lets
50
63
  * consumers distinguish a permanently-dead token (400 invalid_grant →
@@ -101,6 +114,7 @@ export type OAuthQuotaSnapshot = Partial<Record<QuotaWindowName, AccountQuotaWin
101
114
  extraUsage?: OAuthExtraUsageSnapshot;
102
115
  bindingWindow?: string;
103
116
  bindingWindowSource?: 'poll' | 'headers';
117
+ fieldSources?: QuotaFieldSources;
104
118
  fallbackAdvised?: boolean;
105
119
  source?: 'poll' | 'headers';
106
120
  checkedAt?: number;
@@ -152,6 +166,7 @@ export type AccountStorage = {
152
166
  intervalMinutes?: number;
153
167
  refreshBeforeExpiryMinutes?: number;
154
168
  mainLastRefreshError?: AccountOperationError;
169
+ mainRefreshErrorClearedAt?: number;
155
170
  mainRefreshLeaseId?: string;
156
171
  mainRefreshLeaseUntil?: number;
157
172
  mainRefreshLeaseTokenHash?: string;
@@ -187,6 +202,9 @@ export type AccountStorage = {
187
202
  claudeFast?: {
188
203
  enabled?: boolean;
189
204
  };
205
+ thinkingBinding?: {
206
+ prefixMismatchBehavior?: 'account-default' | 'error' | 'drop_block';
207
+ };
190
208
  /**
191
209
  * Zero out Anthropic OAuth model costs in the provider hook. Default: enabled
192
210
  * (OAuth usage is quota-based, not per-token billed, so costs show as $0).
@@ -216,6 +234,7 @@ export type AccountStorage = {
216
234
  fallbackToDirect?: boolean;
217
235
  transport?: 'http' | 'websocket';
218
236
  };
237
+ claustrum?: ClaustrumConfig;
219
238
  killswitch?: KillswitchConfig;
220
239
  accounts: FallbackAccount[];
221
240
  };
@@ -225,7 +244,7 @@ export type AccountStorage = {
225
244
  * (to display the provider's real model costs).
226
245
  */
227
246
  export declare function isCostZeroingEnabled(storage: Pick<AccountStorage, 'costZeroing'>): boolean;
228
- export type AccountRuntimeEntry = Partial<Pick<OAuthAccount, 'access' | 'authLineageId' | 'refresh' | 'expires' | 'lastUsed' | 'lastRefreshedAt' | 'lastRefreshError' | 'lastQuotaRefreshError' | 'quota' | 'profile' | 'prime'> & Pick<ApiKeyAccount, 'apiKey' | 'lastUsed'>>;
247
+ export type AccountRuntimeEntry = Partial<Pick<OAuthAccount, 'access' | 'authLineageId' | 'claustrumHandle' | 'refresh' | 'expires' | 'lastUsed' | 'lastRefreshedAt' | 'lastRefreshError' | 'lastQuotaRefreshError' | 'quota' | 'profile' | 'prime'> & Pick<ApiKeyAccount, 'apiKey' | 'lastUsed'>>;
229
248
  export type AccountRuntimeState = {
230
249
  version: 1;
231
250
  main?: {
@@ -238,6 +257,7 @@ export type AccountRuntimeState = {
238
257
  quotaErrorGeneration?: number;
239
258
  quotaErrorClearedAt?: number;
240
259
  lastRefreshError?: AccountOperationError;
260
+ refreshErrorClearedAt?: number;
241
261
  refreshLeaseId?: string;
242
262
  refreshLeaseUntil?: number;
243
263
  refreshLeaseTokenHash?: string;
@@ -259,6 +279,13 @@ export type AccountManagerOptions = {
259
279
  fetchImpl?: typeof fetch;
260
280
  configPath?: string;
261
281
  quotaManager?: import('./quota-manager.ts').QuotaManager;
282
+ isFallbackAccountVaultServed?: (accountId: string, storage: AccountStorage) => boolean;
283
+ isFallbackAccountVaultEnabled?: (accountId: string, storage: AccountStorage) => boolean;
284
+ resolveFallbackAccessToken?: (account: OAuthAccount, storage: AccountStorage) => {
285
+ token: string;
286
+ source: 'vault' | 'sidecar';
287
+ } | undefined;
288
+ onBackgroundRefresh?: (initial?: boolean) => Promise<void> | void;
262
289
  onFallbackStorageChanged?: () => void;
263
290
  setIntervalImpl?: typeof globalThis.setInterval;
264
291
  clearIntervalImpl?: typeof globalThis.clearInterval;
@@ -267,14 +294,18 @@ export type AccountRefreshError = {
267
294
  accountId: string;
268
295
  message: string;
269
296
  };
297
+ export declare const FALLBACK_BACKGROUND_TICK_MS = 60000;
270
298
  export declare function getAccountStoragePath(): string;
271
299
  export declare function getAccountStatePath(configPath?: string): string;
272
300
  export declare function createEmptyStorage(): AccountStorage;
273
301
  export declare function mergeMainQuotaErrorClearedAt(existing: number | undefined, incoming: number | undefined): number | undefined;
302
+ export declare function mergeMainRefreshErrorClearedAt(existing: number | undefined, incoming: number | undefined): number | undefined;
274
303
  export declare function loadAccounts(path?: string): Promise<AccountStorage | null>;
275
304
  /** Returns the latest timestamp carried by any quota snapshot window. */
276
305
  export declare function quotaSnapshotCheckedAt(quota: OAuthQuotaSnapshot | undefined): number;
306
+ export declare function quotaFieldSource(snapshot: OAuthQuotaSnapshot | undefined, field: QuotaFieldName): QuotaFieldSource | undefined;
277
307
  export declare function mergeHeaderQuotaForPersistence(existing: OAuthQuotaSnapshot | undefined, incoming: OAuthQuotaSnapshot): OAuthQuotaSnapshot;
308
+ export declare function isClaustrumEnabledForAccount(storage: AccountStorage, accountId: string): boolean;
278
309
  export interface SaveAccountsOptions {
279
310
  /** Account ids intentionally removed by this mutation. */
280
311
  removedAccountIds?: readonly string[];
@@ -289,6 +320,7 @@ export declare function saveOAuthProfileState(input: {
289
320
  profile: OAuthAccountProfile | undefined;
290
321
  accountIdentity?: string;
291
322
  }, path?: string): Promise<boolean>;
323
+ export declare function clearClaustrumRefreshErrorPersistent(accountId: string, handle: string, path?: string): Promise<boolean>;
292
324
  export declare function acquireRefreshFileLock(options: {
293
325
  name: string;
294
326
  ttlMs: number;
@@ -331,12 +363,14 @@ export declare function getQuotaMinimumRemainingThresholds(storage: AccountStora
331
363
  five_hour: number;
332
364
  seven_day: number;
333
365
  };
366
+ export declare function getRefreshBeforeExpiryMs(storage: AccountStorage | null): number;
334
367
  export declare function getRefreshIntervalMs(storage: AccountStorage | null): number;
335
368
  export declare function hashRefreshToken(refreshToken: string): string;
336
369
  export declare function buildRefreshOperationError(input: {
337
370
  error: unknown;
338
371
  now: number;
339
372
  accountIdentity: string | undefined;
373
+ refreshTokenFingerprint?: string;
340
374
  previous?: AccountOperationError;
341
375
  }): AccountOperationError;
342
376
  /**
@@ -355,7 +389,7 @@ export declare function buildRefreshOperationError(input: {
355
389
  * the error with the explicit field.
356
390
  */
357
391
  export declare function isPermanentRefreshError(error: AccountOperationError | undefined): boolean;
358
- export declare function refreshBackoffActive(error: AccountOperationError | undefined, accountIdentity: string | undefined, now: number): boolean;
392
+ export declare function refreshBackoffActive(error: AccountOperationError | undefined, accountIdentity: string | undefined, now: number, currentRefreshTokenFingerprint: string | undefined): boolean;
359
393
  export declare function formatRefreshBackoffMessage(error: AccountOperationError, now: number): string;
360
394
  export declare function getFallbackReauthLabels(storage: AccountStorage | null | undefined): string[];
361
395
  export declare function isQuotaPolicyAuthError(error: unknown): boolean;
@@ -436,6 +470,10 @@ export declare class FallbackAccountManager {
436
470
  private refreshTimer;
437
471
  private quotaTimer;
438
472
  readonly quotaManager: import('./quota-manager.ts').QuotaManager | null;
473
+ private readonly isFallbackAccountVaultServed;
474
+ private readonly isFallbackAccountVaultEnabled;
475
+ private readonly resolveFallbackAccessToken;
476
+ private readonly onBackgroundRefresh;
439
477
  private readonly onFallbackStorageChanged;
440
478
  private readonly setIntervalImpl;
441
479
  private readonly clearIntervalImpl;
@@ -447,7 +485,7 @@ export declare class FallbackAccountManager {
447
485
  private seedFallbackQuota;
448
486
  load(): Promise<AccountStorage | null>;
449
487
  save(storage: AccountStorage, accountIds?: string[]): Promise<void>;
450
- startBackgroundRefresh(): void;
488
+ startBackgroundRefresh(): Promise<void>;
451
489
  stopBackgroundRefresh(): void;
452
490
  getUsableFallbackAccounts(existingStorage?: AccountStorage | null, options?: {
453
491
  modelId?: string;
@@ -473,11 +511,13 @@ export declare class FallbackAccountManager {
473
511
  }>;
474
512
  refreshAccount(account: OAuthAccount, storage: AccountStorage, options?: {
475
513
  force?: boolean;
514
+ persistError?: boolean;
476
515
  }): Promise<OAuthAccount>;
477
516
  private waitForConcurrentFallbackRefresh;
478
517
  private refreshAccountNow;
479
518
  refreshAccountQuota(account: OAuthAccount, storage: AccountStorage): Promise<{
480
519
  account: OAuthAccount;
481
520
  fetched: boolean;
521
+ changed: boolean;
482
522
  }>;
483
523
  }