@modelprofile.com/authswitch 6.4.0 → 7.0.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_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/authority-contract.d.ts +302 -6
- package/dist_ts/authority-contract.js +1 -1
- package/dist_ts/authority-runtime-contract.d.ts +15 -0
- package/dist_ts/authorityrehearsal.child.d.ts +1 -0
- package/dist_ts/authorityrehearsal.child.js +395 -0
- package/dist_ts/classes.accountlist.js +4 -3
- package/dist_ts/classes.authoritybackup.d.ts +134 -0
- package/dist_ts/classes.authoritybackup.js +769 -0
- package/dist_ts/classes.authoritybroker.d.ts +29 -6
- package/dist_ts/classes.authoritybroker.js +413 -122
- package/dist_ts/classes.authoritycli.d.ts +24 -0
- package/dist_ts/classes.authoritycli.js +675 -0
- package/dist_ts/classes.authorityclient.d.ts +34 -9
- package/dist_ts/classes.authorityclient.js +136 -38
- package/dist_ts/classes.authoritydaemon.d.ts +47 -0
- package/dist_ts/classes.authoritydaemon.js +705 -16
- package/dist_ts/classes.authoritydatabase.d.ts +182 -8
- package/dist_ts/classes.authoritydatabase.js +1188 -41
- package/dist_ts/classes.authoritymodels.d.ts +247 -1
- package/dist_ts/classes.authoritymodels.js +870 -6
- package/dist_ts/classes.authoritypreuse.d.ts +47 -0
- package/dist_ts/classes.authoritypreuse.js +278 -0
- package/dist_ts/classes.authorityregistry.d.ts +24 -0
- package/dist_ts/classes.authorityregistry.js +88 -0
- package/dist_ts/classes.authorityrehearsal.d.ts +127 -0
- package/dist_ts/classes.authorityrehearsal.js +632 -0
- package/dist_ts/classes.authorityusage.d.ts +160 -0
- package/dist_ts/classes.authorityusage.js +429 -0
- package/dist_ts/classes.claudeauthority.d.ts +66 -0
- package/dist_ts/classes.claudeauthority.js +532 -0
- package/dist_ts/classes.claudecodeharness.js +3 -2
- package/dist_ts/classes.claudecodelocks.d.ts +13 -0
- package/dist_ts/classes.claudecodelocks.js +75 -3
- package/dist_ts/classes.claudenative.d.ts +137 -0
- package/dist_ts/classes.claudenative.js +731 -0
- package/dist_ts/classes.claudestatus.d.ts +9 -0
- package/dist_ts/classes.claudestatus.js +26 -9
- package/dist_ts/classes.claudetokenrefresh.d.ts +15 -1
- package/dist_ts/classes.claudetokenrefresh.js +74 -21
- package/dist_ts/classes.codexharness.js +4 -2
- package/dist_ts/classes.codexmanaged.d.ts +91 -0
- package/dist_ts/classes.codexmanaged.js +404 -0
- package/dist_ts/classes.codexpreuse.d.ts +8 -0
- package/dist_ts/classes.codexpreuse.js +24 -6
- package/dist_ts/classes.fileharness.d.ts +2 -0
- package/dist_ts/classes.fileharness.js +6 -4
- package/dist_ts/classes.limits.js +12 -7
- package/dist_ts/classes.opencodeharness.js +2 -2
- package/dist_ts/claudehttp.d.ts +10 -0
- package/dist_ts/claudehttp.js +29 -3
- package/dist_ts/index.d.ts +2 -0
- package/dist_ts/index.js +8 -1
- package/dist_ts/interfaces.harness.d.ts +6 -0
- package/dist_ts/interfaces.list.d.ts +9 -3
- package/dist_ts/plugins.d.ts +7 -3
- package/dist_ts/plugins.js +9 -4
- package/dist_ts/ts_migration/0001_authority_meta.d.ts +3 -0
- package/dist_ts/ts_migration/0001_authority_meta.js +32 -0
- package/dist_ts/ts_migration/index.d.ts +3 -0
- package/dist_ts/ts_migration/index.js +6 -0
- package/package.json +12 -2
- package/readme.md +205 -13
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/authority-contract.ts +264 -9
- package/ts/authority-runtime-contract.ts +21 -1
- package/ts/authorityrehearsal.child.ts +330 -0
- package/ts/classes.accountlist.ts +3 -2
- package/ts/classes.authoritybackup.ts +780 -0
- package/ts/classes.authoritybroker.ts +410 -120
- package/ts/classes.authoritycli.ts +719 -0
- package/ts/classes.authorityclient.ts +164 -38
- package/ts/classes.authoritydaemon.ts +614 -17
- package/ts/classes.authoritydatabase.ts +1229 -44
- package/ts/classes.authoritymodels.ts +579 -4
- package/ts/classes.authoritypreuse.ts +297 -0
- package/ts/classes.authorityregistry.ts +118 -0
- package/ts/classes.authorityrehearsal.ts +625 -0
- package/ts/classes.authorityusage.ts +527 -0
- package/ts/classes.claudeauthority.ts +541 -0
- package/ts/classes.claudecodeharness.ts +2 -1
- package/ts/classes.claudecodelocks.ts +70 -1
- package/ts/classes.claudenative.ts +816 -0
- package/ts/classes.claudestatus.ts +38 -9
- package/ts/classes.claudetokenrefresh.ts +82 -19
- package/ts/classes.codexharness.ts +3 -1
- package/ts/classes.codexmanaged.ts +402 -0
- package/ts/classes.codexpreuse.ts +33 -5
- package/ts/classes.fileharness.ts +7 -3
- package/ts/classes.limits.ts +11 -6
- package/ts/classes.opencodeharness.ts +1 -1
- package/ts/claudehttp.ts +31 -2
- package/ts/index.ts +7 -0
- package/ts/interfaces.harness.ts +6 -0
- package/ts/interfaces.list.ts +9 -3
- package/ts/plugins.ts +9 -3
- package/ts/ts_migration/0001_authority_meta.ts +33 -0
- package/ts/ts_migration/index.ts +7 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import type { IClaudeLogin, IClaudeStatusRead } from './classes.claudestatus.js';
|
|
3
|
+
type TRateLimits = plugins.flexAccounts.ISmartAiProviderAccountRateLimits;
|
|
4
|
+
export type TAuthSwitchUsageProblem = 'none' | 'unsupported' | 'access_unavailable' | 'provider_unavailable' | 'provider_rejected' | 'profile_unavailable' | 'usage_unavailable' | 'context_changed' | 'expired';
|
|
5
|
+
export interface IAuthSwitchNativeUsageSource {
|
|
6
|
+
homeId: string;
|
|
7
|
+
credentialDigest: string;
|
|
8
|
+
configDigest: string;
|
|
9
|
+
accessTokenDigest: string;
|
|
10
|
+
}
|
|
11
|
+
/** A credential-free, exact view of the account and login used for one usage read. */
|
|
12
|
+
export interface IAuthSwitchUsageContext {
|
|
13
|
+
epoch: string;
|
|
14
|
+
accountId: string;
|
|
15
|
+
loginId: string;
|
|
16
|
+
subjectId: string;
|
|
17
|
+
workspaceId: string;
|
|
18
|
+
providerId: string;
|
|
19
|
+
purpose: string;
|
|
20
|
+
owner: string;
|
|
21
|
+
grantState: string;
|
|
22
|
+
removed: boolean;
|
|
23
|
+
authorizationGeneration: number;
|
|
24
|
+
grantGeneration: number;
|
|
25
|
+
nativeSource: IAuthSwitchNativeUsageSource | null;
|
|
26
|
+
}
|
|
27
|
+
/** A bounded, credential-free projection; it is independent of the legacy harness API. */
|
|
28
|
+
export interface IAuthSwitchClaudeStatus {
|
|
29
|
+
plan: {
|
|
30
|
+
name: string;
|
|
31
|
+
source: 'live' | 'stored';
|
|
32
|
+
} | null;
|
|
33
|
+
windows: {
|
|
34
|
+
label: string;
|
|
35
|
+
scope: 'account' | 'feature';
|
|
36
|
+
durationSeconds: number;
|
|
37
|
+
usedPercent: number;
|
|
38
|
+
resetAt: string | null;
|
|
39
|
+
severity?: 'normal' | 'warning' | 'critical';
|
|
40
|
+
headline?: true;
|
|
41
|
+
}[] | null;
|
|
42
|
+
facts: {
|
|
43
|
+
section: string | null;
|
|
44
|
+
label: string;
|
|
45
|
+
value: string;
|
|
46
|
+
summaryKey?: 'subscription' | 'billing' | 'usageWindows' | 'resets' | 'resetDetails';
|
|
47
|
+
}[];
|
|
48
|
+
problems: string[];
|
|
49
|
+
rateLimit: {
|
|
50
|
+
retryAt: string | null;
|
|
51
|
+
} | null;
|
|
52
|
+
}
|
|
53
|
+
export type TAuthSwitchUsageReading = {
|
|
54
|
+
kind: 'openai';
|
|
55
|
+
rateLimits: TRateLimits;
|
|
56
|
+
} | {
|
|
57
|
+
kind: 'anthropic';
|
|
58
|
+
status: IAuthSwitchClaudeStatus;
|
|
59
|
+
};
|
|
60
|
+
export interface IAuthSwitchUsageAccess {
|
|
61
|
+
accessToken: string;
|
|
62
|
+
accountId: string;
|
|
63
|
+
isFedrampAccount: boolean;
|
|
64
|
+
expiresAt: string;
|
|
65
|
+
grantGeneration: number;
|
|
66
|
+
}
|
|
67
|
+
/** Persist through SmartData in the authority integration. No credential belongs in this record. */
|
|
68
|
+
export interface IAuthSwitchStoredUsage {
|
|
69
|
+
context: IAuthSwitchUsageContext;
|
|
70
|
+
updateId: string;
|
|
71
|
+
reading: TAuthSwitchUsageReading | null;
|
|
72
|
+
observedAt: string | null;
|
|
73
|
+
currentUntil: string | null;
|
|
74
|
+
staleUntil: string | null;
|
|
75
|
+
lastAttemptAt: string;
|
|
76
|
+
nextAttemptAt: string;
|
|
77
|
+
failures: number;
|
|
78
|
+
problem: Exclude<TAuthSwitchUsageProblem, 'context_changed' | 'expired'>;
|
|
79
|
+
}
|
|
80
|
+
export interface IAuthSwitchUsageSnapshot {
|
|
81
|
+
accountId: string;
|
|
82
|
+
loginId: string;
|
|
83
|
+
state: 'current' | 'partial' | 'stale' | 'unavailable';
|
|
84
|
+
reading: TAuthSwitchUsageReading | null;
|
|
85
|
+
observedAt: string | null;
|
|
86
|
+
currentUntil: string | null;
|
|
87
|
+
staleUntil: string | null;
|
|
88
|
+
lastAttemptAt: string | null;
|
|
89
|
+
nextAttemptAt: string | null;
|
|
90
|
+
problem: TAuthSwitchUsageProblem;
|
|
91
|
+
}
|
|
92
|
+
export interface IAuthSwitchUsageStore {
|
|
93
|
+
/** Read only the exact login's record. The helper discards a mismatched context. */
|
|
94
|
+
read(accountId: string, loginId: string): Promise<IAuthSwitchStoredUsage | null>;
|
|
95
|
+
/**
|
|
96
|
+
* In one SmartData transaction, re-read epoch/account/login and compare every semantic
|
|
97
|
+
* context field, compare the previous usage update ID, write next, and append a revisioned
|
|
98
|
+
* account event. The account row revision may increase in that transaction; it is not
|
|
99
|
+
* part of the usage validity key and must not invalidate the reading just published.
|
|
100
|
+
* A null previousUpdateId also permits replacing a record for a different context;
|
|
101
|
+
* it must reject a concurrently written record for this same context.
|
|
102
|
+
* Return false on either conflict; do not publish an old provider callback.
|
|
103
|
+
*/
|
|
104
|
+
publishIfCurrent(context: IAuthSwitchUsageContext, previousUpdateId: string | null, next: IAuthSwitchStoredUsage): Promise<boolean>;
|
|
105
|
+
}
|
|
106
|
+
export interface IAuthSwitchAuthorityUsageOptions {
|
|
107
|
+
/** Re-read from the owning SmartData authority. Return null for an absent login. */
|
|
108
|
+
readContext(accountId: string, loginId: string): Promise<IAuthSwitchUsageContext | null>;
|
|
109
|
+
/** Broker-owned access resolution; rejected generation may perform at most one durable refresh. */
|
|
110
|
+
resolveAccess(context: IAuthSwitchUsageContext, rejectedGrantGeneration: number | undefined, minValidityMs: number): Promise<IAuthSwitchUsageAccess>;
|
|
111
|
+
resolveClaudeLogin?(context: IAuthSwitchUsageContext, rejectedGrantGeneration: number | undefined, minValidityMs: number): Promise<{
|
|
112
|
+
login: IClaudeLogin;
|
|
113
|
+
grantGeneration: number;
|
|
114
|
+
expiresAt: string | null;
|
|
115
|
+
}>;
|
|
116
|
+
claudeStatus?: Pick<{
|
|
117
|
+
readDetailed(login: IClaudeLogin): Promise<IClaudeStatusRead>;
|
|
118
|
+
}, 'readDetailed'>;
|
|
119
|
+
/** The callback holds the qualified vendor lease through the whole read and publication. */
|
|
120
|
+
withNativeSource?(context: IAuthSwitchUsageContext, action: (source: {
|
|
121
|
+
context: IAuthSwitchUsageContext;
|
|
122
|
+
login: IClaudeLogin;
|
|
123
|
+
readContext(): Promise<IAuthSwitchUsageContext | null>;
|
|
124
|
+
}) => Promise<IAuthSwitchUsageSnapshot>): Promise<IAuthSwitchUsageSnapshot>;
|
|
125
|
+
store: IAuthSwitchUsageStore;
|
|
126
|
+
provider: Pick<plugins.flexAccounts.ISmartAiProviderAdapter, 'getAccountRateLimits'>;
|
|
127
|
+
now?: () => number;
|
|
128
|
+
currentMaxAgeMs?: number;
|
|
129
|
+
maxStaleAgeMs?: number;
|
|
130
|
+
minAttemptIntervalMs?: number;
|
|
131
|
+
retryBaseMs?: number;
|
|
132
|
+
retryMaxMs?: number;
|
|
133
|
+
providerTimeoutMs?: number;
|
|
134
|
+
minAccessValidityMs?: number;
|
|
135
|
+
}
|
|
136
|
+
/** On-demand daemon cache coordinator. The injected store is the only publication authority. */
|
|
137
|
+
export declare class AuthSwitchAuthorityUsage {
|
|
138
|
+
private readonly options;
|
|
139
|
+
private readonly now;
|
|
140
|
+
private readonly policy;
|
|
141
|
+
private readonly pending;
|
|
142
|
+
private readonly admitted;
|
|
143
|
+
private closed;
|
|
144
|
+
private closing?;
|
|
145
|
+
constructor(options: IAuthSwitchAuthorityUsageOptions);
|
|
146
|
+
private unavailable;
|
|
147
|
+
private snapshot;
|
|
148
|
+
private currentContext;
|
|
149
|
+
get(accountId: string, loginId: string, force?: boolean): Promise<IAuthSwitchUsageSnapshot>;
|
|
150
|
+
private read;
|
|
151
|
+
private readWithContext;
|
|
152
|
+
/** Coalesce the entire read/decision/fetch lifecycle, including the first stored read. */
|
|
153
|
+
private readForContext;
|
|
154
|
+
private refresh;
|
|
155
|
+
private validAccess;
|
|
156
|
+
private query;
|
|
157
|
+
/** Wait for admitted reads before the daemon disposes the shared provider or database. */
|
|
158
|
+
close(): Promise<void>;
|
|
159
|
+
}
|
|
160
|
+
export {};
|
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
const defaults = {
|
|
3
|
+
currentMaxAgeMs: 60_000,
|
|
4
|
+
maxStaleAgeMs: 300_000,
|
|
5
|
+
minAttemptIntervalMs: 15_000,
|
|
6
|
+
retryBaseMs: 30_000,
|
|
7
|
+
retryMaxMs: 300_000,
|
|
8
|
+
providerTimeoutMs: 15_000,
|
|
9
|
+
minAccessValidityMs: 60_000,
|
|
10
|
+
};
|
|
11
|
+
const sameContext = (left, right) => left.epoch === right.epoch && left.accountId === right.accountId && left.loginId === right.loginId
|
|
12
|
+
&& left.subjectId === right.subjectId && left.workspaceId === right.workspaceId
|
|
13
|
+
&& left.providerId === right.providerId
|
|
14
|
+
&& left.purpose === right.purpose && left.owner === right.owner && left.grantState === right.grantState
|
|
15
|
+
&& left.removed === right.removed && left.authorizationGeneration === right.authorizationGeneration
|
|
16
|
+
&& left.grantGeneration === right.grantGeneration
|
|
17
|
+
&& (left.nativeSource === null ? right.nativeSource === null
|
|
18
|
+
: right.nativeSource !== null && left.nativeSource.homeId === right.nativeSource.homeId
|
|
19
|
+
&& left.nativeSource.credentialDigest === right.nativeSource.credentialDigest
|
|
20
|
+
&& left.nativeSource.configDigest === right.nativeSource.configDigest
|
|
21
|
+
&& left.nativeSource.accessTokenDigest === right.nativeSource.accessTokenDigest);
|
|
22
|
+
const sameGrantAuthority = (left, right) => left.epoch === right.epoch && left.accountId === right.accountId && left.loginId === right.loginId
|
|
23
|
+
&& left.subjectId === right.subjectId && left.workspaceId === right.workspaceId
|
|
24
|
+
&& left.providerId === right.providerId
|
|
25
|
+
&& left.purpose === right.purpose && left.owner === right.owner
|
|
26
|
+
&& left.authorizationGeneration === right.authorizationGeneration && !right.removed
|
|
27
|
+
&& (left.nativeSource === null ? right.nativeSource === null : sameContext(left, right));
|
|
28
|
+
const usable = (context) => !context.removed && ((context.providerId === 'openai' && context.purpose === 'openai_managed'
|
|
29
|
+
&& context.owner === 'daemon' && context.nativeSource === null
|
|
30
|
+
&& (context.grantState === 'ready' || context.grantState === 'retry_wait'))
|
|
31
|
+
|| (context.providerId === 'anthropic' && context.purpose === 'claude_host_native'
|
|
32
|
+
&& ((context.owner === 'daemon' && context.nativeSource === null
|
|
33
|
+
&& (context.grantState === 'ready' || context.grantState === 'retry_wait'))
|
|
34
|
+
|| (context.owner === 'claude_native' && context.nativeSource !== null
|
|
35
|
+
&& context.grantState === 'native'))));
|
|
36
|
+
const timestamp = (millis) => new Date(millis).toISOString();
|
|
37
|
+
const future = (value, now) => value !== null && Date.parse(value) > now;
|
|
38
|
+
const safeText = (value) => {
|
|
39
|
+
const text = value.replace(/[\u0000-\u001f\u007f-\u009f]/g, '');
|
|
40
|
+
if (Array.from(text).length > 500)
|
|
41
|
+
throw new Error('Claude status text exceeds the authority projection bound.');
|
|
42
|
+
return text;
|
|
43
|
+
};
|
|
44
|
+
const publicClaudeStatus = (source) => {
|
|
45
|
+
if ((source.summary?.usageWindows?.length ?? 0) > 128 || source.facts.length > 128
|
|
46
|
+
|| source.problems.length > 32)
|
|
47
|
+
throw new Error('Claude status exceeds the authority projection bound.');
|
|
48
|
+
return {
|
|
49
|
+
plan: source.summary?.subscription
|
|
50
|
+
? { name: safeText(source.summary.subscription.plan), source: source.summary.subscription.source } : null,
|
|
51
|
+
windows: source.summary?.usageWindows?.map(window => ({
|
|
52
|
+
label: safeText(window.label), scope: window.scope ?? 'account',
|
|
53
|
+
durationSeconds: window.durationSeconds, usedPercent: window.usedPercent, resetAt: window.resetAt,
|
|
54
|
+
...(window.severity ? { severity: window.severity } : {}),
|
|
55
|
+
...(window.headline ? { headline: true } : {}),
|
|
56
|
+
})) ?? null,
|
|
57
|
+
facts: source.facts.map(fact => ({
|
|
58
|
+
section: fact.section ? safeText(fact.section) : null,
|
|
59
|
+
label: safeText(fact.label), value: safeText(fact.value),
|
|
60
|
+
...(fact.summaryKey ? { summaryKey: fact.summaryKey } : {}),
|
|
61
|
+
})),
|
|
62
|
+
problems: source.problems.map(safeText),
|
|
63
|
+
rateLimit: source.rateLimit ? { retryAt: source.rateLimit.retryAt } : null,
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
/** Allowlist the provider projection before it enters a management DTO or stored usage record. */
|
|
67
|
+
const publicRateLimits = (source) => {
|
|
68
|
+
const window = (value) => ({
|
|
69
|
+
usedPercent: value.usedPercent, limitWindowSeconds: value.limitWindowSeconds,
|
|
70
|
+
resetAfterSeconds: value.resetAfterSeconds, resetsAt: value.resetsAt,
|
|
71
|
+
});
|
|
72
|
+
const detail = (value) => ({
|
|
73
|
+
allowed: value.allowed, limitReached: value.limitReached,
|
|
74
|
+
...(value.primaryWindow ? { primaryWindow: window(value.primaryWindow) } : {}),
|
|
75
|
+
...(value.secondaryWindow ? { secondaryWindow: window(value.secondaryWindow) } : {}),
|
|
76
|
+
});
|
|
77
|
+
return {
|
|
78
|
+
providerId: 'openai', plan: source.plan, observedAt: source.observedAt,
|
|
79
|
+
...(source.rateLimit ? { rateLimit: detail(source.rateLimit) } : {}),
|
|
80
|
+
additionalRateLimits: source.additionalRateLimits.map(item => ({
|
|
81
|
+
limitName: item.limitName, meteredFeature: item.meteredFeature,
|
|
82
|
+
...(item.rateLimit ? { rateLimit: detail(item.rateLimit) } : {}),
|
|
83
|
+
})),
|
|
84
|
+
...(source.rateLimitReachedType === undefined ? {} : { rateLimitReachedType: source.rateLimitReachedType }),
|
|
85
|
+
...(source.rateLimitResetCreditsAvailableCount === undefined ? {}
|
|
86
|
+
: { rateLimitResetCreditsAvailableCount: source.rateLimitResetCreditsAvailableCount }),
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
/** On-demand daemon cache coordinator. The injected store is the only publication authority. */
|
|
90
|
+
export class AuthSwitchAuthorityUsage {
|
|
91
|
+
options;
|
|
92
|
+
now;
|
|
93
|
+
policy;
|
|
94
|
+
pending = new Map();
|
|
95
|
+
admitted = new Set();
|
|
96
|
+
closed = false;
|
|
97
|
+
closing;
|
|
98
|
+
constructor(options) {
|
|
99
|
+
this.options = options;
|
|
100
|
+
this.now = options.now ?? Date.now;
|
|
101
|
+
this.policy = {
|
|
102
|
+
currentMaxAgeMs: options.currentMaxAgeMs ?? defaults.currentMaxAgeMs,
|
|
103
|
+
maxStaleAgeMs: options.maxStaleAgeMs ?? defaults.maxStaleAgeMs,
|
|
104
|
+
minAttemptIntervalMs: options.minAttemptIntervalMs ?? defaults.minAttemptIntervalMs,
|
|
105
|
+
retryBaseMs: options.retryBaseMs ?? defaults.retryBaseMs,
|
|
106
|
+
retryMaxMs: options.retryMaxMs ?? defaults.retryMaxMs,
|
|
107
|
+
providerTimeoutMs: options.providerTimeoutMs ?? defaults.providerTimeoutMs,
|
|
108
|
+
minAccessValidityMs: options.minAccessValidityMs ?? defaults.minAccessValidityMs,
|
|
109
|
+
};
|
|
110
|
+
if (Object.values(this.policy).some(value => !Number.isSafeInteger(value) || value < 1 || value > 3_600_000)
|
|
111
|
+
|| this.policy.maxStaleAgeMs <= this.policy.currentMaxAgeMs
|
|
112
|
+
|| this.policy.retryMaxMs < this.policy.retryBaseMs) {
|
|
113
|
+
throw new Error('Invalid authority usage freshness policy.');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
unavailable(accountId, loginId, problem) {
|
|
117
|
+
return { accountId, loginId, state: 'unavailable', reading: null, observedAt: null,
|
|
118
|
+
currentUntil: null, staleUntil: null, lastAttemptAt: null, nextAttemptAt: null, problem };
|
|
119
|
+
}
|
|
120
|
+
snapshot(context, record, now = this.now()) {
|
|
121
|
+
if (!record || !sameContext(context, record.context)) {
|
|
122
|
+
return this.unavailable(context.accountId, context.loginId, 'expired');
|
|
123
|
+
}
|
|
124
|
+
const state = record.reading && future(record.currentUntil, now)
|
|
125
|
+
? record.problem === 'none' ? 'current'
|
|
126
|
+
: record.reading.kind === 'anthropic' && ['profile_unavailable', 'usage_unavailable'].includes(record.problem)
|
|
127
|
+
? 'partial' : 'stale'
|
|
128
|
+
: record.reading && future(record.staleUntil, now) ? 'stale' : 'unavailable';
|
|
129
|
+
return {
|
|
130
|
+
accountId: context.accountId, loginId: context.loginId, state,
|
|
131
|
+
reading: state === 'unavailable' ? null : record.reading,
|
|
132
|
+
observedAt: state === 'unavailable' ? null : record.observedAt,
|
|
133
|
+
currentUntil: record.currentUntil, staleUntil: record.staleUntil,
|
|
134
|
+
lastAttemptAt: record.lastAttemptAt, nextAttemptAt: record.nextAttemptAt,
|
|
135
|
+
problem: state === 'unavailable' && record.reading && !future(record.staleUntil, now)
|
|
136
|
+
? 'expired' : record.problem,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
async currentContext(accountId, loginId) {
|
|
140
|
+
try {
|
|
141
|
+
return await this.options.readContext(accountId, loginId);
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
get(accountId, loginId, force = false) {
|
|
148
|
+
if (this.closed)
|
|
149
|
+
return Promise.reject(new Error('Authority usage helper is closed.'));
|
|
150
|
+
const request = this.read(accountId, loginId, force);
|
|
151
|
+
this.admitted.add(request);
|
|
152
|
+
void request.finally(() => this.admitted.delete(request)).catch(() => undefined);
|
|
153
|
+
return request;
|
|
154
|
+
}
|
|
155
|
+
async read(accountId, loginId, force) {
|
|
156
|
+
if (!/^[a-f0-9]{64}$/.test(accountId) || !/^[a-f0-9]{64}$/.test(loginId)) {
|
|
157
|
+
throw new Error('Invalid authority usage identity.');
|
|
158
|
+
}
|
|
159
|
+
const context = await this.currentContext(accountId, loginId);
|
|
160
|
+
if (!context)
|
|
161
|
+
return this.unavailable(accountId, loginId, 'access_unavailable');
|
|
162
|
+
if (context.accountId !== accountId || context.loginId !== loginId) {
|
|
163
|
+
return this.unavailable(accountId, loginId, 'context_changed');
|
|
164
|
+
}
|
|
165
|
+
if (context.providerId === 'anthropic' && context.purpose === 'claude_host_native'
|
|
166
|
+
&& context.owner === 'claude_native' && context.grantState === 'native') {
|
|
167
|
+
if (!this.options.withNativeSource)
|
|
168
|
+
return this.unavailable(accountId, loginId, 'access_unavailable');
|
|
169
|
+
try {
|
|
170
|
+
return await this.options.withNativeSource(context, async (source) => {
|
|
171
|
+
const readCurrent = async () => {
|
|
172
|
+
try {
|
|
173
|
+
return await source.readContext();
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
return this.readWithContext(source.context, force, readCurrent, source.login);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
return this.unavailable(accountId, loginId, 'access_unavailable');
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return this.readWithContext(context, force, () => this.currentContext(accountId, loginId), null);
|
|
187
|
+
}
|
|
188
|
+
readWithContext(context, force, readCurrent, nativeLogin) {
|
|
189
|
+
if (!usable(context))
|
|
190
|
+
return Promise.resolve(this.unavailable(context.accountId, context.loginId, context.removed || ['handoff_pending', 'handoff_quarantined', 'legacy_native_pending'].includes(context.grantState)
|
|
191
|
+
? 'access_unavailable' : 'unsupported'));
|
|
192
|
+
const key = JSON.stringify([context.epoch, context.accountId, context.loginId,
|
|
193
|
+
context.subjectId, context.workspaceId,
|
|
194
|
+
context.authorizationGeneration, context.grantGeneration, context.owner, context.grantState,
|
|
195
|
+
context.nativeSource]);
|
|
196
|
+
const existing = this.pending.get(key);
|
|
197
|
+
if (existing)
|
|
198
|
+
return existing;
|
|
199
|
+
const task = this.readForContext(context, force, readCurrent, nativeLogin).finally(() => {
|
|
200
|
+
if (this.pending.get(key) === task)
|
|
201
|
+
this.pending.delete(key);
|
|
202
|
+
});
|
|
203
|
+
this.pending.set(key, task);
|
|
204
|
+
return task;
|
|
205
|
+
}
|
|
206
|
+
/** Coalesce the entire read/decision/fetch lifecycle, including the first stored read. */
|
|
207
|
+
async readForContext(context, force, readCurrent, nativeLogin) {
|
|
208
|
+
let stored;
|
|
209
|
+
try {
|
|
210
|
+
stored = await this.options.store.read(context.accountId, context.loginId);
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
return this.unavailable(context.accountId, context.loginId, 'access_unavailable');
|
|
214
|
+
}
|
|
215
|
+
const record = stored && sameContext(context, stored.context) ? stored : null;
|
|
216
|
+
const verified = await readCurrent();
|
|
217
|
+
if (!verified || !sameContext(context, verified)) {
|
|
218
|
+
return this.unavailable(context.accountId, context.loginId, 'context_changed');
|
|
219
|
+
}
|
|
220
|
+
const now = this.now();
|
|
221
|
+
const cached = this.snapshot(context, record, now);
|
|
222
|
+
if (record && future(record.nextAttemptAt, now))
|
|
223
|
+
return cached;
|
|
224
|
+
if (cached.state === 'current' && !force)
|
|
225
|
+
return cached;
|
|
226
|
+
return this.refresh(context, record, readCurrent, nativeLogin);
|
|
227
|
+
}
|
|
228
|
+
async refresh(initial, initialRecord, readCurrent, nativeLogin) {
|
|
229
|
+
let context = initial;
|
|
230
|
+
let previous = initialRecord;
|
|
231
|
+
let reading = null;
|
|
232
|
+
let problem = 'none';
|
|
233
|
+
try {
|
|
234
|
+
if (context.providerId === 'openai') {
|
|
235
|
+
let access = await this.options.resolveAccess(context, undefined, this.policy.minAccessValidityMs);
|
|
236
|
+
const resolved = await readCurrent();
|
|
237
|
+
if (!resolved || !sameGrantAuthority(context, resolved) || !usable(resolved)
|
|
238
|
+
|| resolved.grantGeneration !== access.grantGeneration) {
|
|
239
|
+
return this.unavailable(context.accountId, context.loginId, 'context_changed');
|
|
240
|
+
}
|
|
241
|
+
context = resolved;
|
|
242
|
+
if (!this.validAccess(context, access))
|
|
243
|
+
throw new Error('Access grant is unavailable.');
|
|
244
|
+
if (!sameContext(initial, context)) {
|
|
245
|
+
const stored = await this.options.store.read(context.accountId, context.loginId);
|
|
246
|
+
previous = stored && sameContext(context, stored.context) ? stored : null;
|
|
247
|
+
}
|
|
248
|
+
let response;
|
|
249
|
+
try {
|
|
250
|
+
response = await this.query(access);
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
problem = 'provider_unavailable';
|
|
254
|
+
response = { success: false, errorCode: 'ACCOUNT_RATE_LIMITS_FAILED' };
|
|
255
|
+
}
|
|
256
|
+
if (!response.success && response.errorCode === 'CREDENTIAL_REFRESH_REQUIRED') {
|
|
257
|
+
const beforeRotation = await readCurrent();
|
|
258
|
+
if (!beforeRotation || !sameContext(context, beforeRotation)) {
|
|
259
|
+
return this.unavailable(context.accountId, context.loginId, 'context_changed');
|
|
260
|
+
}
|
|
261
|
+
access = await this.options.resolveAccess(context, access.grantGeneration, this.policy.minAccessValidityMs);
|
|
262
|
+
const rotated = await readCurrent();
|
|
263
|
+
if (!rotated || !sameGrantAuthority(context, rotated) || !usable(rotated)
|
|
264
|
+
|| rotated.grantGeneration !== access.grantGeneration
|
|
265
|
+
|| rotated.grantGeneration <= context.grantGeneration) {
|
|
266
|
+
return this.unavailable(context.accountId, context.loginId, 'context_changed');
|
|
267
|
+
}
|
|
268
|
+
context = rotated;
|
|
269
|
+
if (!this.validAccess(context, access))
|
|
270
|
+
throw new Error('Access grant is unavailable.');
|
|
271
|
+
const stored = await this.options.store.read(context.accountId, context.loginId);
|
|
272
|
+
previous = stored && sameContext(context, stored.context) ? stored : null;
|
|
273
|
+
try {
|
|
274
|
+
response = await this.query(access);
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
problem = 'provider_unavailable';
|
|
278
|
+
response = { success: false, errorCode: 'ACCOUNT_RATE_LIMITS_FAILED' };
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (response.success)
|
|
282
|
+
reading = { kind: 'openai', rateLimits: publicRateLimits(response.rateLimits) };
|
|
283
|
+
else if (problem === 'none')
|
|
284
|
+
problem = response.errorCode === 'CREDENTIAL_REFRESH_REQUIRED'
|
|
285
|
+
? 'provider_rejected' : 'provider_unavailable';
|
|
286
|
+
}
|
|
287
|
+
else if (context.providerId === 'anthropic' && this.options.claudeStatus) {
|
|
288
|
+
let login = nativeLogin;
|
|
289
|
+
let grantGeneration = context.grantGeneration;
|
|
290
|
+
if (context.owner === 'daemon') {
|
|
291
|
+
if (!this.options.resolveClaudeLogin)
|
|
292
|
+
throw new Error('Claude status access is unavailable.');
|
|
293
|
+
const access = await this.options.resolveClaudeLogin(context, undefined, this.policy.minAccessValidityMs);
|
|
294
|
+
login = access.login;
|
|
295
|
+
grantGeneration = access.grantGeneration;
|
|
296
|
+
if (login.scopes.includes('user:profile')
|
|
297
|
+
&& !future(access.expiresAt, this.now() + this.policy.minAccessValidityMs)) {
|
|
298
|
+
throw new Error('Claude status access is not fresh enough.');
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const resolved = await readCurrent();
|
|
302
|
+
if (!resolved || !sameGrantAuthority(context, resolved) || !usable(resolved)
|
|
303
|
+
|| resolved.grantGeneration !== grantGeneration || !login) {
|
|
304
|
+
return this.unavailable(context.accountId, context.loginId, 'context_changed');
|
|
305
|
+
}
|
|
306
|
+
context = resolved;
|
|
307
|
+
if (!sameContext(initial, context)) {
|
|
308
|
+
const stored = await this.options.store.read(context.accountId, context.loginId);
|
|
309
|
+
previous = stored && sameContext(context, stored.context) ? stored : null;
|
|
310
|
+
}
|
|
311
|
+
if (!login.scopes.includes('user:profile')) {
|
|
312
|
+
problem = 'unsupported';
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
let result = await this.options.claudeStatus.readDetailed(login);
|
|
316
|
+
if (result.credentialRejected && context.owner === 'daemon') {
|
|
317
|
+
const beforeRotation = await readCurrent();
|
|
318
|
+
if (!beforeRotation || !sameContext(context, beforeRotation)) {
|
|
319
|
+
return this.unavailable(context.accountId, context.loginId, 'context_changed');
|
|
320
|
+
}
|
|
321
|
+
const rotated = await this.options.resolveClaudeLogin(context, grantGeneration, this.policy.minAccessValidityMs);
|
|
322
|
+
const updated = await readCurrent();
|
|
323
|
+
if (!updated || !sameGrantAuthority(context, updated) || !usable(updated)
|
|
324
|
+
|| updated.grantGeneration !== rotated.grantGeneration
|
|
325
|
+
|| updated.grantGeneration <= grantGeneration
|
|
326
|
+
|| (rotated.login.scopes.includes('user:profile')
|
|
327
|
+
&& !future(rotated.expiresAt, this.now() + this.policy.minAccessValidityMs))) {
|
|
328
|
+
return this.unavailable(context.accountId, context.loginId, 'context_changed');
|
|
329
|
+
}
|
|
330
|
+
context = updated;
|
|
331
|
+
login = rotated.login;
|
|
332
|
+
const stored = await this.options.store.read(context.accountId, context.loginId);
|
|
333
|
+
previous = stored && sameContext(context, stored.context) ? stored : null;
|
|
334
|
+
if (login.scopes.includes('user:profile')) {
|
|
335
|
+
result = await this.options.claudeStatus.readDetailed(login);
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
problem = 'unsupported';
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
if (problem !== 'unsupported' && result.profile === 'mismatch') {
|
|
342
|
+
return this.unavailable(context.accountId, context.loginId, 'context_changed');
|
|
343
|
+
}
|
|
344
|
+
else if (problem !== 'unsupported' && result.credentialRejected)
|
|
345
|
+
problem = 'provider_rejected';
|
|
346
|
+
else if (problem !== 'unsupported' && context.owner === 'claude_native' && result.profile !== 'verified') {
|
|
347
|
+
problem = 'profile_unavailable';
|
|
348
|
+
}
|
|
349
|
+
else if (problem !== 'unsupported') {
|
|
350
|
+
try {
|
|
351
|
+
reading = { kind: 'anthropic', status: publicClaudeStatus(result.status) };
|
|
352
|
+
problem = result.profile !== 'verified' ? 'profile_unavailable'
|
|
353
|
+
: result.usage !== 'available' ? 'usage_unavailable' : 'none';
|
|
354
|
+
}
|
|
355
|
+
catch {
|
|
356
|
+
problem = 'unsupported';
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
problem = 'unsupported';
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
problem = 'access_unavailable';
|
|
367
|
+
}
|
|
368
|
+
const latest = await readCurrent();
|
|
369
|
+
if (!latest || !sameContext(context, latest) || !usable(latest)) {
|
|
370
|
+
return this.unavailable(context.accountId, context.loginId, 'context_changed');
|
|
371
|
+
}
|
|
372
|
+
const now = this.now();
|
|
373
|
+
const failures = reading && problem === 'none' ? 0 : Math.min((previous?.failures ?? 0) + 1, 16);
|
|
374
|
+
const retryMs = Math.min(this.policy.retryBaseMs * 2 ** Math.min(failures - 1, 10), this.policy.retryMaxMs);
|
|
375
|
+
const retained = !reading && previous?.reading && future(previous.staleUntil, now) ? previous : null;
|
|
376
|
+
const next = {
|
|
377
|
+
context, updateId: plugins.crypto.randomUUID(),
|
|
378
|
+
reading: reading ?? retained?.reading ?? null,
|
|
379
|
+
observedAt: reading ? timestamp(now) : retained?.observedAt ?? null,
|
|
380
|
+
currentUntil: reading ? timestamp(now + this.policy.currentMaxAgeMs) : retained?.currentUntil ?? null,
|
|
381
|
+
staleUntil: reading ? timestamp(now + this.policy.maxStaleAgeMs) : retained?.staleUntil ?? null,
|
|
382
|
+
lastAttemptAt: timestamp(now),
|
|
383
|
+
nextAttemptAt: timestamp(now + (reading && problem === 'none' ? this.policy.minAttemptIntervalMs : retryMs)),
|
|
384
|
+
failures, problem,
|
|
385
|
+
};
|
|
386
|
+
try {
|
|
387
|
+
if (!await this.options.store.publishIfCurrent(context, previous?.updateId ?? null, next)) {
|
|
388
|
+
const current = await readCurrent();
|
|
389
|
+
if (!current || !sameContext(context, current)) {
|
|
390
|
+
return this.unavailable(context.accountId, context.loginId, 'context_changed');
|
|
391
|
+
}
|
|
392
|
+
const stored = await this.options.store.read(context.accountId, context.loginId);
|
|
393
|
+
const confirmed = await readCurrent();
|
|
394
|
+
if (!confirmed || !sameContext(context, confirmed)) {
|
|
395
|
+
return this.unavailable(context.accountId, context.loginId, 'context_changed');
|
|
396
|
+
}
|
|
397
|
+
return this.snapshot(context, stored);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
catch {
|
|
401
|
+
return this.unavailable(context.accountId, context.loginId, 'access_unavailable');
|
|
402
|
+
}
|
|
403
|
+
const confirmed = await readCurrent();
|
|
404
|
+
if (!confirmed || !sameContext(context, confirmed)) {
|
|
405
|
+
return this.unavailable(context.accountId, context.loginId, 'context_changed');
|
|
406
|
+
}
|
|
407
|
+
return this.snapshot(context, next);
|
|
408
|
+
}
|
|
409
|
+
validAccess(context, access) {
|
|
410
|
+
return Boolean(access.accessToken) && access.accountId === context.workspaceId
|
|
411
|
+
&& access.grantGeneration === context.grantGeneration
|
|
412
|
+
&& future(access.expiresAt, this.now() + this.policy.minAccessValidityMs);
|
|
413
|
+
}
|
|
414
|
+
query(access) {
|
|
415
|
+
const credential = { kind: 'chatgptAccess', providerId: 'openai',
|
|
416
|
+
accessToken: access.accessToken, accountId: access.accountId,
|
|
417
|
+
isFedrampAccount: access.isFedrampAccount };
|
|
418
|
+
return this.options.provider.getAccountRateLimits(credential, { timeoutMs: this.policy.providerTimeoutMs });
|
|
419
|
+
}
|
|
420
|
+
/** Wait for admitted reads before the daemon disposes the shared provider or database. */
|
|
421
|
+
close() {
|
|
422
|
+
if (this.closing)
|
|
423
|
+
return this.closing;
|
|
424
|
+
this.closed = true;
|
|
425
|
+
this.closing = Promise.allSettled([...this.admitted]).then(() => undefined);
|
|
426
|
+
return this.closing;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5hdXRob3JpdHl1c2FnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuYXV0aG9yaXR5dXNhZ2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFnSXhDLE1BQU0sUUFBUSxHQUFHO0lBQ2YsZUFBZSxFQUFFLE1BQU07SUFDdkIsYUFBYSxFQUFFLE9BQU87SUFDdEIsb0JBQW9CLEVBQUUsTUFBTTtJQUM1QixXQUFXLEVBQUUsTUFBTTtJQUNuQixVQUFVLEVBQUUsT0FBTztJQUNuQixpQkFBaUIsRUFBRSxNQUFNO0lBQ3pCLG1CQUFtQixFQUFFLE1BQU07Q0FDNUIsQ0FBQztBQUVGLE1BQU0sV0FBVyxHQUFHLENBQUMsSUFBNkIsRUFBRSxLQUE4QixFQUFXLEVBQUUsQ0FDN0YsSUFBSSxDQUFDLEtBQUssS0FBSyxLQUFLLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssS0FBSyxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLEtBQUssQ0FBQyxPQUFPO09BQy9GLElBQUksQ0FBQyxTQUFTLEtBQUssS0FBSyxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLEtBQUssQ0FBQyxXQUFXO09BQzVFLElBQUksQ0FBQyxVQUFVLEtBQUssS0FBSyxDQUFDLFVBQVU7T0FDcEMsSUFBSSxDQUFDLE9BQU8sS0FBSyxLQUFLLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssS0FBSyxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLEtBQUssQ0FBQyxVQUFVO09BQ3BHLElBQUksQ0FBQyxPQUFPLEtBQUssS0FBSyxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsdUJBQXVCLEtBQUssS0FBSyxDQUFDLHVCQUF1QjtPQUNoRyxJQUFJLENBQUMsZUFBZSxLQUFLLEtBQUssQ0FBQyxlQUFlO09BQzlD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
|