@modelprofile.com/authswitch 9.2.0 → 10.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 +2 -2
- package/dist_ts/authority-contract.d.ts +52 -6
- package/dist_ts/authority-contract.js +1 -1
- package/dist_ts/classes.authoritybroker.d.ts +20 -4
- package/dist_ts/classes.authoritybroker.js +44 -8
- package/dist_ts/classes.authoritycli.d.ts +4 -1
- package/dist_ts/classes.authoritycli.js +42 -7
- package/dist_ts/classes.authorityclient.d.ts +9 -1
- package/dist_ts/classes.authorityclient.js +9 -3
- package/dist_ts/classes.authoritydaemon.js +8 -5
- package/dist_ts/classes.authoritydatabase.d.ts +6 -2
- package/dist_ts/classes.authoritydatabase.js +13 -6
- package/dist_ts/classes.authorityimport.d.ts +4 -4
- package/dist_ts/classes.authorityimport.js +8 -7
- package/dist_ts/classes.authoritymodels.d.ts +11 -3
- package/dist_ts/classes.authoritymodels.js +43 -13
- package/dist_ts/classes.authoritypreuse.d.ts +8 -2
- package/dist_ts/classes.authoritypreuse.js +27 -17
- package/dist_ts/classes.authorityusage.d.ts +4 -3
- package/dist_ts/classes.authorityusage.js +3 -5
- package/dist_ts/classes.cli.js +3 -5
- package/dist_ts/classes.codexpreuse.d.ts +14 -3
- package/dist_ts/classes.codexpreuse.js +127 -44
- package/dist_ts/classes.codexstatus.js +44 -95
- package/dist_ts/classes.login.d.ts +20 -10
- package/dist_ts/classes.login.js +14 -13
- package/dist_ts/classes.openaiprovider.d.ts +53 -0
- package/dist_ts/classes.openaiprovider.js +340 -0
- package/dist_ts/classes.opencodeharness.js +3 -2
- package/dist_ts/classes.service.js +3 -5
- package/dist_ts/index.d.ts +2 -0
- package/dist_ts/index.js +3 -1
- package/dist_ts/interfaces.openai.d.ts +118 -0
- package/dist_ts/interfaces.openai.js +3 -0
- package/dist_ts/openaiauth.d.ts +76 -0
- package/dist_ts/openaiauth.js +371 -0
- package/dist_ts/openaiusage.d.ts +59 -0
- package/dist_ts/openaiusage.js +222 -0
- package/dist_ts/plugins.d.ts +1 -3
- package/dist_ts/plugins.js +2 -4
- package/dist_ts/preuse.d.ts +50 -0
- package/dist_ts/preuse.js +63 -4
- package/dist_ts/ts_migration/legacysources/shared.js +4 -3
- package/openai-codex-license.txt +201 -0
- package/package.json +6 -4
- package/readme.md +86 -10
- package/third-party-notices.md +29 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/authority-contract.ts +56 -8
- package/ts/classes.authoritybroker.ts +52 -13
- package/ts/classes.authoritycli.ts +48 -6
- package/ts/classes.authorityclient.ts +11 -3
- package/ts/classes.authoritydaemon.ts +7 -4
- package/ts/classes.authoritydatabase.ts +14 -6
- package/ts/classes.authorityimport.ts +12 -12
- package/ts/classes.authoritymodels.ts +42 -14
- package/ts/classes.authoritypreuse.ts +30 -17
- package/ts/classes.authorityusage.ts +8 -9
- package/ts/classes.cli.ts +3 -3
- package/ts/classes.codexpreuse.ts +130 -40
- package/ts/classes.codexstatus.ts +40 -73
- package/ts/classes.login.ts +34 -21
- package/ts/classes.openaiprovider.ts +365 -0
- package/ts/classes.opencodeharness.ts +3 -2
- package/ts/classes.service.ts +3 -4
- package/ts/index.ts +2 -0
- package/ts/interfaces.openai.ts +142 -0
- package/ts/openaiauth.ts +422 -0
- package/ts/openaiusage.ts +247 -0
- package/ts/plugins.ts +1 -3
- package/ts/preuse.ts +88 -3
- package/ts/ts_migration/legacysources/shared.ts +4 -3
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { IOpenAiAccountRateLimits } from './interfaces.openai.js';
|
|
2
|
+
/**
|
|
3
|
+
* Why a backend read failed, never with the response body:
|
|
4
|
+
* - `unauthorized`: the access token was rejected (401); renew it or sign in again.
|
|
5
|
+
* - `rate_limited`: the service refused for too many requests (429); `retryAfter` is its raw header.
|
|
6
|
+
* - `forbidden`: access denied (403). `challenge`: a Cloudflare verification challenge answered instead.
|
|
7
|
+
* - `http`: another error status. `protocol`: an answer too large or not what this route returns.
|
|
8
|
+
* - `network`: the request did not complete. `aborted` / `timeout`: the caller's signal or the time limit.
|
|
9
|
+
*/
|
|
10
|
+
export type TOpenAiBackendFailure = 'unauthorized' | 'rate_limited' | 'forbidden' | 'challenge' | 'http' | 'protocol' | 'network' | 'aborted' | 'timeout';
|
|
11
|
+
export declare class OpenAiBackendError extends Error {
|
|
12
|
+
readonly reason: TOpenAiBackendFailure;
|
|
13
|
+
readonly status?: number | undefined;
|
|
14
|
+
readonly retryAfter: string | null;
|
|
15
|
+
constructor(reason: TOpenAiBackendFailure, status?: number | undefined, retryAfter?: string | null);
|
|
16
|
+
}
|
|
17
|
+
/** Access to read one ChatGPT account. A legacy login may carry no workspace; its reads send none. */
|
|
18
|
+
export interface IOpenAiReadAccess {
|
|
19
|
+
accessToken: string;
|
|
20
|
+
accountId?: string;
|
|
21
|
+
isFedrampAccount: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface IOpenAiBackendReadOptions {
|
|
24
|
+
fetch?: typeof fetch;
|
|
25
|
+
signal?: AbortSignal;
|
|
26
|
+
timeoutMs?: number;
|
|
27
|
+
/** The `originator` header; defaults to `authswitch`. */
|
|
28
|
+
originator?: string;
|
|
29
|
+
/** Extra request headers a route requires. */
|
|
30
|
+
headers?: Record<string, string>;
|
|
31
|
+
}
|
|
32
|
+
/** One bounded GET of `https://chatgpt.com/backend-api/<path>`, answered as a JSON object or an `OpenAiBackendError`. */
|
|
33
|
+
export declare const readChatGptBackend: (path: string, access: IOpenAiReadAccess, options?: IOpenAiBackendReadOptions) => Promise<Record<string, unknown>>;
|
|
34
|
+
/** Credits and spend control, which only the account views show; the stored reading keeps the limits alone. */
|
|
35
|
+
export interface IOpenAiAccountUsage {
|
|
36
|
+
/** The workspace the service answered for, when it names one. */
|
|
37
|
+
accountId: string | null;
|
|
38
|
+
rateLimits: IOpenAiAccountRateLimits;
|
|
39
|
+
credits?: {
|
|
40
|
+
unlimited: boolean;
|
|
41
|
+
hasCredits: boolean;
|
|
42
|
+
balance?: string;
|
|
43
|
+
};
|
|
44
|
+
spendControl?: {
|
|
45
|
+
reached: boolean;
|
|
46
|
+
individualLimit?: {
|
|
47
|
+
used: string;
|
|
48
|
+
limit: string;
|
|
49
|
+
remaining: string;
|
|
50
|
+
resetsAt: number;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** Projects one `wham/usage` answer, refusing it whole when any member it carries is not the documented shape. */
|
|
55
|
+
export declare const projectOpenAiAccountUsage: (value: unknown, observedAt: string) => IOpenAiAccountUsage;
|
|
56
|
+
/** Reads and projects one account's `wham/usage`. An answer for another workspace is refused. */
|
|
57
|
+
export declare const readOpenAiAccountUsage: (access: IOpenAiReadAccess, options?: IOpenAiBackendReadOptions & {
|
|
58
|
+
now?: () => Date;
|
|
59
|
+
}) => Promise<IOpenAiAccountUsage>;
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
// OpenAI protocol portions are adapted in TypeScript from OpenAI Codex (Apache-2.0) and modified by Task Venture Capital GmbH; see third-party-notices.md.
|
|
2
|
+
import * as plugins from './plugins.js';
|
|
3
|
+
import { commitinfo } from './00_commitinfo_data.js';
|
|
4
|
+
/**
|
|
5
|
+
* The one reader of the ChatGPT backend's account routes, and of `wham/usage` in particular (Codex
|
|
6
|
+
* `codex-rs/backend-client`: `client.rs`, `models/rate_limit_status_payload.rs`). The authority's usage reading,
|
|
7
|
+
* the import's access-token proof and the legacy `limits` view all read an account through here.
|
|
8
|
+
*/
|
|
9
|
+
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
10
|
+
const MAX_RESPONSE_BYTES = 1024 * 1024;
|
|
11
|
+
const MAX_ADDITIONAL_RATE_LIMITS = 128;
|
|
12
|
+
const MAX_TEXT_BYTES = 256;
|
|
13
|
+
export class OpenAiBackendError extends Error {
|
|
14
|
+
reason;
|
|
15
|
+
status;
|
|
16
|
+
retryAfter;
|
|
17
|
+
constructor(reason, status, retryAfter = null) {
|
|
18
|
+
super(`ChatGPT backend request failed (${reason}${status === undefined ? '' : ` ${status}`}).`);
|
|
19
|
+
this.reason = reason;
|
|
20
|
+
this.status = status;
|
|
21
|
+
this.retryAfter = retryAfter;
|
|
22
|
+
this.name = 'OpenAiBackendError';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const isRecord = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
26
|
+
/** One bounded GET of `https://chatgpt.com/backend-api/<path>`, answered as a JSON object or an `OpenAiBackendError`. */
|
|
27
|
+
export const readChatGptBackend = async (path, access, options = {}) => {
|
|
28
|
+
// A referenced timer, unlike `AbortSignal.timeout`, so the read settles within its limit even when the
|
|
29
|
+
// transport ignores its signal and holds nothing else open.
|
|
30
|
+
const timeout = new AbortController();
|
|
31
|
+
const timer = setTimeout(() => timeout.abort(), options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
32
|
+
const signal = options.signal ? AbortSignal.any([options.signal, timeout.signal]) : timeout.signal;
|
|
33
|
+
const fetcher = options.fetch ?? globalThis.fetch;
|
|
34
|
+
const failure = () => new OpenAiBackendError(timeout.signal.aborted ? 'timeout' : signal.aborted ? 'aborted' : 'network');
|
|
35
|
+
// The signal settles the read even when a transport ignores it.
|
|
36
|
+
let onAbort;
|
|
37
|
+
const aborted = new Promise((_resolve, reject) => {
|
|
38
|
+
onAbort = () => reject(failure());
|
|
39
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
40
|
+
if (signal.aborted)
|
|
41
|
+
onAbort();
|
|
42
|
+
});
|
|
43
|
+
aborted.catch(() => undefined);
|
|
44
|
+
try {
|
|
45
|
+
return await Promise.race([readBody(fetcher, path, access, options, signal, failure), aborted]);
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
clearTimeout(timer);
|
|
49
|
+
signal.removeEventListener('abort', onAbort);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const readBody = async (fetcher, path, access, options, signal, failure) => {
|
|
53
|
+
if (signal.aborted)
|
|
54
|
+
throw failure();
|
|
55
|
+
let response;
|
|
56
|
+
try {
|
|
57
|
+
response = await fetcher(`https://chatgpt.com/backend-api/${path}`, {
|
|
58
|
+
method: 'GET', redirect: 'error', signal,
|
|
59
|
+
headers: { ...plugins.flexOpenAi.createOpenAiChatGptAccessHeaders(access, options.originator ?? 'authswitch'),
|
|
60
|
+
'User-Agent': `authswitch/${commitinfo.version}`, Accept: 'application/json', ...options.headers },
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
throw failure();
|
|
65
|
+
}
|
|
66
|
+
if (signal.aborted) {
|
|
67
|
+
await response.body?.cancel().catch(() => undefined);
|
|
68
|
+
throw failure();
|
|
69
|
+
}
|
|
70
|
+
if (!response.ok) {
|
|
71
|
+
await response.body?.cancel().catch(() => undefined);
|
|
72
|
+
if (response.headers.get('cf-mitigated') === 'challenge')
|
|
73
|
+
throw new OpenAiBackendError('challenge', response.status);
|
|
74
|
+
if (response.status === 401)
|
|
75
|
+
throw new OpenAiBackendError('unauthorized', 401);
|
|
76
|
+
if (response.status === 429)
|
|
77
|
+
throw new OpenAiBackendError('rate_limited', 429, response.headers.get('retry-after'));
|
|
78
|
+
if (response.status === 403)
|
|
79
|
+
throw new OpenAiBackendError('forbidden', 403);
|
|
80
|
+
throw new OpenAiBackendError('http', response.status);
|
|
81
|
+
}
|
|
82
|
+
const declared = response.headers.get('content-length');
|
|
83
|
+
if (declared !== null && (!/^\d+$/.test(declared) || Number(declared) > MAX_RESPONSE_BYTES)) {
|
|
84
|
+
await response.body?.cancel().catch(() => undefined);
|
|
85
|
+
throw new OpenAiBackendError('protocol', response.status);
|
|
86
|
+
}
|
|
87
|
+
const reader = response.body?.getReader();
|
|
88
|
+
if (!reader)
|
|
89
|
+
throw new OpenAiBackendError('protocol', response.status);
|
|
90
|
+
const chunks = [];
|
|
91
|
+
let size = 0;
|
|
92
|
+
const cancel = () => { void reader.cancel().catch(() => undefined); };
|
|
93
|
+
signal.addEventListener('abort', cancel, { once: true });
|
|
94
|
+
try {
|
|
95
|
+
while (true) {
|
|
96
|
+
const part = await reader.read();
|
|
97
|
+
if (part.done)
|
|
98
|
+
break;
|
|
99
|
+
size += part.value.byteLength;
|
|
100
|
+
if (size > MAX_RESPONSE_BYTES) {
|
|
101
|
+
await reader.cancel().catch(() => undefined);
|
|
102
|
+
throw new OpenAiBackendError('protocol', response.status);
|
|
103
|
+
}
|
|
104
|
+
chunks.push(part.value);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
if (error instanceof OpenAiBackendError)
|
|
109
|
+
throw error;
|
|
110
|
+
throw failure();
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
signal.removeEventListener('abort', cancel);
|
|
114
|
+
reader.releaseLock();
|
|
115
|
+
}
|
|
116
|
+
if (signal.aborted)
|
|
117
|
+
throw failure();
|
|
118
|
+
let body;
|
|
119
|
+
try {
|
|
120
|
+
body = JSON.parse(Buffer.concat(chunks).toString('utf8'));
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
throw new OpenAiBackendError('protocol', response.status);
|
|
124
|
+
}
|
|
125
|
+
if (!isRecord(body))
|
|
126
|
+
throw new OpenAiBackendError('protocol', response.status);
|
|
127
|
+
return body;
|
|
128
|
+
};
|
|
129
|
+
const invalid = () => { throw new OpenAiBackendError('protocol'); };
|
|
130
|
+
const boundedInteger = (value, minimum, maximum = Number.MAX_SAFE_INTEGER) => Number.isSafeInteger(value) && value >= minimum && value <= maximum ? value : invalid();
|
|
131
|
+
const boundedText = (value) => typeof value === 'string' && value.length > 0 && Buffer.byteLength(value, 'utf8') <= MAX_TEXT_BYTES ? value : invalid();
|
|
132
|
+
const present = (value) => value !== null && value !== undefined;
|
|
133
|
+
const projectWindow = (value) => {
|
|
134
|
+
if (!isRecord(value))
|
|
135
|
+
return invalid();
|
|
136
|
+
return {
|
|
137
|
+
usedPercent: boundedInteger(value.used_percent, 0, 100),
|
|
138
|
+
limitWindowSeconds: boundedInteger(value.limit_window_seconds, 1),
|
|
139
|
+
resetAfterSeconds: boundedInteger(value.reset_after_seconds, 0),
|
|
140
|
+
resetsAt: boundedInteger(value.reset_at, 0),
|
|
141
|
+
};
|
|
142
|
+
};
|
|
143
|
+
const projectDetails = (value) => {
|
|
144
|
+
if (!isRecord(value) || typeof value.allowed !== 'boolean' || typeof value.limit_reached !== 'boolean')
|
|
145
|
+
return invalid();
|
|
146
|
+
return {
|
|
147
|
+
allowed: value.allowed,
|
|
148
|
+
limitReached: value.limit_reached,
|
|
149
|
+
...(present(value.primary_window) ? { primaryWindow: projectWindow(value.primary_window) } : {}),
|
|
150
|
+
...(present(value.secondary_window) ? { secondaryWindow: projectWindow(value.secondary_window) } : {}),
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
/** Projects one `wham/usage` answer, refusing it whole when any member it carries is not the documented shape. */
|
|
154
|
+
export const projectOpenAiAccountUsage = (value, observedAt) => {
|
|
155
|
+
if (!isRecord(value))
|
|
156
|
+
return invalid();
|
|
157
|
+
const additional = value.additional_rate_limits ?? [];
|
|
158
|
+
if (!Array.isArray(additional) || additional.length > MAX_ADDITIONAL_RATE_LIMITS)
|
|
159
|
+
return invalid();
|
|
160
|
+
let credits;
|
|
161
|
+
if (present(value.credits)) {
|
|
162
|
+
const raw = value.credits;
|
|
163
|
+
if (!isRecord(raw) || typeof raw.unlimited !== 'boolean' || typeof raw.has_credits !== 'boolean')
|
|
164
|
+
return invalid();
|
|
165
|
+
credits = { unlimited: raw.unlimited, hasCredits: raw.has_credits,
|
|
166
|
+
...(present(raw.balance) ? { balance: boundedText(raw.balance) } : {}) };
|
|
167
|
+
}
|
|
168
|
+
let spendControl;
|
|
169
|
+
if (present(value.spend_control)) {
|
|
170
|
+
const raw = value.spend_control;
|
|
171
|
+
if (!isRecord(raw) || typeof raw.reached !== 'boolean')
|
|
172
|
+
return invalid();
|
|
173
|
+
let individualLimit;
|
|
174
|
+
if (present(raw.individual_limit)) {
|
|
175
|
+
const limit = raw.individual_limit;
|
|
176
|
+
if (!isRecord(limit))
|
|
177
|
+
return invalid();
|
|
178
|
+
individualLimit = { used: boundedText(limit.used), limit: boundedText(limit.limit),
|
|
179
|
+
remaining: boundedText(limit.remaining), resetsAt: boundedInteger(limit.reset_at, 0) };
|
|
180
|
+
}
|
|
181
|
+
spendControl = { reached: raw.reached, ...(individualLimit ? { individualLimit } : {}) };
|
|
182
|
+
}
|
|
183
|
+
const reachedType = value.rate_limit_reached_type;
|
|
184
|
+
if (present(reachedType) && !isRecord(reachedType))
|
|
185
|
+
return invalid();
|
|
186
|
+
const resetCredits = value.rate_limit_reset_credits;
|
|
187
|
+
if (present(resetCredits) && !isRecord(resetCredits))
|
|
188
|
+
return invalid();
|
|
189
|
+
return {
|
|
190
|
+
accountId: present(value.account_id) ? boundedText(value.account_id) : null,
|
|
191
|
+
rateLimits: {
|
|
192
|
+
providerId: 'openai',
|
|
193
|
+
plan: boundedText(value.plan_type),
|
|
194
|
+
observedAt,
|
|
195
|
+
...(present(value.rate_limit) ? { rateLimit: projectDetails(value.rate_limit) } : {}),
|
|
196
|
+
additionalRateLimits: additional.map(raw => {
|
|
197
|
+
if (!isRecord(raw))
|
|
198
|
+
return invalid();
|
|
199
|
+
return {
|
|
200
|
+
limitName: boundedText(raw.limit_name),
|
|
201
|
+
meteredFeature: boundedText(raw.metered_feature),
|
|
202
|
+
...(present(raw.rate_limit) ? { rateLimit: projectDetails(raw.rate_limit) } : {}),
|
|
203
|
+
};
|
|
204
|
+
}),
|
|
205
|
+
...(isRecord(reachedType) ? { rateLimitReachedType: boundedText(reachedType.type) } : {}),
|
|
206
|
+
...(isRecord(resetCredits)
|
|
207
|
+
? { rateLimitResetCreditsAvailableCount: boundedInteger(resetCredits.available_count, 0) } : {}),
|
|
208
|
+
},
|
|
209
|
+
...(credits ? { credits } : {}),
|
|
210
|
+
...(spendControl ? { spendControl } : {}),
|
|
211
|
+
};
|
|
212
|
+
};
|
|
213
|
+
/** Reads and projects one account's `wham/usage`. An answer for another workspace is refused. */
|
|
214
|
+
export const readOpenAiAccountUsage = async (access, options = {}) => {
|
|
215
|
+
const body = await readChatGptBackend('wham/usage', access, options);
|
|
216
|
+
const usage = projectOpenAiAccountUsage(body, (options.now ?? (() => new Date()))().toISOString());
|
|
217
|
+
if (usage.accountId !== null && access.accountId !== undefined && usage.accountId !== access.accountId) {
|
|
218
|
+
throw new OpenAiBackendError('protocol');
|
|
219
|
+
}
|
|
220
|
+
return usage;
|
|
221
|
+
};
|
|
222
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpdXNhZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9vcGVuYWl1c2FnZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwySkFBMko7QUFFM0osT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBR3JEOzs7O0dBSUc7QUFFSCxNQUFNLGtCQUFrQixHQUFHLE1BQU0sQ0FBQztBQUNsQyxNQUFNLGtCQUFrQixHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFDdkMsTUFBTSwwQkFBMEIsR0FBRyxHQUFHLENBQUM7QUFDdkMsTUFBTSxjQUFjLEdBQUcsR0FBRyxDQUFDO0FBYTNCLE1BQU0sT0FBTyxrQkFBbUIsU0FBUSxLQUFLO0lBQ2Y7SUFBK0M7SUFDekQ7SUFEbEIsWUFBNEIsTUFBNkIsRUFBa0IsTUFBZSxFQUN4RSxhQUE0QixJQUFJO1FBQ2hELEtBQUssQ0FBQyxtQ0FBbUMsTUFBTSxHQUFHLE1BQU0sS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFGdEUsV0FBTSxHQUFOLE1BQU0sQ0FBdUI7UUFBa0IsV0FBTSxHQUFOLE1BQU0sQ0FBUztRQUN4RSxlQUFVLEdBQVYsVUFBVSxDQUFzQjtRQUVoRCxJQUFJLENBQUMsSUFBSSxHQUFHLG9CQUFvQixDQUFDO0lBQ25DLENBQUM7Q0FDRjtBQW1CRCxNQUFNLFFBQVEsR0FBRyxDQUFDLEtBQWMsRUFBb0MsRUFBRSxDQUNwRSxLQUFLLEtBQUssSUFBSSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7QUFFdkUseUhBQXlIO0FBQ3pILE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLEtBQUssRUFBRSxJQUFZLEVBQUUsTUFB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
|
package/dist_ts/plugins.d.ts
CHANGED
|
@@ -29,7 +29,5 @@ import * as typedrequest from '@api.global/typedrequest';
|
|
|
29
29
|
export { smartconsole, smartsecret, smartdaemon, typedrequest };
|
|
30
30
|
import * as flexModels from '@modelprofile.com/flexharness-models';
|
|
31
31
|
import * as flexOpenAi from '@modelprofile.com/flexharness-providers/openai';
|
|
32
|
-
import * as flexAuth from '@modelprofile.com/flexharness-providers/auth';
|
|
33
|
-
import * as flexAccounts from '@modelprofile.com/flexharness-providers/accounts';
|
|
34
32
|
import * as crossharness from '@modelprofile.com/mcp-crossharness';
|
|
35
|
-
export { flexModels, flexOpenAi,
|
|
33
|
+
export { flexModels, flexOpenAi, crossharness };
|
package/dist_ts/plugins.js
CHANGED
|
@@ -31,8 +31,6 @@ export { smartconsole, smartsecret, smartdaemon, typedrequest };
|
|
|
31
31
|
// @modelprofile.com modules
|
|
32
32
|
import * as flexModels from '@modelprofile.com/flexharness-models';
|
|
33
33
|
import * as flexOpenAi from '@modelprofile.com/flexharness-providers/openai';
|
|
34
|
-
import * as flexAuth from '@modelprofile.com/flexharness-providers/auth';
|
|
35
|
-
import * as flexAccounts from '@modelprofile.com/flexharness-providers/accounts';
|
|
36
34
|
import * as crossharness from '@modelprofile.com/mcp-crossharness';
|
|
37
|
-
export { flexModels, flexOpenAi,
|
|
38
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
35
|
+
export { flexModels, flexOpenAi, crossharness };
|
|
36
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsc0JBQXNCO0FBQ3RCLE9BQU8sS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sS0FBSyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxZQUFZLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxLQUFLLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFDdEMsT0FBTyxLQUFLLEdBQUcsTUFBTSxVQUFVLENBQUM7QUFDaEMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM1QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBR3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUVsRSxNQUFNLGFBQWEsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNyRCxrR0FBa0c7QUFDbEcsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLEdBQWlDLEVBQUUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUM7QUFLM0Y7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUcsR0FBNkIsRUFBRSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0FBRTVGLHdCQUF3QjtBQUN4QiwrREFBK0Q7QUFDL0QsT0FBTyxLQUFLLE9BQU8sTUFBTSw4QkFBOEIsQ0FBQztBQUN4RCxpR0FBaUc7QUFDakcsT0FBTyxLQUFLLGFBQWEsTUFBTSx1QkFBdUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxDQUFDO0FBRWxDLHNCQUFzQjtBQUN0QixPQUFPLEtBQUssWUFBWSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxXQUFXLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxLQUFLLFdBQVcsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEtBQUssWUFBWSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsQ0FBQztBQUVoRSw0QkFBNEI7QUFDNUIsT0FBTyxLQUFLLFVBQVUsTUFBTSxzQ0FBc0MsQ0FBQztBQUNuRSxPQUFPLEtBQUssVUFBVSxNQUFNLGdEQUFnRCxDQUFDO0FBQzdFLE9BQU8sS0FBSyxZQUFZLE1BQU0sb0NBQW9DLENBQUM7QUFDbkUsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLENBQUMifQ==
|
package/dist_ts/preuse.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { IAuthHarness, IHarnessAccount, IHarnessPreuseOptions, IHarnessPreuseResult, IHarnessUsageWindow } from './interfaces.harness.js';
|
|
2
2
|
export declare const defaultPreusePrompt = "Write 2000 words about strawberries.";
|
|
3
|
+
/** The close of every message about a prompt that may have reached the provider. */
|
|
4
|
+
export declare const preuseMayHaveConsumed = "Tokens may already have been consumed; no automatic retry was made. Check the account status before trying again.";
|
|
3
5
|
/**
|
|
4
6
|
* Only fixed local messages may cross the inference error boundary.
|
|
5
7
|
*
|
|
@@ -12,6 +14,54 @@ export declare class PreuseError extends Error {
|
|
|
12
14
|
readonly requestStarted: boolean;
|
|
13
15
|
constructor(messageArg: string, requestStarted?: boolean);
|
|
14
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* A limit that kept a preuse prompt from being answered.
|
|
19
|
+
*
|
|
20
|
+
* `usage_limit` is the account's quota, spent until it resets; `rate_limit` a short throttle. `window` names the
|
|
21
|
+
* window by its length (`weekly`, `five-hour`) and `resetsAt` is an ISO time; either is null when the account's
|
|
22
|
+
* usage reading or the provider's refusal did not state it.
|
|
23
|
+
*/
|
|
24
|
+
export interface IPreuseLimit {
|
|
25
|
+
kind: 'usage_limit' | 'rate_limit';
|
|
26
|
+
window: string | null;
|
|
27
|
+
resetsAt: string | null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* `Weekly usage limit reached, resets in 16h 46min (2026-09-27 05:12)`: human text, so the reset reads in local time.
|
|
31
|
+
* The limit itself keeps its ISO `resetsAt` for receipts and JSON output.
|
|
32
|
+
*/
|
|
33
|
+
export declare const describePreuseLimit: (limitArg: IPreuseLimit, nowArg: number) => string;
|
|
34
|
+
/**
|
|
35
|
+
* A preuse a limit stopped. `usage` is the account's own usage reading before anything was sent; `provider`
|
|
36
|
+
* is the provider's refusal of the prompt, which `generationStarted` says came before or after it began to
|
|
37
|
+
* answer: a refusal before its answer consumed nothing.
|
|
38
|
+
*/
|
|
39
|
+
export declare class PreuseLimitError extends PreuseError {
|
|
40
|
+
readonly limit: IPreuseLimit;
|
|
41
|
+
readonly source: 'usage' | 'provider';
|
|
42
|
+
readonly generationStarted: boolean;
|
|
43
|
+
constructor(limit: IPreuseLimit, source: 'usage' | 'provider', generationStarted: boolean, nowArg: number);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Why a sent preuse prompt failed without a limit, and never with the provider's text.
|
|
47
|
+
*
|
|
48
|
+
* `http` is an answer with an HTTP error status; `stream` an error the answer stream reported after it began,
|
|
49
|
+
* with the machine-readable code the provider stated and no status, since its answer was a success; `response` an answer that could not be read;
|
|
50
|
+
* `network` a connection that failed before any answer; `aborted` an abort that was neither the caller's nor the
|
|
51
|
+
* deadline; `unknown` anything else. `status` and `providerCode` are null when the failure did not state them.
|
|
52
|
+
*/
|
|
53
|
+
export interface IPreuseFailure {
|
|
54
|
+
kind: 'http' | 'stream' | 'response' | 'network' | 'aborted' | 'unknown';
|
|
55
|
+
status: number | null;
|
|
56
|
+
providerCode: string | null;
|
|
57
|
+
}
|
|
58
|
+
/** `the provider answered HTTP 503`: the cause of a failed preuse, as the tail of a sentence. */
|
|
59
|
+
export declare const describePreuseFailure: (failureArg: IPreuseFailure) => string;
|
|
60
|
+
/** A sent preuse prompt that failed for the stated cause; its tokens may have been consumed. */
|
|
61
|
+
export declare class PreuseFailureError extends PreuseError {
|
|
62
|
+
readonly failure: IPreuseFailure;
|
|
63
|
+
constructor(failure: IPreuseFailure);
|
|
64
|
+
}
|
|
15
65
|
export declare const validatePreuseOptions: (optionsArg: IHarnessPreuseOptions) => void;
|
|
16
66
|
/**
|
|
17
67
|
* What one account's turn in a run did.
|
package/dist_ts/preuse.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { orderedUsageWindows } from './accounts.js';
|
|
1
|
+
import { localDateTime, orderedUsageWindows, until } from './accounts.js';
|
|
2
2
|
export const defaultPreusePrompt = 'Write 2000 words about strawberries.';
|
|
3
|
+
/** The close of every message about a prompt that may have reached the provider. */
|
|
4
|
+
export const preuseMayHaveConsumed = 'Tokens may already have been consumed; no automatic retry was made. Check the account status before trying again.';
|
|
3
5
|
/**
|
|
4
6
|
* Only fixed local messages may cross the inference error boundary.
|
|
5
7
|
*
|
|
@@ -15,6 +17,59 @@ export class PreuseError extends Error {
|
|
|
15
17
|
this.requestStarted = requestStarted;
|
|
16
18
|
}
|
|
17
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* `Weekly usage limit reached, resets in 16h 46min (2026-09-27 05:12)`: human text, so the reset reads in local time.
|
|
22
|
+
* The limit itself keeps its ISO `resetsAt` for receipts and JSON output.
|
|
23
|
+
*/
|
|
24
|
+
export const describePreuseLimit = (limitArg, nowArg) => {
|
|
25
|
+
const name = `${limitArg.window === null ? '' : `${limitArg.window} `}${limitArg.kind === 'usage_limit' ? 'usage' : 'rate'} limit reached`;
|
|
26
|
+
const countdown = limitArg.resetsAt === null ? null : until(limitArg.resetsAt, nowArg);
|
|
27
|
+
const at = localDateTime(limitArg.resetsAt);
|
|
28
|
+
const reset = limitArg.resetsAt === null ? ''
|
|
29
|
+
: countdown === 'due' ? `, due to reset now (${at})` : `, resets in ${countdown} (${at})`;
|
|
30
|
+
return `${name.charAt(0).toUpperCase()}${name.slice(1)}${reset}`;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* A preuse a limit stopped. `usage` is the account's own usage reading before anything was sent; `provider`
|
|
34
|
+
* is the provider's refusal of the prompt, which `generationStarted` says came before or after it began to
|
|
35
|
+
* answer: a refusal before its answer consumed nothing.
|
|
36
|
+
*/
|
|
37
|
+
export class PreuseLimitError extends PreuseError {
|
|
38
|
+
limit;
|
|
39
|
+
source;
|
|
40
|
+
generationStarted;
|
|
41
|
+
constructor(limit, source, generationStarted, nowArg) {
|
|
42
|
+
const described = describePreuseLimit(limit, nowArg);
|
|
43
|
+
super(source === 'usage' ? `${described}. No preuse prompt was sent.`
|
|
44
|
+
: generationStarted
|
|
45
|
+
? `The provider stopped the answer: ${described}. Tokens may already have been consumed; no automatic retry was made.`
|
|
46
|
+
: `The provider refused the prompt before answering it: ${described}. No tokens were consumed; no automatic retry was made.`, source === 'provider');
|
|
47
|
+
this.limit = limit;
|
|
48
|
+
this.source = source;
|
|
49
|
+
this.generationStarted = generationStarted;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** `the provider answered HTTP 503`: the cause of a failed preuse, as the tail of a sentence. */
|
|
53
|
+
export const describePreuseFailure = (failureArg) => {
|
|
54
|
+
const status = failureArg.status === null ? null : `HTTP ${failureArg.status}`;
|
|
55
|
+
switch (failureArg.kind) {
|
|
56
|
+
case 'http': return `the provider answered ${status ?? 'with an HTTP error'}`;
|
|
57
|
+
case 'stream':
|
|
58
|
+
return `the answer stream reported an error${failureArg.providerCode === null ? '' : ` (code ${failureArg.providerCode})`}`;
|
|
59
|
+
case 'response': return `the provider's answer${status ? ` (${status})` : ''} could not be read`;
|
|
60
|
+
case 'network': return 'no answer arrived: the connection failed';
|
|
61
|
+
case 'aborted': return 'the request was aborted';
|
|
62
|
+
case 'unknown': return 'the request ended in an error that names no cause';
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
/** A sent preuse prompt that failed for the stated cause; its tokens may have been consumed. */
|
|
66
|
+
export class PreuseFailureError extends PreuseError {
|
|
67
|
+
failure;
|
|
68
|
+
constructor(failure) {
|
|
69
|
+
super(`Preuse did not complete: ${describePreuseFailure(failure)}. ${preuseMayHaveConsumed}`, true);
|
|
70
|
+
this.failure = failure;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
18
73
|
export const validatePreuseOptions = (optionsArg) => {
|
|
19
74
|
if (typeof optionsArg.prompt !== 'string' || !optionsArg.prompt.trim() || Buffer.byteLength(optionsArg.prompt, 'utf8') > 16_384) {
|
|
20
75
|
throw new PreuseError('The preuse prompt must contain between 1 and 16384 UTF-8 bytes.');
|
|
@@ -54,10 +109,14 @@ export const preuseCountsText = (summaryArg) => [
|
|
|
54
109
|
...(summaryArg.counts.interrupted ? [`${summaryArg.counts.interrupted} interrupted`] : []),
|
|
55
110
|
...(summaryArg.notRun.length ? [`${summaryArg.notRun.length} not run`] : []),
|
|
56
111
|
].join(', ');
|
|
57
|
-
/**
|
|
112
|
+
/**
|
|
113
|
+
* An adapter's own fixed message, or, for an error that crossed the boundary unnamed, the fixed local text with
|
|
114
|
+
* the error's class name -- never its message, which may carry a provider body or a token.
|
|
115
|
+
*/
|
|
58
116
|
const preuseReason = (errorArg) => errorArg instanceof PreuseError
|
|
59
117
|
? errorArg.message
|
|
60
|
-
:
|
|
118
|
+
: `Preuse failed with an error the adapter did not name (${errorArg instanceof Error && /^[A-Za-z]{1,64}$/.test(errorArg.name) ? errorArg.name : 'unknown'}). `
|
|
119
|
+
+ 'Tokens may already have been consumed; check account status before trying again.';
|
|
61
120
|
/**
|
|
62
121
|
* The account's reset schedule, read after its prompt completed, exactly as the single-account command reads it.
|
|
63
122
|
*
|
|
@@ -115,4 +174,4 @@ export const preuseAccounts = async (harnessArg, accountsArg, optionsArg, report
|
|
|
115
174
|
}
|
|
116
175
|
return { results, counts, notRun };
|
|
117
176
|
};
|
|
118
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
177
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJldXNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvcHJldXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsbUJBQW1CLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRzFFLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLHNDQUFzQyxDQUFDO0FBRTFFLG9GQUFvRjtBQUNwRixNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxtSEFBbUgsQ0FBQztBQUV6Sjs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxPQUFPLFdBQVksU0FBUSxLQUFLO0lBQ1k7SUFBaEQsWUFBWSxVQUFrQixFQUFrQixpQkFBaUIsS0FBSztRQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUE1QyxtQkFBYyxHQUFkLGNBQWMsQ0FBUTtJQUF1QixDQUFDO0NBQy9GO0FBZUQ7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxRQUFzQixFQUFFLE1BQWMsRUFBVSxFQUFFO0lBQ3BGLE1BQU0sSUFBSSxHQUFHLEdBQUcsUUFBUSxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLElBQUksS0FBSyxhQUFhLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxnQkFBZ0IsQ0FBQztJQUMzSSxNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsUUFBUSxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN2RixNQUFNLEVBQUUsR0FBRyxhQUFhLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzVDLE1BQU0sS0FBSyxHQUFHLFFB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
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
2
|
import { readCredentialRaw } from '../../classes.credentialstore.js';
|
|
3
|
+
import { parseOpenAiTokenClaims } from '../../openaiauth.js';
|
|
3
4
|
import { resolveClaudeNativeHome } from '../../classes.claudenative.js';
|
|
4
5
|
export const resolveLegacySourceLocations = (env, homeDirectory) => {
|
|
5
6
|
const dataHome = env.XDG_DATA_HOME || plugins.path.join(homeDirectory, '.local', 'share');
|
|
@@ -54,7 +55,7 @@ export const parseLegacyJson = (raw) => {
|
|
|
54
55
|
export const openAiSourceIdentity = (idToken) => {
|
|
55
56
|
let info;
|
|
56
57
|
try {
|
|
57
|
-
info =
|
|
58
|
+
info = parseOpenAiTokenClaims(idToken);
|
|
58
59
|
}
|
|
59
60
|
catch {
|
|
60
61
|
return null;
|
|
@@ -122,7 +123,7 @@ export const accessTokenExpiry = (accessToken) => {
|
|
|
122
123
|
if (!accessToken)
|
|
123
124
|
return null;
|
|
124
125
|
try {
|
|
125
|
-
return
|
|
126
|
+
return parseOpenAiTokenClaims(accessToken).expiresAt ?? null;
|
|
126
127
|
}
|
|
127
128
|
catch {
|
|
128
129
|
return null;
|
|
@@ -137,4 +138,4 @@ export const accessProofAvailable = (expiresAt, now) => {
|
|
|
137
138
|
};
|
|
138
139
|
export const EXPIRED_ACCESS_PROBLEM = 'the stored access token has expired, so the non-rotating proof is unavailable until the native tool '
|
|
139
140
|
+ 'refreshes its own store';
|
|
140
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
141
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvdHNfbWlncmF0aW9uL2xlZ2FjeXNvdXJjZXMvc2hhcmVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDckUsT0FBTyxFQUFFLHNCQUFzQixFQUEyQixNQUFNLHFCQUFxQixDQUFDO0FBQ3RGLE9BQU8sRUFBRSx1QkFBdUIsRUFBb0MsTUFBTSwrQkFBK0IsQ0FBQztBQXdEMUcsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBQUcsQ0FBQyxHQUFzQixFQUNqRSxhQUFxQixFQUEwQixFQUFFO0lBQ2pELE1BQU0sUUFBUSxHQUFHLEdBQUcsQ0FBQyxhQUFhLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUMxRixPQUFPO1FBQ0wsY0FBYyxFQUFFLEdBQUcsQ0FBQyxlQUFlLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQztRQUN0RixTQUFTLEVBQUUsR0FBRyxDQUFDLFVBQVUsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsUUFBUSxDQUFDO1FBQ3ZFLFVBQVUsRUFBRSx1QkFBdUIsQ0FBQyxHQUFHLEVBQUUsYUFBYSxDQUFDO1FBQ3ZELGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxVQUFVLEVBQUUsV0FBVyxDQUFDO0tBQ3ZFLENBQUM7QUFDSixDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsQ0FBQyxLQUFhLEVBQVUsRUFBRSxDQUNsRCxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FB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
|