@cortexkit/anthropic-auth-core 1.19.1 → 1.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/accounts.d.ts +81 -5
- package/dist/accounts.js +531 -81
- package/dist/auth.d.ts +2 -0
- package/dist/auth.js +3 -2
- package/dist/cache1h.d.ts +1 -1
- package/dist/cache1h.js +1 -1
- package/dist/cachekeep.d.ts +20 -2
- package/dist/cachekeep.js +134 -28
- package/dist/cch.d.ts +1 -0
- package/dist/cch.js +6 -1
- package/dist/claude-code.d.ts +5 -2
- package/dist/claude-code.js +127 -24
- package/dist/commands/account.js +1 -1
- package/dist/constants.d.ts +3 -3
- package/dist/dump.d.ts +13 -1
- package/dist/dump.js +171 -22
- package/dist/index.d.ts +3 -0
- package/dist/index.js +27 -24
- package/dist/killswitch.js +1 -1
- package/dist/models.d.ts +22 -6
- package/dist/models.js +16 -0
- package/dist/oauth-profile.d.ts +2 -1
- package/dist/oauth-profile.js +10 -4
- package/dist/prime.d.ts +219 -0
- package/dist/prime.js +823 -0
- package/dist/quota-header-feed.d.ts +40 -0
- package/dist/quota-header-feed.js +248 -0
- package/dist/quota-headers.js +6 -4
- package/dist/quota-manager.d.ts +41 -25
- package/dist/quota-manager.js +391 -151
- package/dist/quotas.d.ts +4 -4
- package/dist/quotas.js +2 -2
- package/dist/relay.d.ts +2 -0
- package/dist/relay.js +10 -4
- package/dist/routing.d.ts +1 -1
- package/dist/routing.js +1 -1
- package/dist/start.d.ts +13 -0
- package/dist/start.js +29 -0
- package/dist/sticky-routing.d.ts +15 -2
- package/dist/sticky-routing.js +44 -17
- package/package.json +1 -1
package/dist/dump.d.ts
CHANGED
|
@@ -9,6 +9,11 @@ export type DumpCommandAction = {
|
|
|
9
9
|
} | {
|
|
10
10
|
type: 'usage';
|
|
11
11
|
};
|
|
12
|
+
export type DumpTag = 'cachekeep' | 'start';
|
|
13
|
+
export type DumpHandle = {
|
|
14
|
+
responsePath: string;
|
|
15
|
+
tag?: DumpTag;
|
|
16
|
+
};
|
|
12
17
|
export declare function isDumpEnabled(): boolean;
|
|
13
18
|
export declare function setDumpEnabled(enabled: boolean): void;
|
|
14
19
|
export declare function resetDumpState(): void;
|
|
@@ -49,7 +54,8 @@ export declare function dumpDirectRequest(input: {
|
|
|
49
54
|
url?: string;
|
|
50
55
|
method?: string;
|
|
51
56
|
headers?: DumpHeaders;
|
|
52
|
-
|
|
57
|
+
tag?: DumpTag;
|
|
58
|
+
}): Promise<DumpHandle | null>;
|
|
53
59
|
export declare function dumpRelayRequest(input: {
|
|
54
60
|
affinity: string;
|
|
55
61
|
transport: 'http' | 'websocket';
|
|
@@ -60,5 +66,11 @@ export declare function dumpRelayRequest(input: {
|
|
|
60
66
|
previousBodyText?: string;
|
|
61
67
|
payload: unknown;
|
|
62
68
|
relayBytes: number;
|
|
69
|
+
tag?: DumpTag;
|
|
70
|
+
}): Promise<DumpHandle | null>;
|
|
71
|
+
export declare function dumpResponseArtifact(handle: DumpHandle | null, input: {
|
|
72
|
+
status: number;
|
|
73
|
+
message: unknown;
|
|
74
|
+
complete?: boolean;
|
|
63
75
|
}): Promise<void>;
|
|
64
76
|
export {};
|
package/dist/dump.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createHash, randomBytes } from 'node:crypto';
|
|
2
|
-
import { lstat, mkdir, readdir, rename, unlink, writeFile, } from 'node:fs/promises';
|
|
2
|
+
import { lstat, mkdir, readdir, readFile, rename, unlink, writeFile, } from 'node:fs/promises';
|
|
3
3
|
import { tmpdir } from 'node:os';
|
|
4
4
|
import { join, resolve } from 'node:path';
|
|
5
|
-
import { extractBillingHeaderCCH } from
|
|
6
|
-
import { isSecretKey, logger, relayLog } from
|
|
5
|
+
import { extractBillingHeaderCCH } from './cch.js';
|
|
6
|
+
import { isSecretKey, logger, relayLog } from './logger.js';
|
|
7
7
|
export const CLAUDE_DUMP_COMMAND_NAME = 'claude-dump';
|
|
8
8
|
const DUMP_STATUS_TITLE = '## Claude Dump Status';
|
|
9
9
|
const DUMP_ENABLED_TITLE = '## Claude Dump Enabled';
|
|
@@ -17,12 +17,14 @@ const DEFAULT_DUMP_MAX_BYTES = 512 * 1024 * 1024;
|
|
|
17
17
|
const DUMP_SWEEP_INTERVAL_MS = 5 * 60 * 1000;
|
|
18
18
|
const DUMP_SWEEP_NEWNESS_FLOOR_MS = 60 * 1000;
|
|
19
19
|
const DUMP_PARTIAL_STALE_MS = 10 * 60 * 1000;
|
|
20
|
-
const DUMP_ARTIFACT_SUFFIX_PATTERN = /\.(body|meta|relay|request)\.json$/;
|
|
20
|
+
const DUMP_ARTIFACT_SUFFIX_PATTERN = /\.(body|meta|relay|request|response)\.json$/;
|
|
21
21
|
// Earlier builds emitted five-digit counters; current counters grow without truncation.
|
|
22
22
|
const DUMP_ARTIFACT_ID_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-\d{3}Z-\d{5,}-(.+)$/;
|
|
23
23
|
const DUMP_SEGMENT_PATTERN = '[a-zA-Z0-9._-]';
|
|
24
24
|
const DIRECT_DUMP_PATTERN = new RegExp(`^${DUMP_SEGMENT_PATTERN}{1,80}-direct(?:-${DUMP_SEGMENT_PATTERN}{1,80})?$`);
|
|
25
25
|
const RELAY_DUMP_PATTERN = new RegExp(`^${DUMP_SEGMENT_PATTERN}{1,80}-(?:http|websocket)-p[12]-(?:full_sync|patch)$`);
|
|
26
|
+
const DIRECT_DUMP_SUFFIX_PATTERN = new RegExp(`^-direct(?:-${DUMP_SEGMENT_PATTERN}{1,80})?$`);
|
|
27
|
+
const RELAY_DUMP_SUFFIX_PATTERN = /^-(?:http|websocket)-p[12]-(?:full_sync|patch)$/;
|
|
26
28
|
let dumpEnabled = false;
|
|
27
29
|
let nextDumpId = 0;
|
|
28
30
|
let lastDumpSweepAt = 0;
|
|
@@ -136,6 +138,9 @@ export async function sweepDumpDirectory(options) {
|
|
|
136
138
|
size: stats.size,
|
|
137
139
|
mtimeMs: stats.mtimeMs,
|
|
138
140
|
partial,
|
|
141
|
+
...(!partial && {
|
|
142
|
+
artifactGroup: entry.name.replace(DUMP_ARTIFACT_SUFFIX_PATTERN, ''),
|
|
143
|
+
}),
|
|
139
144
|
});
|
|
140
145
|
}
|
|
141
146
|
catch {
|
|
@@ -143,18 +148,9 @@ export async function sweepDumpDirectory(options) {
|
|
|
143
148
|
}
|
|
144
149
|
}));
|
|
145
150
|
let totalBytes = files.reduce((total, file) => total + file.size, 0);
|
|
146
|
-
files.sort((left, right) => left.mtimeMs - right.mtimeMs || left.path.localeCompare(right.path));
|
|
147
151
|
let removed = 0;
|
|
148
152
|
let freedBytes = 0;
|
|
149
|
-
|
|
150
|
-
if (protectedPaths.has(resolve(file.path)))
|
|
151
|
-
continue;
|
|
152
|
-
const ageMs = now - file.mtimeMs;
|
|
153
|
-
const stalePartial = file.partial && ageMs >= partialStaleMs;
|
|
154
|
-
if (!stalePartial && totalBytes <= maxBytes)
|
|
155
|
-
continue;
|
|
156
|
-
if (file.partial ? !stalePartial : ageMs < minAgeMs)
|
|
157
|
-
continue;
|
|
153
|
+
const removeFile = async (file) => {
|
|
158
154
|
try {
|
|
159
155
|
await unlink(file.path);
|
|
160
156
|
totalBytes -= file.size;
|
|
@@ -164,6 +160,43 @@ export async function sweepDumpDirectory(options) {
|
|
|
164
160
|
catch {
|
|
165
161
|
// Dump cleanup is best-effort and must not affect request handling.
|
|
166
162
|
}
|
|
163
|
+
};
|
|
164
|
+
// Partials are not usable dump records. Reclaim stale ones independently,
|
|
165
|
+
// including while the completed-artifact set is already below the cap.
|
|
166
|
+
const partials = files
|
|
167
|
+
.filter((file) => file.partial)
|
|
168
|
+
.sort((left, right) => left.mtimeMs - right.mtimeMs || left.path.localeCompare(right.path));
|
|
169
|
+
for (const file of partials) {
|
|
170
|
+
if (protectedPaths.has(resolve(file.path)))
|
|
171
|
+
continue;
|
|
172
|
+
if (now - file.mtimeMs < partialStaleMs)
|
|
173
|
+
continue;
|
|
174
|
+
await removeFile(file);
|
|
175
|
+
}
|
|
176
|
+
const artifactGroups = new Map();
|
|
177
|
+
for (const file of files) {
|
|
178
|
+
if (file.partial || !file.artifactGroup)
|
|
179
|
+
continue;
|
|
180
|
+
const group = artifactGroups.get(file.artifactGroup) ?? {
|
|
181
|
+
files: [],
|
|
182
|
+
newestMtimeMs: 0,
|
|
183
|
+
};
|
|
184
|
+
group.files.push(file);
|
|
185
|
+
group.newestMtimeMs = Math.max(group.newestMtimeMs, file.mtimeMs);
|
|
186
|
+
artifactGroups.set(file.artifactGroup, group);
|
|
187
|
+
}
|
|
188
|
+
const completedGroups = [...artifactGroups.entries()].sort(([leftName, left], [rightName, right]) => left.newestMtimeMs - right.newestMtimeMs ||
|
|
189
|
+
leftName.localeCompare(rightName));
|
|
190
|
+
for (const [, group] of completedGroups) {
|
|
191
|
+
if (totalBytes <= maxBytes)
|
|
192
|
+
break;
|
|
193
|
+
if (now - group.newestMtimeMs < minAgeMs)
|
|
194
|
+
continue;
|
|
195
|
+
if (group.files.some((file) => protectedPaths.has(resolve(file.path)))) {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
for (const file of group.files)
|
|
199
|
+
await removeFile(file);
|
|
167
200
|
}
|
|
168
201
|
if (removed > 0) {
|
|
169
202
|
logger.debug('dump', 'removed old dump files', { removed, freedBytes });
|
|
@@ -233,14 +266,16 @@ export function executeDumpCommand(input) {
|
|
|
233
266
|
function shortAffinity(affinity) {
|
|
234
267
|
return affinity.length <= 16 ? affinity : `${affinity.slice(0, 12)}…`;
|
|
235
268
|
}
|
|
236
|
-
function dumpFileSessionSegment(affinity) {
|
|
269
|
+
function dumpFileSessionSegment(affinity, maxLength = 80) {
|
|
237
270
|
const normalized = affinity
|
|
238
271
|
.trim()
|
|
239
272
|
.replace(/[^a-zA-Z0-9._-]+/g, '-')
|
|
240
273
|
.replace(/^-+|-+$/g, '');
|
|
241
274
|
if (!normalized)
|
|
242
275
|
return 'session-unknown';
|
|
243
|
-
return normalized.length <=
|
|
276
|
+
return normalized.length <= maxLength
|
|
277
|
+
? normalized
|
|
278
|
+
: normalized.slice(0, maxLength);
|
|
244
279
|
}
|
|
245
280
|
function dumpRequestSegment(input) {
|
|
246
281
|
if (input.transport !== 'direct') {
|
|
@@ -249,12 +284,85 @@ function dumpRequestSegment(input) {
|
|
|
249
284
|
const route = input.route ? `-${dumpFileSessionSegment(input.route)}` : '';
|
|
250
285
|
return `direct${route}`;
|
|
251
286
|
}
|
|
287
|
+
function dumpTagSegment(tag) {
|
|
288
|
+
if (tag === 'cachekeep')
|
|
289
|
+
return '-prewarm-cachekeep';
|
|
290
|
+
if (tag === 'start')
|
|
291
|
+
return '-start';
|
|
292
|
+
return '';
|
|
293
|
+
}
|
|
252
294
|
function directDumpPreviousKey(input) {
|
|
253
295
|
const affinity = input.affinity?.trim();
|
|
254
296
|
if (affinity)
|
|
255
297
|
return `session:${affinity}`;
|
|
256
298
|
return `request:${input.route ?? 'direct'}:${input.url ?? ''}`;
|
|
257
299
|
}
|
|
300
|
+
function dumpBodyTagForAffinity(name, affinity) {
|
|
301
|
+
if (!name.endsWith('.body.json'))
|
|
302
|
+
return undefined;
|
|
303
|
+
const stem = name.replace(DUMP_ARTIFACT_SUFFIX_PATTERN, '');
|
|
304
|
+
const requestPath = DUMP_ARTIFACT_ID_PATTERN.exec(stem)?.[1];
|
|
305
|
+
if (!requestPath ||
|
|
306
|
+
(!DIRECT_DUMP_PATTERN.test(requestPath) &&
|
|
307
|
+
!RELAY_DUMP_PATTERN.test(requestPath))) {
|
|
308
|
+
return undefined;
|
|
309
|
+
}
|
|
310
|
+
const cachekeepTag = dumpTagSegment('cachekeep');
|
|
311
|
+
const candidates = [
|
|
312
|
+
{ prefix: dumpFileSessionSegment(affinity), tag: null },
|
|
313
|
+
{
|
|
314
|
+
prefix: `${dumpFileSessionSegment(affinity, 80 - cachekeepTag.length)}${cachekeepTag}`,
|
|
315
|
+
tag: 'cachekeep',
|
|
316
|
+
},
|
|
317
|
+
];
|
|
318
|
+
for (const candidate of candidates) {
|
|
319
|
+
if (!requestPath.startsWith(`${candidate.prefix}-`))
|
|
320
|
+
continue;
|
|
321
|
+
const suffix = requestPath.slice(candidate.prefix.length);
|
|
322
|
+
if (DIRECT_DUMP_SUFFIX_PATTERN.test(suffix) ||
|
|
323
|
+
RELAY_DUMP_SUFFIX_PATTERN.test(suffix)) {
|
|
324
|
+
return candidate.tag;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return undefined;
|
|
328
|
+
}
|
|
329
|
+
async function loadLatestDumpBody(input) {
|
|
330
|
+
const affinity = input.affinity?.trim();
|
|
331
|
+
if (!affinity)
|
|
332
|
+
return undefined;
|
|
333
|
+
const dumpDir = getDumpDirectory();
|
|
334
|
+
let names;
|
|
335
|
+
try {
|
|
336
|
+
names = await readdir(dumpDir);
|
|
337
|
+
}
|
|
338
|
+
catch {
|
|
339
|
+
return undefined;
|
|
340
|
+
}
|
|
341
|
+
const candidates = names
|
|
342
|
+
.map((name) => ({ name, tag: dumpBodyTagForAffinity(name, affinity) }))
|
|
343
|
+
.filter((candidate) => candidate.tag !== undefined)
|
|
344
|
+
.sort((a, b) => b.name.localeCompare(a.name));
|
|
345
|
+
for (const candidate of candidates) {
|
|
346
|
+
try {
|
|
347
|
+
const path = join(dumpDir, candidate.name);
|
|
348
|
+
const metadataPath = path.replace(/\.body\.json$/, '.meta.json');
|
|
349
|
+
if (!(await lstat(path)).isFile())
|
|
350
|
+
continue;
|
|
351
|
+
const metadata = JSON.parse(await readFile(metadataPath, 'utf8'));
|
|
352
|
+
if (metadata.session !== shortAffinity(affinity) ||
|
|
353
|
+
(candidate.tag === null
|
|
354
|
+
? metadata.tag != null
|
|
355
|
+
: metadata.tag !== candidate.tag)) {
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
return await readFile(path, 'utf8');
|
|
359
|
+
}
|
|
360
|
+
catch {
|
|
361
|
+
// A concurrent sweep can remove the newest artifact; try its predecessor.
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return undefined;
|
|
365
|
+
}
|
|
258
366
|
function rememberDirectDumpBody(key, bodyText) {
|
|
259
367
|
if (!directDumpPreviousBodies.has(key)) {
|
|
260
368
|
while (directDumpPreviousBodies.size >= DIRECT_DUMP_PREVIOUS_BODY_LIMIT) {
|
|
@@ -376,15 +484,17 @@ function redactForDump(value) {
|
|
|
376
484
|
}
|
|
377
485
|
async function dumpRequest(input) {
|
|
378
486
|
if (!dumpEnabled)
|
|
379
|
-
return;
|
|
487
|
+
return null;
|
|
380
488
|
nextDumpId += 1;
|
|
381
489
|
const affinity = input.affinity?.trim() || 'session-unknown';
|
|
382
|
-
const
|
|
490
|
+
const tagSegment = dumpTagSegment(input.tag);
|
|
491
|
+
const id = `${new Date().toISOString().replace(/[:.]/g, '-')}-${String(nextDumpId).padStart(6, '0')}-${dumpFileSessionSegment(affinity, 80 - tagSegment.length)}${tagSegment}-${dumpRequestSegment(input)}`;
|
|
383
492
|
const dumpDir = getDumpDirectory();
|
|
384
493
|
const prefix = join(dumpDir, id);
|
|
385
494
|
const files = {
|
|
386
495
|
body: `${prefix}.body.json`,
|
|
387
496
|
metadata: `${prefix}.meta.json`,
|
|
497
|
+
response: `${prefix}.response.json`,
|
|
388
498
|
};
|
|
389
499
|
if (input.payload !== undefined)
|
|
390
500
|
files.relay = `${prefix}.relay.json`;
|
|
@@ -392,6 +502,7 @@ async function dumpRequest(input) {
|
|
|
392
502
|
files.request = `${prefix}.request.json`;
|
|
393
503
|
try {
|
|
394
504
|
await mkdir(dumpDir, { recursive: true });
|
|
505
|
+
const previousBodyText = input.previousBodyText ?? (await loadLatestDumpBody(input));
|
|
395
506
|
const metadata = {
|
|
396
507
|
id,
|
|
397
508
|
createdAt: new Date().toISOString(),
|
|
@@ -402,10 +513,11 @@ async function dumpRequest(input) {
|
|
|
402
513
|
route: input.route,
|
|
403
514
|
status: input.status,
|
|
404
515
|
error: input.error,
|
|
516
|
+
tag: input.tag,
|
|
405
517
|
bodyBytes: input.bodyText.length,
|
|
406
518
|
relayBytes: input.relayBytes,
|
|
407
519
|
bodyHash: hashText(input.bodyText),
|
|
408
|
-
diff: diffSummary(
|
|
520
|
+
diff: diffSummary(previousBodyText, input.bodyText),
|
|
409
521
|
body: bodyStructureSummary(input.bodyText),
|
|
410
522
|
files,
|
|
411
523
|
};
|
|
@@ -428,14 +540,19 @@ async function dumpRequest(input) {
|
|
|
428
540
|
}
|
|
429
541
|
catch (error) {
|
|
430
542
|
relayLog(`dump failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
543
|
+
return null;
|
|
431
544
|
}
|
|
545
|
+
return {
|
|
546
|
+
responsePath: files.response,
|
|
547
|
+
...(input.tag ? { tag: input.tag } : {}),
|
|
548
|
+
};
|
|
432
549
|
}
|
|
433
550
|
export async function dumpDirectRequest(input) {
|
|
434
551
|
if (!dumpEnabled)
|
|
435
|
-
return;
|
|
552
|
+
return null;
|
|
436
553
|
const previousKey = directDumpPreviousKey(input);
|
|
437
554
|
const previousBodyText = directDumpPreviousBodies.get(previousKey);
|
|
438
|
-
await dumpRequest({
|
|
555
|
+
const handle = await dumpRequest({
|
|
439
556
|
affinity: input.affinity,
|
|
440
557
|
transport: 'direct',
|
|
441
558
|
route: input.route,
|
|
@@ -448,11 +565,13 @@ export async function dumpDirectRequest(input) {
|
|
|
448
565
|
method: input.method,
|
|
449
566
|
headers: input.headers,
|
|
450
567
|
},
|
|
568
|
+
tag: input.tag,
|
|
451
569
|
});
|
|
452
570
|
rememberDirectDumpBody(previousKey, input.bodyText);
|
|
571
|
+
return handle;
|
|
453
572
|
}
|
|
454
573
|
export async function dumpRelayRequest(input) {
|
|
455
|
-
|
|
574
|
+
return dumpRequest({
|
|
456
575
|
affinity: input.affinity,
|
|
457
576
|
transport: input.transport,
|
|
458
577
|
protocol: input.protocol,
|
|
@@ -462,5 +581,35 @@ export async function dumpRelayRequest(input) {
|
|
|
462
581
|
previousBodyText: input.previousBodyText,
|
|
463
582
|
payload: input.payload,
|
|
464
583
|
relayBytes: input.relayBytes,
|
|
584
|
+
tag: input.tag,
|
|
465
585
|
});
|
|
466
586
|
}
|
|
587
|
+
export async function dumpResponseArtifact(handle, input) {
|
|
588
|
+
if (!handle)
|
|
589
|
+
return;
|
|
590
|
+
const message = input.message != null &&
|
|
591
|
+
typeof input.message === 'object' &&
|
|
592
|
+
!Array.isArray(input.message)
|
|
593
|
+
? input.message
|
|
594
|
+
: {};
|
|
595
|
+
const artifact = {
|
|
596
|
+
status: input.status,
|
|
597
|
+
stream_complete: input.complete ?? true,
|
|
598
|
+
};
|
|
599
|
+
if (typeof message.id === 'string' && message.id.length > 0)
|
|
600
|
+
artifact.message_id = message.id;
|
|
601
|
+
if (typeof message.model === 'string' && message.model.length > 0)
|
|
602
|
+
artifact.model = message.model;
|
|
603
|
+
if (Object.hasOwn(message, 'usage'))
|
|
604
|
+
artifact.usage = message.usage;
|
|
605
|
+
if (Object.hasOwn(message, 'diagnostics'))
|
|
606
|
+
artifact.diagnostics = message.diagnostics;
|
|
607
|
+
if (typeof message.stop_reason === 'string' && message.stop_reason.length > 0)
|
|
608
|
+
artifact.stop_reason = message.stop_reason;
|
|
609
|
+
try {
|
|
610
|
+
await writeDumpFile(handle.responsePath, `${JSON.stringify(artifact, null, 2)}\n`);
|
|
611
|
+
}
|
|
612
|
+
catch (error) {
|
|
613
|
+
relayLog(`dump response failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
614
|
+
}
|
|
615
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -15,10 +15,13 @@ export * from './logging.ts';
|
|
|
15
15
|
export * from './models.ts';
|
|
16
16
|
export * from './oauth-profile.ts';
|
|
17
17
|
export * from './pkce.ts';
|
|
18
|
+
export * from './prime.ts';
|
|
18
19
|
export * from './provider.ts';
|
|
20
|
+
export * from './quota-header-feed.ts';
|
|
19
21
|
export * from './quota-headers.ts';
|
|
20
22
|
export * from './quota-manager.ts';
|
|
21
23
|
export * from './quotas.ts';
|
|
22
24
|
export * from './relay.ts';
|
|
23
25
|
export * from './routing.ts';
|
|
26
|
+
export * from './start.ts';
|
|
24
27
|
export * from './sticky-routing.ts';
|
package/dist/index.js
CHANGED
|
@@ -1,24 +1,27 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
9
|
-
export * from
|
|
10
|
-
export * from
|
|
11
|
-
export * from
|
|
12
|
-
export * from
|
|
13
|
-
export * from
|
|
14
|
-
export * from
|
|
15
|
-
export * from
|
|
16
|
-
export * from
|
|
17
|
-
export * from
|
|
18
|
-
export * from
|
|
19
|
-
export * from
|
|
20
|
-
export * from
|
|
21
|
-
export * from
|
|
22
|
-
export * from
|
|
23
|
-
export * from
|
|
24
|
-
export * from
|
|
1
|
+
export * from './accounts.js';
|
|
2
|
+
export * from './auth.js';
|
|
3
|
+
export * from './cache1h.js';
|
|
4
|
+
export * from './cachekeep.js';
|
|
5
|
+
export * from './cachekeep-registry.js';
|
|
6
|
+
export * from './cch.js';
|
|
7
|
+
export * from './claude-code.js';
|
|
8
|
+
export * from './commands/account.js';
|
|
9
|
+
export * from './constants.js';
|
|
10
|
+
export * from './dump.js';
|
|
11
|
+
export * from './fast.js';
|
|
12
|
+
export * from './killswitch.js';
|
|
13
|
+
export * from './logger.js';
|
|
14
|
+
export * from './logging.js';
|
|
15
|
+
export * from './models.js';
|
|
16
|
+
export * from './oauth-profile.js';
|
|
17
|
+
export * from './pkce.js';
|
|
18
|
+
export * from './prime.js';
|
|
19
|
+
export * from './provider.js';
|
|
20
|
+
export * from './quota-header-feed.js';
|
|
21
|
+
export * from './quota-headers.js';
|
|
22
|
+
export * from './quota-manager.js';
|
|
23
|
+
export * from './quotas.js';
|
|
24
|
+
export * from './relay.js';
|
|
25
|
+
export * from './routing.js';
|
|
26
|
+
export * from './start.js';
|
|
27
|
+
export * from './sticky-routing.js';
|
package/dist/killswitch.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DEFAULT_KILLSWITCH_THRESHOLDS as DEFAULT_THRESHOLDS, normalizeKillswitchThresholds, } from
|
|
1
|
+
import { DEFAULT_KILLSWITCH_THRESHOLDS as DEFAULT_THRESHOLDS, normalizeKillswitchThresholds, } from './accounts.js';
|
|
2
2
|
export const KILLSWITCH_COMMAND_NAME = 'claude-killswitch';
|
|
3
3
|
export function parseKillswitchCommandAction(argumentsText) {
|
|
4
4
|
const parts = argumentsText.trim().split(/\s+/).filter(Boolean);
|
package/dist/models.d.ts
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
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
|
+
/**
|
|
4
|
+
* Haiku 4.5 model identifier used by `/claude-prime` to start each OAuth
|
|
5
|
+
* account's five-hour quota window with a minimal request. Usage is measured
|
|
6
|
+
* from response accounting. Kept distinct from the Fable/Mythos pricing block
|
|
7
|
+
* above so per-million-token cost estimation does not conflate families.
|
|
8
|
+
*/
|
|
9
|
+
export declare const CLAUDE_HAIKU_4_5_MODEL_ID = "claude-haiku-4-5";
|
|
10
|
+
/**
|
|
11
|
+
* Per-million-token USD pricing for Haiku 4.5. Used to project the cumulative
|
|
12
|
+
* cost of prime requests from persisted usage counters — never persisted on
|
|
13
|
+
* disk; derive at display time so future pricing revisions land in one place.
|
|
14
|
+
*/
|
|
15
|
+
export declare const CLAUDE_HAIKU_4_5_PRICING: {
|
|
16
|
+
readonly input: 1;
|
|
17
|
+
readonly output: 5;
|
|
18
|
+
};
|
|
3
19
|
export declare const CLAUDE_FABLE_MYTHOS_5_MODEL_IDS: readonly ["claude-fable-5", "claude-mythos-5"];
|
|
4
20
|
export type ClaudeFableMythos5ModelId = (typeof CLAUDE_FABLE_MYTHOS_5_MODEL_IDS)[number];
|
|
5
21
|
export declare const CLAUDE_FABLE_MYTHOS_5_SUMMARIZED_THINKING: {
|
|
6
|
-
readonly type:
|
|
7
|
-
readonly display:
|
|
22
|
+
readonly type: 'adaptive';
|
|
23
|
+
readonly display: 'summarized';
|
|
8
24
|
};
|
|
9
25
|
export declare const CLAUDE_FABLE_MYTHOS_5_PRICING: {
|
|
10
26
|
readonly input: 10;
|
|
@@ -30,8 +46,8 @@ export declare const CLAUDE_SONNET_5_MODEL_ID = "claude-sonnet-5";
|
|
|
30
46
|
* shape because the API contract is identical.
|
|
31
47
|
*/
|
|
32
48
|
export declare const CLAUDE_SONNET_5_ADAPTIVE_THINKING: {
|
|
33
|
-
readonly type:
|
|
34
|
-
readonly display:
|
|
49
|
+
readonly type: 'adaptive';
|
|
50
|
+
readonly display: 'summarized';
|
|
35
51
|
};
|
|
36
52
|
export declare function isClaudeSonnet5Model(model: unknown): boolean;
|
|
37
53
|
export declare const CLAUDE_OPUS_5_MODEL_ID = "claude-opus-5";
|
|
@@ -44,8 +60,8 @@ export declare const CLAUDE_OPUS_5_MODEL_ID = "claude-opus-5";
|
|
|
44
60
|
* only changes this re-export, not every call site.
|
|
45
61
|
*/
|
|
46
62
|
export declare const CLAUDE_OPUS_5_ADAPTIVE_THINKING: {
|
|
47
|
-
readonly type:
|
|
48
|
-
readonly display:
|
|
63
|
+
readonly type: 'adaptive';
|
|
64
|
+
readonly display: 'summarized';
|
|
49
65
|
};
|
|
50
66
|
export declare function isClaudeOpus5Model(model: unknown): boolean;
|
|
51
67
|
export declare function isOpenAIReasoningSignature(value: unknown): boolean;
|
package/dist/models.js
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
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
|
+
/**
|
|
4
|
+
* Haiku 4.5 model identifier used by `/claude-prime` to start each OAuth
|
|
5
|
+
* account's five-hour quota window with a minimal request. Usage is measured
|
|
6
|
+
* from response accounting. Kept distinct from the Fable/Mythos pricing block
|
|
7
|
+
* above so per-million-token cost estimation does not conflate families.
|
|
8
|
+
*/
|
|
9
|
+
export const CLAUDE_HAIKU_4_5_MODEL_ID = 'claude-haiku-4-5';
|
|
10
|
+
/**
|
|
11
|
+
* Per-million-token USD pricing for Haiku 4.5. Used to project the cumulative
|
|
12
|
+
* cost of prime requests from persisted usage counters — never persisted on
|
|
13
|
+
* disk; derive at display time so future pricing revisions land in one place.
|
|
14
|
+
*/
|
|
15
|
+
export const CLAUDE_HAIKU_4_5_PRICING = {
|
|
16
|
+
input: 1,
|
|
17
|
+
output: 5,
|
|
18
|
+
};
|
|
3
19
|
export const CLAUDE_FABLE_MYTHOS_5_MODEL_IDS = [
|
|
4
20
|
CLAUDE_FABLE_5_MODEL_ID,
|
|
5
21
|
CLAUDE_MYTHOS_5_MODEL_ID,
|
package/dist/oauth-profile.d.ts
CHANGED
|
@@ -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
|
|
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;
|
package/dist/oauth-profile.js
CHANGED
|
@@ -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
|
-
|
|
29
|
+
...(input.accountIdentity !== undefined && {
|
|
30
|
+
accountIdentity: input.accountIdentity,
|
|
31
|
+
}),
|
|
31
32
|
};
|
|
32
33
|
}
|
|
33
|
-
export function
|
|
34
|
-
|
|
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 &&
|