@oh-my-pi/pi-ai 18.2.8 → 18.2.10
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 +37 -18
- package/dist/types/auth-gateway/types.d.ts +5 -0
- package/dist/types/auth-storage.d.ts +35 -32
- package/dist/types/index.d.ts +1 -0
- package/dist/types/providers/amazon-bedrock.d.ts +7 -0
- package/dist/types/providers/claude-code-fingerprint.d.ts +22 -3
- package/dist/types/providers/google-gemini-cli.d.ts +0 -2
- package/dist/types/providers/openai-chat-server-schema.d.ts +2 -2
- package/dist/types/usage/claude-api.d.ts +22 -0
- package/dist/types/usage/claude-reset.d.ts +49 -0
- package/dist/types/usage.d.ts +111 -5
- package/dist/types/utils/schema/json-schema-validator.d.ts +5 -2
- package/dist/types/utils/tool-call-loop-guard.d.ts +1 -1
- package/package.json +6 -6
- package/src/auth/sqlite-credential-store.ts +44 -1
- package/src/auth-broker/remote-store.ts +6 -6
- package/src/auth-broker/wire-schemas.ts +14 -0
- package/src/auth-gateway/server.ts +4 -0
- package/src/auth-gateway/types.ts +5 -0
- package/src/auth-storage.ts +263 -140
- package/src/error/flags.ts +10 -0
- package/src/index.ts +1 -0
- package/src/providers/amazon-bedrock.ts +55 -5
- package/src/providers/anthropic.ts +64 -21
- package/src/providers/aws-credentials.ts +124 -11
- package/src/providers/claude-code-fingerprint.ts +55 -3
- package/src/providers/gitlab-duo.ts +20 -4
- package/src/providers/google-gemini-cli.ts +0 -8
- package/src/providers/google-shared.ts +1 -18
- package/src/providers/openai-chat-server-schema.ts +1 -1
- package/src/providers/openai-chat-server.ts +3 -1
- package/src/providers/openai-codex-responses.ts +27 -5
- package/src/providers/openai-completions.ts +122 -19
- package/src/providers/pi-native-server.ts +1 -0
- package/src/registry/oauth/anthropic.ts +2 -3
- package/src/stream.ts +13 -4
- package/src/usage/alibaba-token-plan.ts +7 -1
- package/src/usage/claude-api.ts +66 -0
- package/src/usage/claude-reset.ts +641 -0
- package/src/usage/claude.ts +37 -59
- package/src/usage/kimi.ts +32 -1
- package/src/usage.ts +52 -5
- package/src/utils/schema/json-schema-validator.ts +23 -10
- package/src/utils/tool-call-loop-guard.ts +2 -2
- package/src/utils/validation.ts +145 -50
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,42 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Fixed Claude Opus 5.5 ignoring a mid-session switch to high effort when the session started without an explicit effort; the change is now sent as a cache-preserving per-message effort control ([#12909](https://github.com/can1357/oh-my-pi/pull/12909) by [@h4vc](https://github.com/h4vc)).
|
|
8
|
+
|
|
9
|
+
## [18.2.9] - 2026-09-22
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Added Claude saved-reset discovery and redemption, including session-only resets, grant eligibility, expiry, and safe retry handling.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Fixed custom OpenAI-compatible extension streamers failing when no compatibility configuration was provided.
|
|
18
|
+
- Fixed local provider sign-in for LM Studio, llama.cpp, and vLLM so an empty API key is not treated as successful authentication.
|
|
19
|
+
- Fixed Vercel AI Gateway models backed by non-Anthropic providers failing tool calls because of strict schema validation; requests now retry with compatible non-strict tool handling.
|
|
20
|
+
- Improved AWS Bedrock authentication by refreshing expired AWS SSO sessions automatically, reducing the need to run `aws sso login` again.
|
|
21
|
+
- Fixed Bedrock tool-enabled requests when tool descriptions are included in the system prompt.
|
|
22
|
+
- Improved Alibaba Token Plan (Beijing) quota reporting across workspaces and made gateway rejection codes visible in error logs.
|
|
23
|
+
- Fixed the tool-call loop guard so repeated identical calls continue to be redirected after the detection threshold is reached.
|
|
24
|
+
- Fixed valid required null values inside tool argument unions being removed before dispatch ([#12523](https://github.com/can1357/oh-my-pi/pull/12523) by [@cswenor](https://github.com/cswenor)).
|
|
25
|
+
- Signing in to a local provider (lm-studio, llama.cpp, vllm) with an empty key paste no longer reports the provider as logged in while its requests go out unauthenticated. ([#12436](https://github.com/can1357/oh-my-pi/pull/12436) by [@xiechimon](https://github.com/xiechimon))
|
|
26
|
+
- Fixed every turn failing with `400 Invalid schema for function '<tool>' … Missing '<param>'` on Vercel AI Gateway models served from a non-Anthropic upstream (e.g. `openai/gpt-5.6-sol`): the translated strict-tool rejection now triggers the existing non-strict retry instead of failing the turn ([#12760](https://github.com/can1357/oh-my-pi/pull/12760) by [@primitive-type](https://github.com/primitive-type)).
|
|
27
|
+
- Expired AWS SSO access tokens are now refreshed via the SSO OIDC `refresh_token` grant instead of failing with `sso-token-expired`, so Bedrock profiles keep working between `aws sso login` runs the same way the AWS CLI does ([#12736](https://github.com/can1357/oh-my-pi/pull/12736) by [@nwbb](https://github.com/nwbb)).
|
|
28
|
+
- Fixed Bedrock rejecting tool-enabled requests when tool descriptions are inlined into the system prompt ([#12732](https://github.com/can1357/oh-my-pi/pull/12732) by [@mustafaabidali](https://github.com/mustafaabidali)).
|
|
29
|
+
- Alibaba Token Plan (Beijing) quota reporting no longer pins requests to a single workspace, and HTTP-200 gateway rejections now log their error code ([#12395](https://github.com/can1357/oh-my-pi/pull/12395) by [@Dante-dan](https://github.com/Dante-dan)).
|
|
30
|
+
- The tool-call loop guard keeps redirecting when a model continues the same identical call past the detection threshold instead of firing only once ([#12709](https://github.com/can1357/oh-my-pi/pull/12709) by [@F0Rextasy](https://github.com/F0Rextasy)).
|
|
31
|
+
- Fixed OpenAI-compatible Gemini gateways losing message-level thought signatures when replaying tool-call history.
|
|
32
|
+
- Added support for explicitly disabling reasoning with `reasoning_effort: "none"` through Chat Completions authentication gateways.
|
|
33
|
+
- Improved Bedrock resilience by retrying transient in-stream internal server, service unavailable, and throttling errors.
|
|
34
|
+
- Fixed Anthropic prompt-cache keep-alive refreshes for turns that used forced tool selection.
|
|
35
|
+
- Fixed auth-broker usage reports incorrectly sharing usage limits between Team members with shared workspace and organization identifiers.
|
|
36
|
+
- Fixed OpenAI Codex requests hanging when an error response body is delayed.
|
|
37
|
+
- Fixed Kimi usage reporting so monthly totals and code quotas are shown alongside the five-hour usage window.
|
|
38
|
+
- Bedrock no longer sends provider-invalid payloads when an errored tool result contains an image; the image is hoisted into a sibling block ([#12865](https://github.com/can1357/oh-my-pi/pull/12865) by [@roboomp](https://github.com/roboomp)).
|
|
39
|
+
- Gemini, Vertex, and Cloud Code Assist requests no longer include the unsupported `minP`/`repetitionPenalty` sampling fields, which caused 400s when set globally ([#12850](https://github.com/can1357/oh-my-pi/pull/12850) by [@roboomp](https://github.com/roboomp)).
|
|
40
|
+
|
|
5
41
|
## [18.2.8] - 2026-09-21
|
|
6
42
|
|
|
7
43
|
### Added
|
|
@@ -2255,21 +2291,4 @@
|
|
|
2255
2291
|
- Made the openai-completions non-strict retry reachable for `"mixed"` strict mode (previously gated to `all_strict`, i.e. Cerebras only) and taught it to recognize upstream tool-schema validation 400s (`Invalid tool parameters schema …`, `Invalid schema for function …`). A matching rejection now retries the request with base (non-strict) schemas and persists `strictToolsDisabled` on the provider session, so later requests skip the doomed strict attempt instead of paying a 400 + retry round-trip each turn. ([#2270](https://github.com/can1357/oh-my-pi/issues/2270))
|
|
2256
2292
|
- Cross-model `anthropic-messages → anthropic-messages` continuations now preserve prior assistant turns' reasoning chains end-to-end: every prior `thinking`/`redactedThinking` block survives (not just the latest surviving assistant), and third-party ↔ third-party replays keep their signatures intact so the reasoning chain stays signed for the next turn. Signatures are stripped (and any `redacted_thinking` sibling without a native landing spot is dropped) only when an official Anthropic endpoint is on either end of the replay — official Anthropic cryptographically binds reasoning signatures to its key+session+model, while compatible reasoning endpoints (Z.AI, DeepSeek, custom anthropic-messages providers configured via `models.yaml`) treat them as opaque continuation hints. Source-side official detection uses the canonical catalog provider id `"anthropic"` (assistant messages carry no `baseUrl`); target-side detection reuses the baked `compat.officialEndpoint` flag. Latest-turn byte-for-byte behavior (Anthropic's "thinking blocks in the latest assistant message cannot be modified" rule) and existing aborted/errored last-block sanitization are unchanged. ([#2257](https://github.com/can1357/oh-my-pi/issues/2257), [#2265](https://github.com/can1357/oh-my-pi/issues/2265))
|
|
2257
2293
|
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
### Added
|
|
2261
|
-
|
|
2262
|
-
- Added `antigravityRankingStrategy` and registered it for `google-antigravity` in `DEFAULT_RANKING_STRATEGIES`, so new sessions are routed to OAuth credentials with quota headroom for the requested model backend (lowest relevant `remainingFraction` counter as the sole ranked window, 24h `windowDefaults` matching `daily-cloudcode-pa.googleapis.com` resets). Without it, the existing `antigravityUsageProvider` data never reached credential selection. ([#2198](https://github.com/can1357/oh-my-pi/issues/2198))
|
|
2263
|
-
|
|
2264
|
-
### Changed
|
|
2265
|
-
|
|
2266
|
-
- Updated MiniMax and MiniMax Token Plan defaults to `MiniMax-M3` and refreshed Token Plan login copy/links ([#1725](https://github.com/can1357/oh-my-pi/issues/1725)).
|
|
2267
|
-
|
|
2268
|
-
### Fixed
|
|
2269
|
-
|
|
2270
|
-
- Fixed OpenAI Responses and Azure OpenAI Responses streams silently surfacing incomplete output as successful when a custom/proxy provider drops the connection without sending a terminal `response.completed`/`response.incomplete` event. Both providers now detect premature stream closure and throw with `stopReason: "error"` ([#2184](https://github.com/can1357/oh-my-pi/pull/2184))
|
|
2271
|
-
- Fixed `isUsageLimitError` missing Antigravity / Cloud Code Assist's `Individual quota reached` 429 phrasing. The `USAGE_LIMIT_PATTERN` only knew `quota.?exceeded` / `limit_reached`, so `auth-retry` and `AuthStorage.markUsageLimitReached` treated the response as a terminal provider error and pinned sessions to the exhausted OAuth account instead of rotating to a sibling credential. The pattern now also matches `quota.?reached`. ([#2198](https://github.com/can1357/oh-my-pi/issues/2198))
|
|
2272
|
-
- Scoped Antigravity usage blocking and ranking by model family (`gemini-*`/`gemma-*` → Google, `claude-*` → Anthropic, `gpt-*`/`openai/*` → OpenAI), so an exhausted Gemini counter no longer makes a healthy Claude/OpenAI Antigravity credential unavailable until reset. ([#2198](https://github.com/can1357/oh-my-pi/issues/2198))
|
|
2273
|
-
- Fixed no-model Antigravity credential lookups (e.g. image-provider discovery) inheriting provider-wide exhaustion: `scopeLimits` now returns no limits without a concrete backend counter, and `blockScope` always returns a counter scope so missing model context can never fall through to AuthStorage's provider-wide block bucket. ([#2198](https://github.com/can1357/oh-my-pi/issues/2198))
|
|
2274
|
-
|
|
2275
|
-
Older entries are archived in [packages/ai/CHANGELOG.md@8a9097246135](https://github.com/can1357/oh-my-pi/blob/8a9097246135bd572ff96fb552121fe1194d2906/packages/ai/CHANGELOG.md).
|
|
2294
|
+
Older entries are archived in [packages/ai/CHANGELOG.md@1f7329fc2c7c](https://github.com/can1357/oh-my-pi/blob/1f7329fc2c7c366b38731738e0db9c170f9bb348/packages/ai/CHANGELOG.md).
|
|
@@ -47,6 +47,11 @@ export interface AuthGatewayParsedRequestOptions {
|
|
|
47
47
|
reasoning?: Effort;
|
|
48
48
|
/** Force-disable reasoning (Anthropic `thinking: { type: "disabled" }`). */
|
|
49
49
|
disableReasoning?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Preserve an explicit wire-level reasoning-off request through providers
|
|
52
|
+
* that distinguish it from the generic disable hint.
|
|
53
|
+
*/
|
|
54
|
+
forceReasoningOff?: boolean;
|
|
50
55
|
/**
|
|
51
56
|
* Explicit Anthropic `thinking.budget_tokens`. Mirrors Rust's
|
|
52
57
|
* `resolve_thinking_budget`: pins onto whichever effort the client
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { ApiKeyResolver } from "./auth-retry.js";
|
|
2
2
|
import type { OAuthAuthInfo, OAuthController, OAuthCredentials, OAuthPrompt, OAuthProviderId } from "./registry/oauth/types.js";
|
|
3
3
|
import type { Provider } from "./types.js";
|
|
4
|
-
import type { ClientUsageIdentity, ClientUsageReport, ClientUsageSummary, CredentialRankingStrategy, ObservedUsageEntry, UsageHistoryEntry, UsageHistoryQuery, UsageLogger, UsageProvider, UsageReport } from "./usage.js";
|
|
5
|
-
import { type CodexResetConsumeCode, type CodexResetCredit } from "./usage/openai-codex-reset.js";
|
|
4
|
+
import type { ClientUsageIdentity, ClientUsageReport, ClientUsageSummary, CredentialRankingStrategy, ObservedUsageEntry, UsageHistoryEntry, UsageHistoryQuery, UsageLogger, UsageProvider, UsageReport, UsageResetCredit, UsageResetCredits } from "./usage.js";
|
|
6
5
|
export { isSqliteBusyError, isSqliteCorruptionError, SqliteAuthCredentialStore } from "./auth/sqlite-credential-store.js";
|
|
7
6
|
export type ApiKeyCredential = {
|
|
8
7
|
type: "api_key";
|
|
@@ -685,14 +684,15 @@ export interface StoredOAuthRefreshResult<T extends OAuthCredential = OAuthCrede
|
|
|
685
684
|
refreshed: boolean;
|
|
686
685
|
removed: boolean;
|
|
687
686
|
}
|
|
688
|
-
/**
|
|
689
|
-
* Identifies which stored account to redeem a saved rate-limit reset for.
|
|
690
|
-
* Any one field is enough; `credentialId` is the most precise.
|
|
691
|
-
*/
|
|
687
|
+
/** A saved-reset option bound to one provider and durable stored credential. */
|
|
692
688
|
export interface ResetCreditTarget {
|
|
693
|
-
|
|
689
|
+
provider: string;
|
|
690
|
+
credentialId: number;
|
|
691
|
+
/** Grant selected by the caller; a changed offer must be confirmed again. */
|
|
692
|
+
creditId?: string;
|
|
694
693
|
accountId?: string;
|
|
695
694
|
email?: string;
|
|
695
|
+
orgId?: string;
|
|
696
696
|
}
|
|
697
697
|
/** Outcome of {@link AuthStorage.redeemResetCredit}. */
|
|
698
698
|
export interface ResetCreditRedeemOutcome {
|
|
@@ -706,20 +706,27 @@ export interface ResetCreditRedeemOutcome {
|
|
|
706
706
|
* retryable, unlike a genuine `no_credit`), `http_<status>` (unexpected
|
|
707
707
|
* HTTP).
|
|
708
708
|
*/
|
|
709
|
-
code:
|
|
709
|
+
code: string;
|
|
710
|
+
provider?: string;
|
|
710
711
|
accountId?: string;
|
|
711
712
|
email?: string;
|
|
713
|
+
orgId?: string;
|
|
714
|
+
/** Provider explanation for an unavailable or refused reset. */
|
|
715
|
+
reason?: string;
|
|
716
|
+
/** Normalized usage limit IDs the provider confirmed it cleared. */
|
|
717
|
+
cleared?: string[];
|
|
712
718
|
/** The credit that was spent (when one was). */
|
|
713
719
|
creditId?: string;
|
|
714
720
|
}
|
|
715
721
|
/** One stored account's live saved-reset status, from {@link AuthStorage.listResetCredits}. */
|
|
716
|
-
export interface ResetCreditAccountStatus {
|
|
717
|
-
|
|
722
|
+
export interface ResetCreditAccountStatus extends UsageResetCredits {
|
|
723
|
+
provider: string;
|
|
724
|
+
credentialId: number;
|
|
718
725
|
accountId?: string;
|
|
719
726
|
email?: string;
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
credits:
|
|
727
|
+
orgId?: string;
|
|
728
|
+
orgName?: string;
|
|
729
|
+
credits: UsageResetCredit[];
|
|
723
730
|
/** Whether this is the given session's active account. */
|
|
724
731
|
active: boolean;
|
|
725
732
|
/** Set when the account's token refresh or list call failed. */
|
|
@@ -858,11 +865,23 @@ export declare class AuthStorage {
|
|
|
858
865
|
* Check if credentials exist for a provider in storage.
|
|
859
866
|
*/
|
|
860
867
|
has(provider: string): boolean;
|
|
868
|
+
/**
|
|
869
|
+
* True when the provider has stored credentials but none of them carries
|
|
870
|
+
* auth — i.e. its only credential is the KDL `empty-fallback` keyless-mode
|
|
871
|
+
* marker (an empty paste at an optional-key login prompt). Such a provider
|
|
872
|
+
* is configured-but-keyless: model availability treats it like an
|
|
873
|
+
* `auth: none` endpoint instead of locking it out (issue #12281).
|
|
874
|
+
*/
|
|
875
|
+
hasKeylessPlaceholder(provider: string): boolean;
|
|
861
876
|
/**
|
|
862
877
|
* Dedicated auth for default-model availability (picker / `getAvailable`).
|
|
863
878
|
* Unlike {@link getApiKey}, this does not refresh OAuth tokens, and unlike
|
|
864
879
|
* {@link hasResolvableAuth} it ignores cross-provider env aliases so
|
|
865
880
|
* `XAI_API_KEY` does not auto-select SuperGrok (`xai-oauth`).
|
|
881
|
+
*
|
|
882
|
+
* A stored keyless-fallback marker (empty paste at an optional-key login)
|
|
883
|
+
* does not count: it never reaches the wire as a bearer, so treating it as
|
|
884
|
+
* auth would present the provider as signed-in while requests go out bare.
|
|
866
885
|
*/
|
|
867
886
|
hasAuth(provider: string): boolean;
|
|
868
887
|
/**
|
|
@@ -1170,16 +1189,7 @@ export declare class AuthStorage {
|
|
|
1170
1189
|
* explicit runtime/config API-key override suppresses OAuth.
|
|
1171
1190
|
*/
|
|
1172
1191
|
getOAuthAccessByCredentialId(provider: string, credentialId: number, options?: AuthApiKeyOptions): Promise<OAuthAccessResolution | undefined>;
|
|
1173
|
-
/**
|
|
1174
|
-
* List saved rate-limit resets for every stored OAuth account of `provider`
|
|
1175
|
-
* (Codex), fetched LIVE from the dedicated `rate-limit-reset-credits` route.
|
|
1176
|
-
*
|
|
1177
|
-
* This deliberately bypasses the usage-report cache: `/wham/usage` is
|
|
1178
|
-
* IP-rate-limited and may serve stale (or pre-feature) snapshots when many
|
|
1179
|
-
* accounts are polled, which would hide redeemable credits. One entry per
|
|
1180
|
-
* account, with the session's active account flagged and unreachable
|
|
1181
|
-
* accounts carrying an `error`.
|
|
1182
|
-
*/
|
|
1192
|
+
/** List live saved-reset balances and eligibility for one provider's stored OAuth accounts. */
|
|
1183
1193
|
listResetCredits(options?: {
|
|
1184
1194
|
provider?: string;
|
|
1185
1195
|
sessionId?: string;
|
|
@@ -1187,18 +1197,11 @@ export declare class AuthStorage {
|
|
|
1187
1197
|
signal?: AbortSignal;
|
|
1188
1198
|
}): Promise<ResetCreditAccountStatus[]>;
|
|
1189
1199
|
/**
|
|
1190
|
-
* Redeem
|
|
1191
|
-
*
|
|
1192
|
-
*
|
|
1193
|
-
* Resolves a fresh access token for the target account, picks an available
|
|
1194
|
-
* credit (the given `creditId`, else the first redeemable one), spends it,
|
|
1195
|
-
* and invalidates the cached usage report so the next `/usage` reflects the
|
|
1196
|
-
* reset. Never throws for business outcomes — inspect the returned `code`.
|
|
1200
|
+
* Redeem a stored account's saved reset after checking its live offer.
|
|
1201
|
+
* Business refusals return a code; transport errors may throw without losing Claude's request ID.
|
|
1197
1202
|
*/
|
|
1198
1203
|
redeemResetCredit(options: {
|
|
1199
1204
|
target: ResetCreditTarget;
|
|
1200
|
-
provider?: string;
|
|
1201
|
-
creditId?: string;
|
|
1202
1205
|
baseUrlResolver?: (provider: string) => string | undefined;
|
|
1203
1206
|
signal?: AbortSignal;
|
|
1204
1207
|
}): Promise<ResetCreditRedeemOutcome>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -39,6 +39,7 @@ export * from "./stream.js";
|
|
|
39
39
|
export * from "./types.js";
|
|
40
40
|
export * from "./usage.js";
|
|
41
41
|
export * from "./usage/claude.js";
|
|
42
|
+
export * from "./usage/claude-reset.js";
|
|
42
43
|
export * from "./usage/cursor.js";
|
|
43
44
|
export * from "./usage/gemini.js";
|
|
44
45
|
export * from "./usage/github-copilot.js";
|
|
@@ -11,6 +11,13 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import type { Effort } from "@oh-my-pi/pi-catalog/effort";
|
|
13
13
|
import type { StreamFunction, StreamOptions, ThinkingBudgets } from "../types.js";
|
|
14
|
+
/**
|
|
15
|
+
* Resolve the service-model status for an in-stream exception/error code.
|
|
16
|
+
* Frame headers carry the bare shape name in either camelCase
|
|
17
|
+
* (`internalServerException`) or PascalCase (`InternalServerException`); both
|
|
18
|
+
* normalize to the same map key. Unknown shapes default to 400.
|
|
19
|
+
*/
|
|
20
|
+
export declare function bedrockStreamExceptionStatus(code: string): number;
|
|
14
21
|
export type BedrockThinkingDisplay = "summarized" | "omitted";
|
|
15
22
|
/** Bedrock guardrail trace verbosity, mirrors the Converse `guardrailConfig.trace` values. */
|
|
16
23
|
export type BedrockGuardrailTrace = "enabled" | "disabled" | "enabled_full";
|
|
@@ -7,12 +7,31 @@
|
|
|
7
7
|
* `registry` → `registry/oauth/anthropic` → back into the still-initializing
|
|
8
8
|
* provider module.
|
|
9
9
|
*/
|
|
10
|
-
/**
|
|
11
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Pinned Claude Code CLI version: the offline fallback for {@link getClaudeCodeVersion}.
|
|
12
|
+
* Bumped to the latest npm release by `bun run check-spoofed-versions --update`.
|
|
13
|
+
*/
|
|
14
|
+
export declare const DEFAULT_CLAUDE_CODE_VERSION = "2.1.280";
|
|
12
15
|
/** `@anthropic-ai/sdk` version bundled by the current Claude Code release. */
|
|
13
16
|
export declare const claudeCodeSdkVersion = "0.112.1";
|
|
17
|
+
/**
|
|
18
|
+
* Claude Code CLI version represented on the Anthropic wire (User-Agent, billing
|
|
19
|
+
* header): `PI_AI_CLAUDE_CODE_VERSION` → version adopted from a server rejection
|
|
20
|
+
* (see {@link adoptRequiredClaudeCodeVersion}) → {@link DEFAULT_CLAUDE_CODE_VERSION}.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getClaudeCodeVersion(): string;
|
|
14
23
|
/** User-Agent emitted by Claude Code's CLI inference entrypoint. */
|
|
15
|
-
export declare
|
|
24
|
+
export declare function getClaudeCodeUserAgent(): string;
|
|
25
|
+
/**
|
|
26
|
+
* Adopts the minimum version named by an Anthropic `claude_code_version_too_old`
|
|
27
|
+
* rejection for the rest of the process, so the pinned fallback going stale costs
|
|
28
|
+
* one rejected request instead of a hard failure.
|
|
29
|
+
*
|
|
30
|
+
* Returns true only when the wire version actually increased — callers retry on
|
|
31
|
+
* true, so a repeated rejection at the same version cannot loop. Always false
|
|
32
|
+
* while `PI_AI_CLAUDE_CODE_VERSION` pins the version explicitly.
|
|
33
|
+
*/
|
|
34
|
+
export declare function adoptRequiredClaudeCodeVersion(error: unknown): boolean;
|
|
16
35
|
/** Prefix used to isolate custom Anthropic OAuth tools from built-in tools. */
|
|
17
36
|
export declare const claudeToolPrefix: string;
|
|
18
37
|
/** Identity block prepended by Claude Code's CLI runtime. */
|
|
@@ -1048,7 +1048,7 @@ export declare const openaiChatRequestSchema: import("@oh-my-pi/omptype").Fluent
|
|
|
1048
1048
|
prediction?: unknown;
|
|
1049
1049
|
presence_penalty?: number | undefined;
|
|
1050
1050
|
prompt_cache_key?: unknown;
|
|
1051
|
-
reasoning_effort?: "high" | "low" | "max" | "medium" | "minimal" | "xhigh" | undefined;
|
|
1051
|
+
reasoning_effort?: "high" | "low" | "max" | "medium" | "minimal" | "none" | "xhigh" | undefined;
|
|
1052
1052
|
response_format?: unknown;
|
|
1053
1053
|
safety_identifier?: unknown;
|
|
1054
1054
|
seed?: number | undefined;
|
|
@@ -1263,7 +1263,7 @@ export declare const openaiChatRequestSchema: import("@oh-my-pi/omptype").Fluent
|
|
|
1263
1263
|
prediction?: unknown;
|
|
1264
1264
|
presence_penalty?: number | undefined;
|
|
1265
1265
|
prompt_cache_key?: unknown;
|
|
1266
|
-
reasoning_effort?: "high" | "low" | "max" | "medium" | "minimal" | "xhigh" | undefined;
|
|
1266
|
+
reasoning_effort?: "high" | "low" | "max" | "medium" | "minimal" | "none" | "xhigh" | undefined;
|
|
1267
1267
|
response_format?: unknown;
|
|
1268
1268
|
safety_identifier?: unknown;
|
|
1269
1269
|
seed?: number | undefined;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Canonical host for Claude's first-party account API. */
|
|
2
|
+
export declare const DEFAULT_CLAUDE_API_BASE_URL = "https://api.anthropic.com";
|
|
3
|
+
/** Canonical subscription usage and profile endpoint. */
|
|
4
|
+
export declare const DEFAULT_CLAUDE_OAUTH_BASE_URL = "https://api.anthropic.com/api/oauth";
|
|
5
|
+
/** OAuth protocol beta required by Claude's account routes. */
|
|
6
|
+
export declare const CLAUDE_OAUTH_BETA = "oauth-2025-04-20";
|
|
7
|
+
/**
|
|
8
|
+
* Normalize Messages (`/v1`) and OAuth (`/api/oauth`) endpoints to the common
|
|
9
|
+
* API root used by both usage and reset routes. Custom path prefixes survive.
|
|
10
|
+
*/
|
|
11
|
+
export declare function normalizeClaudeApiBaseUrl(baseUrl?: string): string;
|
|
12
|
+
/** Resolve the OAuth API base while retaining a configured proxy path prefix. */
|
|
13
|
+
export declare function claudeOAuthBaseUrl(baseUrl?: string): string;
|
|
14
|
+
/** Configured OAuth endpoint followed by canonical fallback, without duplicates. */
|
|
15
|
+
export declare function claudeOAuthBaseUrls(baseUrl?: string): readonly string[];
|
|
16
|
+
/** Resolve a first-party account route against the configured Claude API root. */
|
|
17
|
+
export declare function claudeApiUrl(baseUrl: string | undefined, path: string): string;
|
|
18
|
+
/** Shared OAuth and CLI identity headers for Claude usage, profile, and resets. */
|
|
19
|
+
export declare function buildClaudeOAuthHeaders(accessToken: string, options?: {
|
|
20
|
+
beta?: string;
|
|
21
|
+
json?: boolean;
|
|
22
|
+
}): Record<string, string>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { UsageResetCredit, UsageResetCredits } from "../usage.js";
|
|
2
|
+
import type { FetchImpl } from "../types.js";
|
|
3
|
+
/** OAuth credential and transport used for an account's Claude reset operations. */
|
|
4
|
+
export interface ClaudeResetAuth {
|
|
5
|
+
accessToken: string;
|
|
6
|
+
orgId?: string;
|
|
7
|
+
baseUrl?: string;
|
|
8
|
+
fetch: FetchImpl;
|
|
9
|
+
signal?: AbortSignal;
|
|
10
|
+
}
|
|
11
|
+
/** Live reset eligibility plus the exact organization and host used for redemption. */
|
|
12
|
+
export interface ClaudeResetCreditList extends UsageResetCredits {
|
|
13
|
+
credits: UsageResetCredit[];
|
|
14
|
+
orgId?: string;
|
|
15
|
+
/** OAuth API base that answered discovery; pass back as consume `baseUrl`. */
|
|
16
|
+
baseUrl?: string;
|
|
17
|
+
}
|
|
18
|
+
/** Confirmed reset outcome; transport uncertainty never reports a successful spend. */
|
|
19
|
+
export interface ClaudeResetConsumeResult {
|
|
20
|
+
ok: boolean;
|
|
21
|
+
code: string;
|
|
22
|
+
status: number;
|
|
23
|
+
cleared?: string[];
|
|
24
|
+
reason?: string;
|
|
25
|
+
raw?: unknown;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Reuse program blocks when a normal usage response actually evaluated them.
|
|
29
|
+
* Anthropic lists every promo program as a key on the plain `/usage` body and
|
|
30
|
+
* leaves the value `null` until the matching probe query (`?cedar_ember=1`,
|
|
31
|
+
* `?at_wall=1`) asks for an evaluation, so a `null` block is "unknown", never
|
|
32
|
+
* "no resets". Only an object block is an answer; anything else returns `null`
|
|
33
|
+
* so the caller falls through to {@link listClaudeResetCredits}. A lone
|
|
34
|
+
* non-redeemable Cedar block is likewise inconclusive because Juniper requires
|
|
35
|
+
* the separate at-wall read.
|
|
36
|
+
*
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
export declare function parseClaudeResetCreditsFromUsagePayload(payload: unknown, orgId?: string, baseUrl?: string): ClaudeResetCreditList | null;
|
|
40
|
+
/**
|
|
41
|
+
* Discover Claude's saved Cedar grant first, then its Juniper session reset.
|
|
42
|
+
* `null` means discovery failed; a zero-count object is an authoritative answer.
|
|
43
|
+
*/
|
|
44
|
+
export declare function listClaudeResetCredits(auth: ClaudeResetAuth): Promise<ClaudeResetCreditList | null>;
|
|
45
|
+
/** Spend exactly the server-selected Claude reset. Mutation requests are never retried. */
|
|
46
|
+
export declare function consumeClaudeResetCredit(auth: ClaudeResetAuth & {
|
|
47
|
+
credit: UsageResetCredit;
|
|
48
|
+
redeemRequestId?: string;
|
|
49
|
+
}): Promise<ClaudeResetConsumeResult>;
|
package/dist/types/usage.d.ts
CHANGED
|
@@ -62,11 +62,29 @@ export interface UsageLimit {
|
|
|
62
62
|
* Per-credit detail for a saved/banked rate-limit reset.
|
|
63
63
|
*
|
|
64
64
|
* Populated when the provider's listing endpoint returns individual credit
|
|
65
|
-
* metadata (e.g. OpenAI Codex
|
|
65
|
+
* metadata (e.g. OpenAI Codex credits or Claude Cedar grants). Callers that
|
|
66
66
|
* only need the count can ignore this; display layers use `expiresAt` to show
|
|
67
67
|
* when banked resets expire ([#3339](https://github.com/can1357/oh-my-pi/issues/3339)).
|
|
68
68
|
*/
|
|
69
69
|
export interface UsageResetCreditDetail {
|
|
70
|
+
/** Opaque provider credit/grant identifier. */
|
|
71
|
+
id?: string;
|
|
72
|
+
/** Human-facing name for the reset. */
|
|
73
|
+
title?: string;
|
|
74
|
+
/** Provider reset program/family. */
|
|
75
|
+
program?: string;
|
|
76
|
+
/** Resets still banked in this credit/grant. */
|
|
77
|
+
remainingCount?: number;
|
|
78
|
+
/** Whether the provider says this credit can be redeemed now. */
|
|
79
|
+
usable?: boolean;
|
|
80
|
+
/** Whether redemption requires an exhausted covered limit. */
|
|
81
|
+
requiresLimit?: boolean;
|
|
82
|
+
/** Normalized {@link UsageLimit.id}s this credit resets. */
|
|
83
|
+
clears?: string[];
|
|
84
|
+
/** Normalized limit ids currently preventing redemption. */
|
|
85
|
+
blocking?: string[];
|
|
86
|
+
/** Used fractions for covered limits, keyed by normalized limit id. */
|
|
87
|
+
usedFractions?: Record<string, number>;
|
|
70
88
|
/** ISO timestamp when the credit was granted. */
|
|
71
89
|
grantedAt?: string;
|
|
72
90
|
/** ISO timestamp when the credit expires and can no longer be redeemed. */
|
|
@@ -74,17 +92,31 @@ export interface UsageResetCreditDetail {
|
|
|
74
92
|
/** Backend status, e.g. `available`, `redeemed`. */
|
|
75
93
|
status?: string;
|
|
76
94
|
}
|
|
95
|
+
/** Reset credit carrying the provider id required by its consume endpoint. */
|
|
96
|
+
export interface UsageResetCredit extends UsageResetCreditDetail {
|
|
97
|
+
id: string;
|
|
98
|
+
}
|
|
77
99
|
/**
|
|
78
100
|
* Saved/banked rate-limit resets an account can redeem on demand.
|
|
79
101
|
*
|
|
80
102
|
* Surfaced by providers that let users defer a usage-window reset and spend it
|
|
81
|
-
* later (OpenAI Codex
|
|
82
|
-
* separate, provider-specific action; this is the read-only
|
|
103
|
+
* later (OpenAI Codex and Claude Cedar resets). The redeem itself is a
|
|
104
|
+
* separate, provider-specific action; this is the read-only state for display.
|
|
83
105
|
*/
|
|
84
106
|
export interface UsageResetCredits {
|
|
85
|
-
/** Number of resets
|
|
107
|
+
/** Number of banked resets, including grants that are not currently usable. */
|
|
86
108
|
availableCount: number;
|
|
87
|
-
/**
|
|
109
|
+
/** Number of resets the provider says can be redeemed now. */
|
|
110
|
+
redeemableCount?: number;
|
|
111
|
+
/** Provider-selected credit/grant eligible for the next redemption. */
|
|
112
|
+
nextCreditId?: string;
|
|
113
|
+
/** Whether this account is eligible for the reset program. */
|
|
114
|
+
eligible?: boolean;
|
|
115
|
+
/** Provider reason the program or its credits are unavailable. */
|
|
116
|
+
reason?: string;
|
|
117
|
+
/** ISO timestamp until which redemption is cooling down. */
|
|
118
|
+
cooldownUntil?: string;
|
|
119
|
+
/** Individual credit details (expiry dates, coverage, etc.) when exposed. */
|
|
88
120
|
credits?: UsageResetCreditDetail[];
|
|
89
121
|
}
|
|
90
122
|
/** Aggregated usage report for a provider. */
|
|
@@ -321,28 +353,74 @@ export declare const usageLimitSchema: import("@oh-my-pi/omptype").FluentType<{
|
|
|
321
353
|
} | undefined;
|
|
322
354
|
}>;
|
|
323
355
|
export declare const usageResetCreditDetailSchema: import("@oh-my-pi/omptype").FluentType<{
|
|
356
|
+
blocking?: string[] | undefined;
|
|
357
|
+
clears?: string[] | undefined;
|
|
324
358
|
expiresAt?: string | undefined;
|
|
325
359
|
grantedAt?: string | undefined;
|
|
360
|
+
id?: string | undefined;
|
|
361
|
+
program?: string | undefined;
|
|
362
|
+
remainingCount?: number | undefined;
|
|
363
|
+
requiresLimit?: boolean | undefined;
|
|
326
364
|
status?: string | undefined;
|
|
365
|
+
title?: string | undefined;
|
|
366
|
+
usable?: boolean | undefined;
|
|
367
|
+
usedFractions?: Record<string, number> | undefined;
|
|
327
368
|
}, {
|
|
369
|
+
blocking?: string[] | undefined;
|
|
370
|
+
clears?: string[] | undefined;
|
|
328
371
|
expiresAt?: string | undefined;
|
|
329
372
|
grantedAt?: string | undefined;
|
|
373
|
+
id?: string | undefined;
|
|
374
|
+
program?: string | undefined;
|
|
375
|
+
remainingCount?: number | undefined;
|
|
376
|
+
requiresLimit?: boolean | undefined;
|
|
330
377
|
status?: string | undefined;
|
|
378
|
+
title?: string | undefined;
|
|
379
|
+
usable?: boolean | undefined;
|
|
380
|
+
usedFractions?: Record<string, number> | undefined;
|
|
331
381
|
}>;
|
|
332
382
|
export declare const usageResetCreditsSchema: import("@oh-my-pi/omptype").FluentType<{
|
|
333
383
|
availableCount: number;
|
|
384
|
+
cooldownUntil?: string | undefined;
|
|
334
385
|
credits?: {
|
|
386
|
+
blocking?: string[] | undefined;
|
|
387
|
+
clears?: string[] | undefined;
|
|
335
388
|
expiresAt?: string | undefined;
|
|
336
389
|
grantedAt?: string | undefined;
|
|
390
|
+
id?: string | undefined;
|
|
391
|
+
program?: string | undefined;
|
|
392
|
+
remainingCount?: number | undefined;
|
|
393
|
+
requiresLimit?: boolean | undefined;
|
|
337
394
|
status?: string | undefined;
|
|
395
|
+
title?: string | undefined;
|
|
396
|
+
usable?: boolean | undefined;
|
|
397
|
+
usedFractions?: Record<string, number> | undefined;
|
|
338
398
|
}[] | undefined;
|
|
399
|
+
eligible?: boolean | undefined;
|
|
400
|
+
nextCreditId?: string | undefined;
|
|
401
|
+
reason?: string | undefined;
|
|
402
|
+
redeemableCount?: number | undefined;
|
|
339
403
|
}, {
|
|
340
404
|
availableCount: number;
|
|
405
|
+
cooldownUntil?: string | undefined;
|
|
341
406
|
credits?: {
|
|
407
|
+
blocking?: string[] | undefined;
|
|
408
|
+
clears?: string[] | undefined;
|
|
342
409
|
expiresAt?: string | undefined;
|
|
343
410
|
grantedAt?: string | undefined;
|
|
411
|
+
id?: string | undefined;
|
|
412
|
+
program?: string | undefined;
|
|
413
|
+
remainingCount?: number | undefined;
|
|
414
|
+
requiresLimit?: boolean | undefined;
|
|
344
415
|
status?: string | undefined;
|
|
416
|
+
title?: string | undefined;
|
|
417
|
+
usable?: boolean | undefined;
|
|
418
|
+
usedFractions?: Record<string, number> | undefined;
|
|
345
419
|
}[] | undefined;
|
|
420
|
+
eligible?: boolean | undefined;
|
|
421
|
+
nextCreditId?: string | undefined;
|
|
422
|
+
reason?: string | undefined;
|
|
423
|
+
redeemableCount?: number | undefined;
|
|
346
424
|
}>;
|
|
347
425
|
export declare const usageReportSchema: import("@oh-my-pi/omptype").FluentType<{
|
|
348
426
|
fetchedAt: number;
|
|
@@ -384,11 +462,25 @@ export declare const usageReportSchema: import("@oh-my-pi/omptype").FluentType<{
|
|
|
384
462
|
raw?: unknown;
|
|
385
463
|
resetCredits?: {
|
|
386
464
|
availableCount: number;
|
|
465
|
+
cooldownUntil?: string | undefined;
|
|
387
466
|
credits?: {
|
|
467
|
+
blocking?: string[] | undefined;
|
|
468
|
+
clears?: string[] | undefined;
|
|
388
469
|
expiresAt?: string | undefined;
|
|
389
470
|
grantedAt?: string | undefined;
|
|
471
|
+
id?: string | undefined;
|
|
472
|
+
program?: string | undefined;
|
|
473
|
+
remainingCount?: number | undefined;
|
|
474
|
+
requiresLimit?: boolean | undefined;
|
|
390
475
|
status?: string | undefined;
|
|
476
|
+
title?: string | undefined;
|
|
477
|
+
usable?: boolean | undefined;
|
|
478
|
+
usedFractions?: Record<string, number> | undefined;
|
|
391
479
|
}[] | undefined;
|
|
480
|
+
eligible?: boolean | undefined;
|
|
481
|
+
nextCreditId?: string | undefined;
|
|
482
|
+
reason?: string | undefined;
|
|
483
|
+
redeemableCount?: number | undefined;
|
|
392
484
|
} | undefined;
|
|
393
485
|
}, {
|
|
394
486
|
fetchedAt: number;
|
|
@@ -430,11 +522,25 @@ export declare const usageReportSchema: import("@oh-my-pi/omptype").FluentType<{
|
|
|
430
522
|
raw?: unknown;
|
|
431
523
|
resetCredits?: {
|
|
432
524
|
availableCount: number;
|
|
525
|
+
cooldownUntil?: string | undefined;
|
|
433
526
|
credits?: {
|
|
527
|
+
blocking?: string[] | undefined;
|
|
528
|
+
clears?: string[] | undefined;
|
|
434
529
|
expiresAt?: string | undefined;
|
|
435
530
|
grantedAt?: string | undefined;
|
|
531
|
+
id?: string | undefined;
|
|
532
|
+
program?: string | undefined;
|
|
533
|
+
remainingCount?: number | undefined;
|
|
534
|
+
requiresLimit?: boolean | undefined;
|
|
436
535
|
status?: string | undefined;
|
|
536
|
+
title?: string | undefined;
|
|
537
|
+
usable?: boolean | undefined;
|
|
538
|
+
usedFractions?: Record<string, number> | undefined;
|
|
437
539
|
}[] | undefined;
|
|
540
|
+
eligible?: boolean | undefined;
|
|
541
|
+
nextCreditId?: string | undefined;
|
|
542
|
+
reason?: string | undefined;
|
|
543
|
+
redeemableCount?: number | undefined;
|
|
438
544
|
} | undefined;
|
|
439
545
|
}>;
|
|
440
546
|
/** Optional logger for usage fetchers. */
|
|
@@ -16,7 +16,10 @@ export interface JsonSchemaValidationResult {
|
|
|
16
16
|
success: boolean;
|
|
17
17
|
issues: JsonSchemaValidationIssue[];
|
|
18
18
|
}
|
|
19
|
+
/** The unique discriminator-selected branch, or undefined when selection is ambiguous or absent. */
|
|
20
|
+
export declare function getTagSelectedUnionBranch(branches: readonly unknown[], value: unknown): unknown;
|
|
19
21
|
/** Whether any same-instance schema declaration or constraint owns this property name. */
|
|
20
22
|
export declare function schemaDefinesProperty(schema: unknown, key: string): boolean;
|
|
21
|
-
export declare function validateJsonSchemaValue(schema: unknown, value: unknown): JsonSchemaValidationResult;
|
|
22
|
-
|
|
23
|
+
export declare function validateJsonSchemaValue(schema: unknown, value: unknown, root?: unknown): JsonSchemaValidationResult;
|
|
24
|
+
/** Validate a subschema using its complete schema's local-reference context. */
|
|
25
|
+
export declare function isJsonSchemaValueValid(schema: unknown, value: unknown, root?: unknown): boolean;
|
|
@@ -21,6 +21,6 @@ export interface RepeatedToolCallDetection {
|
|
|
21
21
|
export declare class ToolCallLoopGuard {
|
|
22
22
|
#private;
|
|
23
23
|
constructor(options: ToolCallLoopGuardOptions);
|
|
24
|
-
/** Records one completed turn and
|
|
24
|
+
/** Records one completed turn and reports repetitions at or beyond the threshold. */
|
|
25
25
|
recordTurn(turn: ToolCallLoopTurn): RepeatedToolCallDetection | null;
|
|
26
26
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-ai",
|
|
3
|
-
"version": "18.2.
|
|
3
|
+
"version": "18.2.10",
|
|
4
4
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -152,11 +152,11 @@
|
|
|
152
152
|
"fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
|
|
153
153
|
},
|
|
154
154
|
"dependencies": {
|
|
155
|
-
"@oh-my-pi/omptype": "18.2.
|
|
156
|
-
"@oh-my-pi/pi-catalog": "18.2.
|
|
157
|
-
"@oh-my-pi/pi-natives": "18.2.
|
|
158
|
-
"@oh-my-pi/pi-utils": "18.2.
|
|
159
|
-
"@oh-my-pi/pi-wire": "18.2.
|
|
155
|
+
"@oh-my-pi/omptype": "18.2.10",
|
|
156
|
+
"@oh-my-pi/pi-catalog": "18.2.10",
|
|
157
|
+
"@oh-my-pi/pi-natives": "18.2.10",
|
|
158
|
+
"@oh-my-pi/pi-utils": "18.2.10",
|
|
159
|
+
"@oh-my-pi/pi-wire": "18.2.10"
|
|
160
160
|
},
|
|
161
161
|
"devDependencies": {
|
|
162
162
|
"@types/bun": "^1.3.14"
|