@cortexkit/anthropic-auth-core 1.20.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/dist/index.d.ts CHANGED
@@ -5,18 +5,22 @@ export * from './cachekeep.ts';
5
5
  export * from './cachekeep-registry.ts';
6
6
  export * from './cch.ts';
7
7
  export * from './claude-code.ts';
8
+ export * from './claustrum.ts';
8
9
  export * from './commands/account.ts';
9
10
  export * from './constants.ts';
10
11
  export * from './dump.ts';
11
12
  export * from './fast.ts';
13
+ export * from './json.ts';
12
14
  export * from './killswitch.ts';
13
15
  export * from './logger.ts';
14
16
  export * from './logging.ts';
17
+ export * from './mid-conversation-output-config.ts';
15
18
  export * from './models.ts';
16
19
  export * from './oauth-profile.ts';
17
20
  export * from './pkce.ts';
18
21
  export * from './prime.ts';
19
22
  export * from './provider.ts';
23
+ export * from './quota-header-feed.ts';
20
24
  export * from './quota-headers.ts';
21
25
  export * from './quota-manager.ts';
22
26
  export * from './quotas.ts';
@@ -24,3 +28,4 @@ export * from './relay.ts';
24
28
  export * from './routing.ts';
25
29
  export * from './start.ts';
26
30
  export * from './sticky-routing.ts';
31
+ export * from './thinking-binding.ts';
package/dist/index.js CHANGED
@@ -5,18 +5,22 @@ export * from './cachekeep.js';
5
5
  export * from './cachekeep-registry.js';
6
6
  export * from './cch.js';
7
7
  export * from './claude-code.js';
8
+ export * from './claustrum.js';
8
9
  export * from './commands/account.js';
9
10
  export * from './constants.js';
10
11
  export * from './dump.js';
11
12
  export * from './fast.js';
13
+ export * from './json.js';
12
14
  export * from './killswitch.js';
13
15
  export * from './logger.js';
14
16
  export * from './logging.js';
17
+ export * from './mid-conversation-output-config.js';
15
18
  export * from './models.js';
16
19
  export * from './oauth-profile.js';
17
20
  export * from './pkce.js';
18
21
  export * from './prime.js';
19
22
  export * from './provider.js';
23
+ export * from './quota-header-feed.js';
20
24
  export * from './quota-headers.js';
21
25
  export * from './quota-manager.js';
22
26
  export * from './quotas.js';
@@ -24,3 +28,4 @@ export * from './relay.js';
24
28
  export * from './routing.js';
25
29
  export * from './start.js';
26
30
  export * from './sticky-routing.js';
31
+ export * from './thinking-binding.js';
package/dist/json.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare function parseJsonRedacted(text: string): unknown;
package/dist/json.js ADDED
@@ -0,0 +1,10 @@
1
+ export function parseJsonRedacted(text) {
2
+ try {
3
+ return JSON.parse(text);
4
+ }
5
+ catch (error) {
6
+ if (error instanceof SyntaxError)
7
+ throw new SyntaxError('invalid JSON');
8
+ throw error;
9
+ }
10
+ }
@@ -0,0 +1,13 @@
1
+ export declare const MID_CONVERSATION_OUTPUT_CONFIG_BETA = "mid-conversation-output-config-2026-07-01";
2
+ export type AdaptiveEffort = 'low' | 'medium' | 'high' | 'xhigh' | 'max';
3
+ export type MidConversationEffortTransition = {
4
+ /** Number of assistant messages preceding the user boundary for this effort. */
5
+ afterAssistantMessages: number;
6
+ effort: AdaptiveEffort;
7
+ };
8
+ export declare function normalizeAdaptiveEffort(value: unknown): AdaptiveEffort | undefined;
9
+ export declare function usesMidConversationOutputConfig(body: Record<string, unknown>): boolean;
10
+ export declare function applyMidConversationOutputConfig(body: Record<string, unknown>, transitions: readonly MidConversationEffortTransition[]): {
11
+ applied: boolean;
12
+ inserted: number;
13
+ };
@@ -0,0 +1,89 @@
1
+ import { isClaudeFable51Model } from './models.js';
2
+ export const MID_CONVERSATION_OUTPUT_CONFIG_BETA = 'mid-conversation-output-config-2026-07-01';
3
+ function isRecord(value) {
4
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
5
+ }
6
+ export function normalizeAdaptiveEffort(value) {
7
+ if (value === 'minimal')
8
+ return 'low';
9
+ if (value === 'low' ||
10
+ value === 'medium' ||
11
+ value === 'high' ||
12
+ value === 'xhigh' ||
13
+ value === 'max') {
14
+ return value;
15
+ }
16
+ return undefined;
17
+ }
18
+ export function usesMidConversationOutputConfig(body) {
19
+ return isClaudeFable51Model(body.model);
20
+ }
21
+ function compactTransitions(transitions) {
22
+ const compacted = [];
23
+ for (const transition of transitions) {
24
+ if (!Number.isSafeInteger(transition.afterAssistantMessages) ||
25
+ transition.afterAssistantMessages < 0 ||
26
+ !normalizeAdaptiveEffort(transition.effort)) {
27
+ continue;
28
+ }
29
+ const normalized = {
30
+ afterAssistantMessages: transition.afterAssistantMessages,
31
+ effort: transition.effort,
32
+ };
33
+ const previous = compacted.at(-1);
34
+ if (previous &&
35
+ previous.afterAssistantMessages === normalized.afterAssistantMessages) {
36
+ previous.effort = normalized.effort;
37
+ continue;
38
+ }
39
+ if (previous?.effort === normalized.effort)
40
+ continue;
41
+ compacted.push(normalized);
42
+ }
43
+ return compacted;
44
+ }
45
+ export function applyMidConversationOutputConfig(body, transitions) {
46
+ if (!usesMidConversationOutputConfig(body) || !Array.isArray(body.messages)) {
47
+ return { applied: false, inserted: 0 };
48
+ }
49
+ const compacted = compactTransitions(transitions);
50
+ const currentOutputConfig = isRecord(body.output_config)
51
+ ? body.output_config
52
+ : {};
53
+ const baseline = compacted[0]?.effort ??
54
+ normalizeAdaptiveEffort(currentOutputConfig.effort) ??
55
+ 'high';
56
+ body.output_config = { ...currentOutputConfig, effort: baseline };
57
+ if (compacted.length < 2)
58
+ return { applied: true, inserted: 0 };
59
+ const messages = body.messages;
60
+ const transitionsByBoundary = new Map();
61
+ for (const transition of compacted.slice(1)) {
62
+ transitionsByBoundary.set(transition.afterAssistantMessages, transition.effort);
63
+ }
64
+ let assistantMessages = 0;
65
+ let activeEffort = baseline;
66
+ let inserted = 0;
67
+ const rewritten = [];
68
+ for (const message of messages) {
69
+ if (isRecord(message) &&
70
+ message.role === 'user' &&
71
+ transitionsByBoundary.has(assistantMessages)) {
72
+ const effort = transitionsByBoundary.get(assistantMessages);
73
+ if (effort && effort !== activeEffort) {
74
+ rewritten.push({
75
+ role: 'system',
76
+ content: [],
77
+ output_config: { effort },
78
+ });
79
+ activeEffort = effort;
80
+ inserted++;
81
+ }
82
+ }
83
+ rewritten.push(message);
84
+ if (isRecord(message) && message.role === 'assistant')
85
+ assistantMessages++;
86
+ }
87
+ body.messages = rewritten;
88
+ return { applied: true, inserted };
89
+ }
package/dist/models.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export declare const CLAUDE_FABLE_5_MODEL_ID = "claude-fable-5";
2
2
  export declare const CLAUDE_MYTHOS_5_MODEL_ID = "claude-mythos-5";
3
+ export declare const CLAUDE_FABLE_5_1_MODEL_ID = "claude-fable-5-1";
4
+ export declare const CLAUDE_MYTHOS_5_1_MODEL_ID = "claude-mythos-5-1";
3
5
  /**
4
6
  * Haiku 4.5 model identifier used by `/claude-prime` to start each OAuth
5
7
  * account's five-hour quota window with a minimal request. Usage is measured
@@ -16,7 +18,8 @@ export declare const CLAUDE_HAIKU_4_5_PRICING: {
16
18
  readonly input: 1;
17
19
  readonly output: 5;
18
20
  };
19
- export declare const CLAUDE_FABLE_MYTHOS_5_MODEL_IDS: readonly ["claude-fable-5", "claude-mythos-5"];
21
+ export declare const CLAUDE_FABLE_MYTHOS_5_1_MODEL_IDS: readonly ["claude-fable-5-1", "claude-mythos-5-1"];
22
+ export declare const CLAUDE_FABLE_MYTHOS_5_MODEL_IDS: readonly ["claude-fable-5", "claude-mythos-5", "claude-fable-5-1", "claude-mythos-5-1"];
20
23
  export type ClaudeFableMythos5ModelId = (typeof CLAUDE_FABLE_MYTHOS_5_MODEL_IDS)[number];
21
24
  export declare const CLAUDE_FABLE_MYTHOS_5_SUMMARIZED_THINKING: {
22
25
  readonly type: 'adaptive';
@@ -29,15 +32,38 @@ export declare const CLAUDE_FABLE_MYTHOS_5_PRICING: {
29
32
  readonly cacheWrite5m: 12.5;
30
33
  readonly cacheWrite1h: 20;
31
34
  };
35
+ export declare const CLAUDE_FABLE_MYTHOS_5_1_PRICING: {
36
+ readonly input: 10;
37
+ readonly output: 50;
38
+ readonly cacheRead: 0.25;
39
+ readonly cacheWrite5m: 12.5;
40
+ readonly cacheWrite1h: 20;
41
+ };
32
42
  export declare const CLAUDE_FABLE_MYTHOS_5_CONTEXT_WINDOW = 1000000;
33
43
  export declare const CLAUDE_FABLE_MYTHOS_5_MAX_OUTPUT_TOKENS = 128000;
34
44
  export declare const CLAUDE_FABLE_MYTHOS_5_RELEASE_DATE = "2026-06-09";
45
+ export declare const CLAUDE_FABLE_MYTHOS_5_1_RELEASE_DATE = "2026-09-01";
35
46
  export declare const CLAUDE_FABLE_MYTHOS_5_MODEL_SPECS: Record<ClaudeFableMythos5ModelId, {
36
47
  id: ClaudeFableMythos5ModelId;
37
48
  name: string;
38
49
  limited?: boolean;
39
50
  }>;
51
+ export declare const CLAUDE_FABLE_MYTHOS_5_1_MODEL_SPECS: {
52
+ "claude-fable-5-1": {
53
+ id: ClaudeFableMythos5ModelId;
54
+ name: string;
55
+ limited?: boolean;
56
+ };
57
+ "claude-mythos-5-1": {
58
+ id: ClaudeFableMythos5ModelId;
59
+ name: string;
60
+ limited?: boolean;
61
+ };
62
+ };
40
63
  export declare function isClaudeFableOrMythos5Model(model: unknown): boolean;
64
+ export declare function isClaudeFableOrMythos51Model(model: unknown): boolean;
65
+ export declare function isClaudeFable51Model(model: unknown): boolean;
66
+ export declare function getClaudeFableMythos5ReleaseDate(model: unknown): "2026-06-09" | "2026-09-01";
41
67
  export declare const CLAUDE_SONNET_5_MODEL_ID = "claude-sonnet-5";
42
68
  /**
43
69
  * Sonnet 5 enables adaptive thinking by default but ships `display: "omitted"`,
package/dist/models.js CHANGED
@@ -1,5 +1,7 @@
1
1
  export const CLAUDE_FABLE_5_MODEL_ID = 'claude-fable-5';
2
2
  export const CLAUDE_MYTHOS_5_MODEL_ID = 'claude-mythos-5';
3
+ export const CLAUDE_FABLE_5_1_MODEL_ID = 'claude-fable-5-1';
4
+ export const CLAUDE_MYTHOS_5_1_MODEL_ID = 'claude-mythos-5-1';
3
5
  /**
4
6
  * Haiku 4.5 model identifier used by `/claude-prime` to start each OAuth
5
7
  * account's five-hour quota window with a minimal request. Usage is measured
@@ -16,9 +18,14 @@ export const CLAUDE_HAIKU_4_5_PRICING = {
16
18
  input: 1,
17
19
  output: 5,
18
20
  };
21
+ export const CLAUDE_FABLE_MYTHOS_5_1_MODEL_IDS = [
22
+ CLAUDE_FABLE_5_1_MODEL_ID,
23
+ CLAUDE_MYTHOS_5_1_MODEL_ID,
24
+ ];
19
25
  export const CLAUDE_FABLE_MYTHOS_5_MODEL_IDS = [
20
26
  CLAUDE_FABLE_5_MODEL_ID,
21
27
  CLAUDE_MYTHOS_5_MODEL_ID,
28
+ ...CLAUDE_FABLE_MYTHOS_5_1_MODEL_IDS,
22
29
  ];
23
30
  export const CLAUDE_FABLE_MYTHOS_5_SUMMARIZED_THINKING = {
24
31
  type: 'adaptive',
@@ -31,9 +38,17 @@ export const CLAUDE_FABLE_MYTHOS_5_PRICING = {
31
38
  cacheWrite5m: 12.5,
32
39
  cacheWrite1h: 20,
33
40
  };
41
+ export const CLAUDE_FABLE_MYTHOS_5_1_PRICING = {
42
+ input: 10,
43
+ output: 50,
44
+ cacheRead: 0.25,
45
+ cacheWrite5m: 12.5,
46
+ cacheWrite1h: 20,
47
+ };
34
48
  export const CLAUDE_FABLE_MYTHOS_5_CONTEXT_WINDOW = 1_000_000;
35
49
  export const CLAUDE_FABLE_MYTHOS_5_MAX_OUTPUT_TOKENS = 128_000;
36
50
  export const CLAUDE_FABLE_MYTHOS_5_RELEASE_DATE = '2026-06-09';
51
+ export const CLAUDE_FABLE_MYTHOS_5_1_RELEASE_DATE = '2026-09-01';
37
52
  export const CLAUDE_FABLE_MYTHOS_5_MODEL_SPECS = {
38
53
  [CLAUDE_FABLE_5_MODEL_ID]: {
39
54
  id: CLAUDE_FABLE_5_MODEL_ID,
@@ -44,11 +59,39 @@ export const CLAUDE_FABLE_MYTHOS_5_MODEL_SPECS = {
44
59
  name: 'Claude Mythos 5',
45
60
  limited: true,
46
61
  },
62
+ [CLAUDE_FABLE_5_1_MODEL_ID]: {
63
+ id: CLAUDE_FABLE_5_1_MODEL_ID,
64
+ name: 'Claude Fable 5.1',
65
+ },
66
+ [CLAUDE_MYTHOS_5_1_MODEL_ID]: {
67
+ id: CLAUDE_MYTHOS_5_1_MODEL_ID,
68
+ name: 'Claude Mythos 5.1',
69
+ limited: true,
70
+ },
71
+ };
72
+ export const CLAUDE_FABLE_MYTHOS_5_1_MODEL_SPECS = {
73
+ [CLAUDE_FABLE_5_1_MODEL_ID]: CLAUDE_FABLE_MYTHOS_5_MODEL_SPECS[CLAUDE_FABLE_5_1_MODEL_ID],
74
+ [CLAUDE_MYTHOS_5_1_MODEL_ID]: CLAUDE_FABLE_MYTHOS_5_MODEL_SPECS[CLAUDE_MYTHOS_5_1_MODEL_ID],
47
75
  };
48
76
  export function isClaudeFableOrMythos5Model(model) {
49
77
  return (typeof model === 'string' &&
50
78
  CLAUDE_FABLE_MYTHOS_5_MODEL_IDS.some((id) => model === id || model.startsWith(`${id}-`)));
51
79
  }
80
+ export function isClaudeFableOrMythos51Model(model) {
81
+ return (typeof model === 'string' &&
82
+ CLAUDE_FABLE_MYTHOS_5_1_MODEL_IDS.some((id) => model === id || model.startsWith(`${id}-`)));
83
+ }
84
+ export function isClaudeFable51Model(model) {
85
+ if (typeof model !== 'string')
86
+ return false;
87
+ return (model === CLAUDE_FABLE_5_1_MODEL_ID ||
88
+ model.startsWith(`${CLAUDE_FABLE_5_1_MODEL_ID}-`));
89
+ }
90
+ export function getClaudeFableMythos5ReleaseDate(model) {
91
+ return isClaudeFableOrMythos51Model(model)
92
+ ? CLAUDE_FABLE_MYTHOS_5_1_RELEASE_DATE
93
+ : CLAUDE_FABLE_MYTHOS_5_RELEASE_DATE;
94
+ }
52
95
  export const CLAUDE_SONNET_5_MODEL_ID = 'claude-sonnet-5';
53
96
  /**
54
97
  * Sonnet 5 enables adaptive thinking by default but ships `display: "omitted"`,
@@ -0,0 +1 @@
1
+ export declare function isTransientNetworkError(error: unknown): boolean;
@@ -0,0 +1,27 @@
1
+ const TRANSIENT_NETWORK_ERROR_CODES = new Set([
2
+ 'EAI_AGAIN',
3
+ 'ECONNREFUSED',
4
+ 'ECONNRESET',
5
+ 'EHOSTUNREACH',
6
+ 'ENETUNREACH',
7
+ 'ENOTFOUND',
8
+ 'ETIMEDOUT',
9
+ 'UND_ERR_CONNECT_TIMEOUT',
10
+ ]);
11
+ function errorField(error, field) {
12
+ if (!error || typeof error !== 'object')
13
+ return undefined;
14
+ const value = error[field];
15
+ return typeof value === 'string' ? value : undefined;
16
+ }
17
+ export function isTransientNetworkError(error) {
18
+ const code = errorField(error, 'code');
19
+ if (code && TRANSIENT_NETWORK_ERROR_CODES.has(code))
20
+ return true;
21
+ const message = error instanceof Error
22
+ ? error.message
23
+ : (errorField(error, 'message') ?? String(error));
24
+ if (message.includes('fetch failed'))
25
+ return true;
26
+ return [...TRANSIENT_NETWORK_ERROR_CODES].some((candidate) => message.includes(candidate));
27
+ }
@@ -2,10 +2,11 @@ import type { OAuthAccountProfile } from './accounts.ts';
2
2
  export declare const PROFILE_TTL_MS: number;
3
3
  export declare function fetchOAuthAccountProfile(input: {
4
4
  accessToken: string;
5
+ accountIdentity?: string;
5
6
  fetchImpl?: typeof fetch;
6
7
  now?: () => number;
7
8
  signal?: AbortSignal;
8
9
  }): Promise<OAuthAccountProfile>;
9
- export declare function oauthProfileMatchesToken(profile: OAuthAccountProfile | undefined, accessToken: string): boolean;
10
+ export declare function oauthProfileMatchesIdentity(profile: OAuthAccountProfile | undefined, accountIdentity: string | undefined): boolean;
10
11
  export declare function oauthProfileIsFresh(profile: OAuthAccountProfile | undefined, now?: number): boolean;
11
12
  export declare function formatOAuthAccountTier(profile: OAuthAccountProfile | undefined): string | undefined;
@@ -1,4 +1,3 @@
1
- import { tokenFingerprint } from './quota-manager.js';
2
1
  const PROFILE_URL = 'https://api.anthropic.com/api/oauth/profile';
3
2
  export const PROFILE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
4
3
  export async function fetchOAuthAccountProfile(input) {
@@ -27,11 +26,18 @@ export async function fetchOAuthAccountProfile(input) {
27
26
  tier,
28
27
  orgType,
29
28
  checkedAt: input.now?.() ?? Date.now(),
30
- tokenFingerprint: tokenFingerprint(input.accessToken),
29
+ ...(input.accountIdentity !== undefined && {
30
+ accountIdentity: input.accountIdentity,
31
+ }),
31
32
  };
32
33
  }
33
- export function oauthProfileMatchesToken(profile, accessToken) {
34
- return profile?.tokenFingerprint === tokenFingerprint(accessToken);
34
+ export function oauthProfileMatchesIdentity(profile, accountIdentity) {
35
+ if (!profile)
36
+ return false;
37
+ if (accountIdentity === undefined)
38
+ return true;
39
+ return (profile.accountIdentity === undefined ||
40
+ profile.accountIdentity === accountIdentity);
35
41
  }
36
42
  export function oauthProfileIsFresh(profile, now = Date.now()) {
37
43
  return Boolean(profile &&
@@ -0,0 +1,52 @@
1
+ import { type AccountStorage, type OAuthQuotaSnapshot, type QuotaFieldName, type QuotaFieldSource, type QuotaFieldSources } from './accounts.ts';
2
+ export declare const QUOTA_HEADER_FEED_SCHEMA_VERSION = 3;
3
+ export declare const QUOTA_HEADER_FEED_LEASE_MS = 180000;
4
+ export type QuotaHeaderFeedIdentity = {
5
+ identity_source: 'credential_id';
6
+ credential_id: string;
7
+ } | {
8
+ identity_source: 'account_ref';
9
+ account_ref: string;
10
+ } | {
11
+ identity_source: 'none';
12
+ };
13
+ export type QuotaHeaderFeedProvenance = Partial<Record<QuotaFieldName, QuotaFieldSource>>;
14
+ type QuotaHeaderFeedQuota = Pick<OAuthQuotaSnapshot, 'five_hour' | 'seven_day' | 'bindingWindow' | 'fallbackAdvised' | 'scoped' | 'extraUsage'> & {
15
+ provenance?: QuotaHeaderFeedProvenance;
16
+ };
17
+ type QuotaHeaderFeedMetadata = {
18
+ schema_version: typeof QUOTA_HEADER_FEED_SCHEMA_VERSION;
19
+ provider: 'anthropic';
20
+ configured_account_count: number;
21
+ /** Header observation time; merged poll-owned fields retain their own checkedAt. */
22
+ observed_at_ms: number;
23
+ };
24
+ export type QuotaHeaderFeedEntry = QuotaHeaderFeedIdentity & QuotaHeaderFeedMetadata & {
25
+ quota: QuotaHeaderFeedQuota;
26
+ };
27
+ export type QuotaHeaderFeedPublishEntry = QuotaHeaderFeedIdentity & QuotaHeaderFeedMetadata & {
28
+ quota: Omit<QuotaHeaderFeedQuota, 'provenance'> & {
29
+ fieldSources?: QuotaFieldSources;
30
+ };
31
+ accountKey: string;
32
+ };
33
+ export declare function getDefaultQuotaHeaderFeedDirectory(): string;
34
+ export declare function configuredAnthropicOAuthAccountCount(input: {
35
+ storage: AccountStorage | null;
36
+ mainOAuthConfigured: boolean;
37
+ }): number;
38
+ export declare class QuotaHeaderFeedRegistry {
39
+ private readonly options;
40
+ private readonly filePath;
41
+ private writeChain;
42
+ constructor(options?: {
43
+ directory?: string;
44
+ now?: () => number;
45
+ leaseMs?: number;
46
+ instanceId?: string;
47
+ });
48
+ publish(entry: QuotaHeaderFeedPublishEntry): Promise<void>;
49
+ list(): Promise<QuotaHeaderFeedEntry[]>;
50
+ dispose(): Promise<void>;
51
+ }
52
+ export {};