@oh-my-pi/pi-ai 18.4.0 → 18.4.2
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/CHANGELOG.md +26 -0
- package/README.md +12 -0
- package/dist/types/auth/oauth.d.ts +2 -2
- package/dist/types/auth/refresh.d.ts +3 -3
- package/dist/types/auth/store.d.ts +4 -2
- package/dist/types/auth/types.d.ts +20 -3
- package/dist/types/auth/usage-cache.d.ts +9 -2
- package/dist/types/auth/usage.d.ts +6 -5
- package/dist/types/auth-broker/client.d.ts +2 -2
- package/dist/types/auth-broker/remote-store.d.ts +2 -2
- package/dist/types/error/flags.d.ts +9 -2
- package/dist/types/error/rate-limit.d.ts +3 -2
- package/dist/types/providers/cursor/exec-modern.d.ts +1 -1
- package/dist/types/providers/cursor-pi-args.d.ts +13 -18
- package/dist/types/stream.d.ts +7 -0
- package/dist/types/usage/cursor.d.ts +3 -1
- package/dist/types/usage/zai.d.ts +2 -0
- package/dist/types/usage.d.ts +6 -0
- package/package.json +6 -6
- package/src/auth/cascade.ts +1 -0
- package/src/auth/oauth.ts +4 -3
- package/src/auth/refresh.ts +105 -16
- package/src/auth/resets.ts +6 -2
- package/src/auth/select.ts +11 -1
- package/src/auth/store.ts +4 -0
- package/src/auth/types.ts +22 -2
- package/src/auth/usage-cache.ts +12 -8
- package/src/auth/usage.ts +45 -19
- package/src/auth-broker/client.ts +8 -3
- package/src/auth-broker/remote-store.ts +4 -2
- package/src/auth-broker/server.ts +7 -1
- package/src/auth-gateway/dispatch.ts +1 -0
- package/src/auth-retry.ts +5 -1
- package/src/error/flags.ts +10 -3
- package/src/error/rate-limit.ts +23 -3
- package/src/providers/anthropic.ts +62 -53
- package/src/providers/cowork-fetch.ts +45 -3
- package/src/providers/cursor/exec-modern.ts +1 -1
- package/src/providers/cursor-pi-args.ts +13 -18
- package/src/providers/cursor.ts +179 -57
- package/src/providers/devin.ts +43 -13
- package/src/providers/openai-completions.ts +122 -30
- package/src/stream.ts +77 -16
- package/src/usage/claude.ts +5 -0
- package/src/usage/cursor.ts +43 -1
- package/src/usage/devin.ts +8 -7
- package/src/usage/registry.ts +2 -1
- package/src/usage/zai.ts +20 -0
- package/src/usage.ts +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.4.2] - 2026-09-28
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Fixed successful Cursor agent turns being treated as context overflows, which ran overflow compaction and showed "Compaction freed too little context to make progress" while `/context` read well under the window; overflow detection now uses the reported context size instead of input totals summed across a turn's model calls ([#13608](https://github.com/can1357/oh-my-pi/pull/13608) by [@H4vC](https://github.com/H4vC))
|
|
10
|
+
- Fixed Anthropic requests with thinking enabled failing on models whose output ceiling cannot fit the minimum thinking budget; thinking is now disabled for those requests instead ([#13359](https://github.com/can1357/oh-my-pi/pull/13359) by [@jchanghong023](https://github.com/jchanghong023))
|
|
11
|
+
- Fixed Cursor native Grep/Glob results showing no matches or raw output, Write failing to create files, StrReplace missing edits beyond the read limit, and Read/Shell/Delete results misreporting content or metadata ([#13600](https://github.com/can1357/oh-my-pi/issues/13600)).
|
|
12
|
+
|
|
13
|
+
## [18.4.1] - 2026-09-28
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Fixed extension-provided usage reports missing from broker-connected clients when the broker does not have that provider ([#13579](https://github.com/can1357/oh-my-pi/issues/13579)).
|
|
18
|
+
- Fixed signed LiteLLM `thinking_blocks` being dropped on openai-completions tool-call turns ([#13407](https://github.com/can1357/oh-my-pi/issues/13407)).
|
|
19
|
+
- Fixed Anthropic turns ending on a bare `aborted` error with no retry when the connection dropped mid-response (typically during long thinking). The first-party Anthropic transport runs on `node:https`, whose Bun shim reports a response cut off mid-body as `Error("aborted")` (ECONNRESET) — indistinguishable from a cancellation, so it classified as unknown. It now surfaces as "The socket connection was closed unexpectedly…", the same wording native `fetch` uses, so the drop classifies as transient and the turn is retried; caller aborts keep their original error ([#13384](https://github.com/can1357/oh-my-pi/pull/13384) by [@jerryfane](https://github.com/jerryfane))
|
|
20
|
+
- Fixed a stale Z.AI quota block pinning sessions to a fallback model after live usage recovered ([#13343](https://github.com/can1357/oh-my-pi/issues/13343)).
|
|
21
|
+
- Fixed OAuth credentials being re-minted on every provider 401 during an outage; recently minted tokens are reused for auth recovery ([#13350](https://github.com/can1357/oh-my-pi/issues/13350)) ([#13485](https://github.com/can1357/oh-my-pi/pull/13485) by [@ShivamB25](https://github.com/ShivamB25)).
|
|
22
|
+
- Fixed Claude usage reports intermittently dropping an account's saved resets when the separate reset probe was rate-limited or timed out; the last known saved resets now stay visible until the probe answers again ([#13474](https://github.com/can1357/oh-my-pi/pull/13474) by [@schickling-assistant](https://github.com/schickling-assistant))
|
|
23
|
+
- Fixed transient Windows `EPERM` when creating the provider in-flight lock failing the request instead of retrying ([#13334](https://github.com/can1357/oh-my-pi/pull/13334) by [@1Morganmore](https://github.com/1Morganmore)).
|
|
24
|
+
- Fixed rolling per-minute TPM/RPM 429s worded as quota errors being treated as exhausted quota and ending the turn ([#13253](https://github.com/can1357/oh-my-pi/issues/13253)).
|
|
25
|
+
- Fixed keyless Anthropic-compatible endpoints receiving `Authorization: Bearer N/A` and `X-Api-Key: N/A` headers ([#13043](https://github.com/can1357/oh-my-pi/pull/13043) by [@jchanghong023](https://github.com/jchanghong023)).
|
|
26
|
+
- Fixed legacy Windsurf Enterprise API keys being rejected because they were always sent with the Devin session-token prefix ([#12960](https://github.com/can1357/oh-my-pi/pull/12960)).
|
|
27
|
+
- Fixed an exhausted Cursor "Other Models" pool blocking Grok and Composer, which Cursor bills to its own pool ([#13198](https://github.com/can1357/oh-my-pi/issues/13198)).
|
|
28
|
+
- Fixed Anthropic OAuth requests leaving the agent system prompt without its own cache breakpoint: the breakpoint on the short Claude Code identity block now moves to the last system block, so a request whose messages miss the cache (such as the first after a compaction) reads the cached system prompt instead of writing it again ([#13104](https://github.com/can1357/oh-my-pi/issues/13104), [#13556](https://github.com/can1357/oh-my-pi/pull/13556) by [@aktanazat](https://github.com/aktanazat)).
|
|
29
|
+
- Fixed the Anthropic system cache breakpoint covering working-directory-specific system text: it now sits before the first `<project-context>` or `<memories>` block, and on OAuth it replaces the identity-block breakpoint instead of taking a message breakpoint ([#13104](https://github.com/can1357/oh-my-pi/issues/13104)).
|
|
30
|
+
|
|
5
31
|
## [18.4.0] - 2026-09-28
|
|
6
32
|
|
|
7
33
|
### Breaking Changes
|
package/README.md
CHANGED
|
@@ -1161,6 +1161,18 @@ const response = await complete(
|
|
|
1161
1161
|
);
|
|
1162
1162
|
```
|
|
1163
1163
|
|
|
1164
|
+
When an auth-broker client requests recovery after a provider rejects an OAuth
|
|
1165
|
+
bearer, the broker may reuse a still-fresh token that it minted in the previous
|
|
1166
|
+
five minutes instead of rotating the refresh token again. The process-local
|
|
1167
|
+
cache is bound to the credential ID and access token. Scheduled expiry refreshes,
|
|
1168
|
+
direct forced refreshes such as MCP recovery, ordinary hard-auth blocks, and
|
|
1169
|
+
sibling rotation keep their existing behavior. Cached refresh responses rebind
|
|
1170
|
+
by durable credential ID so concurrent row removal cannot switch a pinned
|
|
1171
|
+
session to another account.
|
|
1172
|
+
Generic `forceRefresh: true` requests do not opt into reuse. Provider-401 retry
|
|
1173
|
+
paths pass `refreshReason: "auth-recovery"` explicitly; expiry sentinels and
|
|
1174
|
+
usage polling do not imply that reason.
|
|
1175
|
+
|
|
1164
1176
|
### Provider Notes
|
|
1165
1177
|
|
|
1166
1178
|
**OpenAI Codex**: Requires a ChatGPT Plus or Pro subscription. Provides access to GPT-5.x Codex models with extended context windows and reasoning capabilities. The library automatically handles session-based prompt caching when `sessionId` is provided in stream options.
|
|
@@ -5,7 +5,7 @@ import type { AccountPolicies } from "./policy.js";
|
|
|
5
5
|
import type { CredentialPool } from "./pool.js";
|
|
6
6
|
import type { OAuthRefresher } from "./refresh.js";
|
|
7
7
|
import type { CredentialSelector } from "./select.js";
|
|
8
|
-
import type { AuthAccountPolicy, AuthApiKeyOptions, OAuthAccess, OAuthAccessResolution, OAuthAccountIdentity, OAuthAccountSummary, OAuthApi, OAuthCredential, OAuthLoginController, OAuthLoginIdentity, StoredOAuthRefreshOptions, StoredOAuthRefreshResult
|
|
8
|
+
import type { AuthAccountPolicy, AuthApiKeyOptions, AuthCredentialSnapshotEntry, OAuthAccess, OAuthAccessResolution, OAuthAccountIdentity, OAuthAccountSummary, OAuthApi, OAuthCredential, OAuthLoginController, OAuthLoginIdentity, OAuthRefreshByIdOptions, StoredOAuthRefreshOptions, StoredOAuthRefreshResult } from "./types.js";
|
|
9
9
|
/** Dependencies used by the OAuth account operations. */
|
|
10
10
|
export interface OAuthAccountsDeps {
|
|
11
11
|
pool: CredentialPool;
|
|
@@ -87,7 +87,7 @@ export declare class OAuthAccounts implements OAuthApi {
|
|
|
87
87
|
*/
|
|
88
88
|
policy(provider: string, identity: OAuthAccountIdentity): AuthAccountPolicy | undefined;
|
|
89
89
|
/** Force-refresh one stored credential by its durable row id. */
|
|
90
|
-
refresh(id: number, signal?: AbortSignal): Promise<AuthCredentialSnapshotEntry>;
|
|
90
|
+
refresh(id: number, signal?: AbortSignal, options?: OAuthRefreshByIdOptions): Promise<AuthCredentialSnapshotEntry>;
|
|
91
91
|
/** Refresh one stored OAuth credential through the durable ownership path. */
|
|
92
92
|
refreshStored<T extends OAuthCredential = OAuthCredential>(provider: string, options: StoredOAuthRefreshOptions<T>): Promise<StoredOAuthRefreshResult<T>>;
|
|
93
93
|
}
|
|
@@ -3,7 +3,7 @@ import type { Provider } from "../types.js";
|
|
|
3
3
|
import { type CredentialPool } from "./pool.js";
|
|
4
4
|
import type { AccountPolicies } from "./policy.js";
|
|
5
5
|
import { type AuthCredentialStore } from "./store.js";
|
|
6
|
-
import { type AuthCredentialSnapshotEntry, type AuthStorageOptions, type OAuthCredential, type StoredOAuthRefreshOptions, type StoredOAuthRefreshResult } from "./types.js";
|
|
6
|
+
import { type AuthCredentialSnapshotEntry, type AuthStorageOptions, type OAuthCredential, type OAuthRefreshByIdOptions, type OAuthRefreshReason, type StoredOAuthRefreshOptions, type StoredOAuthRefreshResult } from "./types.js";
|
|
7
7
|
/**
|
|
8
8
|
* Refresh OAuth access tokens this many ms before their stated expiry. The
|
|
9
9
|
* skew exists so callers downstream of {@link OAuthRefresher} (stream providers,
|
|
@@ -48,12 +48,12 @@ export declare class OAuthRefresher {
|
|
|
48
48
|
* continuing.
|
|
49
49
|
*/
|
|
50
50
|
disableDefinitiveFailure(provider: string, credentialId: number | undefined, attemptedCredential: OAuthCredential, index: number, errorMsg: string): Promise<"disabled" | "peer-rotated" | "cas-lost">;
|
|
51
|
-
refresh(provider: Provider, credential: OAuthCredential, credentialId: number | undefined, signal?: AbortSignal): Promise<OAuthCredentials>;
|
|
51
|
+
refresh(provider: Provider, credential: OAuthCredential, credentialId: number | undefined, signal?: AbortSignal, reason?: OAuthRefreshReason): Promise<OAuthCredentials>;
|
|
52
52
|
/**
|
|
53
53
|
* Refresh the OAuth credential with the given id through a per-credential
|
|
54
54
|
* single-flight. Concurrent callers for the same row await the same upstream
|
|
55
55
|
* refresh attempt, which is required for providers that rotate refresh tokens
|
|
56
56
|
* on every successful refresh.
|
|
57
57
|
*/
|
|
58
|
-
refreshById(id: number, signal?: AbortSignal): Promise<AuthCredentialSnapshotEntry>;
|
|
58
|
+
refreshById(id: number, signal?: AbortSignal, options?: OAuthRefreshByIdOptions): Promise<AuthCredentialSnapshotEntry>;
|
|
59
59
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { OAuthCredentials } from "../registry/oauth/types.js";
|
|
2
2
|
import type { Provider } from "../types.js";
|
|
3
3
|
import type { ClientUsageIdentity, ClientUsageReport, ClientUsageSummary, ObservedUsageEntry, UsageHistoryEntry, UsageHistoryQuery, UsageReport } from "../usage.js";
|
|
4
|
-
import type { AuthCredential, DisabledCredentialSummary, OAuthCredential, StoredAuthCredential, StoredCredentialBlock } from "./types.js";
|
|
4
|
+
import type { AuthCredential, DisabledCredentialSummary, OAuthCredential, OAuthRefreshReason, StoredAuthCredential, StoredCredentialBlock } from "./types.js";
|
|
5
5
|
/** Owner and timestamp that fence a durable credential refresh lease. */
|
|
6
6
|
export interface CredentialRefreshLeaseFence {
|
|
7
7
|
owner: string;
|
|
@@ -128,8 +128,10 @@ export interface CredentialUpstream {
|
|
|
128
128
|
* `signal` propagates the agent's cancel (ESC, request abort, …) all the
|
|
129
129
|
* way to the broker fetch so a hung connection can't strand the caller
|
|
130
130
|
* for `timeoutMs * (maxRetries + 1)`.
|
|
131
|
+
* `reason` distinguishes provider-auth recovery from generic/MCP refreshes
|
|
132
|
+
* that must always mint a new access token.
|
|
131
133
|
*/
|
|
132
|
-
refreshOAuthCredential(provider: Provider, credentialId: number, credential: OAuthCredential, signal?: AbortSignal): Promise<OAuthCredentials>;
|
|
134
|
+
refreshOAuthCredential(provider: Provider, credentialId: number, credential: OAuthCredential, signal?: AbortSignal, reason?: OAuthRefreshReason): Promise<OAuthCredentials>;
|
|
133
135
|
/**
|
|
134
136
|
* Optional async pre-read hook invoked after AuthStorage selects a stored
|
|
135
137
|
* credential but before it returns that credential for an outbound request.
|
|
@@ -272,6 +272,8 @@ export interface CredentialDisabledEvent {
|
|
|
272
272
|
orgId?: string;
|
|
273
273
|
orgName?: string;
|
|
274
274
|
}
|
|
275
|
+
/** Why a delegated OAuth refresh was requested. */
|
|
276
|
+
export type OAuthRefreshReason = "auth-recovery";
|
|
275
277
|
/** Configuration supplied when constructing credential storage. */
|
|
276
278
|
export type AuthStorageOptions = {
|
|
277
279
|
usageProviderResolver?: (provider: Provider) => UsageProvider | undefined;
|
|
@@ -301,11 +303,14 @@ export type AuthStorageOptions = {
|
|
|
301
303
|
* per-provider local refresh function. Receives the credential id so the
|
|
302
304
|
* implementation can address remote credentials.
|
|
303
305
|
*
|
|
306
|
+
* `reason` is `"auth-recovery"` only for a provider-auth retry; generic and
|
|
307
|
+
* managed MCP force-refresh calls leave it unset.
|
|
308
|
+
*
|
|
304
309
|
* Must return updated {@link OAuthCredentials} with at least `access` and
|
|
305
310
|
* `expires`. `refresh` may be an opaque sentinel (e.g. `"__remote__"`) when
|
|
306
311
|
* the actual refresh token never leaves the broker.
|
|
307
312
|
*/
|
|
308
|
-
refreshOAuthCredential?: (provider: Provider, credentialId: number, credential: OAuthCredential, signal?: AbortSignal) => Promise<OAuthCredentials>;
|
|
313
|
+
refreshOAuthCredential?: (provider: Provider, credentialId: number, credential: OAuthCredential, signal?: AbortSignal, reason?: OAuthRefreshReason) => Promise<OAuthCredentials>;
|
|
309
314
|
/**
|
|
310
315
|
* Human-readable description of the credential store backing this
|
|
311
316
|
* AuthStorage instance. Surfaced through {@link AuthStorage.keys.describe}
|
|
@@ -414,6 +419,8 @@ export type AuthApiKeyOptions = {
|
|
|
414
419
|
* that a peer/broker rotated out from under us is replaced before retrying.
|
|
415
420
|
*/
|
|
416
421
|
forceRefresh?: boolean;
|
|
422
|
+
/** Explicit provider-401 recovery; generic force refreshes leave this unset. */
|
|
423
|
+
refreshReason?: OAuthRefreshReason;
|
|
417
424
|
};
|
|
418
425
|
/**
|
|
419
426
|
* Refreshed OAuth access plus identity metadata returned by
|
|
@@ -876,6 +883,15 @@ export interface KeysApi {
|
|
|
876
883
|
modelId?: string;
|
|
877
884
|
}): ApiKeyResolver;
|
|
878
885
|
}
|
|
886
|
+
/** Controls whether a row-id refresh may reuse a token minted by this refresher. */
|
|
887
|
+
export interface OAuthRefreshByIdOptions {
|
|
888
|
+
/**
|
|
889
|
+
* Return the stored credential when it still holds a fresh access token this
|
|
890
|
+
* refresher minted recently. Auth-recovery callers use this to avoid rotating
|
|
891
|
+
* refresh tokens repeatedly when a provider rejects every valid bearer.
|
|
892
|
+
*/
|
|
893
|
+
reuseRecentMint?: boolean;
|
|
894
|
+
}
|
|
879
895
|
/** OAuth login, access, account identity, and refresh operations. */
|
|
880
896
|
export interface OAuthApi {
|
|
881
897
|
/**
|
|
@@ -950,9 +966,10 @@ export interface OAuthApi {
|
|
|
950
966
|
* Refresh the OAuth credential with the given id through a per-credential
|
|
951
967
|
* single-flight. Concurrent callers for the same row await the same upstream
|
|
952
968
|
* refresh attempt, which is required for providers that rotate refresh tokens
|
|
953
|
-
* on every successful refresh.
|
|
969
|
+
* on every successful refresh. Mints unconditionally unless
|
|
970
|
+
* {@link OAuthRefreshByIdOptions.reuseRecentMint} is set.
|
|
954
971
|
*/
|
|
955
|
-
refresh(id: number, signal?: AbortSignal): Promise<AuthCredentialSnapshotEntry>;
|
|
972
|
+
refresh(id: number, signal?: AbortSignal, options?: OAuthRefreshByIdOptions): Promise<AuthCredentialSnapshotEntry>;
|
|
956
973
|
/**
|
|
957
974
|
* Refresh one stored OAuth credential under durable row ownership.
|
|
958
975
|
*/
|
|
@@ -66,10 +66,17 @@ export declare class UsageCache {
|
|
|
66
66
|
/**
|
|
67
67
|
* Force the next usage fetch for `provider` to bypass the 5-min cache, so
|
|
68
68
|
* `/usage` reflects a freshly-redeemed reset instead of stale numbers.
|
|
69
|
+
* `resetSpentCredentialId` also forgets that credential's cached saved-reset
|
|
70
|
+
* block, so a failed follow-up reset probe cannot carry the pre-spend
|
|
71
|
+
* inventory forward.
|
|
69
72
|
*/
|
|
70
|
-
invalidate(provider: string, baseUrl?: string
|
|
73
|
+
invalidate(provider: string, baseUrl?: string, options?: {
|
|
74
|
+
resetSpentCredentialId?: number;
|
|
75
|
+
}): void;
|
|
71
76
|
/** A confirmed reset permits one fresh probe even during a pre-reset failure cooldown. */
|
|
72
|
-
invalidateAfterReset(provider: Provider, baseUrl?: string
|
|
77
|
+
invalidateAfterReset(provider: Provider, baseUrl?: string, options?: {
|
|
78
|
+
resetSpentCredentialId?: number;
|
|
79
|
+
}): void;
|
|
73
80
|
/**
|
|
74
81
|
* Expire cached reports for a provider after its runtime usage implementation changes.
|
|
75
82
|
* This keeps a newly installed extension provider from serving a built-in snapshot.
|
|
@@ -29,6 +29,10 @@ export interface UsageServiceDeps {
|
|
|
29
29
|
requestTimeoutMs: number;
|
|
30
30
|
logger: UsageLogger;
|
|
31
31
|
}
|
|
32
|
+
type UsageReportsOptions = {
|
|
33
|
+
baseUrlResolver?: (provider: Provider) => string | undefined;
|
|
34
|
+
signal?: AbortSignal;
|
|
35
|
+
};
|
|
32
36
|
/** Usage reports: per-credential cached fetches, aggregate reports, header ingestion, history. */
|
|
33
37
|
export declare class UsageService implements UsageApi {
|
|
34
38
|
#private;
|
|
@@ -95,11 +99,7 @@ export declare class UsageService implements UsageApi {
|
|
|
95
99
|
*/
|
|
96
100
|
reportingModelIds(provider: Provider, modelIds: readonly string[], reports: readonly UsageReport[]): string[];
|
|
97
101
|
/** Fetch all providers’ current usage reports, sharing concurrent polls. */
|
|
98
|
-
reports(options?:
|
|
99
|
-
baseUrlResolver?: (provider: Provider) => string | undefined;
|
|
100
|
-
/** Caller's cancel signal; only rejects this caller, never the shared upstream fetch. */
|
|
101
|
-
signal?: AbortSignal;
|
|
102
|
-
}): Promise<UsageReport[] | null>;
|
|
102
|
+
reports(options?: UsageReportsOptions): Promise<UsageReport[] | null>;
|
|
103
103
|
/**
|
|
104
104
|
* Discard cached usage reports before a user-requested refresh. The next
|
|
105
105
|
* read probes upstream serially per provider unless a failure cooldown is
|
|
@@ -107,3 +107,4 @@ export declare class UsageService implements UsageApi {
|
|
|
107
107
|
*/
|
|
108
108
|
invalidate(provider?: string, signal?: AbortSignal): Promise<void>;
|
|
109
109
|
}
|
|
110
|
+
export {};
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* `omp auth-broker status` (liveness checks). All endpoints except
|
|
6
6
|
* `/v1/healthz` require a bearer token.
|
|
7
7
|
*/
|
|
8
|
-
import type { AuthCredential, DisabledCredentialSummary } from "../auth-storage.js";
|
|
8
|
+
import type { AuthCredential, DisabledCredentialSummary, OAuthRefreshReason } from "../auth-storage.js";
|
|
9
9
|
import type { ClientUsageReportRequest, ClientUsageReportResponse, ClientUsageSummaryResponse, CredentialBlockDeleteRequest, CredentialBlockRequest, CredentialBlockResponse, CredentialBlocksDeleteResponse, CredentialDisableResponse, CredentialRefreshResponse, CredentialUploadResponse, HealthzResponse, SnapshotResponse, SnapshotStreamEvent, UsageHistoryResponse, UsageResponse, UsageStaleResponse } from "./types.js";
|
|
10
10
|
export interface AuthBrokerClientOptions {
|
|
11
11
|
/** Base URL (e.g. `https://broker.tailnet:8765`). Trailing slashes are trimmed. */
|
|
@@ -86,7 +86,7 @@ export declare class AuthBrokerClient {
|
|
|
86
86
|
sinceMs?: number;
|
|
87
87
|
}, signal?: AbortSignal): Promise<ClientUsageSummaryResponse>;
|
|
88
88
|
notifyUsageStale(signal?: AbortSignal): Promise<UsageStaleResponse>;
|
|
89
|
-
refreshCredential(id: number, signal?: AbortSignal): Promise<CredentialRefreshResponse>;
|
|
89
|
+
refreshCredential(id: number, signal?: AbortSignal, reason?: OAuthRefreshReason): Promise<CredentialRefreshResponse>;
|
|
90
90
|
disableCredential(id: number, cause: string, signal?: AbortSignal): Promise<CredentialDisableResponse>;
|
|
91
91
|
/**
|
|
92
92
|
* Disabled-credential tombstones (identity + cause, no token material).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AuthCredentialStore } from "../auth/store.js";
|
|
2
|
-
import { type AuthCredential, type DisabledCredentialSummary, type OAuthCredential, type StoredAuthCredential, type StoredCredentialBlock } from "../auth/types.js";
|
|
2
|
+
import { type AuthCredential, type DisabledCredentialSummary, type OAuthCredential, type OAuthRefreshReason, type StoredAuthCredential, type StoredCredentialBlock } from "../auth/types.js";
|
|
3
3
|
import type { OAuthCredentials } from "../registry/oauth/types.js";
|
|
4
4
|
import type { Provider } from "../types.js";
|
|
5
5
|
import type { ClientUsageIdentity, ObservedUsageEntry, UsageReport } from "../usage.js";
|
|
@@ -128,7 +128,7 @@ export declare class RemoteAuthCredentialStore implements AuthCredentialStore {
|
|
|
128
128
|
* the broker-redacted credential with {@link REMOTE_REFRESH_SENTINEL} in
|
|
129
129
|
* the `refresh` slot.
|
|
130
130
|
*/
|
|
131
|
-
refreshOAuthCredential(_provider: Provider, credentialId: number, _credential: OAuthCredential, signal?: AbortSignal): Promise<OAuthCredentials>;
|
|
131
|
+
refreshOAuthCredential(_provider: Provider, credentialId: number, _credential: OAuthCredential, signal?: AbortSignal, reason?: OAuthRefreshReason): Promise<OAuthCredentials>;
|
|
132
132
|
/**
|
|
133
133
|
* Store-level hook consumed by `AuthStorage.usage.reports()` — proxies
|
|
134
134
|
* to the broker's `/v1/usage` endpoint. Shared per-credential caches and
|
|
@@ -126,9 +126,16 @@ export declare function classifyMessage(message: {
|
|
|
126
126
|
export declare function attach<E extends object>(error: E, id: number): E;
|
|
127
127
|
/** Overflow-classification evidence, including errors received before token usage is available. */
|
|
128
128
|
export interface ContextOverflowMessage extends Pick<AssistantMessage, "errorId" | "stopReason" | "errorMessage"> {
|
|
129
|
-
readonly usage?: Pick<Usage, "input" | "cacheRead" | "cacheWrite">;
|
|
129
|
+
readonly usage?: Pick<Usage, "input" | "cacheRead" | "cacheWrite" | "contextTokens">;
|
|
130
130
|
}
|
|
131
|
-
/**
|
|
131
|
+
/**
|
|
132
|
+
* Provider-reported usage proves context-window excess — authoritative, compaction-owned (#9235).
|
|
133
|
+
*
|
|
134
|
+
* Prefers `contextTokens` when the provider reports it: providers that run
|
|
135
|
+
* several model calls per turn (Cursor's server-side tool loop) report
|
|
136
|
+
* `input`/`cacheRead` summed across those calls, which can exceed the window
|
|
137
|
+
* many times over while the conversation itself stays small.
|
|
138
|
+
*/
|
|
132
139
|
export declare function isUsageBackedContextOverflow(message: ContextOverflowMessage, contextWindow?: number): boolean;
|
|
133
140
|
/** Classify overflow from error flags, available token usage, or provider error text. */
|
|
134
141
|
export declare function isContextOverflow(message: ContextOverflowMessage, contextWindow?: number): boolean;
|
|
@@ -9,8 +9,9 @@ export declare function isDashScopeTokenLimitText(errorMessage: string): boolean
|
|
|
9
9
|
* Classify a rate-limit error message into a reason category.
|
|
10
10
|
* Priority order: explicit details in a resource-exhausted error > QUOTA
|
|
11
11
|
* (Antigravity "quota will reset") > CN quota > DASHSCOPE_TOKEN_LIMIT (TPM/TPS
|
|
12
|
-
* throttle) > CONCURRENT_LIMIT > MODEL_CAPACITY > QUOTA (account) > RATE_LIMIT
|
|
13
|
-
* QUOTA (generic) > SERVER_ERROR > bare
|
|
12
|
+
* throttle) > CONCURRENT_LIMIT > MODEL_CAPACITY > QUOTA (account) > RATE_LIMIT
|
|
13
|
+
* (including TPM/RPM rolling windows) > QUOTA (generic) > SERVER_ERROR > bare
|
|
14
|
+
* resource-exhausted > UNKNOWN.
|
|
14
15
|
*
|
|
15
16
|
* Bare "resource exhausted" / "resource_exhausted" maps to MODEL_CAPACITY (transient, short wait).
|
|
16
17
|
* Explicit details such as "quota exceeded" retain their normal classification.
|
|
@@ -17,7 +17,7 @@ import type { ToolResultMessage } from "../../types.js";
|
|
|
17
17
|
* virtual registry. Re-exported here because this is where the frame builders
|
|
18
18
|
* and their translation are consumed together.
|
|
19
19
|
*/
|
|
20
|
-
export {
|
|
20
|
+
export { cursorExecReadPath, cursorRawReadPath, omitUndefinedArgs, piEscapeRegexLiteral, piGrepSkip, piJoinPath, piLimit, piLsPath, piReadDisplayPath, piReadPath, piReadPathHasRange, piTimeout, shellTimeoutSeconds, } from "../cursor-pi-args.js";
|
|
21
21
|
/** Flatten a tool result's content into the single `output` string the Pi frames carry. */
|
|
22
22
|
export declare function piOutputText(toolResult: ToolResultMessage): string;
|
|
23
23
|
/**
|
|
@@ -22,18 +22,14 @@
|
|
|
22
22
|
* A `pi_read` range composed onto the path as `read`'s inline `:raw:N+K`
|
|
23
23
|
* selector.
|
|
24
24
|
*
|
|
25
|
-
* `read` exposes no range kwargs
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* wrong for a caller that asked for exactly `limit` lines from `offset`. The
|
|
34
|
-
* wire result is an opaque `output` string, so the hashline and line-number
|
|
35
|
-
* gutter that `raw` also drops carry nothing the frame's contract needs.
|
|
36
|
-
* A range-free read keeps the ordinary form — whole-file reads want them.
|
|
25
|
+
* `read` exposes no range kwargs; `offset` and `limit` are composed onto the
|
|
26
|
+
* path. A negative offset needs the source line count and is resolved by the
|
|
27
|
+
* coding-agent bridge before calling this helper. `limit: 0` has no selector
|
|
28
|
+
* representation and returns `null`.
|
|
29
|
+
*
|
|
30
|
+
* Range selectors are raw because plain ranges add context lines. Cursor
|
|
31
|
+
* numbers the returned text itself, so it cannot use read's hashline gutter.
|
|
32
|
+
* Use [`cursorExecReadPath`] for a range-free read, which also needs `:raw`.
|
|
37
33
|
*/
|
|
38
34
|
export declare function piReadPath(readPath: string, offset?: number, limit?: number): string | null;
|
|
39
35
|
/**
|
|
@@ -55,14 +51,13 @@ export declare function piReadPathHasRange(readPath: string): boolean;
|
|
|
55
51
|
*/
|
|
56
52
|
export declare function cursorRawReadPath(readPath: string): string;
|
|
57
53
|
/**
|
|
58
|
-
*
|
|
54
|
+
* Raw selector for a Cursor exec read, including edit-owned materialization.
|
|
59
55
|
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* second `:raw` onto the already-composed selector.
|
|
56
|
+
* Compose a requested window before forcing `:raw` on whole-file reads. The
|
|
57
|
+
* caller drops `offset`/`limit` after composing so the handler cannot append
|
|
58
|
+
* another selector.
|
|
64
59
|
*/
|
|
65
|
-
export declare function
|
|
60
|
+
export declare function cursorExecReadPath(readPath: string, offset?: number, limit?: number): string | null;
|
|
66
61
|
/**
|
|
67
62
|
* The same range as {@link piReadPath}, rendered for a transcript block rather
|
|
68
63
|
* than for execution.
|
package/dist/types/stream.d.ts
CHANGED
|
@@ -19,6 +19,13 @@ export declare const __providerInFlightForTesting: {
|
|
|
19
19
|
setWaitObserver(observer: ((provider: string) => void) | undefined): void;
|
|
20
20
|
setLockCreatedObserver(observer: ((lockDir: string) => Promise<void>) | undefined): void;
|
|
21
21
|
setLockIdentifiedObserver(observer: ((lockDir: string) => Promise<void>) | undefined): void;
|
|
22
|
+
setLockMkdirOverride(mkdir: ((lockDir: string) => Promise<void>) | undefined): void;
|
|
23
|
+
setLockPlatformOverride(platform: NodeJS.Platform | undefined): void;
|
|
24
|
+
setLockRetryTimings(timings: {
|
|
25
|
+
budgetMs?: number;
|
|
26
|
+
initialDelayMs?: number;
|
|
27
|
+
maxDelayMs?: number;
|
|
28
|
+
} | undefined): void;
|
|
22
29
|
providerDir(provider: string): string;
|
|
23
30
|
lockDir(provider: string): string;
|
|
24
31
|
captureStaleLockRelease(provider: string): Promise<(() => Promise<void>) | null>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { UsageProvider, UsageReport } from "../usage.js";
|
|
1
|
+
import type { CredentialRankingStrategy, UsageProvider, UsageReport } from "../usage.js";
|
|
2
2
|
/**
|
|
3
3
|
* Cursor's `/api/usage-summary` has shipped two personal-bucket shapes:
|
|
4
4
|
* - Enterprise/team dashboards historically exposed `individualUsage.overall`
|
|
@@ -12,4 +12,6 @@ import type { UsageProvider, UsageReport } from "../usage.js";
|
|
|
12
12
|
*/
|
|
13
13
|
export declare function parseCursorIndividualUsage(payload: unknown, fetchedAt?: number): UsageReport | null;
|
|
14
14
|
export declare function parseCursorUsage(payload: unknown, fetchedAt?: number): UsageReport | null;
|
|
15
|
+
/** Routes Cursor credential ranking and reserve checks through the requested model's billing pool. */
|
|
16
|
+
export declare const cursorRankingStrategy: CredentialRankingStrategy;
|
|
15
17
|
export declare const cursorUsageProvider: UsageProvider;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import type { CredentialRankingStrategy, UsageProvider } from "../usage.js";
|
|
2
|
+
/** Fetches the account-wide quota windows for ZAI credentials. */
|
|
2
3
|
export declare const zaiUsageProvider: UsageProvider;
|
|
4
|
+
/** Ranks ZAI credentials and identifies quota blocks a live report can heal. */
|
|
3
5
|
export declare const zaiRankingStrategy: CredentialRankingStrategy;
|
package/dist/types/usage.d.ts
CHANGED
|
@@ -580,6 +580,12 @@ export interface UsageFetchContext {
|
|
|
580
580
|
fetch: FetchImpl;
|
|
581
581
|
logger?: UsageLogger;
|
|
582
582
|
retryWait?: (delayMs: number, signal?: AbortSignal) => Promise<void>;
|
|
583
|
+
/**
|
|
584
|
+
* Last report cached for this exact credential cache key, when one exists.
|
|
585
|
+
* Lets a fetcher keep a field it could not re-read this time (a failed
|
|
586
|
+
* secondary probe) instead of reporting it as absent.
|
|
587
|
+
*/
|
|
588
|
+
previousReport?: UsageReport;
|
|
583
589
|
}
|
|
584
590
|
/** Provider implementation for fetching usage information. */
|
|
585
591
|
export interface UsageProvider {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-ai",
|
|
3
|
-
"version": "18.4.
|
|
3
|
+
"version": "18.4.2",
|
|
4
4
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -155,11 +155,11 @@
|
|
|
155
155
|
"fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
|
|
156
156
|
},
|
|
157
157
|
"dependencies": {
|
|
158
|
-
"@oh-my-pi/omptype": "18.4.
|
|
159
|
-
"@oh-my-pi/pi-catalog": "18.4.
|
|
160
|
-
"@oh-my-pi/pi-natives": "18.4.
|
|
161
|
-
"@oh-my-pi/pi-utils": "18.4.
|
|
162
|
-
"@oh-my-pi/pi-wire": "18.4.
|
|
158
|
+
"@oh-my-pi/omptype": "18.4.2",
|
|
159
|
+
"@oh-my-pi/pi-catalog": "18.4.2",
|
|
160
|
+
"@oh-my-pi/pi-natives": "18.4.2",
|
|
161
|
+
"@oh-my-pi/pi-utils": "18.4.2",
|
|
162
|
+
"@oh-my-pi/pi-wire": "18.4.2"
|
|
163
163
|
},
|
|
164
164
|
"devDependencies": {
|
|
165
165
|
"@types/bun": "^1.3.14"
|
package/src/auth/cascade.ts
CHANGED
package/src/auth/oauth.ts
CHANGED
|
@@ -13,6 +13,7 @@ import type { CredentialSelector } from "./select";
|
|
|
13
13
|
import type {
|
|
14
14
|
AuthAccountPolicy,
|
|
15
15
|
AuthApiKeyOptions,
|
|
16
|
+
AuthCredentialSnapshotEntry,
|
|
16
17
|
OAuthAccess,
|
|
17
18
|
OAuthAccessResolution,
|
|
18
19
|
OAuthAccountIdentity,
|
|
@@ -21,9 +22,9 @@ import type {
|
|
|
21
22
|
OAuthCredential,
|
|
22
23
|
OAuthLoginController,
|
|
23
24
|
OAuthLoginIdentity,
|
|
25
|
+
OAuthRefreshByIdOptions,
|
|
24
26
|
StoredOAuthRefreshOptions,
|
|
25
27
|
StoredOAuthRefreshResult,
|
|
26
|
-
AuthCredentialSnapshotEntry,
|
|
27
28
|
} from "./types";
|
|
28
29
|
|
|
29
30
|
type StoredOAuthSelection = {
|
|
@@ -338,8 +339,8 @@ export class OAuthAccounts implements OAuthApi {
|
|
|
338
339
|
}
|
|
339
340
|
|
|
340
341
|
/** Force-refresh one stored credential by its durable row id. */
|
|
341
|
-
refresh(id: number, signal?: AbortSignal): Promise<AuthCredentialSnapshotEntry> {
|
|
342
|
-
return this.#deps.refresher.refreshById(id, signal);
|
|
342
|
+
refresh(id: number, signal?: AbortSignal, options?: OAuthRefreshByIdOptions): Promise<AuthCredentialSnapshotEntry> {
|
|
343
|
+
return this.#deps.refresher.refreshById(id, signal, options);
|
|
343
344
|
}
|
|
344
345
|
|
|
345
346
|
/** Refresh one stored OAuth credential through the durable ownership path. */
|