@cortexkit/pi-anthropic-auth 2.0.3 → 2.1.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/custody.js +1 -1
- package/dist/stream.d.ts +3 -1
- package/dist/stream.js +30 -18
- package/package.json +2 -2
package/README.md
CHANGED
package/dist/custody.js
CHANGED
|
@@ -26,7 +26,7 @@ export function createPiCustodyCommands() {
|
|
|
26
26
|
// Mode changes can remove host credentials and require offline consent.
|
|
27
27
|
// A menu never enrolls, grants custody or writes the authority journal.
|
|
28
28
|
return {
|
|
29
|
-
text: `Refused: Changing Pi authentication to ${mode} requires offline setup. Run \`
|
|
29
|
+
text: `Refused: Changing Pi authentication to ${mode} requires offline setup. Run \`npx @cortexkit/opencode-anthropic-auth setup\` and review the migration and host OAuth removal consent.`,
|
|
30
30
|
};
|
|
31
31
|
},
|
|
32
32
|
};
|
package/dist/stream.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { type ApiKeyAccount, CacheKeepManager, type MidConversationEffortTransition } from '@cortexkit/anthropic-auth-core';
|
|
1
|
+
import { type ApiKeyAccount, CacheKeepManager, type MidConversationEffortTransition, type QuotaManagerOptions } from '@cortexkit/anthropic-auth-core';
|
|
2
2
|
import { type Api, type AssistantMessageEventStream, type Context, type Model, type SimpleStreamOptions } from '@earendil-works/pi-ai';
|
|
3
|
+
/** Set or clear the test replacement for the wait between quota usage polls. */
|
|
4
|
+
export declare function __setPiQuotaCallPauseForTest(pause: QuotaManagerOptions['pauseBetweenQuotaCalls']): void;
|
|
3
5
|
export declare function clearPiStickyRoutingSession(storagePath: string, sessionId: string): Promise<void>;
|
|
4
6
|
export declare function getPiTrackedCacheKeepSessions(): Promise<import("@cortexkit/anthropic-auth-core").CacheKeepTrackedSession[]>;
|
|
5
7
|
/** Call prewarmNow directly to exercise its provider request without clock or timer mocks. */
|
package/dist/stream.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { applyClaudeCodeHeaders, applyCustomHeaders, CACHE_KEEP_EXTENDED_TTL_BETA, CacheKeepManager, CacheKeepSessionRegistry, createProviderErrorResponseScope, createSseFramer, createStickyNoRouteResponse, decideStickyQuotaFailure, decodeSseFrame, dumpDirectRequest, FAST_MODE_BETA, getCache1hPersistentMode, getClaudeCodeIdentityForVerifiedAccount, getDefaultCacheKeepRegistryDirectory, getFallbackReauthLabels, getQuotaCheckIntervalMs, getRoutingMode, getScopedQuotaWindowForModel, getThinkingPrefixMismatchBehavior,
|
|
1
|
+
import { applyClaudeCodeHeaders, applyCustomHeaders, CACHE_KEEP_EXTENDED_TTL_BETA, CacheKeepManager, CacheKeepSessionRegistry, createProviderErrorResponseScope, createSseFramer, createStickyNoRouteResponse, decideStickyQuotaFailure, decodeSseFrame, dumpDirectRequest, FAST_MODE_BETA, getCache1hPersistentMode, getClaudeCodeIdentityForVerifiedAccount, getDefaultCacheKeepRegistryDirectory, getFallbackReauthLabels, getQuotaCheckIntervalMs, getRequestGzipLatch, getRequestGzipLatchPath, getRoutingMode, getScopedQuotaWindowForModel, getThinkingPrefixMismatchBehavior, isCache1hPersistentlyEnabled, isCacheKeepHybridActive, isDumpPersistentlyEnabled, isFastModePersistentlyEnabled, isKillswitchEnabled, isNativeTransientAccountError, isOAuthAccount, isPermanentRefreshError, isValidApiBaseURL, killswitchPassesPolicy, logger, mergeAnthropicBetas, NativeVaultNoAccountError, nativeAccountCanServe, parseSseFrame, QuotaManager, quotaBackoffActive, quotaSnapshotHasStandardWindows, quotaSnapshotModelScopeIsExhausted, quotaSnapshotPassesModelScope, quotaSnapshotPassesPolicy, STICKY_ROUTING_MAIN_ACCOUNT_ID, StickySessionRouter, sendViaRelay, sendWithRequestGzip, setDumpEnabled, shouldFallbackStatus, stickyQuotaSnapshotIsFresh, stickyRetryAfterWithJitter, stickyRouteFamilyForModel, } from '@cortexkit/anthropic-auth-core';
|
|
2
2
|
import { calculateCost, createAssistantMessageEventStream, } from '@earendil-works/pi-ai';
|
|
3
3
|
import { buildAnthropicRequest, fromClaudeCodeToolName } from './convert.js';
|
|
4
4
|
import { getPiNativeRuntime, piAttemptAccessToken, } from './native.js';
|
|
@@ -11,6 +11,15 @@ let cacheKeepRegistryDirectory;
|
|
|
11
11
|
const stickyRouters = new Map();
|
|
12
12
|
const quotaManagers = new Map();
|
|
13
13
|
const PI_SERVICE_CACHE_LIMIT = 16;
|
|
14
|
+
/**
|
|
15
|
+
* Tests only: replaces the real-time wait between quota usage polls in quota
|
|
16
|
+
* managers created after it is set. Unset, managers keep Core's real timer.
|
|
17
|
+
*/
|
|
18
|
+
let quotaCallPauseForTest;
|
|
19
|
+
/** Set or clear the test replacement for the wait between quota usage polls. */
|
|
20
|
+
export function __setPiQuotaCallPauseForTest(pause) {
|
|
21
|
+
quotaCallPauseForTest = pause;
|
|
22
|
+
}
|
|
14
23
|
function setBoundedService(map, key, value) {
|
|
15
24
|
map.delete(key);
|
|
16
25
|
map.set(key, value);
|
|
@@ -37,11 +46,12 @@ function getPiRoutingServices(storagePath, snapshot) {
|
|
|
37
46
|
if (!quotaManager) {
|
|
38
47
|
quotaManager = new QuotaManager({
|
|
39
48
|
storage,
|
|
49
|
+
pauseBetweenQuotaCalls: quotaCallPauseForTest,
|
|
40
50
|
fetchQuotaSnapshot: async (request, dispatch) => {
|
|
41
51
|
const id = request.kind === 'main' ? 'main' : request.accountId;
|
|
42
52
|
if (!id)
|
|
43
53
|
throw new Error('Native quota request has no account identity');
|
|
44
|
-
return (await native.service()).fetchQuota(id, fetchPiOAuth, undefined, dispatch);
|
|
54
|
+
return (await native.service()).fetchQuota(id, fetchPiOAuth, undefined, dispatch, request.purpose);
|
|
45
55
|
},
|
|
46
56
|
});
|
|
47
57
|
setBoundedService(quotaManagers, storagePath, {
|
|
@@ -74,7 +84,7 @@ function getPiRoutingServices(storagePath, snapshot) {
|
|
|
74
84
|
quotas.isFallbackStale(account.id, undefined, options.modelId, account) &&
|
|
75
85
|
!quotaBackoffActive(account.lastQuotaRefreshError, Date.now())) {
|
|
76
86
|
try {
|
|
77
|
-
await quotas.refreshFallback(account.id, '', account);
|
|
87
|
+
await quotas.refreshFallback(account.id, '', account, 'admission');
|
|
78
88
|
}
|
|
79
89
|
catch (error) {
|
|
80
90
|
// A transient account error means another writer is still saving
|
|
@@ -122,23 +132,15 @@ function getPiCacheKeepRegistry() {
|
|
|
122
132
|
* betas this body needs. Model requests and CacheKeep prewarms both call it:
|
|
123
133
|
* a prewarm replays a model request's body, and Anthropic needs the same
|
|
124
134
|
* betas to accept it (for example, the effort beta for the empty
|
|
125
|
-
* `role: "system"` effort markers in a Fable 5.1 body). `leadingBetas`
|
|
126
|
-
*
|
|
135
|
+
* `role: "system"` effort markers in a Fable 5.1 body). `leadingBetas` appends
|
|
136
|
+
* adapter-requested feature betas without changing Core's model-beta selection.
|
|
127
137
|
*/
|
|
128
138
|
function applyPiOAuthRequestHeaders(headers, accessToken, options) {
|
|
129
139
|
const { body } = options;
|
|
130
140
|
applyClaudeCodeHeaders(headers, accessToken, {
|
|
131
141
|
body,
|
|
132
142
|
identity: options.identity,
|
|
133
|
-
extraBetas:
|
|
134
|
-
...(options.leadingBetas ?? []),
|
|
135
|
-
...(hasThinkingBindingControls(body)
|
|
136
|
-
? [THINKING_BINDING_CONTROLS_BETA]
|
|
137
|
-
: []),
|
|
138
|
-
...(usesMidConversationOutputConfig(body)
|
|
139
|
-
? [MID_CONVERSATION_OUTPUT_CONFIG_BETA]
|
|
140
|
-
: []),
|
|
141
|
-
],
|
|
143
|
+
extraBetas: options.leadingBetas,
|
|
142
144
|
});
|
|
143
145
|
if (body.speed === 'fast')
|
|
144
146
|
headers.set('anthropic-beta', mergeAnthropicBetas(headers.get('anthropic-beta'), [FAST_MODE_BETA]));
|
|
@@ -442,7 +444,17 @@ async function sendAnthropicRequest(options) {
|
|
|
442
444
|
const send = async () => {
|
|
443
445
|
const scope = createProviderErrorResponseScope([secret], 'event-stream');
|
|
444
446
|
physical.scope = scope;
|
|
445
|
-
|
|
447
|
+
// OAuth bodies go gzipped as Claude Code sends them; `bodyText` stays
|
|
448
|
+
// the signed identity text for dumps and CacheKeep.
|
|
449
|
+
if (options.apiAccount || typeof init.body !== 'string')
|
|
450
|
+
return scope.redactResponse(await fetch(input, init));
|
|
451
|
+
return scope.redactResponse(await sendWithRequestGzip({
|
|
452
|
+
url: input,
|
|
453
|
+
body: init.body,
|
|
454
|
+
headers,
|
|
455
|
+
latch: getRequestGzipLatch(getRequestGzipLatchPath(options.storagePath)),
|
|
456
|
+
send: (wireBody, wireHeaders) => fetch(input, { ...init, body: wireBody, headers: wireHeaders }),
|
|
457
|
+
}));
|
|
446
458
|
};
|
|
447
459
|
let response;
|
|
448
460
|
try {
|
|
@@ -778,7 +790,7 @@ async function executeWithFallback(options) {
|
|
|
778
790
|
if (primaryAvailable() &&
|
|
779
791
|
!stickyQuotaSnapshotIsFresh(mainEntry?.quota, storage, Date.now(), modelId)) {
|
|
780
792
|
try {
|
|
781
|
-
mainQuota = await quotaManager.refreshMain(mainAccountId, '');
|
|
793
|
+
mainQuota = await quotaManager.refreshMain(mainAccountId, '', undefined, 'admission');
|
|
782
794
|
}
|
|
783
795
|
catch { }
|
|
784
796
|
}
|
|
@@ -803,7 +815,7 @@ async function executeWithFallback(options) {
|
|
|
803
815
|
let accountQuota = quotaManager.getFallback(account.id, account)?.quota ?? account.quota;
|
|
804
816
|
if (!stickyQuotaSnapshotIsFresh(accountQuota, storage, Date.now(), modelId)) {
|
|
805
817
|
try {
|
|
806
|
-
accountQuota = await quotaManager.refreshFallback(account.id, '', account);
|
|
818
|
+
accountQuota = await quotaManager.refreshFallback(account.id, '', account, 'admission');
|
|
807
819
|
}
|
|
808
820
|
catch { }
|
|
809
821
|
}
|
|
@@ -1150,7 +1162,7 @@ async function executeWithFallback(options) {
|
|
|
1150
1162
|
let mainQuota = quotaManager.getMain(mainAccountId)?.quota;
|
|
1151
1163
|
if (!mainQuota || quotaManager.isMainStale(options.model.id)) {
|
|
1152
1164
|
try {
|
|
1153
|
-
mainQuota = await quotaManager.refreshMain(mainAccountId, '');
|
|
1165
|
+
mainQuota = await quotaManager.refreshMain(mainAccountId, '', undefined, 'admission');
|
|
1154
1166
|
}
|
|
1155
1167
|
catch { }
|
|
1156
1168
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cortexkit/pi-anthropic-auth",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"prepublishOnly": "bun run build"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@cortexkit/anthropic-auth-core": "2.0
|
|
39
|
+
"@cortexkit/anthropic-auth-core": "2.1.0"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"@earendil-works/pi-ai": ">=0.86.1 <2",
|